Keep master's quiet system/rate_limit_event handlers while preserving
the story-62 permission_request handler (the core feature).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the "agents-at-work" list section from AgentPanel. The roster
badges with flying lozenge animations already convey which agents are
active, making the redundant list unnecessary.
- Remove StatusBadge, DiffCommand, EditorCommand components
- Remove expandedKey, logEndRefs, fade-timer state and effects
- Remove handleStop (no more Stop buttons)
- Keep agents state + SSE subscriptions (roster badges still need it)
- Delete diff-command and fade-out tests (feature removed)
- Add test asserting no agent-entry divs are rendered
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change chat input from <input> to <textarea> so multi-line messages
are supported. Enter (without Shift) still sends; Shift+Enter inserts
a newline via the native textarea behavior.
- Replace <input> with <textarea rows={1}> in Chat.tsx
- Update onKeyDown: guard sendMessage() with !e.shiftKey check
and call e.preventDefault() to suppress the default newline on Enter
- Update inputRef type from HTMLInputElement to HTMLTextAreaElement
- Add style props: resize:none, overflowY:auto, fontFamily:inherit
- Add 3 new Vitest tests covering all 3 acceptance criteria (AC1-AC3)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When Claude Code requires user approval before executing a tool (file
writes, commits, etc.) the agent sends a permission_request message
over the WebSocket. The web UI now intercepts that message, surfaces a
modal dialog showing the tool name and input, and lets the user approve
or deny. The decision is sent back as a permission_response, allowing
the agent to continue or adjust its approach.
Backend changes:
- claude_code.rs: parse "permission_request" NDJSON events from the PTY,
block the PTY thread via a sync channel, and write the user's decision
back to the PTY stdin as a JSON permission_response.
- chat.rs: thread an optional UnboundedSender<PermissionReqMsg> through
to the provider.
- ws.rs: create a permission-request channel, forward requests to the
client, collect responses via a pending-perms map, and interleave all
of this with the active chat session using tokio::select!.
Frontend changes:
- client.ts: add permission_request to WsResponse, permission_response
to WsRequest, onPermissionRequest handler to ChatWebSocket.connect(),
and sendPermissionResponse() method.
- types.ts: mirror the same type additions.
- Chat.tsx: add permissionRequest state, wire onPermissionRequest
callback, and render an approval modal with tool name, input context,
Approve and Deny buttons.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add data-testid="roster-dot-{name}" to both active and idle dot spans for testability
- Change idle badge from grey (#888, #555, #333) to green (#3fb950, #3fb95015, #3fb95040)
- Update idle label from "idle" to "available" to reinforce positive availability signal
- Update tooltip from "— idle" to "— available" for consistency
- Active/running agents retain blue (#58a6ff) pulsing dot styling unchanged
- Add 4 new Vitest tests covering green idle dot, green badge styling, blue active dot, and blue active badge
Closes story 81: Agent roster badges show availability state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Suppresses the noisy system-init notification '[model | apiKey: source]'
and rate limit notifications that were being streamed into the chat UI
from the claude_code provider. Normal chat functionality is unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>