feat: pi as a fifth backend - #338
Merged
Merged
Conversation
`pi [prompt]` opens the TUI already running the prompt, which is graphcode's session model. Presence, activity, usage and the resume id come from one extension loaded with `-e <path>`, writing the same zmx labels Claude Code's hooks do, so the Claude readers serve pi unchanged. It reports idle on `agent_settled` rather than `agent_end`, because pi can retry or run a queued follow-up after a run ends. Resume is `--session <id>`, which exits 1 when the conversation is gone, so the resume-dead fallback applies. pi has no tool approvals; its one unattended stall is the project-trust prompt, settled by `--approve` (new PiProjectTrust setting, default approve). It has no `/goal`, `/loop`, MCP or sub-agents, so goals ride as prose and time loops use the daemon's cadence. Spiked against pi 0.85.1: flags read off `pi --help`, events off a probe extension run against the real binary with a fake zmx. Not yet: the summary rail and export/import. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
pi keeps one JSONL per session under ~/.pi/agent/sessions/<cwd slug>/, named <timestamp>_<id>.jsonl, whose header line names the id and cwd. Export carries that file (locally by the banked id, remotely through the same tar-over-ssh fetch Claude uses); restore rewrites the header's id to a fresh UUID and its cwd to the target, installs it under the target's slug, and banks the fresh id so --session <id> resumes it. The slug must be the target's own: pi only offers an interactive fork prompt for a session it finds under another project. The layout and file-plumbing helpers move to SessionTransplant+Layouts so the enum body stays under swiftlint's type_body_length limit, which the base branch already exceeded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KBuQWNV3dpDAtb6SnGN15P
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
pi names a session at startup but writes its JSONL only with the first
assistant message, and `pi --session <id>` exits 1 ("No session found
matching") on an id with no file. Banking at session_start left a dead id
for any session quit before its first reply, or a /new a reboot interrupted.
Bank when the file exists, retrying at tool_call and agent_settled.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDp19dXj5ZKDEAMt65uRES
feat: carry pi sessions through node export/import (reviewed by PiBackendReview: MERGE) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
fix: pi extension banks a session id only once its file exists (review finding) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
Review findings F2 and F3. pi parses a positional argument starting with `-` as an option and one starting with `@` as a file, so such a goal never reached the agent; it now gets a leading space, on both the daemon and the app launch. `--` could not rescue `@` and would swallow the remote `-e` suffix. pi's project-trust prompt runs before session_start and fires no ui_prompt event, so the extension now reports awaitingInput from project_trust and leaves the decision to pi. Verified live against pi 0.85.1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh
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.
Closes #214
Adds pi as a fifth CLI backend alongside Claude Code, Copilot, Codex and OpenCode.
What changes
--backend picreates loops that runpiin a zmx session, from both the daemon and the app terminal.PiPresenceExtension, loaded with-e) reports busy / idle / needs-input, tool activity and token usage, and banks the session id for resume. Works on remote hosts too.--session <id>.--approve(trust the project, default) or ask./goal); time-based loops use graphcode's heartbeat.pi -p --no-tools --no-session.Not yet
Verification
graphcodescheme testsgraphcode-cli/graphcodedbuildsnode create --backend pi)🤖 Generated with Claude Code
https://claude.ai/code/session_01KMVJyUtec3hpH5hF44xAgh