This repository was archived by the owner on Sep 4, 2026. It is now read-only.
feat(chat): render pi-kit lane cards inside a pickforge-lanes MCP row - #395
Merged
Conversation
#362 PR 3, the last slice of that issue. When an agent dispatched lanes and waited, the chat showed nothing about which lanes existed or how they were doing, while the Settings panel had exactly that information a screen away. **One card, not two.** `RunCard` is extracted out of `PiKitLanesPanel` into `PiKitRunCard.tsx` and rendered by both surfaces. The issue was explicit about this: a second lane card would drift from the first the moment either changed. The extraction is behaviour-neutral — the panel's own tests pass untouched. **Correlation is a pure function.** `pikitRunRef` reads the run id out of the row's argument summary, which the parser already attaches: `lanes_wait` and `lanes_status` take a `run` argument, and `lanes_spawn` names its run only in the result. So an in-flight spawn correctly resolves to nothing rather than guessing. Matching `run-<stamp>` rather than any token keeps a stray word in a result from being read as a run id. **Live in flight, frozen after** (decided 2026-07-27). Polling while the call runs is what makes `lanes_wait` worth watching; freezing afterwards keeps a replayed row from quietly rewriting itself from a run that has since moved on or been pruned. A finished run whose status is gone says so plainly instead of rendering an empty box. Polling is scoped to a mounted, open row — `Disclosure` keeps closed bodies out of the DOM, so a transcript full of old lanes rows costs nothing — and `startPiKitLanesPolling` is idempotent, so it will not double the interval or stop the Settings panel's own poll. **Abandon is inert in a transcript.** Acting on a run belongs in the panel that owns it; a destructive action two clicks from a replayed message is a trap. Refs #362
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
#362 PR 3 — the last slice of that issue.
When an agent dispatched lanes and waited, the chat showed nothing about which lanes existed or how they were doing, while the Settings panel had exactly that information a screen away.
One card, not two
RunCardis extracted out ofPiKitLanesPanelintoPiKitRunCard.tsxand rendered by both surfaces. The issue was explicit about this — "avoid a second divergent lane card" — and it is right: a copy drifts from the original the moment either changes.The extraction is behaviour-neutral: the Settings panel's own tests pass untouched, which is the issue's acceptance criterion for it.
Correlation is a pure function
pikitRunRefreads the run id out of the row's argument summary, which the parser already attaches (#387):lanes_wait/lanes_statusrunargument, present immediatelylanes_spawnIt matches
run-<stamp>rather than any token, so a stray word in a result is not read as a run id. Pure, so the correlation is testable without a store, a timer, or a chat — 10 tests.Live in flight, frozen after
The open decision, resolved:
lanes_waitA finished run whose status is gone says so plainly (
No lane status retained for run-…) rather than rendering an empty box; an in-flight one with no status yet says it is waiting.Polling is scoped to a mounted, open row —
Disclosure(#385) keeps closed bodies out of the DOM, so a transcript full of old lanes rows costs nothing — andstartPiKitLanesPollingis idempotent, so it neither doubles the interval nor stops the Settings panel's poll on cleanup.Abandon is inert in a transcript
readOnlyhides both abandon affordances. Acting on a run belongs in the panel that owns it; a destructive action two clicks from a replayed message is a trap.Tests
16 new. Verified load-bearing — removing the live gate fails "never polls once the call has finished"; ignoring
readOnlyfails "offers no Abandon control in a transcript".lanes_waitargument,lanes_spawnresult, in-flight spawn resolves to null, other servers ignored, no detail, and an ordinary word is not a run idValidation
bun run test:unit— 119 files, 1640 passedbunx tsc --noEmitclean;bun run lintcleanNot done
No VRT scenario for a
lanes_waitrow with lanes — the mock emits nopickforge-lanescall, so that needs a fixture. Flagging rather than skipping silently.Closes #362