Skip to content

feat: carry pi sessions through node export/import - #339

Merged
scgopi merged 1 commit into
feature/pi-backendfrom
feature/pi-transplant
Sep 12, 2026
Merged

scgopi merged 1 commit into
feature/pi-backendfrom
feature/pi-transplant

Conversation

@scgopi

@scgopi scgopi commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Builds on #338. An exported pi loop now carries its conversation, and the imported loop resumes it instead of starting fresh.

What changed

  • Export: the pi session file (~/.pi/agent/sessions/<cwd slug>/<timestamp>_<id>.jsonl) travels with the loop. Local loops find it by the banked id. Remote loops fetch it over the same tar-over-ssh path Claude sessions use.
  • Import: the session's header gets a fresh id and the target working directory. The file is installed under the target's own slug, and the fresh id is banked so pi --session <id> resumes it. This works for both local and remote projects.
  • The slug has to be the target's own. pi only offers an interactive "fork into current directory?" prompt for a session it finds under another project, and that would stall a loop.
  • Layout and file helpers moved into SessionTransplant+Layouts.swift. The enum was already over swiftlint's type_body_length limit on the base branch.

Verified against pi 0.85.1

  • A session file shaped the way restore writes it (fresh id, rewritten header, target slug) is listed and opened by pi's own SessionManager under a throwaway HOME, with the right id, cwd and entries.
  • pi --session <that id> gets past session lookup to the model call. An unknown id prints No session found.

Tests

  • PiSessionTransplantTests: header rewrite, refusal of files that aren't pi sessions, slug encoding, filename shape, and the remote install script run through /bin/sh under a fake HOME (lands at the Swift-computed slug, banks the id).
  • The remote export and install suites now cover pi.

Refs #214

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
@scgopi

scgopi commented Sep 12, 2026

Copy link
Copy Markdown
Owner Author

Gate on 95471b86 (= remote head), private DerivedData: xcodebuild test exit 0 — ✔ Test run with 1739 tests in 184 suites passed after 83.905 seconds. / ** TEST SUCCEEDED **, all 8 new pi tests passed; graphcode-cli build exit 0; graphcoded build exit 0; SwiftPM build exit 0 + CLI smoke exit 0 (5 commands); swiftlint 0 errors; swift-format clean; Linux pass (https://github.com/scgopi/GraphCode/actions/runs/34724108071/job/103635100484).

@scgopi
scgopi merged commit 09c79ea into feature/pi-backend Sep 12, 2026
1 check passed
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