aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-07 22:09:15 -0500
committerCraig Jennings <c@cjennings.net>2026-05-07 22:09:15 -0500
commit1d93e1a6569e4193c2b078a3d5df0bf47eeba9df (patch)
treed2a7854143ece485f60da53a466c3508f79829e1 /docs
parenta41ef9774f6550da446a3ae8fbbcbcd5bf6c23c4 (diff)
downloaddotemacs-1d93e1a6569e4193c2b078a3d5df0bf47eeba9df.tar.gz
dotemacs-1d93e1a6569e4193c2b078a3d5df0bf47eeba9df.zip
fix(ai-vterm): direction-based display + per-project tmux session names
Two post-ship issues blocked practical use of the new launcher. The display rule used `display-buffer-in-side-window` with `(dedicated . t)`. Side-window dedication caused `set-window-buffer` to error during `buffer-move` (C-M-arrows), which left a half-finished swap with both sides showing the claude buffer. Then `switch-to-buffer` on a non-claude buffer in that dedicated window split instead of replacing. I rewrote the rule as `display-buffer-reuse-window -> display-buffer-use-some-window -> display-buffer-in-direction (right)`. The resulting window is ordinary, not dedicated, so swap and replace work normally. I also narrowed `vterm-toggle`'s broad lambda (which matches any vterm-mode buffer) to exclude `claude [` buffers. Otherwise vterm-toggle's `:defer` made it install last and capture our buffers first with its own bottom-split + dedicated treatment. The tmux side: vterm's auto-launch hook ran a bare `tmux\n`, so each session got an auto-named one. After an Emacs crash the tmux session would survive but I couldn't find it. A second F9 just spawned another. The launcher now sends `tmux new-session -A -s <basename> -c <dir> '<claude>; exec bash'`. The `-A` reattaches to a same-named session if it already exists. The `exec bash` keeps the tmux window alive if claude itself exits. A `cj/--ai-vterm-suppress-tmux` flag tells the existing vterm hook to skip its bare tmux step so the named launch runs instead. 11 new tests across 2 files cover the session-name and launch-command helpers. I updated tests for show-or-create and the display rule. All 34 ai-vterm tests are green.
Diffstat (limited to 'docs')
-rw-r--r--docs/design/ai-vterm.org15
1 files changed, 14 insertions, 1 deletions
diff --git a/docs/design/ai-vterm.org b/docs/design/ai-vterm.org
index 62bafbc8..99526b63 100644
--- a/docs/design/ai-vterm.org
+++ b/docs/design/ai-vterm.org
@@ -106,9 +106,22 @@ After this, all navigation is handled by existing global bindings: Shift-arrows
| Side-window already showing a different =claude [...]= | =display-buffer= swaps which buffer occupies the slot; hidden one keeps running |
| =vterm= not installed | Module fails to load loudly (no graceful degradation) |
+** Per-project tmux sessions
+
+The launch command sent to a fresh AI-vterm shell is
+
+#+begin_example
+tmux new-session -A -s <basename> -c <dir> '<claude-cmd>; exec bash'
+#+end_example
+
+- =-A= reattaches to an existing session of the same name instead of creating a new one. So a second F9 on the same project after an Emacs crash brings the running Claude back without spawning a duplicate.
+- =-s <basename>= names the session after the project's directory basename. =tmux ls= shows the active sessions by project name.
+- =-c <dir>= sets the start directory for new sessions (ignored on attach).
+- =exec bash= tails the shell command so the tmux window survives Claude exiting -- the session stays alive with a bare prompt for recovery, and reattach is unaffected.
+
** Tmux Auto-Launch Suppression
-Existing =cj/vterm-launch-tmux= on =vterm-mode-hook= types =tmux\n= unconditionally. AI vterms set a buffer-local =cj/--ai-vterm-suppress-tmux= flag before =(vterm)=; the hook checks the flag and skips tmux when set.
+The existing =cj/vterm-launch-tmux= on =vterm-mode-hook= types =tmux\n= unconditionally for any vterm buffer. AI-vterm =let='s a dynamic =cj/--ai-vterm-suppress-tmux= flag around =(vterm)= so the hook skips its bare =tmux\n= and the project-named launch command (above) runs instead.
** Testing