Uh oh!
There was an error while loading. Please reload this page.
feat(enter): switch existing worktrees in process - #25
Merged
Conversation
pi can rebuild a live session around a new working directory without the process restarting: `switchSession` recreates the runtime with the cwd recorded in the target session file, which rebuilds the built-in tools from that cwd and re-resolves settings, extensions and context files against it. This extension relaunches pi through a terminal multiplexer to do the same thing. Records the mechanism, the evidence, and the two constraints that shape any use of it. A session file is not written until the session holds an assistant message, so `SessionManager.forkFrom` refuses a session whose turn is still in flight and the in-memory entries have to carry it. And `process.cwd()` never moves, so nothing may treat it as the session's location once a switch is possible. Verification that drives a real runtime is described in the findings rather than run by the suite: standing a runtime up and switching it is the one operation here that can relocate a session, which does not belong in a test that runs on a developer's machine. Refs #18
Replace the slash-command enter relaunch with Pi's session-replacement API. The target session is complete before teardown: it preserves the active conversation branch and appends a visible custom orientation that participates in the next model context without triggering a model turn. Build unflushed and zero-entry sessions from in-memory entries because Pi does not write a session file until it has an assistant message. A flushed session still uses forkFrom so the full tree carries across. Verify target cwd, active leaf and orientation before attempting replacement. Consume relaunch handoffs exactly once and use the replacement context's cwd in the caveat. A successful in-process replacement also retires an unconsumed predecessor handoff; cancellation leaves it available to the source session. Do not relaunch after a replacement error because Pi tears the old runtime down before constructing the new one, making its captured context unsafe. Live replacement is excluded from the normal host test suite. A dedicated CI job builds a disposable Docker image, loads the real extension into a real runtime, invokes /worktree enter and proves cwd/resource rebinding, persisted orientation, next-turn context, no synthetic turn and one-shot handoff use. Closes#19Fixes#24
Importing SessionManager at runtime exposes the actual compatibility floor of the pi peer dependency. pi-coding-agent 0.83.0 and its undici 8.5.0 dependency both require Node >=22.19.0; the previous >=18 package claim and Node 20 CI seat passed only while every pi import was erased as a type. Declare the real floor and replace the false Node 20 matrix seat with Node 22. Refs #19
neilwashere
commented
Aug 23, 2026
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Carry every in-memory session entry when the persisted leaf is stale, then attach orientation to the selected leaf or root. This preserves sibling branches and prevents a reset leaf from being mistaken for an empty session. Let Pi derive the worktree's cwd-specific default session directory while retaining explicitly configured stores. Delete prepared target files when a switch is cancelled or preparation fails, and surface cleanup failures. Persist the complete transition handoff in the target orientation. The fresh replacement verifies registration, provisioning and receipt identity during session_start, records successful verification, and emits a durable caveat for partial or mismatched arrivals. Reloads restore that result without repeating the check. Treat --worktree as startup-only so command-line flag values reapplied by Pi do not bounce a resumed replacement back to its original checkout. Expand the disposable runtime proof to use Pi's real rebind lifecycle and cover default session relocation, cancellation cleanup, retained CLI flags and a receipt mutation between planning and successor verification. Refs #19Fixes#24
🎉 This PR is included in version 1.2.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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 freeto 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.
Summary
/worktree enter's terminal-multiplexer relaunch with Pi's in-processswitchSessionAPIpi-worktree-transitionorientation in the target session before teardown, so the replacement cannot arrive rudderlessforkFromwhen the session file is authoritativePI_WT_HANDOFFpayloads exactly once and usectx.cwd, neverprocess.cwd(), as the session locationCloses#19.
Fixes#24.
Part of #17.
Why the container boundary exists
The mechanism probe proved that Pi rebuilds cwd-bound tools and resources correctly, but two early host integration attempts reached an unoriented temp-worktree session and had to be manually abandoned. The missing protocol was the handoff: relaunches deliver it through a new process environment; an in-process replacement has no such boundary.
The implementation now writes orientation into the target session before switching. The normal host suite contains no
switchSessioncall.test/container/enter-switch.e2e.tsrefuses to run unless both/.dockerenvandPI_WORKTREE_CONTAINER_TEST=1are present.Behaviour
SessionManager.forkFromcarries the full tree;ctx.switchSessionand return without touching the stale source context.Preparation failure or cancellation stays put and leaves the worktree available. A replacement error is allowed to propagate to Pi; relaunching after teardown would use a stale command context.
Verification
The disposable proof loads the real extension into a real runtime, invokes the registered
/worktree enter feat/xcommand with no multiplexer present, and verifies:Residual scope
This changes only the human slash-command enter path. Model-callable create/enter remains on the existing transition machinery and is tracked by #20. Create and dispose still relaunch; their migration is tracked separately in #21 and #22.