feat(protocol,gui-app): managed-command Monitors & Shells — delivery chips, UI surface - #855
Conversation
Monitor and shell output reaches an agent as a real queue item rather than a side-channel, so the chat queue is the single ordering authority for everything an agent will be asked to work on next. - `chat.subscribe` v1.5 carries the delivery-backed queue items; the registry's stream lines are hoisted into annotated consts so declaration emit stays under TS7056 now that the method carries six minors. - `host-background` request-context origin distinguishes host-initiated work from work done on behalf of a caller. - The composer queue surface renders delivery chips, keeps them reorderable alongside user messages, and reconciles them against the host's view. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
Both sides independently added a `chat.subscribe@1.5` and both hit TS7056 on the stream registry, so the conflicts were design-level rather than textual. - `chat.subscribe`: upstream's 1.5 (`archivedAt` + `sameTurnSteeringSupported`) keeps that number; managed-command queue items move to 1.6. 1.4 is now frozen against BOTH additions, and a new frozen 1.5 shape pins the pre-union queue so 1.6 cannot mutate it. - `registry.ts`: kept upstream's split-`chat.subscribe`-via-spread fix for TS7056 and dropped our hoisted-per-method-const fix. One workaround is enough; ours reduced to adding the 1.6 entry. - `compact-conversation.ts`: narrow the queue scan to prompt items, which alone carry `messageId`. A managed-command item stays in the settled list because it is still a valid reorder target. - `queued-message-surface.tsx`: adopt `TooltipWrapper` for the managed-command badge; upstream added a lint rule banning native `title` tooltips after this code was written. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
Protocol: new managedCommand.subscribeList/.subscribeOutput streams and
start/stop/delete unary methods (all @1.0); resources.subscribe@1.4 adds the
managed-command owner kind with frozen pre-1.4 wire; commandKind on the
managed-command queue item; a defaulted managedCommand {commandId, kind} key
on the resume-divider trigger (scoped compat exception per the mcp/live
precedent).
GUI: epic-level Monitors & Shells sidebar (kind-explicit rows, status dots,
CPU/mem readouts, chat backlinks); renderer-local output-window tile with an
interleaved stdout/stderr/lifecycle timeline, follow mode, bounded scroll-up
paging with explicit prepend anchoring, and dead/disconnected/unsupported
states; chip and divider doors; running-work strip rows via client-side
composition; kind-explicit copy throughout; start/stop/delete with a
history-destroying delete confirmation. Removes the orphaned ChatControlStrip.
Review fixes included: keyboard Enter no longer hijacked from nested row
controls; stale tile restores show a dead state instead of a blank window.
Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
…hase fixture The chat-turn-completions fixture landed on main before chat.subscribe@1.6 split queued items into a discriminated union, so the merged tree left it without the `kind` tag the union now requires. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
The Background panel now separates managed-command rows from harness work with a divider and an honest header count (Stop all's reach matches what it says), gives managed rows a Stop-only hover action and elapsed time. The live resume divider says Monitor/Shell when the trigger names the kind; the chip tooltip uses the monitor/shell vocabulary. New shared kind icons (Radar for monitors, CirclePlay for shells) applied across sidebar, output window, strip, chip, and resources popover; color stays status-only. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
…t-raccoon Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com> # Conflicts: # clients/gui-app/src/components/epic-canvas/canvas/tab-group-view.tsx # clients/gui-app/src/components/epic-canvas/canvas/tab-strip.tsx # clients/gui-app/src/components/epic-canvas/dnd/drag-overlay-chip.tsx # clients/gui-app/src/components/epic-canvas/renderers/tile-render.tsx # clients/gui-app/src/stores/epics/canvas/tile-kind-types.ts # clients/gui-app/src/stores/epics/canvas/tile-kinds.ts # clients/gui-app/src/stores/epics/canvas/tile-schema/index.ts # clients/gui-app/src/stores/epics/canvas/types.ts
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Summary by CodeRabbit
WalkthroughThis change adds managed-command protocol contracts, live stores, output tiles, sidebar and chat surfaces, lifecycle controls, resource metadata, persistence fields, compatibility handling, and GUI and protocol tests. ChangesManaged command integration
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@clients/gui-app/src/__tests__/acceptance/managed-command-s5-sidebar.test.tsx`:
- Around line 461-470: Dispose the first epic store before the second render in
this test by calling the existing epicHandle cleanup/disposal path immediately
after the initial empty-sidebar assertions and before renderSidebar() is called
again. Preserve the second render’s handle for afterEach cleanup, ensuring both
OpenEpicStoreHandle instances and their Yjs documents are released.
In `@clients/gui-app/src/components/chat/chat-lower-dock.tsx`:
- Around line 64-73: Update ChatLowerInteractionSurfaces so its
backgroundVisible calculation matches ChatLowerDock: include running managed
commands, not only non-empty backgroundItems, when selecting the scroll budget
and top spacing. Reuse the shared visibility state if available; otherwise
derive the managed-command count with useRunningManagedCommandsForChat using the
same epicId and chatId inputs.
In
`@clients/gui-app/src/components/epic-canvas/renderers/__tests__/managed-command-output-tile.test.tsx`:
- Around line 307-335: The test uses getByTestId and queryByTestId to locate the
jump-to-live button and timeline elements, but these components expose proper
accessibility roles and names (the button has role="button" with name "Jump to
live", and the timeline has role="log" with an aria-label). Replace all
queryByTestId("managed-command-output-jump-live") calls with
queryByRole("button", { name: "Jump to live" }) and all
getByTestId("managed-command-output-jump-live") calls with getByRole("button", {
name: "Jump to live" }). Update the timeline() helper to use getByRole("log")
instead of getByTestId to verify the accessible role is properly exposed. Keep
data-testid attributes only for elements that share a single role, such as
per-line rows and timestamp cells.
In
`@clients/gui-app/src/components/epic-canvas/renderers/managed-command-output-tile.tsx`:
- Around line 215-230: Update the onScroll callback to guard the loadOlder call
when fatalClose is active, preventing top-of-scroll loading after the stream has
closed. Preserve the existing loadingOlder and reachedStart protections inside
loadOlder, and include fatalClose in the callback’s dependencies as needed.
In
`@clients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsx`:
- Around line 148-190: Replace the row-level role="button" container and its
keyboard activation with a native button covering only the command title/content
area, keeping ManagedCommandLifecycleActions and ManagedCommandChatBacklink as
sibling controls outside that button. Move the managed-command-row-${command.id}
test id onto the new activation button, preserve open() behavior and styling,
and remove the redundant role/keyboard guard from the non-interactive wrapper.
- Around line 45-54: Update ManagedCommandsPanelBody and
ManagedCommandChatBacklink so UNKNOWN_HOST_PLACEHOLDER is never used to create a
chat tile when chat.hostId is null. Disable the backlink until hostId resolves
to a real host, or handle the nullable fallback before creating the tile ref;
preserve normal backlink behavior for valid hosts.
In
`@clients/gui-app/src/components/managed-commands/__tests__/managed-command-lifecycle-actions.test.tsx`:
- Around line 17-24: The managed-command lifecycle tests only cover non-pending
mutations. Extend the mocks and tests around useManagedCommandStart,
useManagedCommandStop, useManagedCommandDelete, and ActionButton to set each
mutation’s isPending state to true and verify the corresponding action button is
disabled, preserves its label, and renders AgentSpinningDots; cover the pending
behavior for all three actions.
In `@clients/gui-app/src/components/resources/resource-monitor-popover.tsx`:
- Around line 2340-2345: Update resourceOwnerKindForRef, isOwnerNodeRef, and
OpenOwnerLocation to recognize ManagedCommandOutputTileRef as an openable owner,
using the appropriate managed-command resource kind. Extend openResourceOwner to
focus an already-open managed-command output tile without relying on a record
fallback, and add an acceptance test covering focus of an open output tile.
In `@clients/gui-app/src/lib/host-rpc-policy/host-method-policy-table.ts`:
- Around line 386-403: Serialize managedCommand.start, managedCommand.stop, and
managedCommand.delete through one shared FIFO queue identity so lifecycle
actions execute in request order across methods. Update the host-RPC
coordinator/policy configuration rather than relying on each method’s separate
queue, and add coverage verifying both start → stop and start → delete ordering.
In `@clients/gui-app/src/lib/managed-commands/managed-command-copy.ts`:
- Around line 76-82: In the managedCommandStatusTone function, the final return
statement does not account for a null exitCode, treating an unknown exit outcome
as a failure. Update the last return statement to handle the case where exitCode
is null by returning "idle" (neutral) in that scenario, while preserving the
existing logic that returns "idle" for exitCode === 0 and "failed" for a
non-zero exitCode.
In `@protocol/src/host/agent/gui/subscribe.ts`:
- Around line 2-6: Update the stale version references in
protocol/src/host/agent/gui/subscribe.ts:2-6, 317-326, and 375-383. In the
header, identify chatSubscribeV16 as chat.subscribe@1.6, the frozen range as
`@1.0`–@1.5, and state that 1.6 bridges to hosts supporting 1.0–1.5; change
“pre-1.5 payload” to “pre-1.6 payload”; and attribute the unshipped variant and
status rationale to 1.6 rather than 1.5.
In
`@protocol/src/host/managed-command/__tests__/managed-command-contracts.test.ts`:
- Around line 166-184: Add a matching registry membership test in the
“managedCommand stream registry membership” suite for
managedCommand.subscribeOutput, asserting its registered latest minor version
and contract.method just as the existing subscribeList test does. This should
detect both missing registration and an incorrect method string.
In `@protocol/src/host/managed-command/subscribe.ts`:
- Around line 22-30: Update the “Gaplessness” documentation near the snapshot
stream description to stop claiming that snapshot names the position where its
lines end. Describe snapshot.start as the position where its lines begin, and
explain that the host retains the read position while output frames continue
with the client appending them, without introducing an end cursor or client-side
cursor.
In `@protocol/src/persistence/epic/content-blocks.ts`:
- Around line 602-605: Extract the shared monitor/shell kind enum into a common
protocol module under the existing `@traycer/protocol/common` area, then update
managedCommand in the persistence schema, managedCommandKindSchema, and the
queue item’s commandKind to reference it. Preserve the current nullable/default
behavior of managedCommand and ensure future kind additions require changing
only the shared definition without introducing persistence-to-host imports.
- Around line 126-136: Replace deprecated z.ZodIssueCode.custom with the string
literal "custom" in each ctx.addIssue call across content-blocks.ts and the two
corresponding locations in messages.ts, while preserving the existing issue
messages, paths, and validation behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4a61709f-e779-4ca6-b9fb-3434f6953625
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (115)
clients/gui-app/src/__tests__/acceptance/managed-command-s4-output-window.test.tsxclients/gui-app/src/__tests__/acceptance/managed-command-s5-sidebar.test.tsxclients/gui-app/src/__tests__/acceptance/managed-command-s6-s7-chat-doors.test.tsxclients/gui-app/src/__tests__/acceptance/managed-command-s8-s9-tile-ref-resources.test.tsxclients/gui-app/src/components/chat/__tests__/chat-background-items-panel.test.tsxclients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsxclients/gui-app/src/components/chat/__tests__/managed-command-chat-surfaces.test.tsxclients/gui-app/src/components/chat/__tests__/queued-message-reorder-dnd.test.tsclients/gui-app/src/components/chat/__tests__/queued-message-surface.test.tsxclients/gui-app/src/components/chat/__tests__/queued-message-utils.test.tsclients/gui-app/src/components/chat/chat-background-items-panel.tsxclients/gui-app/src/components/chat/chat-lower-dock.tsxclients/gui-app/src/components/chat/chat-queue-utils.tsclients/gui-app/src/components/chat/managed-command-strip-rows.tsxclients/gui-app/src/components/chat/queued-message-surface.tsxclients/gui-app/src/components/chat/queued-message-utils.tsclients/gui-app/src/components/chat/segments/__tests__/autonomous-resume-segment.test.tsxclients/gui-app/src/components/chat/segments/autonomous-resume-segment.tsxclients/gui-app/src/components/epic-canvas/__tests__/chat-tile-queue-edit-steer.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/chat-tile.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/left-panel-registry.test.tsclients/gui-app/src/components/epic-canvas/__tests__/root-dnd-commits.test.tsclients/gui-app/src/components/epic-canvas/canvas/tab-group-view.tsxclients/gui-app/src/components/epic-canvas/canvas/tab-strip.tsxclients/gui-app/src/components/epic-canvas/dnd/drag-overlay-chip.tsxclients/gui-app/src/components/epic-canvas/epic-shell.tsxclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-tile-session-state.test.tsclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-tile-setup.test.tsxclients/gui-app/src/components/epic-canvas/renderers/__tests__/managed-command-output-tile.test.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile-control-strip.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile-lower-surfaces.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile.tsxclients/gui-app/src/components/epic-canvas/renderers/dead-tile-banner.tsxclients/gui-app/src/components/epic-canvas/renderers/managed-command-output-tile.tsxclients/gui-app/src/components/epic-canvas/renderers/tile-render.tsxclients/gui-app/src/components/epic-canvas/renderers/use-chat-queue-actions.tsclients/gui-app/src/components/epic-canvas/sidebar/__tests__/managed-command-sidebar.test.tsxclients/gui-app/src/components/epic-canvas/sidebar/epic-sidebar.tsxclients/gui-app/src/components/epic-canvas/sidebar/left-panel-registry.tsclients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsxclients/gui-app/src/components/managed-commands/__tests__/managed-command-kind-icon.test.tsxclients/gui-app/src/components/managed-commands/__tests__/managed-command-lifecycle-actions.test.tsxclients/gui-app/src/components/managed-commands/managed-command-chat-backlink.tsxclients/gui-app/src/components/managed-commands/managed-command-connection-notice.tsxclients/gui-app/src/components/managed-commands/managed-command-kind-icon.tsxclients/gui-app/src/components/managed-commands/managed-command-lifecycle-actions.tsxclients/gui-app/src/components/managed-commands/managed-command-status-dot.tsxclients/gui-app/src/components/resources/__tests__/resource-monitor-popover.test.tsxclients/gui-app/src/components/resources/__tests__/resource-usage-chip.test.tsxclients/gui-app/src/components/resources/resource-monitor-popover.tsxclients/gui-app/src/components/resources/resource-usage-chip.tsxclients/gui-app/src/hooks/managed-command/use-managed-command-lifecycle-mutations.tsclients/gui-app/src/hooks/managed-command/use-managed-command-output-session.tsclients/gui-app/src/lib/chats/__tests__/chat-turn-completions.test.tsclients/gui-app/src/lib/chats/__tests__/compact-conversation.test.tsclients/gui-app/src/lib/chats/compact-conversation.tsclients/gui-app/src/lib/epic-selectors.tsclients/gui-app/src/lib/host-rpc-policy/host-method-policy-table.tsclients/gui-app/src/lib/managed-commands/managed-command-copy.tsclients/gui-app/src/lib/managed-commands/use-managed-command-door.tsclients/gui-app/src/lib/managed-commands/use-open-managed-command-output.tsclients/gui-app/src/lib/query-keys/index.tsclients/gui-app/src/lib/query-keys/managed-command-mutation-keys.tsclients/gui-app/src/providers/managed-command-list-stream-factory-override.tsclients/gui-app/src/providers/managed-command-list-stream-mount.tsxclients/gui-app/src/providers/managed-command-output-stream-factory-override.tsclients/gui-app/src/stores/chats/__tests__/chat-queue-reconciler.test.tsclients/gui-app/src/stores/chats/__tests__/chat-session-store.test.tsclients/gui-app/src/stores/chats/__tests__/optimistic-queue.test.tsclients/gui-app/src/stores/chats/__tests__/profile-durability-d1-queue-restamp.test.tsclients/gui-app/src/stores/chats/__tests__/rendered-messages.test.tsxclients/gui-app/src/stores/chats/chat-queue-reconciler.tsclients/gui-app/src/stores/chats/chat-session-store.tsclients/gui-app/src/stores/chats/optimistic-queue.tsclients/gui-app/src/stores/chats/rendered-messages.tsclients/gui-app/src/stores/epics/__tests__/left-panel-store.test.tsclients/gui-app/src/stores/epics/canvas/__tests__/managed-command-output-tile-schema.test.tsclients/gui-app/src/stores/epics/canvas/tile-kind-types.tsclients/gui-app/src/stores/epics/canvas/tile-kinds.tsclients/gui-app/src/stores/epics/canvas/tile-schema/index.tsclients/gui-app/src/stores/epics/canvas/tile-schema/managed-command-output-tile.tsclients/gui-app/src/stores/epics/canvas/types.tsclients/gui-app/src/stores/epics/left-panel-store.tsclients/gui-app/src/stores/managed-commands/__tests__/managed-command-list-store.test.tsxclients/gui-app/src/stores/managed-commands/__tests__/managed-command-output-store.test.tsclients/gui-app/src/stores/managed-commands/managed-command-list-registry.tsclients/gui-app/src/stores/managed-commands/managed-command-list-store.tsclients/gui-app/src/stores/managed-commands/managed-command-output-store.tsclients/gui-app/src/stores/resources/__tests__/resources-store.test.tsclients/gui-app/src/stores/resources/resources-registry.tsclients/gui-app/src/stores/resources/resources-store.tsclients/shared/host-transport/__tests__/resources-stream-client.test.tsclients/shared/host-transport/managed-command-list-stream-client.tsclients/shared/host-transport/managed-command-output-stream-client.tsclients/shared/host-transport/resources-stream-client.tsprotocol/scripts/compat/compat-exceptions.jsonprotocol/src/auth/request-context.tsprotocol/src/framework/__tests__/versioned-stream-rpc.test.tsprotocol/src/host/agent/gui/__tests__/chat-subscribe.test.tsprotocol/src/host/agent/gui/contracts.tsprotocol/src/host/agent/gui/subscribe.tsprotocol/src/host/index.tsprotocol/src/host/managed-command/__tests__/managed-command-chat-surfaces.test.tsprotocol/src/host/managed-command/__tests__/managed-command-contracts.test.tsprotocol/src/host/managed-command/contracts.tsprotocol/src/host/managed-command/index.tsprotocol/src/host/managed-command/subscribe.tsprotocol/src/host/managed-command/unary-schemas.tsprotocol/src/host/registry.tsprotocol/src/host/resources/__tests__/resources-subscribe.test.tsprotocol/src/host/resources/subscribe.tsprotocol/src/persistence/epic/__tests__/__fixtures__/epic-schema-surface.tsprotocol/src/persistence/epic/__tests__/content-blocks.test.tsprotocol/src/persistence/epic/content-blocks.ts
💤 Files with no reviewable changes (2)
- clients/gui-app/src/components/epic-canvas/renderers/tests/chat-tile-setup.test.tsx
- clients/gui-app/src/components/epic-canvas/renderers/chat-tile-control-strip.tsx
Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
protocol/src/host/registry.ts (1)
978-1000: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winFill
terminalLoginin every provider mutation upgrade.Each
providers.*@2.0->@2.1`` bridge callsupgradeLoginCapabilityFromV10, which fills `codePaste` but not `terminalLogin`. Compose it with `upgradeLoginCapabilityFromV40` so mutation responses from older hosts match the live capability shape.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@protocol/src/host/registry.ts` around lines 978 - 1000, Update every providers.*`@2.0` to `@2.1` mutation upgrade that currently calls upgradeLoginCapabilityFromV10 to also apply upgradeLoginCapabilityFromV40, ensuring older-host mutation responses include terminalLogin: null while preserving the existing null handling and codePaste filling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@protocol/src/host/registry.ts`:
- Around line 978-1000: Update every providers.*`@2.0` to `@2.1` mutation upgrade
that currently calls upgradeLoginCapabilityFromV10 to also apply
upgradeLoginCapabilityFromV40, ensuring older-host mutation responses include
terminalLogin: null while preserving the existing null handling and codePaste
filling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 06908c63-2452-46a0-ae20-8935b27e0774
📒 Files selected for processing (9)
clients/gui-app/src/components/epic-canvas/canvas/tab-strip.tsxclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-tile-session-state.test.tsclients/gui-app/src/components/epic-canvas/renderers/chat-tile-lower-surfaces.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile.tsxclients/gui-app/src/lib/host-rpc-policy/host-method-policy-table.tsclients/gui-app/src/stores/chats/__tests__/chat-session-store.test.tsclients/gui-app/src/stores/chats/chat-session-store.tsclients/gui-app/src/stores/epics/canvas/types.tsprotocol/src/host/registry.ts
- Chat composer keeps flush spacing when only a managed command is running: the dock and its parent now share one background-visibility predicate (chatBackgroundSectionVisible) so the scroll budget and top spacing agree with what the dock renders. - Managed-command sidebar rows no longer nest real buttons inside a role=button container: the activation door is a real <button> with Stop/Delete/backlink as siblings, so assistive tech sees every control. - protocol: correct stale chat.subscribe@1.5 comments now that the managed-command queue variant ships on 1.6, and fix the dangling projectManagedCommandQueueItemsForPreV15 reference. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
clients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsx (1)
143-146: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winDisable the door button when
hostIdis null.
openreturns without action whenhostId === null(Line 144), but the button at Line 163 stays enabled. A user can click it and get no feedback. Setdisabled={hostId === null}on the button so the no-op state is communicated, instead of leaving an active control that silently does nothing.♿ Proposed fix
<button type="button" + disabled={hostId === null} data-testid={`managed-command-row-${command.id}`} onClick={open} className={cn( "flex min-w-0 flex-1 items-center gap-2 rounded-sm text-left", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", + "disabled:cursor-not-allowed disabled:opacity-60", )} >Also applies to: 163-171
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@clients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsx` around lines 143 - 146, Disable the door button rendered near the open handler by binding its disabled state to hostId === null, while preserving the existing open function behavior and enabled state when a host ID is available.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@clients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsx`:
- Around line 143-146: Disable the door button rendered near the open handler by
binding its disabled state to hostId === null, while preserving the existing
open function behavior and enabled state when a host ID is available.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 61880a11-0cbe-424f-b938-1b4fc8cfecf9
📒 Files selected for processing (9)
clients/gui-app/src/__tests__/acceptance/managed-command-s8-s9-tile-ref-resources.test.tsxclients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsxclients/gui-app/src/components/chat/chat-lower-dock.tsxclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-lower-background-spacing.test.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile-lower-surfaces.tsxclients/gui-app/src/components/epic-canvas/sidebar/__tests__/managed-command-sidebar.test.tsxclients/gui-app/src/components/epic-canvas/sidebar/managed-command-sidebar.tsxclients/gui-app/src/lib/chat/chat-lower-scroll-budget.tsprotocol/src/host/agent/gui/subscribe.ts
…t-raccoon Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com> # Conflicts: # clients/gui-app/src/components/epic-canvas/__tests__/root-dnd-commits.test.ts # clients/gui-app/src/components/epic-canvas/canvas/tab-group-view.tsx # clients/gui-app/src/components/epic-canvas/dnd/drag-overlay-chip.tsx # clients/gui-app/src/stores/epics/canvas/tile-kind-types.ts # clients/gui-app/src/stores/epics/canvas/types.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
clients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsx (2)
524-533: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUpdate the test expectations for
managed-commands.The registry now exposes the always-visible
managed-commandspanel. The menu assertion omits"Monitors & Shells", so the rendered panel list does not match the expected list. The last-panel setup also leavesmanaged-commandsvisible, soAgentsis not the only remaining panel.Proposed test updates
"Agents", "Terminals", + "Monitors & Shells", "Artifacts", ... "terminals", + "managed-commands", "artifacts",Also applies to: 642-650
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@clients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsx` around lines 524 - 533, Update the epic-sidebar test expectations to include the always-visible “Monitors & Shells” entry exposed by the managed-commands registry. In the last-panel setup, hide managed-commands before asserting the remaining visible panels so Agents is the only remaining panel.
523-523: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHandle nullable
textContentbefore calling.replace.With strict null checks enabled, use
(item.textContent ?? "").replace(...).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@clients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsx` at line 523, Update the mapping expression in the epic sidebar test to handle nullable item.textContent before invoking replace, using an empty-string fallback while preserving the existing regular-expression cleanup behavior.Source: Coding guidelines
clients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsx (1)
188-188: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the redundant test-ID assertion.
Line 188 uses
getByTestId("active-agents-panel"). The following role query already verifies the visible Active agents control. Remove the test-ID assertion or replace it with an accessible role query.Suggested test change
- expect(screen.getByTestId("active-agents-panel")).toBeDefined(); expect( screen.getByRole("button", { name: /Active agents.*1 running/i }), ).toBeDefined();As per coding guidelines, tests under
clients/gui-app/srcshould use Testing Library role queries.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@clients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsx` at line 188, Remove the redundant getByTestId("active-agents-panel") assertion from the test, relying on the existing accessible role query that verifies the visible Active agents control. Keep the test focused on Testing Library role-based assertions in the chat lower dock test.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@clients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsx`:
- Line 188: Remove the redundant getByTestId("active-agents-panel") assertion
from the test, relying on the existing accessible role query that verifies the
visible Active agents control. Keep the test focused on Testing Library
role-based assertions in the chat lower dock test.
In `@clients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsx`:
- Around line 524-533: Update the epic-sidebar test expectations to include the
always-visible “Monitors & Shells” entry exposed by the managed-commands
registry. In the last-panel setup, hide managed-commands before asserting the
remaining visible panels so Agents is the only remaining panel.
- Line 523: Update the mapping expression in the epic sidebar test to handle
nullable item.textContent before invoking replace, using an empty-string
fallback while preserving the existing regular-expression cleanup behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 68fa3adb-0c89-4f81-a782-5e4e3f7909c4
📒 Files selected for processing (19)
clients/gui-app/src/components/chat/__tests__/chat-lower-dock.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/chat-tile-queue-edit-steer.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/chat-tile.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/epic-sidebar.test.tsxclients/gui-app/src/components/epic-canvas/__tests__/left-panel-registry.test.tsclients/gui-app/src/components/epic-canvas/__tests__/root-dnd-commits.test.tsclients/gui-app/src/components/epic-canvas/canvas/tab-group-view.tsxclients/gui-app/src/components/epic-canvas/canvas/tab-strip.tsxclients/gui-app/src/components/epic-canvas/dnd/drag-overlay-chip.tsxclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-tile-session-state.test.tsclients/gui-app/src/components/epic-canvas/renderers/__tests__/chat-tile-setup.test.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile-lower-surfaces.tsxclients/gui-app/src/components/epic-canvas/renderers/chat-tile.tsxclients/gui-app/src/components/epic-canvas/renderers/dead-tile-banner.tsxclients/gui-app/src/components/epic-canvas/renderers/tile-render.tsxclients/gui-app/src/components/epic-canvas/sidebar/epic-sidebar.tsxclients/gui-app/src/components/epic-canvas/sidebar/left-panel-registry.tsclients/gui-app/src/components/resources/__tests__/resource-monitor-popover.test.tsxclients/gui-app/src/components/resources/resource-monitor-popover.tsx
💤 Files with no reviewable changes (1)
- clients/gui-app/src/components/epic-canvas/renderers/tests/chat-tile-setup.test.tsx
…traycer-silent-raccoon Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
protocol/src/host/registry.ts (1)
5761-5781: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftAdd lower-minor stream projections before exposing these versions.
resources.subscribe@1.0–1.3cannot parse"managed-command"owners.chat.subscribe@1.4–1.5cannot parse managed-command queue items. The referencedprojectManagedCommandQueueItemsForPreV16projection is absent, and no resources projection is present in this tree. Add resolver branches and tests for snapshots, updates, andqueueChangedframes. ThemanagedCommandresume-divider field is additive and already has a compatibility exception; older peers may strip it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@protocol/src/host/registry.ts` around lines 5761 - 5781, Add lower-minor resolver projections before exposing resources.subscribe 1.0–1.3 and chat.subscribe 1.4–1.5, preventing managed-command owners and queue items from reaching peers that cannot parse them. Implement the missing resources projection and projectManagedCommandQueueItemsForPreV16, applying them to snapshots, updates, and queueChanged frames while preserving the existing managedCommand resume-divider compatibility behavior. Add tests covering each projection path and frame type.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@protocol/src/host/registry.ts`:
- Around line 5761-5781: Add lower-minor resolver projections before exposing
resources.subscribe 1.0–1.3 and chat.subscribe 1.4–1.5, preventing
managed-command owners and queue items from reaching peers that cannot parse
them. Implement the missing resources projection and
projectManagedCommandQueueItemsForPreV16, applying them to snapshots, updates,
and queueChanged frames while preserving the existing managedCommand
resume-divider compatibility behavior. Add tests covering each projection path
and frame type.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 91963055-3cb7-4dea-a0c5-1fd3f9438081
📒 Files selected for processing (2)
clients/gui-app/src/lib/epic-selectors.tsprotocol/src/host/registry.ts
…rface The remote-host transport (#188) seams every stream wrapper on IStreamClient so remote sessions can stand in for the local WebSocket client. The two managed-command wrappers landed in parallel and still demanded the concrete WsStreamClient, which no longer typechecks against the interface the gui-app hooks now hand out. Migrate them exactly like their chat/terminal siblings. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
…t-raccoon Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
…t-raccoon Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com> # Conflicts: # clients/gui-app/src/components/chat/queued-message-surface.tsx
…ommand props The chat-scrollbar composer-overlay suite arrived via the update-branch merge and builds ChatLowerDock props by hand; it predates chatId and runningManagedCommandCount. Same drift shape as the rail context-menu fixtures. Signed-off-by: Amiteshwar Randhawa <amiteshwar04@gmail.com>
|
@coderabbitai approve |
✅ Action performedComments resolved and changes approved. |
Summary
Client half of the managed-command (Monitor/Shell) subsystem: persistent host-supervised commands whose output reaches the owning agent as durable, reorderable chat-queue chips, with a full human UI.
chatQueuedItemSchemabecomes aprompt | managed-commandunion (chat.subscribe 1.4→1.5 with frozen wire + per-minor projection); newmanagedCommand.subscribeList/.subscribeOutputstreams and start/stop/delete unary methods (@1.0);resources.subscribe@1.4adds the managed-command owner kind; defaultedlive+managedCommand {commandId, kind}keys on the resume-divider trigger (scoped compat exceptions per the mcp precedent).Counterpart: traycerai/traycer-internal PR (host subsystem + wire).
Test plan
🤖 Generated with Claude Code