aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-06 05:55:29 -0500
committerCraig Jennings <c@cjennings.net>2026-06-06 05:55:29 -0500
commit5e956a8a2e76122c42c5dc7ecbb4180b8340497e (patch)
treedeea061e8cea45f31da97f8021bc243c0e7fdff4
downloadduet-5e956a8a2e76122c42c5dc7ecbb4180b8340497e.tar.gz
duet-5e956a8a2e76122c42c5dc7ecbb4180b8340497e.zip
chore: scaffold the Duet package skeleton
Initial skeleton for Duet, a two-pane file commander built on dirvish/dired: the package header and entry-command stub, the README, and the test directory. Pre-alpha — no functionality yet.
-rw-r--r--.gitignore22
-rw-r--r--README.org58
-rw-r--r--duet.el48
-rw-r--r--tests/.gitkeep0
4 files changed, 128 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a6b2d71
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+# Build artifacts
+*.elc
+*.eln
+/.eldev/
+/eln-cache/
+
+# Emacs cruft
+*~
+\#*\#
+.\#*
+
+# Coverage / test output
+/coverage/
+/.coverage/
+
+# Local planning + AI tooling (kept out of the public repo).
+# The design spec carries multi-round review history with contributor
+# attribution; track it publicly only after anonymizing to roles.
+/.ai/
+/inbox/
+/todo.org
+/docs/design/
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..c803d6d
--- /dev/null
+++ b/README.org
@@ -0,0 +1,58 @@
+#+TITLE: DUET — Dual-Pane File Commander for Emacs
+
+DUET is a two-pane orthodox file manager (Midnight Commander / FileZilla
+style) built on dirvish/dired. Two dired panes each show any location —
+local or remote — and single-key actions on the file under point use the
+opposite pane as the implied target: copy, move, delete, open. The name is
+recursive: *DUET Unifies Endpoint Trees*.
+
+*Status: pre-alpha.* The interaction model and architecture are designed;
+implementation is staged (below). This repository is the skeleton.
+
+* Why DUET
+
+Two dirvish windows already approximate the basics. DUET's durable value is
+transport reach and a community-extensible backend interface — moving files
+dired cannot, through one consistent two-pane UX.
+
+* The transport quartet
+
+DUET ships four transfer utilities as backends, over TRAMP as the
+Emacs-native substrate. They do not overlap:
+
+- *rsync* — Unix-to-Unix and local. Block-level delta-transfer, zero remote
+ install, faithful Unix metadata. The default for an ssh-reachable host.
+- *rclone* — cloud and object stores plus the long protocol tail (S3, B2,
+ GDrive, WebDAV, ...). The reach rsync lacks.
+- *lftp* — FTP/FTPS/HTTP with mirroring, parallel transfers, queueing.
+- *unison* — bidirectional, conflict-aware reconciliation.
+
+One line: rclone is breadth, rsync is depth.
+
+* Roadmap
+
+- *Stage 1* — core commander: two-pane UX, connection wizard, rsync + TRAMP
+ transport, copy/move/delete/open, the keybinding scheme.
+- *Stage 2* — the backend registry plus rclone and lftp. The differentiator.
+- *Stage 3* — directory diff and bidirectional sync (ediff for files;
+ unison / rclone bisync for trees).
+
+* Extending DUET
+
+Transports are pluggable. A backend registers via =duet-register-backend=
+with:
+
+- a *name*;
+- a *handles* predicate =(lambda (src dst) ...)= returning a numeric score
+ (lower preferred) or nil if it cannot handle the endpoint pair;
+- a *command* builder =(lambda (src dst opts) ...)= returning a process spec;
+- *capability* flags: =:async :resume :bidirectional :progress=.
+
+=duet--transfer-spec= asks every registered backend to score an endpoint
+pair and picks the lowest-cost handler. The built-in backends register
+through this same API, so third parties add transports (unison, git-annex,
+or anything else) without patching core.
+
+* License
+
+GPL-3.0-or-later.
diff --git a/duet.el b/duet.el
new file mode 100644
index 0000000..364a7c4
--- /dev/null
+++ b/duet.el
@@ -0,0 +1,48 @@
+;;; duet.el --- Dual-pane file commander over dirvish/dired -*- lexical-binding: t -*-
+
+;; Author: Craig Jennings <c@cjennings.net>
+;; URL: https://github.com/cjennings/duet
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: files, tools, convenience
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;;; Commentary:
+
+;; DUET — "DUET Unifies Endpoint Trees" — is a two-pane orthodox file
+;; manager (Midnight Commander / FileZilla style) built on dirvish/dired.
+;; Two dired panes show any location, local or remote; single-key actions
+;; on the file under point use the opposite pane as the implied target.
+;;
+;; Transfers route through a pluggable backend registry: rsync for
+;; Unix-to-Unix (delta-transfer, faithful metadata, zero remote install),
+;; rclone for cloud and the long protocol tail, lftp for FTP/FTPS/HTTP, and
+;; unison for bidirectional sync. TRAMP is the universal substrate.
+;;
+;; dirvish is recommended as the renderer but not required; DUET degrades to
+;; plain dired.
+;;
+;; STATUS: pre-alpha skeleton. See the design document for the full plan and
+;; the staged roadmap.
+
+;;; Code:
+
+(defgroup duet nil
+ "Dual-pane file commander over dirvish/dired."
+ :group 'files
+ :prefix "duet-")
+
+;;;###autoload
+(defun duet ()
+ "Launch the DUET dual-pane file commander."
+ (interactive)
+ (user-error "DUET is not yet implemented — see the design document"))
+
+(provide 'duet)
+;;; duet.el ends here
diff --git a/tests/.gitkeep b/tests/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/.gitkeep