mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 08:29:42 +02:00
COD-108 auto-reconnect remote tmux sessions on SSH drop
Continuous remote-only reconnect watcher closing the COD-104 durability arc: when a remote session's local ssh pane dies mid-run, re-establish it automatically instead of leaving a dead pane until the user pokes it. Design decisions (per cod108 design doc): - D1 event->owner: TmuxManager watcher DETECTS a dead remote pane and emits `remoteSessionDropped`; the session owner (server) reassembles the same RespawnPaneOptions and calls Session.reattachRemote() -> respawnPane, which re-runs the idempotent remote command (owned new-session -A / non-owned attach) and REJOINS the still-running durable remote tmux session. The watcher never reassembles options itself, and never routes through the Claude-idle respawn-controller. - D2 bounded backoff: per-session exponential backoff [5s,15s,45s,2m,5m,5m], reset on a successful reattach, `remoteReconnectExhausted` emitted once after the cap. Pure, unit-tested schedule + eligibility decision. - D3 always-on + kill-switch: `remoteAutoReconnect` app setting (default ON), read each tick; when false the watcher does nothing. Guards: killSession() (incl. the non-owned DETACH early-return) and shutdown add the session to an intentional-teardown guard set + clear its backoff BEFORE teardown, so a closed/killed tab is never auto-revived. Exactly one reconnect in flight per session (inFlight guard prevents stacked respawns). Per-session reconnect/guard state cleared on session removal. New: src/remote-reconnect.ts (pure backoff + decideReconnect), TmuxManager startRemoteReconnectWatcher/stop + runRemoteReconnectTick + noteRemoteReconnect + guardRemoteReconnect + clearRemoteReconnectState; Session.reattachRemote() (+ extracted _buildRespawnPaneOptions, shared with interactive start); server wiring + watcher start; 3 SSE events (sse-events.ts + constants.js in sync, broadcast + app.js exhausted "Reconnect" affordance); remoteAutoReconnect schema + settings-ui toggle. Tests: test/remote-auto-reconnect.test.ts (21) - pure schedule, eligibility (guarded never reconnects, non-remote/pane-alive/not-due skip, over-cap exhaust), and manager-level integration (dead remote pane -> dropped -> backoff -> exhausted; guarded emits nothing; reset-on-success; kill-switch off; state-cleared-on-remove). Verified real-remote against aa-desktop: drop local ssh pane -> watcher emitted -> respawnPane reattached the SAME remote session (remote pane_pid unchanged 3939->3939); test session cleaned up, the real host sessions left untouched. Checks: tsc, eslint, check:frontend-syntax, check:public-assets, prettier --check, build all green; tmux-manager/session-routes/session-manager/ sse-registry-parity suites pass. (cherry picked from commit d13d58b1994eb6594fd2eadea208104d36204f9d)
This commit is contained in:
@@ -1471,6 +1471,14 @@
|
||||
</label>
|
||||
<span class="form-hint">Use 1M token context window (model: opus[1m]) for all new sessions — ignored when a Claude Model is selected above</span>
|
||||
</div>
|
||||
<div class="form-row form-row-switch">
|
||||
<label>Remote auto-reconnect</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="appSettingsRemoteAutoReconnect">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span class="form-hint">Automatically re-establish remote (SSH) sessions when the connection drops, reattaching to the durable remote tmux session (on by default; bounded backoff)</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Thinking Effort</label>
|
||||
<select id="appSettingsThinkingEffort" class="form-select">
|
||||
|
||||
Reference in New Issue
Block a user