From 351e09c0fc5174dd779969ef746324cd1bceb814 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Date: Sat, 3 Oct 2026 10:34:54 +0200 Subject: [PATCH 1/2] (remote): launch a session on a host inside tmux (#218, #222) Starts claude --session-id in a new detached tmux session on a declared host, after checking the directory, tmux and claude exist, then attaches to the created pane through the existing attach adapter. The launch tier is available with tmux, and the project's + opens a directory and permission dialog on such a host. Refs #218 Refs #222 --- .ai/contexts/session-cache.md | 14 +- CHANGELOG.md | 1 + docs/remote-hosts.md | 38 ++- eslint.config.js | 2 + main.js | 61 +++- preload.js | 1 + public/app.js | 45 +++ public/dialogs.js | 101 +++++++ public/sidebar.js | 19 +- public/style.css | 6 + remote-host-profile.js | 12 +- remote-launch.js | 159 +++++++++++ ...ate-remote-attachable-local-status.test.js | 2 +- test/dom-remote-launch.test.js | 179 ++++++++++++ test/dom-setup.js | 1 + test/dom-sidebar-remote-tier-gates.test.js | 35 ++- test/remote-host-profile.test.js | 35 ++- test/remote-index.test.js | 2 +- test/remote-launch.test.js | 264 ++++++++++++++++++ 19 files changed, 937 insertions(+), 40 deletions(-) create mode 100644 remote-launch.js create mode 100644 test/dom-remote-launch.test.js create mode 100644 test/remote-launch.test.js diff --git a/.ai/contexts/session-cache.md b/.ai/contexts/session-cache.md index af8777a1..ebb7cf14 100644 --- a/.ai/contexts/session-cache.md +++ b/.ai/contexts/session-cache.md @@ -794,7 +794,7 @@ also returns `blocked` (why nothing could be read, or null) and the normalised ` - `liveness`: at least one live descriptor. `inject`: a live descriptor with a `messagingSocketPath` that is a POSIX absolute path. `attach`: a live descriptor naming a tmux pane with a valid pid (the adapter's own test). The tiers are independent requirements: the reported tier is the highest available one, not the highest contiguous one. -- `launch` is never available: starting a session from here is not implemented. +- `launch`: available under the same rule as attach (probe `tmux: true`, or a live descriptor naming a tmux pane, and not `tmux: false`); its reason otherwise starts with "needs tmux on the host". See "Remote hosts — launching a session". - A tier that needs a live session reads as missing on an idle host; that is "nothing to read it from", not "unsupported". - `annotateRemoteAttachable` (main.js) puts the profile on the project (`remoteHostProfile`). After 3 consecutive failed cycles (`attachBlockReason`), it sets `remoteAttachable: false` plus `remoteAttachBlocked` (the last error) on the @@ -828,6 +828,18 @@ also returns `blocked` (why nothing could be read, or null) and the normalised ` `session.remoteSendBlocked` disables the button with the reason in its title. - Stop has no gate (`test/annotate-remote-tier-gates.test.js` and `test/dom-sidebar-remote-tier-gates.test.js` pin it). +## Remote hosts — launching a session (issues #218, #222) + +`remote-launch.js` builds the one ssh command and orchestrates launch then attach; the renderer side is `showRemoteLaunchDialog` (dialogs.js) and `launchRemoteSession` (app.js), the IPC is `remote-launch-session`. + +- **The command is `sh -c '