Skip to content

Add path share --all for bulk upload - #245

Draft
benbaarber wants to merge 7 commits into
mainfrom
ben/share-all
Draft

Add path share --all for bulk upload#245
benbaarber wants to merge 7 commits into
mainfrom
ben/share-all

Conversation

@benbaarber

@benbaarber benbaarber commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • path share --all [--project-under <dir>] [--harness <h>] [--repo o/n] [--dry-run] [-y] [--force] uploads every session in scope instead of opening the picker. Prints a per-project summary with harness breakdown and the configured remote where one resolves, then confirms. Requires login; --anon, --session, and --project conflict with it.
  • Destinations follow the existing single-session rules: --repo > each directory's [[project]] remote > <you>/pathstash. Uploads are sequential; failures warn and continue; exit is non-zero if any failed.
  • Authed uploads are recorded in the sync manifest (SyncRecord.uploads: server, repo, graph id, URL, source fingerprint at upload time). --all skips sessions already uploaded to their destination, and also ones changed since (no update endpoint exists, so re-uploading would only duplicate); the heading reports (N already uploaded, M changed since upload, K new). Single share on an unchanged session prints the existing URL. --force ignores the record. Sync/import rewrite the fingerprint but keep the upload history.
  • Claude and pi metadata readers now expose the session's recorded cwd (ConversationMetadata.cwd, SessionMeta.cwd). Their project paths are decoded from lossy slugs (_/./- all become /), which made the summary show wrong directories and made [[project]] rules on such directories miss. Share (picker and --all) now groups and resolves remotes by the recorded cwd; the slug-decoded path still locates the files.
  • gather_artifacts takes a ProjectScope { Exact, Under } instead of an exact-only filter; Under reuses sync's per-provider matching. The fresh-cache-or-derive step is factored into load_session and shared by both share paths.

Versions: path-cli 0.19.0, toolpath-claude 0.13.1, toolpath-pi 0.6.2.

Test plan

  • cargo test -p path-cli -p toolpath-claude -p toolpath-pi
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --check
  • path share --all --project-under ~/empathic/oss --dry-run against real sessions (before upload tracking): 106 sessions, real worktree paths displayed, empathic/toolpath remote resolved from config
  • Real upload run with --all, then a second run showing the skip counts
  • Interactive picker path with a [[project]] rule on a directory containing . (needs a TTY)

`share --all` uploads every session across the installed harnesses
instead of opening the picker. `--project-under <dir>` restricts it to
sessions under that subtree (same per-provider matching as `p cache
sync`); `--harness` narrows to one harness. It prints one line per
project directory — session count, per-harness breakdown, and the
configured remote where a `[[project]]` rule resolves — and asks
before uploading (`--yes` skips the prompt, `--dry-run` stops after
the summary). Destinations follow the single-session rules: `--repo`
for everything, else each directory's configured remote, else
`<you>/pathstash`. Requires login. Failures warn and continue; the run
exits non-zero if any failed. Nothing records what was already
shared, so re-running uploads everything again.

Claude and pi decode their project directories from lossy slugs, so
the summary showed wrong paths and `[[project]]` rules on directories
containing `_`, `.`, or `-` never matched. The two metadata readers
now also return the cwd the session file records
(`ConversationMetadata.cwd`, `SessionMeta.cwd`), and share — both the
picker and `--all` — groups, displays, and resolves remotes by that.
The slug-decoded path is still what locates the session files.

path-cli 0.19.0, toolpath-claude 0.13.1, toolpath-pi 0.6.2.
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

🔍 Preview deployed: https://95f8d2ec.toolpath.pages.dev

…ions

Authed uploads from `share` (single and `--all`) are recorded on the
artifact's manifest record as `uploads`: server, `owner/name`, graph
id, URL, and the source fingerprint (mtime+size) at upload time, one
entry per destination. Sync and import rewrite the fingerprint but
carry the upload history across (`put_record`); anonymous uploads are
not recorded since there is no repo to key on.

`share --all` classifies each session against its destination and
skips ones already uploaded. Sessions that changed since upload are
skipped too: there is no graph update endpoint, so re-uploading would
only create a duplicate. The summary heading reports both counts and
the prompt shows the number that will actually go. Single-session
`share` on an unchanged session prints the existing URL instead of
uploading again; on a changed one it uploads a new graph and says so.
`--force` ignores the record in both modes.

`run_pathbase_inner` now returns what it uploaded so callers can
record it.
The URL the server returns is <server>/u/<owner>/<name>/graphs/<id>, so
it already names the destination. `in_repo` matches a record to a repo
by host and the `<repo>/graphs/` path prefix; a parent path such as
`/u/<owner>` does not match.
…kipped

Row counts and harness breakdowns now cover the sessions that will be
uploaded; each row appends (N already uploaded, M changed since upload)
so the skipped sessions can be located. The heading gains ", K to
upload" when any are skipped. Rows with nothing to upload stay listed
with 0.
Harness totals move to one line under the heading; rows show the
directory relative to --project-under ("." for the root, ~-relative
otherwise), the count to upload, skip notes, and the configured remote,
with no column padded to the widest breakdown. The destination folds
into the prompt ("Upload N sessions to owner/repo? [y/N]"); --dry-run
prints "Would upload …" instead.
load_session reports where the document came from instead of printing;
single share keeps its one-line note, and --all completes its progress
line in place: "[3/101] claude <id> (cached) → <url>".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant