# Composer The prompt composer: context selectors, height, focus after send, alternate delivery, attachments, `@` mentions, overlays and `/btw`. ## Agent conventions - The composer reserves `/btw` for native `session.generate`, outside ordinary prompt/command submission. Its ephemeral question/answer window uses `DismissibleWindow` and `styles/components/session-aside.css`; cancellation and inactive/session transitions fence late results without interrupting the main session. - Keep agent, model and thinking controls in the composer footer via `PromptContextControls`, on one row with the actions on desktop and touch (truncate selector labels, never wrap the footer); adapt it with the named `prompt-composer` container rather than viewport-only breakpoints. Dense conversation toolbar/footer controls and the session list header actions use `--touch-target-size-compact` (the latter must fit five actions plus the panel-toggle reserve in the 220 px minimum sidebar); timeline markers use the compact control height rather than the global touch target. Toolbar touch spacing lives in `styles/panels/session-toolbar-touch.css`. - Composer height limits depend only on the visible conversation height: minimum 8% (44 px floor), maximum 60% (never below that minimum). `prompt-input/usePromptViewport.ts` observes the conversation and its intersection with `visualViewport`, including keyboard resize/pan. Store manually chosen heights as proportions so the field itself follows viewport changes; saved pixel heights convert to a proportion on the first valid measurement. Viewport-driven changes never overwrite the saved proportion; pointer and keyboard resize controls share the same limits and long drafts remain scrollable. - On desktop a send moves focus to the conversation stream for keyboard reading (arrows, paging, Space); a printable character typed there resumes the composer with that character (`prompt-input/type-to-focus.ts`), while fields, controls, IME composition and plain-key shortcuts keep their keys. Touch-only devices keep the keyboard closed. Do not add delayed refocus timers or a preference for this. - The composer's More actions menu offers the other follow-up delivery than Enter (Queue message when Enter steers, Steer now when Enter queues), enabled only in normal mode while the session runs and a draft can be sent; it reuses the shortcut's delivery resolution and its tooltip shows the `prompt-alternate-send` shortcuts: Alt+Enter plus Mod+Shift+Enter by default, except on macOS where Option+Return is the native line break and only Cmd+Shift+Return sends. Pickers ignore any modified Enter. Covered by `tests/browser/composer-alternate-send.test.ts` and `composer-picker-enter.test.ts`. - Composer overlays show attachment counts, shell-mode state and transient stop confirmation only; keep the textarea's semantic description and transient status announcement. Do not add a keyboard-shortcut strip or help footer. Keep overlay styling in `styles/components/prompt-help.css`, without changing field height limits or adding a footer row. - Composer attachments use one native-device action and project-scoped `@` references. Picker/drop/clipboard bytes share `prompt-input/useDeviceAttachments.ts` for serialized budgets and epoch-based draft/focus fencing; keep lifecycle and read logic out of `prompt-input.tsx`. File listing/search validate the session directory through existing workspace ownership before reading a worktree or translated WSL root. - The `@` mention menu lists Location skills with search, names and descriptions; selecting one attaches a removable skill and drops the `@query` token. Skills use the existing `PromptAttachmentsBar` alongside files and agents, never a separate composer row. The default prompt placeholder lists skills alongside files and agents in every locale. Keep the composer free of a permanent Skills button or `/skills` shortcut. Explicit attachments use native `skill.list` for the session Location and send IDs through `prompt.skills`; selection lives in `prompt-input/usePromptPicker.ts`. Sending clears only the composer selection; OpenCode keeps the instructions stored with the message. `MessageBlock` retains skill labels in sent and historical messages without exposing instruction bodies or inventing tool calls; test through the full transcript, not an isolated badge. Queued edits restore removable attachments, never reinsert removed skills from the original payload.