Composer interaction layout

Current layout for function forms, questions and tool approvals. The existing neutral dark palette, sans-serif interface, 12px spacing and 28px decision controls remain consistent. No new theme or dependency is introduced.

The examples illustrate the current layout. The shared code-block contract is specified under Typography and Discussion behavior; actual installation and visual acceptance remain separate checks.

Tool approval

Your input is needed1/1

Allow this command?

echo approval-layout-check

The two approval actions share the bottom row and submit directly. There is no separate selection, discussion or Send step. Narrow composers keep both controls inside the action region without clipping.

Multiple questions

The current-question panel, navigation and acceptance are specified below.

Function form

Function forms show task inputs only. The browser Workflow retains its task and optional target URL; action limits, timeout and backend are internal controls with working defaults. The same rule applies to Programs Use, favorites and reopened forms. Browser command backend and session handles remain internal. Text polishing chooses an appropriate style from the supplied text unless an internal caller specifies one. Document page ranges, output destinations and revision targets remain task inputs. Pending Use requests are consumed only after chat initialization finishes, so initialization cannot clear the requested form. Hidden or advanced execution parameters have no disclosure or replacement hint. Goal details retain progress and task controls but have no agent or budget editors. Internal callers retain explicit overrides. New Goals select supported reasoning effort with one tool-free model request based on task complexity, falling back to configured defaults on invalid output or failure. Resumed Goals retain saved roles; models, timeouts and budgets retain their configured defaults.

The parameter body retains 12px padding on every side. Automatic height measurement releases textarea flex growth and includes its native row height and border, so the last field cannot consume the bottom padding.

gui_agent

Function-form controls retain their existing header placement. Decision cards own their bottom action row, with no wrapper-level discussion overlay.

Typography

Decision headings, progress, labels, buttons and shared textarea content use the application sans-serif family and base font-size token. Text and placeholders share a 1.5 line height; input text does not shrink at desktop breakpoints. Command and JSON code blocks use the shared monospace font; their language labels use the same font, base size and line height as the first code line. Other interface text remains sans-serif. Decision prompts and field headings use weight 600; values, hints and placeholders use weight 400. This applies to approval, question, multi-question, function-form and discussion states. Button height centers text without changing its line height.

Discussion behavior

Tool approvals present only direct Allow once and Deny actions. Ordinary questions retain Chat about this, which opens an inline feedback field within the existing decision card. The original question stays visible as read-only text, without duplicated editable answer controls. Commands and JSON arguments share the OperationCode component, with the secondary theme background and an inset one-pixel theme border, plus a compact copy icon aligned with the first code line. The inset border preserves padding and toolbar alignment in both light and dark themes. There is no separate language toolbar. Command arguments appear inside native execution-details disclosure, with a 12px gap; the working directory appears only in the JSON arguments. Other tools retain their exact structured arguments, and sandbox escalation explanations remain visible. Copy success is shown only after clipboard acknowledgment; failure is announced. Headings, body text and the discussion editor border share the same left edge, 12px inside the outer container. The discussion editor uses the shared Textarea width and 12px inner padding, without negative margins or an expanded width. The read-only operation context uses the same border alignment, with no negative margins. The discussion editor has a 96px minimum height, and its heading identifies discussion rather than an unanswered question. Step progress is hidden during discussion. Opening or cancelling the field sends nothing and leaves the wait unresolved. The user writes what they want to discuss and explicitly sends it. Deny remains a separate action that declines the operation without creating a discussion turn.

Sending discussion binds the original question, tool details and the user's feedback to the exact canonical wait. Only after decline is acknowledged does the existing session queue send the contextual feedback and request a text-only reply. Ordinary chat drafts and attachments are unchanged. Unknown delivery retains the same command and feedback for retry; competing approval controls are blocked during submission. Switching conversations cannot retarget the message.

Reference

Claude Agent SDK associates denial feedback with the original tool invocation. OpenCode allows rejection feedback. OpenProgram keeps its canonical terminal decline and existing chat queue; it does not synthesize a first-person rejection speech or treat ordinary questions as tool permission requests.

The decision action row is a non-shrinking sibling of the scrolling body. Expanding execution details changes the body height above it; the actions remain anchored to the bottom of the composer, including during height transitions and when content exceeds the available viewport.

When an authoritative execution reaches a terminal state, the active conversation reloads its persisted messages and tool results automatically, provided a newer execution is not active. This reconciles durable approval continuations whose original streaming connection has ended. When a continuation opens another approval without its original event sink, it publishes the new question on the shared WebSocket event stream, so consecutive approvals remain visible.

Project rule management

History project settings use correlated permission-rule requests. Correlated replies are non-coalescing WebSocket frames; rule broadcasts coalesce only within one project. A successful write is read back before acknowledgment; failed or unknown writes retain the draft. Project-scoped broadcasts update other open views. Exact persistent approval grants are also verified after writing. Authenticated interactive owner operations read current merged rules at the next operation boundary; previously authorized calls and already admitted children retain their captured authorization.

A terminal declined or expired wait projects an explicit outcome into its own assistant history node through the durable DAG outbox. This does not execute the pending operation or create another model turn; replay does not duplicate the notice.

Long-lived approvals

Human tool approvals have no default expiry. The durable wait retains the exact operation and file fingerprints while the safe-point handoff ends its attempt and releases the execution slot. Resume loads the persisted checkpoint; it does not keep a live model request waiting. Resume also reuses the exact system prompt saved for that turn, instead of regenerating memory, date or project context and treating those changing text blocks as a runtime incompatibility. The saved browser-tool selection also remains stable while Desktop Page inventory connects or disconnects; actual browser calls still validate live Page access. Model, tool implementation, permissions and execution location are still validated. An incompatible continuation reports that execution did not resume; a saved approval alone is not presented as completed execution. After canonical recovery reaches running or completed, its own prior continuation error metadata is cleared, so the resulting model reply is rendered normally. Replaying that projection repairs an already completed message without rerunning any operation. Explicit deadlines remain available for non-approval waits. Cancellation and terminal execution events remove their pending decisions, including after reconnect. Previously expired requests remain expired. Job recovery handles only Job admissions; conversation recovery uses its own control service. Once a resumed operation has paused for another reason, its old answer does not automatically retry it on restart.

File edit, write and structured patch approvals bind the resolved paths and their current contents. Before dispatch and again before mutation, the tool checks that approved file state. Missing or changed targets are not overwritten or recreated using an old approval. The agent receives a non-executed result and must read the current state before proposing another operation; the approval UI shows only the current operation, with no change-history comparison. Opaque shell commands do not expose a complete file write set and cannot claim this file-specific guarantee.

References: Claude Agent SDK documents indefinite canUseTool waits and deferred persistence. OpenCode permission/next.ts stores pending decisions until reply; Codex tools/approvals.rs awaits a user decision tied to the operation. Those mechanisms inform lifecycle boundaries, not copied implementation.

Acceptance

For ordinary questions in the default installed App, opening discussion exposes an empty feedback field with original context; cancelling retains the request; sending contextual feedback produces a model reply with no tool execution; Deny alone produces no discussion message. Confirm pending submission cannot approve and retries keep one command and one message.

The implementation uses QuestionMode, the shared Textarea and the existing canonical wait command and session send queue. Runtime acceptance evidence is maintained with the release.

Composer interaction design

Question panel above the composer

1/2Choose the output format

Pending questions use the same width as the ordinary composer. The supplied Claude screenshots define the structure: a progress badge and current question in the header; full-width neutral option rows with a title, optional description and number shortcut; an Other row with its input visible; Back on the left and Skip plus Next or Submit on the right. Existing application fonts, base size, theme colors and spacing remain authoritative. Collapse and close both reduce the panel to its header; reopening retains answers and sends no command.

One question is visible at a time. Next validates the current answer and changes the visible question without sending anything. Back retains all selections. The last Submit sends one ordered answer list through the existing acknowledged execution command. Skip declines the entire request through the existing command; the current backend requires a valid answer for each question, so this interface does not introduce partial or empty answers. Explicit permission approval still requires Deny or an allowed Allow scope. Multiple pending requests remain separate keyed session panels, and completed receipts stay in the conversation.

Digits select options only outside editable text. Ctrl or Cmd with Enter advances or submits; IME composition and multiline discussion retain their editing semantics. Arrival never moves focus. The card body scrolls on short screens while header and actions stay visible. The chat draft, attachments, function form, normal send action and owning session remain independent.

Optional question_title and option_descriptions metadata provide the option-row presentation. Existing string answer values and full textual prompts remain available to other clients. In-memory request drafts survive remounts and session switches. Uncertain delivery still freezes the original command and payload for retry, including discussion declines. The session and wait jointly identify the shared discussion request; its message, feedback, in-flight and sent state survive component remounts. Option descriptions render only explicit string entries; inherited object properties are not presentation metadata and do not restrict valid option labels. The reference is the two user-supplied screenshots; no upstream implementation or service is required.

Layout comparison and acceptance

Adopt the screenshot's current-question layout and full option rows. Replace separate narrow choice buttons and simultaneous question lists. Retain the existing permission, discussion and acknowledged command behavior. Reject new sidebar widths, fonts, themes, autofocus and automatic submission. Acceptance exercises actual Composer and QuestionMode, ordered Back/Next/Submit, numeric shortcuts, custom and multiple answers, remounts, narrow and short views, collapse, discussion, per-session isolation, uncertain retry and receipts.