Add remote SSH sessions (Phase 2): index, search & resume past sessions - #77
Closed
HAN-oQo wants to merge 2 commits into
Closed
Add remote SSH sessions (Phase 2): index, search & resume past sessions#77HAN-oQo wants to merge 2 commits into
HAN-oQo wants to merge 2 commits into
Conversation
Run Claude Code and shells on remote hosts over SSH. Remote hosts and directories are first-class projects alongside local ones — no local-only assumption anymore. - shell-profiles + remote-hosts: SSH shell profiles (mirrors the existing WSL wrapped-command pattern), ~/.ssh/config parsing, remote command assembly (single-quoted to survive ssh's argv re-parse), ControlMaster multiplexing. - main.js: open-terminal remote branch (skips local-path checks, local cwd=$HOME, no MCP/shim), plus IPC for remote projects, interactive connect, remote dir browse, host save/test, and write-to-~/.ssh/config. - session-cache: persisted remote projects injected into the sidebar; live remote sessions group under them (remote Claude reads as a Claude session). - renderer: Add Project (Local | Remote SSH) with "+ Add new host", inline Connect with structured password / host-key popups (no raw terminal), remote directory browser, host management in Settings, SSH badges. - 30 unit tests (node --test). Auth stays with the user: passwords/passphrases/passkeys/host-key confirmations are entered by the user; nothing is stored. Remote session indexing/search (Phase 2), fork/resume on the remote (Phase 3), and IDE-over-SSH (Phase 4) are deferred — see the PR description. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Builds on Phase 1 (doctly#76). Remote sessions previously appeared in the sidebar only while live; this indexes a connected host's PAST sessions so they persist, are searchable, and resume in a terminal — with no transcript copied to local disk. - read-session-file: extract pure parseSessionContent(content, meta), shared by local and remote indexing (identical summary/title/search behavior). - remote-index (new): metadata-over-SSH sync over the live ControlMaster socket. Lists a host's ~/.claude/projects/*.jsonl, auto-discovers a remote project per session from its cwd (ssh://<label>/<dir>), fetches only new/changed transcripts (length-framed stream), parses in memory, upserts cache + FTS tagged source=host, prunes vanished sessions. Pure helpers are unit-tested. - db: add `source` column to session_cache + search_map (NULL = local; additive migration, no cache wipe). Source-scoped queries isolate local vs remote rows. DB path overridable via env for tests. - main: sync-remote-host IPC + runRemoteSync; triggers on connect, manual refresh, remote-session exit, and a background sweep at startup (status surfaced to the status bar). read-session-jsonl streams remote transcripts live over SSH (View messages) with a needsConnect fallback. remove-project drops a remote project's indexed rows. - Click-to-resume parity: a remote session resumes in a terminal via `cd <dir> && claude --resume "<id>"` on the host (fork supported); the resume dir is derived from the ssh:// projectPath. Remote Control reconnects automatically on resume when the session had it. - sidebar/app: past remote sessions show the SSH badge + Claude logo; a refresh (⟳) control on remote project headers. - test: run under Electron's node (matches the app's better-sqlite3 ABI). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Superseded by #78, which combines remote-SSH Phase 1–3 into a single PR for easier review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 2 of remote SSH support. Phase 1 (#76) let you launch Claude/shell on remote hosts, but remote sessions appeared in the sidebar only while live. This PR indexes a connected host's past sessions so they persist across restarts, are searchable, and resume in a terminal — reaching local parity. No transcript is copied to your local disk; everything is read on demand over the existing SSH connection.
Past remote sessions now persist in the sidebar — grouped by remote directory, each with the SSH badge, the Claude logo, and a ⟳ refresh control (local projects, e.g.
dev/webapp, have neither):Full-text search covers remote transcripts too — here
memorymatches two remote sessions by their synced content, not just titles:What's new
ssh://<host>/<dir>). No per-directory registration needed.sourcecolumn) and show up in search alongside local ones.cd <dir> && claude --resume "<id>"on the host), same UX as local. Fork supported. Remote Control reconnects automatically on resume when the session had it.How it works
remote-index.js). Lists~/.claude/projects/*.jsonl, derives a project per session from itscwd, fetches only new/changed transcripts via a length-framed stream, parses them in memory with the sharedparseSessionContent(extracted fromread-session-file.js, identical to local behavior), and upserts into the cache + FTS withsource = <host>. Vanished sessions are pruned.sourcecolumn tosession_cacheandsearch_map(NULL= local — no cache wipe). All folder-scoped queries are source-isolated so local and remote rows never collide.Testing
npm test, run under Electron's node to match the app'sbetter-sqlite3ABI): JSONL parsing, the SSH listing/framing/diff/cwd parsers, thesourcemigration + source-isolation, sync orchestration (SSH runners injected), and sidebar grouping.sourcebackfilled to local).Roadmap
Remote SSH support ships in phases, ordered by effort‑to‑value — each is independently useful and lands as its own PR. This PR is Phase 2.
~/.ssh/config).sourcecolumn to the cache/search tables.ssh -R) so remote proposed diffs / file opens land in Switchboard's side panel (behind a setting).Why this order: Phase 1 delivers the core "run Claude Code on my server" value with the least new machinery (reuses the
node‑pty+ shell‑profile path, mirroring how WSL is modeled); Phase 2 unlocks history, search, and resume; Phase 3 adds richer IDE workflows. Nothing later blocks shipping this one.(Remote Control —
claude --remote-controlfor live cross-device mirroring — is orthogonal to local-vs-remote and is tracked separately, not part of this roadmap.)🤖 Generated with Claude Code