Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
39289f2
docs: design `path resume` command
akesling May 8, 2026
c02c1c7
docs: implementation plan for path resume command
akesling May 8, 2026
67cb708
docs: revise path resume design — drop ResumeRecipe
akesling May 8, 2026
1f2c9d2
feat(path-cli): pub(crate) project_<harness> wrappers in cmd_export
akesling May 8, 2026
0bc50f9
test(path-cli): tighten project_opencode test, restore XDG_DATA_HOME
akesling May 8, 2026
89ae5d0
refactor(path-cli): extract pathbase_fetch_to_doc helper
akesling May 8, 2026
8a8d8ac
feat(path-cli): scaffold path resume command (stub)
akesling May 8, 2026
9b05089
feat(path-cli): infer_source_harness and ensure_path_with_agent
akesling May 8, 2026
8f4f741
feat(path-cli): resolve_input dispatcher for path resume
akesling May 8, 2026
8b7943c
feat(path-cli): harness picker + PATH probe for path resume
akesling May 8, 2026
d0b6718
fix(path-cli): always invoke picker when --harness is unset
akesling May 8, 2026
b8d5d22
feat(path-cli): argv_for + project_into_harness dispatcher
akesling May 8, 2026
36c0d1e
feat(path-cli): ExecStrategy with RealExec/RecordingExec
akesling May 8, 2026
b97c243
feat(path-cli): wire path resume orchestration end-to-end
akesling May 8, 2026
180a651
test(path-cli): isolate path resume orchestration test from env races
akesling May 9, 2026
8408377
fix(path-cli): eliminate HOME/XDG races in path-cli test suite
akesling May 9, 2026
0fa8974
test(path-cli): integration tests for path resume
akesling May 9, 2026
af41a99
docs: document path resume command
akesling May 9, 2026
bfbbf1e
chore: bump path-cli and toolpath-cli to 0.9.0 for path resume
akesling May 9, 2026
b34b4d1
chore: clippy nit fix and post-rebase test count
akesling May 9, 2026
ef9c31c
fix(path-cli): reuse cached pathbase doc on path resume cache hit
akesling May 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

All notable changes to the Toolpath workspace are documented here.

## `path resume` — one-shot resume into a coding agent — 2026-05-09

`path-cli` 0.9.0. New subcommand `path resume <input>` that fetches a
Toolpath document (Pathbase URL, `owner/repo/slug` shorthand, local
file, or cache id), validates it as a single agent-bearing `Path`,
launches an `fzf` picker over installed coding-agent harnesses
(`--harness X` skips the picker), projects the session into that
harness's on-disk layout under `-C, --cwd P` (default: shell cwd),
and `execvp`'s the harness's resume command (`claude -r <id>`,
`gemini --resume <id>`, `codex resume <id>`, `opencode --session <id>`,
`pi --session <id>`). On Windows the harness is spawned and waited on
with the exit code propagated.

Source-harness inference reads `path.meta.source` (`claude-code` /
`gemini-cli` / `codex` / `opencode` / `pi`) with actor-string
fallback; the picker pre-selects the source when it's installed.

Implementation introduces five `pub(crate)` `project_<harness>`
helpers in `cmd_export.rs` that compose the existing build + write
pairs and return the projected session id. `cmd_resume.rs` adds an
`ExecStrategy` trait (`RealExec` for production, `RecordingExec` for
tests) so the integration tests can exercise the full
resolve→pick→project pipeline without launching a real harness.

Also fixed an unrelated env-var race in
`cmd_export::tests::opencode_writes_into_db_with_project` that
cleared `$HOME` on cleanup without restoring; this had been quietly
flaking the parallel test suite.

## Conversation-stack realignment onto `toolpath` 0.4 + path-cli schema vendoring

Republish of every `toolpath-convo`-consuming crate so they pin the
Expand Down
7 changes: 6 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ cargo run -p path-cli -- share
cargo run -p path-cli -- share --harness claude --session <session-id> --project /path/to/project
cargo run -p path-cli -- share --url https://my-pathbase.example

# Resume a Toolpath document into your coding agent of choice (interactive harness picker)
cargo run -p path-cli -- resume <pathbase-url-or-shorthand-or-file-or-cache-id>
cargo run -p path-cli -- resume <input> --harness claude -C /path/to/project

# Export toolpath documents into external formats. <ref> is a cache id or a file path.
cargo run -p path-cli -- export claude --input <ref> --project /tmp/sandbox
cargo run -p path-cli -- export claude --input <ref> --output conv.jsonl
Expand Down Expand Up @@ -161,7 +165,7 @@ Tests live alongside the code (`#[cfg(test)] mod tests`), plus `path-cli` has in
- `toolpath-opencode`: 43 unit + 1 doc test (SQLite reader, JSON payload serde, provider assembly, snapshot-based derive, tool-input fallback for gitignored paths)
- `toolpath-pi`: 123 unit + 4 doc tests (types, paths, error, reader, io, provider)
- `toolpath-dot`: 30 unit + 2 doc tests (render, visual conventions, escaping)
- `path-cli`: 187 unit + 31 integration tests (import/export/cache, track sessions, merge, validate, roundtrip, render-md snapshots, deprecation aliases, pathbase HTTP mock-server tests, fzf-friendly TSV output). For an end-to-end check against a real Pathbase deployment, run `scripts/test-pathbase-live.sh <url>` — it does an anon round-trip in a sandboxed config dir and, if you're logged into that URL, an authed pathstash round-trip too.
- `path-cli`: 260 unit + 63 integration tests (import/export/cache, track sessions, merge, validate, roundtrip, render-md snapshots, deprecation aliases, pathbase HTTP mock-server tests, fzf-friendly TSV output, `path resume` orchestration with injectable `ExecStrategy`). For an end-to-end check against a real Pathbase deployment, run `scripts/test-pathbase-live.sh <url>` — it does an anon round-trip in a sandboxed config dir and, if you're logged into that URL, an authed pathstash round-trip too.
- `toolpath-cli`: 0 tests (it's a one-line `path_cli::run()` shim crate that exists only so `cargo install toolpath-cli` keeps installing the `path` binary)

Validate example documents: `for f in examples/*.json; do cargo run -p path-cli -- validate --input "$f"; done`
Expand Down Expand Up @@ -224,3 +228,4 @@ Build the site after changes: `cd site && pnpm run build` (should produce 7 page
- Interactive session selection: `path import <provider>` (claude / gemini / pi / codex / opencode) auto-launches `fzf` when stdin and stderr are TTYs, `fzf` is on `$PATH`, and no `--session` was given. Multi-select (TAB) produces a `Graph` document; single-select produces a `Path`. The picker uses `path show <provider> --…` as its `--preview` command. When fzf isn't available, it falls back to most-recent (with `--project`) or prints the manual recipe (without). `path list <provider> --format tsv` is the documented machine-readable surface — column 1 is the project (for claude/gemini/pi) or session id (for codex/opencode), and the trailing column carries `first_user_message` so consumers can fuzzy-match by topic.
- Conversation metadata title field: `toolpath-claude::ConversationMetadata`, `toolpath-gemini::ConversationMetadata`, and `toolpath-pi::SessionMeta` all expose `first_user_message: Option<String>` — the first non-empty user-prompt text. Populated cheaply during the metadata pass (single-pass for Claude/Gemini; one extra short read for Pi). Used by the picker UI but useful for any "list sessions by topic" surface.
- `path share` is the one-shot equivalent of `path import <harness> | path export pathbase`. It probes installed agent harnesses (claude/gemini/codex/opencode/pi), aggregates their sessions into a single fzf picker, and ranks rows whose project (claude/gemini/pi) or recorded cwd (codex/opencode) canonicalizes to the current directory at the top. `--harness` narrows the picker to one provider; `--harness X --session Y` (and `--project P` for keyed providers) skips the picker entirely. Pathbase flags (`--url`, `--anon`, `--repo`, `--slug`, `--public`) match `path export pathbase`. By default the derived doc is written to the cache like `import` does; pass `--no-cache` to skip.
- `path resume <input>` is the inverse of `path share`. It accepts a Pathbase URL, an `owner/repo/slug` shorthand, a local toolpath JSON file, or a cache id; resolves it (caching URL fetches under `~/.toolpath/documents/` unless `--no-cache`); validates that the document is a single agent-bearing `Path`; then opens an `fzf` harness picker (skipped with `--harness X`). The picker pre-selects the source harness inferred from `path.meta.source` (`claude-code`/`gemini-cli`/`codex`/`opencode`/`pi`) when it's installed. After picking, `path resume` projects the session into the harness's on-disk layout under the chosen working directory (default: shell cwd; override with `-C, --cwd P`) and `execvp`'s the harness's resume command (`claude -r <id>` / `gemini --resume <id>` / `codex resume <id>` / `opencode --session <id>` / `pi --session <id>`). On Windows it spawns and waits, propagating the exit code. The exec is mockable via `cmd_resume::ExecStrategy` — production uses `RealExec`; integration tests use `RecordingExec` to capture the recipe without launching a real harness.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ toolpath-github = { version = "0.3.0", path = "crates/toolpath-github" }
toolpath-dot = { version = "0.2.0", path = "crates/toolpath-dot" }
toolpath-md = { version = "0.4.0", path = "crates/toolpath-md" }
toolpath-pi = { version = "0.3.0", path = "crates/toolpath-pi" }
path-cli = { version = "0.8.0", path = "crates/path-cli" }
path-cli = { version = "0.9.0", path = "crates/path-cli" }
pathbase-client = { version = "0.1.0", path = "crates/pathbase-client" }

reqwest = { version = "0.13", default-features = false, features = ["blocking", "json", "rustls"] }
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ path export pathbase --input claude-<session-id>
# (full URL or bare `<owner>/<repo>/<slug>` triple)
path import pathbase https://pathbase.dev/alex/pathstash/path-pr-42

# Resume a Toolpath document into your coding agent of choice (interactive
# harness picker; project the session and exec the harness's resume command)
path resume https://pathbase.dev/alex/pathstash/path-pr-42
path resume claude-<session-id> --harness claude -C /path/to/project

# Query for dead ends (abandoned approaches)
path query dead-ends --input doc.json

Expand Down
2 changes: 1 addition & 1 deletion crates/path-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "path-cli"
version = "0.8.0"
version = "0.9.0"
edition.workspace = true
license.workspace = true
repository = "https://github.com/empathic/toolpath"
Expand Down
Loading
Loading