feat(cli): path resume takes --remote and plans a Claude resume on an ssh host - #244
Draft
ecalifornica wants to merge 2 commits into
Draft
Conversation
|
🔍 Preview deployed: https://59cc246b.toolpath.pages.dev |
ecalifornica
force-pushed
the
ecalifornica/ssh-transport
branch
2 times, most recently
from
August 26, 2026 19:57
c7fd8c9 to
b17f788
Compare
ecalifornica
force-pushed
the
ecalifornica/ssh-transport
branch
from
August 28, 2026 21:11
884541b to
3265e87
Compare
ecalifornica
changed the base branch from
main
to
ecalifornica/export-claude-derive-session-id
August 28, 2026 21:11
ecalifornica
force-pushed
the
ecalifornica/ssh-transport
branch
from
August 28, 2026 22:59
3265e87 to
198f3e5
Compare
ecalifornica
force-pushed
the
ecalifornica/ssh-transport
branch
from
August 28, 2026 23:40
198f3e5 to
e664212
Compare
`ssh.rs` runs commands on a remote host through an in-process SSH client (`russh`). The destination is `user@host`; the port is 22. The caller passes the agent socket and the ssh directory; the module reads no environment variable. The agent authenticates first, then the default identity files in the ssh directory; an encrypted file is skipped with a hint. `known_hosts` in that directory verifies the host key: a changed key is an error, and an unknown host is learned on first contact with a notice (accept-new). `Transport::run` opens one exec channel per call: one task feeds stdin while another collects stdout, stderr, and the exit status, all under the caller's wall-clock timeout; on expiry the connection drops and the error carries the stderr received so far. Connect, handshake, and authentication share a 30s bound. Keepalives are on every session. `RemoteCommand` is the only way to build the string the exec request carries. `new` is an argv. `script` is a constant `sh` script that reads its values as positional parameters; the text is `&'static str`, so a value cannot be interpolated into shell text. Every word is quoted through shlex. `Destination` requires `user@host`; each side starts alphanumeric and continues with `[A-Za-z0-9._-]`. `parse_facts` reads `TP_<NAME>=<value>` lines and rejects any other shape, so a login banner cannot become a path component. `FakeSsh` scripts replies and records rendered commands for tests. Quoting and scripts are tested against a real `sh`; the live test (`--ignored`, `PATH_TEST_SSH_DEST`) exercises run, stdin, stderr, the exit status, and the timeout against a real host. The module and its dependencies `russh` and `shlex` compile only with the `resume-remote` cargo feature. The module has no caller in this commit, so `lib.rs` allows dead code on it. No version bump: the dependencies become user-visible with the command that consumes the module.
… ssh host `path resume <input> --remote <user@host> [-C <dir>] [--dry-run]` plans a resume on an ssh host without touching it. Claude only. Two read-only ssh calls through the transport module gather the facts: - Call 1: the remote home, the claude path (PATH, then ~/.local/bin, ~/.claude/local, ~/.npm-global/bin), tmux presence. The remote project directory is `-C`, else the local cwd with the local home swapped for the remote home. - Call 2: the directory is physical (`pwd -P` returns it), the tmux session for the derived ID is live, the target session file exists. The plan prints the facts and what a run does: a live tmux session is attached to, a present session file is launched, an absent file is shipped. `--dry-run` exits after the plan. Without it the command errors: ship, launch, and attach are not implemented yet. The session ID comes from `session_id_from_document_hash` and `-C` follows `parse_cwd_arg`, both shared with `p export claude`; they move from `cmd_export` to the new `claude_session` module, the owner both commands import from. `resolve_input` returns a `ResolvedInput` carrying the document text next to the parsed graph, so the ID hashes the input bytes rather than a type round-trip. The tmux session name is `path-<first 8 of the ID>`. The probe scripts are `probe_host.sh` and `probe_project_dir.sh` next to the module, included with `include_str!`. They print `TP_<NAME>=<value>` lines and the parser rejects any other output, so a login banner cannot become a path component. A captured path must be a non-empty single line starting with `/`. A non-physical directory errors with the physical path as a `-C` hint. Remote paths are joined with `/`: `remote_slug_dir` takes only the slug component from `PathResolver`, and the `-C` default joins the cwd's components with `/`, so a Windows local host produces the same remote paths as a Unix one. Tests drive the command through the scripted fake transport; nothing is public for tests. The flags and the planner compile only with the `resume-remote` cargo feature, and `ResumeArgs` derives `Default`. `run_with_strategy` reads `SSH_AUTH_SOCK` and the home directory and hands them to the transport. toolpath-claude 0.13.3 (sanitize_project_path is public); path-cli 0.21.0; toolpath-cli 0.21.0 (lockstep bump of the shim).
ecalifornica
force-pushed
the
ecalifornica/ssh-transport
branch
from
August 29, 2026 00:35
e664212 to
4cb7400
Compare
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.
path resumetakes--remote <user@host>, behind theresume-remotefeature, and plans a Claude resume on that host. Next PRs in the stack add ship, launch, attach.Three new modules:
ssh.rs: the transport, an in-process SSH client on therusshdependency.cmd_resume/remote.rs: the resume. It reads the host state and decides between attach, launch, and ship.claude_session.rs: the session ID derivation and remote project directory rules, whichp export claudeandpath resume --remoteboth use with the addition of the remote resume.toolpath-claude 0.13.3, path-cli 0.21.0, toolpath-cli 0.21.0. Stacked on #241.