计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
summon【效率与协作】Claude Desktop session toolbox: transfer sessions between accounts, recover an old session via a picker + AI handover brief, rebind cwd after a folder move, audit broken bindings, render an in-chat picker. Triggers on: summon, transfer/recover session, session picker, rebind, session doctor.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Claude Desktop session toolbox. Four jobs, one store:
| Mode | Invocation | Job |
|---|---|---|
| Transfer (default) | summon [flags] | Copy/move sessions across accounts so they're visible from the account you switch to next |
| Pick / Recover | summon pick · summon recover <id> | Find a past session, resolve its transcript, distill a handover brief, emit a paste-ready handover for a new session |
| Rebind | summon rebind <id> --cwd <newpath> | Fix a session's recorded cwd after the project folder moved |
| Doctor | summon doctor [--json] | Scan every session for broken cwd bindings; report which need rebinding |
Transfer touches no transcripts and makes no API calls. Recover/pick make exactly one optional, gated LLM call (the distillation) and degrade gracefully without it. Transfer is documented first; the toolbox modes follow under Toolbox modes.
Before you switch accounts, not after. The natural workflow:
summon --to <next-account> — sessions get copied (default) into the next account's dirRunning summon after hitting the usage limit also works — the file moves are pure local ops, no API needed — but you'll still need to Logout/Login on the destination to see the sessions, since Desktop's session list is cached at login. Doing it proactively just means the Logout/Login is no longer "extra friction," it's the same step you'd be doing anyway.
Each Desktop session has two halves:
| Half | Location | Account-bound? |
|---|---|---|
| Metadata JSON | %APPDATA%/Claude/claude-code-sessions/<account>/<workspace>/local_<uuid>.json | Yes — lives under <account> |
| Transcript JSONL | ~/.claude/projects/<encoded-cwd>/<cli-uuid>.jsonl | No — global, shared |
Summon copies (or with --move, relocates) the metadata wrapper into the destination account's dir. The transcript stays put — both wrappers point at the same conversation. After Logout/Login on the destination, the new entries appear in the left-hand session picker (Desktop's Code-tab sidebar).
The uuid-mismatch trap: the transcript is named by the wrapper's cliSessionId, not its sessionId, and may not sit under the wrapper's munged cwd. Every mode resolves by cliSessionId with a scan fallback: references/session-store.md.
# Wrapper (after install — see below)
summon [flags]
# Or direct
python ~/.claude/skills/summon/scripts/summon.py [flags]
Default behaviour: list candidate sessions across all non-destination accounts, grouped Account → Project → Session, then prompt to copy them into the destination account. Copy semantics by default — sessions remain visible in the source account too. Last 3 days; remote-VM sessions auto-skipped.
Push (--to <next-account> before switching) and pull (no --to, after switching) are mechanically identical; push is recommended. references/transfer.md.
| Flag | Default | Effect |
|---|---|---|
--to <account> | most-recently-active account | Destination — where the sessions land. Specify when pushing to a different account; omit when pulling into your current account. UUID prefix or email substring |
--from <account> | all non-destination accounts | Restrict source to one account |
--days N | 3 | Time window |
--all | Disable time filter | |
--cwd <pattern> | Substring match against session cwd | |
--title <pattern> | Substring match against session title | |
--pick | Interactive multi-select by number | |
--move | Move instead of copy — delete source after copying (lean cleanup) | |
--dry-run | Preview without touching files | |
--list-accounts | Show all accounts and exit | |
--peek <id> | Preview a session's last messages and exit (id prefix or full) | |
--flat | Flat list instead of grouped hierarchy | |
--select <picks> | Non-interactive selection: --select "1,2,4" or --select all. Replaces the picker prompt for scripted callers | |
--yes | Skip the final confirmation prompt only — selection is still required (picker prompt, piped stdin, or --select) |
Semantic exit codes across all modes: 0 ok, 2 usage/ambiguous id, 3 session or path not found, 10 doctor found broken sessions.
summon pick — session picker → distilled handoverInteractive picker over the whole session store (all accounts, default last 30 days — --days N/--all to widen, --cwd/--title to narrow). Uses fzf when it's on PATH and the terminal is interactive; falls back to a numbered list (--select N answers it non-interactively). A ● marks sessions active in the last 10 minutes — don't recover a session that's still running.
Selecting a session emits a paste-ready handover on stdout (context panel and progress on stderr, so summon pick | clip stays clean). Same output as recover, below.
summon pick --json emits the inventory as a claude-mods.summon.pick/v1 envelope (no picker); --json --rich adds display metrics as pick/v2, the card picker's feed. Keys: references/toolbox-modes.md.
summon recover <id> — distilled handover briefsummon recover 6577b24c — id is a sessionId or cliSessionId, prefix ok. Four-stage flow:
Extract turns (no LLM), distill with one tool-less claude -p --model sonnet call, cache at <transcript>.handover.md, emit the brief plus a transcript pointer on stdout. Detail and sample: references/toolbox-modes.md.
Degrade, never hard-fail: if the claude CLI is absent from PATH, or the call fails/times out (60s), recover falls back to the classic non-distilled pointer prompt (Title/Branch/Orig cwd/Transcript + tail-reading instruction) with a stderr warning and exit 0 — worker unavailability is advisory, not an error. --no-distill forces the fallback (no LLM call at all).
| Flag | Default | Effect |
|---|---|---|
--no-distill | Skip the LLM distillation; emit the plain pointer prompt | |
--refresh | Ignore a cached <transcript>.handover.md and re-distill | |
--model <m> | sonnet | Model for the distillation call |
--budget <n> | 120000 | Char budget for the transcript extraction fed to the distiller |
summon rebind <id> --cwd <newpath> — fix cwd after a folder moveWhen a project folder moves (e.g. D:\code\myapp → D:\archive\myapp), sessions bound to the old cwd fail to restart in the Desktop UI. Rebind repairs the binding:
summon rebind 6577b24c --cwd "D:\archive\myapp\.claude\worktrees\funny-hypatia-5e54f7"
Backs up, rewrites and verifies the wrapper (every account's copy) and bridges the transcript. For a worktree path, run git worktree repair <new-worktree-path> from the repo root; worktree links break on folder moves. Steps: references/toolbox-modes.md.
--dry-run previews; --force allows a --cwd that doesn't exist yet. The new cwd must normally exist on disk. After a rebind, restart Desktop (or Logout/Login) so the sidebar re-reads the wrapper.
Wrapper edit + backup + transcript bridge are verified against the live store (throwaway-session test, 2026-07-03). End-to-end "session reopens in the Desktop UI after rebind" — confirm on your first real rebind before bulk-rebinding.
summon doctor — find broken sessionsScans every wrapper (all accounts, all time) and reports sessions whose recorded cwd no longer exists on disk, with a ready-made summon rebind <id> --cwd <new-location> line per finding. Also counts transcript-missing and found-by-scan sessions. Exit 10 when anything is broken; --json emits a claude-mods.summon.doctor/v1 envelope for scripted use:
summon doctor --json | jq -r '.data[] | "\(.sessionId) \(.cwd)"'
Broken-cwd findings are mostly pruned worktrees (the session ended, the worktree was cleaned — nothing to fix unless you want to recover it, which needs no rebind: summon recover works regardless of cwd) and moved project folders (the real rebind case).
When summon is invoked from inside a Claude chat session (Desktop chat, claude.ai), the terminal picker can't run interactively — stdin isn't a TTY, so fzf and the numbered prompt are out. This card picker is the default way to present sessions in chat — reach for it whenever the user asks to see, pick, recover, or summon sessions, not just when they say "picker".
summon widget --days 30 (add --cwd/--title filters as asked). It prints the finished, self-contained card-picker HTML on stdout — the rich inventory already trimmed and injected into the template.show_widget tool as widget_code. That's the whole job: no manual injection, no key-trimming, no reading a file back. The builder also writes the same HTML to %TEMP%\claude\summon-widget.html (override with --out), so you can Read it if you'd rather not re-run.Don't hand-assemble the widget.
show_widgettakes only inline code, and a hand-merged file trips the 25k-tokenReadcap. Why, and the trimming flags: references/in-chat-picker.md.
Widget features, and the optional per-row summary that replaces firstAsk: references/in-chat-picker.md.
Manual fallback (only if summon widget is unavailable): inject pick --json --rich output into assets/picker-widget.html; steps in references/in-chat-picker.md.
sendPrompt callbacks the widget fires. Per-card ↗ summon and ⟳ recover (and the footer's "Recover/Summon selected") are worded to be spawned as background chips — when one arrives, call spawn_task (one chip per session) rather than doing the work inline, so the user's current turn keeps flowing:
spawn_task per session (the batch button sends a single prompt listing all selected — fan it into one chip per session, not one mega-chip, so each recovers independently in its own project folder). For each chip:
revoicing) — never a Recover "…" session label. The chip should look like a continuation of the original in the sidebar, not a new errand.cwd = the session's project root (strip any \.claude\worktrees\<name> suffix).summon recover <id> / the wrapper→transcript logic), writes a hand-off brief, and resumes the work in place in the project folder. The chip must not spawn a further chip and must not open the original worktree path as a separate session — that path is reference-only, for locating the branch and any in-progress changes. (The failure mode this prevents: a chip prompt that says "start a fresh session there" plus a worktree path makes the recovering chip spawn a second chip into the worktree. The chip already is the fresh session — tell it to continue, not to spawn.)summon with --select for exactly those sessions, --dry-run preview first, then the real run once the user confirms.summon --peek <id>.The template is deliberately self-contained: host CSS variables + the host's Tabler ti webfont (both available in the show_widget context, light/dark safe), no external assets, and the host-provided sendPrompt(text) bridge for the buttons. Chat contexts only — terminal users keep the fzf/numbered picker; don't route a TTY user through the widget.
--from <account> to restrict to one.Account → Project → Session panel, globally numbered for picker selection (3,5,7), ASCII fallback off UTF-8: references/display.md.
Remote-VM sessions and missing transcripts are skipped, existing sessionIds are idempotent, non-UTF-8/non-TTY output degrades: references/transfer.md.
Desktop reads its session list at login and doesn't watch the filesystem: Logout → Login is required for new sessions to appear. Evidence: references/transfer.md.
Symlink (or copy) the wrapper into a directory on PATH:
# Linux/macOS/Git Bash
ln -s ~/.claude/skills/summon/bin/summon ~/.local/bin/summon
# Windows (PowerShell)
copy "$env:USERPROFILE\.claude\skills\summon\bin\summon.cmd" "$env:USERPROFILE\bin\summon.cmd"
Then summon pick, summon doctor, etc. work directly from any shell.
Full file system layout, session schemas, account binding, and the validated cross-account transfer procedure live in docs/references/claude-desktop-internals.md (claude-mods). That document is canonical; this skill is the operating manual.
--list-accounts first, then email substring (more readable, less brittle).--move for sessions you might want to access from both accounts — copy is default precisely because multi-account workflows are the common case.rebind refuses a nonexistent --cwd for a reason; a typo'd rebind is two edits instead of one. --force is for pre-creating bindings, not for skipping the check.<transcript>.handover.md and reused while the transcript is unchanged; reach for --refresh only when the session has genuinely moved on since the cache was written.