fix(pi-plugin): support pi-web multi-session and RPC hosts - #350
fix(pi-plugin): support pi-web multi-session and RPC hosts#350elrond298 wants to merge 2 commits into
Conversation
Scope in-process child detection to lifecycle AsyncLocalStorage so independent sessions initialize normally, and release lifecycle subscriptions on shutdown. Run startup maintenance once per process and defer session-history reads until the backfill lease is acquired. Resolve the child Pi CLI independently from embedded host argv, present command output through RPC notifications and dialogs, and ensure Dreamer registration before manual runs.
There was a problem hiding this comment.
All reported issues were addressed across 17 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…amer registry, session-scoped drains, presenter ctx capture; NOT a security blocker — rpc-server untouched) Co-Authored-By: Alfonso <alfonso@cortexkit.io>
There was a problem hiding this comment.
1 issue found across 17 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/pi-plugin/src/dreamer/index.ts">
<violation number="1" location="packages/pi-plugin/src/dreamer/index.ts:129">
P2: When a stable owner re-registers after a later worktree change, `Map.set` keeps its original insertion position, so shutdown handoff can select a stale sibling checkout. Delete the owner key before setting it to preserve registration recency.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
|
||
| const existing = registeredProjects.get(opts.projectIdentity); | ||
| const owners = existing?.owners ?? new Map<object, PiDreamerOptions>(); | ||
| owners.set(opts.registrationOwner, opts); |
There was a problem hiding this comment.
P2: When a stable owner re-registers after a later worktree change, Map.set keeps its original insertion position, so shutdown handoff can select a stale sibling checkout. Delete the owner key before setting it to preserve registration recency.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/pi-plugin/src/dreamer/index.ts, line 129:
<comment>When a stable owner re-registers after a later worktree change, `Map.set` keeps its original insertion position, so shutdown handoff can select a stale sibling checkout. Delete the owner key before setting it to preserve registration recency.</comment>
<file context>
@@ -121,8 +125,12 @@ export function registerPiDreamerProject(opts: PiDreamerOptions): void {
const existing = registeredProjects.get(opts.projectIdentity);
+ const owners = existing?.owners ?? new Map<object, PiDreamerOptions>();
+ owners.set(opts.registrationOwner, opts);
if (existing) {
// Same identity, same directory → genuinely already registered, no-op.
</file context>
alfonso-magic-context
left a comment
There was a problem hiding this comment.
Thanks for this — especially as a first contribution. The diagnosis is right: the #247 process-global latch is what makes the second pi-web session skip Magic Context entirely, and routing child suppression through subagents:child:session-created/disposed plus AsyncLocalStorage is the correct seam. Once-per-process startup maintenance, not reusing a non-Pi argv[1], Dreamer sibling ownership, and keeping ctx-status entries model-invisible while presenting them in RPC are all the right instincts. And noted that you already pushed the Dreamer owner-handoff stabilization mid-review — that resolves one of the items we had flagged, and that kind of responsiveness makes this easy to shepherd.
Two clarifications so we don't talk past each other:
- "RPC hosts" here is Pi RPC mode (
ctx.ui.notify/ctx.ui.custom). It does not change Magic Context's RPC server, which must stay on127.0.0.1with a bearer token. We checked; this PR does not touch that. - The old "second init in the process is a no-op" test should change — that contract is the bug for pi-web. Please keep the child-only skip test (you did).
Before we can merge:
- Dreamer
registeredProjectsonglobalThis(same jitimoduleCache:falsereason as the child marker), so two sessions in one repo don't start two timers. session_shutdowndraining only that session's in-flight work — in pi-web, shutdown is not process exit.- RPC presentation using the command's live
ctx, not asession_startclosure. - The #177 "never spawn bare
pi" test kept alongside the new embedded-host test. packages/pi-plugin/PARITY.mdupdated for RPC dialogs, the multi-session process model, and the latch → ALS change.
We've approved CI for this PR so your next push gets the full check suite. Really solid work — happy to re-review quickly.
Summary
This PR adapts the Pi plugin for
pi-web, where multiple Pi sessions share one persistent Node.js process and commands run through Pi’s RPC mode.It addresses shared-process session isolation, duplicate startup work, unsafe subagent CLI detection, RPC command feedback, and
/ctx-dreamfailures before the first model turn.Changes
Session isolation
AsyncLocalStorage<boolean>marker.subagents:child:session-createdandsubagents:child:disposedevents.pi-webprocess to initialize normally.session_shutdownto prevent stale handlers after reloads.Process-wide startup maintenance
Safer subagent CLI detection
process.argv[1]only when it identifies a supported Pi CLI; otherwise use the packaged executable, bundled CLI, orPATHfallback as appropriate.RPC command presentation
ctx.ui.notify.ctx.ui.custom./ctx-status,/ctx-embed,/ctx-recomp,/ctx-session-upgrade, and/ctx-dream.Dreamer registration
/ctx-dreamrun./ctx-dreamto work before the firstbefore_agent_startevent.Verification
bun run --cwd packages/pi-plugin buildbun run --cwd packages/pi-plugin test— 804 passed, 0 failedbun test packages/plugin/src/features/magic-context/session-project-backfill.test.ts— 9 passed, 0 failedgit diff --checkRegression coverage includes:
/ctx-dreamregistration synchronizationNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Adds
pi-webmulti-session and RPC support topackages/pi-pluginand stabilizes Dreamer owner handoff. Old behavior suppressed all same‑process inits via a global latch; new behavior suppresses only in‑process child subagents via lifecycle‑scoped AsyncLocalStorage, runs startup maintenance once per process, and avoids re‑running embedded hosts.subagents:child:session-created/subagents:child:disposedon an AsyncLocalStorage context; only marked children no‑op; independent same‑process sessions initialize normally. Unsubscribe lifecycle listeners onsession_shutdown.process.argv[1]only when it is a Pi CLI (@earendil-works/pi-coding-agent/dist/cli.js). Otherwise use the packaged binary, bundled CLI, orpion PATH. Never spawn with a shell; prevents embedded hosts (e.g., Next.js) from re‑running themselves.ctx-statusentries and present them in RPC. Short progress →ctx.ui.notify; detailed results orrpcDisplay: "dialog"→ modal viactx.ui.custom. Applied to/ctx-status,/ctx-embed,/ctx-recomp,/ctx-session-upgrade, and/ctx-dream. RPC presenter is set only in RPC mode.registerCtxDreamCommandacceptsensureRegisteredto sync before manual runs.Review notes
rpcDisplay: "dialog"across updated commands.Written for commit 72dc718. Summary will update on new commits.
Greptile Summary
This PR adapts the Pi plugin for multiple sessions sharing one process and for RPC-based hosts.
Confidence Score: 5/5
The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD Host[Persistent Pi or pi-web host] --> SessionA[Extension instance A] Host --> SessionB[Extension instance B] SessionA --> Shared[Shared process state and SQLite] SessionB --> Shared SessionA --> OwnerMap[Dreamer owner registry] SessionB --> OwnerMap SessionA --> RPC[RPC notifications and dialogs] SessionB --> RPC SessionA --> Child[Resolved Pi child CLI] SessionB --> ChildReviews (2): Last reviewed commit: "fix(pi-plugin): stabilize Dreamer owner ..." | Re-trigger Greptile
Context used: