Repository navigation
refactor(composer): toolbar reads ComposerCapabilities instead of the agent session - #1892
reachrazamair wants to merge 6 commits into
Conversation
… agent session Step 4 of the Group Chat composer parity plan. No visual or behavioural change in AI chat. New src/renderer/components/ChatComposer/capabilities.ts: - ComposerCapabilities: imageAttach, upload, voice, saveToHistory, permission, thinking, modelEffort. - deriveAiComposerCapabilities(): terminal mode offers nothing; permission is supportsReadOnlyMode, thinking is the provider streaming its reasoning, imageAttach is aiCanAttachImages() (the existing attach rule, now one function InputArea also uses for its other attach gates). - GROUP_CHAT_COMPOSER_CAPABILITIES: attach, upload and voice on, every per-tab agent setting off. imageAttach stays on, as the room offers Attach today, until step 9 derives it from the moderator's provider. Nothing renders it yet. ToolbarControls no longer takes a Session. Each optional control reads its flag; the values it shows come as props (permissionMode, terminalCwd, agentId for the permission wording); tab writes leave through onPermissionModeChange and onThinkingModeChange, bound for AI by the new useAiTabToolbarBinding hook, whose callbacks depend only on the agent and tab ids. InputArea memoizes the capabilities on their sources, so a keystroke does not hand the memoized toolbar new props. The Prompt Composer button shows when its callback is passed (InputArea passes it in AI mode only, as before), and the phone options sheet mounts when one of its section flags is on, which equals the old AI-mode gate. A toolbarExtras slot renders in the toggle group before the Enter toggle, for step 5's Read-Only toggle. ComposerOptionsSheet and ModelEffortPills already took no session and are unchanged. Deviation from the plan's capability list: only flags with a reader exist. Deferred, each to be added by the change that first reads it: - commandMode, slashCommands, shellTabCompletion: step 8, where the shared shell mounts the command ladder, slash and shell completion hooks per capability. - fileMentions: step 6 or 8, when the shared textarea's @ picker needs to know whether it may offer file and folder categories. - mentionRouting: step 8, if the shell mounts MentionRoutingBar. - sendMenu: step 8 at the earliest; the send column already takes its menu as an optional prop, so a flag may never be needed. Tests changed only where they built a session prop: ToolbarControls.test.tsx rendered the toolbar with session fixtures and asserted tab writes through a mocked updateSessionWith. It now passes capabilities and values, and asserts the onPermissionModeChange / onThinkingModeChange calls; the tab-write assertions moved to useAiTabToolbarBinding.test.ts. New tests cover each AI flag from its source, the room constant, capability-gated controls, the toolbarExtras slot, and the phone "..." with no sheet in terminal mode.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review: 2
Please check the settings in the CodeRabbit UI or the
|
[Medium impact] The PR appears safe to merge; no actionable regression was found. SummaryMoves optional toolbar controls behind
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[InputArea] --> B[deriveAiComposerCapabilities]
A --> C[useAiTabToolbarBinding]
B --> D[ToolbarControls]
C --> D
D --> E[Desktop controls]
D --> F[ComposerOptionsSheet]
E --> C
F --> C
C --> G[updateSessionWith]
Reviews (1) · Last reviewed commit: "refactor(composer): toolbar reads Compos..." · Reviewed by Greptile |
Drops "AI tab binding `useAiTabToolbarBinding()`" from the CLAUDE.md index line: a label and a symbol with no path. Naming the hook with its full path would take the line to 329 characters, past the docs:verify cap of 320. The full entry in docs/agent-guides/CANONICAL-UTILITIES.md already names useAiTabToolbarBinding with its path in its opening sentence.
…ties (composer index lines trimmed to symbols and paths)
The Progress section and the Step sequence table still said steps 2-5 were on unmerged stacked branches. Step 2 merged into rc as #1890 (9d6f5b2), so its Progress row cites the rc merge commit as step 1's does, and its Step sequence note says merged. Steps 3, 4 and 5 name their PRs (#1891, #1892, #1945), and step 3 now sits off rc rather than on step 2. The step commits in both tables are unchanged: each branch's tip moved on 2026-10-28 only by a CLAUDE.md index trim and the merges that carry it up the stack, which complete no rows. The Progress intro says so.
…ties (IME guard and picker Escape fixes) # Conflicts: # docs/agent-guides/CANONICAL-UTILITIES.md
Stacked on #1891 (and #1890 below it). Step 4 of the Group Chat composer parity plan (
Plans/group-chat-composer-parity.md). No visual or behaviour change in AI chat.What changed
src/renderer/components/ChatComposer/capabilities.tsholdsComposerCapabilities:imageAttach,upload,voice,saveToHistory,permission,thinking,modelEffort.deriveAiComposerCapabilities()builds the AI's flags. Terminal mode offers nothing,permissioncomes fromsupportsReadOnlyMode, andthinkingfrom the existingsupportsThinking.aiCanAttachImages()is the old attach rule moved into one function;InputAreauses it for its other attach checks too.GROUP_CHAT_COMPOSER_CAPABILITIESis a frozen constant (attach, upload and voice on, the four per-tab agent settings off). Nothing renders it yet; the next step does.ToolbarControlsno longer takes aSession. It takespermissionMode,terminalCwdandagentIdas values. Tab changes go out throughonPermissionModeChange/onThinkingModeChange, which the newuseAiTabToolbarBindingsupplies for AI, with callbacks that depend only on the agent and tab ids.InputAreamemoizes the capabilities object, so typing does not hand the toolbar new props.toolbarExtrasis a slot in the toggle group, ready for the room's Read-Only toggle.Deviation from the plan's flag list
The plan lists 13 flags. Only the seven above have a reader today, so the other six are deferred to the step that first reads each:
commandMode,slashCommandsandshellTabCompletion(step 8),fileMentions(step 6 or 8),mentionRouting(step 8), andsendMenu(step 8 at the earliest, and possibly never, since the send column already takes its menu as a prop). The plan document records this.Tests
ToolbarControls.test.tsxis the only existing test changed: it built session props and checked tab writes through a mockedupdateSessionWith, and now passes capabilities and values and checks the callbacks. The tab-write checks moved touseAiTabToolbarBinding.test.ts.ComposerOptionsSheetand the InputArea tests pass unchanged. New tests cover each AI flag from its source, the room constant, controls hidden by their flag, and thetoolbarExtrasplacement.Found, not fixed here
On a phone, AI terminal mode draws a "..." with no sheet behind it. That predates this change; a test now pins the current behaviour.