@danchamorro/pi-handoff-agent
v0.2.0
Published
Export clean Pi session handoffs for portable agent continuity
Maintainers
Readme
@danchamorro/pi-handoff-agent
Export the active Pi conversation into a portable continuity packet that another agent session can read and continue from.
Why this exists
Long-running agent work often outlives a single session. You may need to move from one Pi session to another, continue work after compaction, hand context to a different model, or preserve the exact decision trail before switching tasks. Native session files are not a good handoff format because they include thinking traces and Pi-specific state, while transcript-only exports can miss important evidence from tools.
pi-handoff-agent turns the current active Pi branch into one clean handoff artifact:
- writes a model-generated briefing when the active model is available
- falls back to a deterministic briefing when model access is unavailable
- preserves user and assistant message text
- preserves tool calls, tool results, command output, MCP output, and subagent context as evidence
- keeps branch or compaction summaries when they are part of active context
- preserves raw pre-compact branch history instead of relying only on lossy compact summaries
- removes thinking and reasoning traces
- omits extension state records that do not participate in LLM context
- writes a canonical JSON file for the next agent session
- writes a Markdown companion for human review
- protects
.handoffs/with.gitignoreso private context is not accidentally committed
The point is not native session cloning. The point is portable continuity: a fresh agent can read the briefing first, then inspect timeline evidence only when needed.
Install
pi install npm:@danchamorro/pi-handoff-agentFor local development from this repo:
pi install ./packages/handoff-pi-agentCommand
Run this inside the Pi session you want to export:
/handoff-exportThe command writes project-local files:
.handoffs/<timestamp-pi-agent>/handoff.json
.handoffs/<timestamp-pi-agent>/handoff.mdhandoff.json is the canonical artifact for receiving agents. handoff.md is generated from the JSON for inspection and review.
How it works in simple terms
- Code reads the active Pi branch through Pi's session API.
- Code builds a clean timeline from that branch.
- The timeline keeps transcript text and tool evidence, including command output and subagent summaries.
- The timeline removes thinking traces and Pi-only state.
- The extension makes a separate one-shot model call using the same active model and credentials. This call has a fresh context window and only sees the cleaned timeline plus stats.
- That model call writes the
briefing. If it fails, code writes a deterministic fallback briefing. - Code writes
handoff.jsonand rendershandoff.mdfrom the same JSON.
Receiving workflow
Start a fresh agent session in the same repo and say:
Please read .handoffs/<timestamp-pi-agent>/handoff.json so we can pick up where I left off. Start with the briefing, then inspect timeline messages only if supporting evidence is needed. The companion handoff.md is for human review.A good receiving session should be able to identify the current goal, key decisions, completed work, open caveats, validation status, and the next action.
Artifact structure
The package intentionally keeps one command and one canonical JSON format:
briefing: current-state handoff summary generated by a fresh one-shot call to the active model when possible.messages: active branch timeline with transcript text and tool evidence preserved after thinking traces are removed.policy: preservation policy for the artifact.stats: counts of entries, preserved tool evidence, omitted state, removed thinking, and warnings.
The model-generated briefing is like a tiny summarizer subagent with no tools. It does not use the current chat context window directly. It only receives the cleaned handoff timeline and stats.
Why a package-backed extension
The export must read the live Pi session branch. File modification time is not reliable when sessions are resumed, forked, compacted, or running concurrently. This package registers a Pi extension command so it can use Pi runtime APIs for the active branch and session metadata instead of guessing from session files.
Privacy and gitignore behavior
Handoffs may contain private prompts, code snippets, local paths, command output, API responses, database rows, logs, and business context. The exporter appends .handoffs/ to an existing .gitignore. If no .gitignore exists, it fails safely rather than silently creating one.
Review handoffs before sharing them outside the project or organization.
What gets preserved
The exporter preserves continuity evidence by default:
- user and assistant text
- context summaries
- tool calls and arguments
- tool results and outputs
- shell command output
- MCP output
- subagent context messages
- compacted branch summaries and raw pre-compact branch history when present
What gets removed
The exporter removes only material that is not appropriate for portable continuity:
- thinking or reasoning blocks
- extension state records such as
customandlabelentries - known Pi settings events such as model changes
- empty messages left after removing thinking or state-only entries
Compaction behavior
Pi compaction is append-only: compacting a session appends a summary entry but does not delete the earlier raw messages from the session file. Because this package exports the active branch path, handoffs can still include pre-compact user and assistant messages. Compaction summaries are preserved as context records so a receiving agent can see that compaction occurred, but they are not the only source of continuity.
CLI for explicit snapshots
The CLI is for tests and explicit normalized snapshots. It cannot export the current Pi session because that requires the live extension context.
node packages/handoff-pi-agent/scripts/extract-handoff.ts \
--input shared/handoff/fixtures/simple-transcript.json \
--cwd "$PWD" \
--out .handoffs/cli-test \
--add-gitignore=falseDevelopment note
This package includes a package-local copy of the shared implementation under shared/handoff/ so the npm tarball is self-contained. Keep those files synchronized with the repo-level canonical source in shared/handoff/ before publishing.
