AGENTS.md@packages/client/src/components/chat · git:20260826.fb8c6e0 · 2026-08-26 · sha256 44ec7017971382a6

AGENTS.md@packages/client/src/components/chat git:20260826.fb8c6e0A

Immutable. This exact content is served forever at /api/v1/blob/44ec7017971382a6.

# DOX — packages/client/src/components/chat

Files in this directory. One row per source file.

| File | Purpose |
|------|---------|
| `BashOutputCard.tsx` | Renders `!`/`!!`/slash-exec bash output card (command header, exit badge, output pre). → see `BashOutputCard.tsx.AGENTS.md` |
| `ChatView.tsx` | `msg.view` rows render as `<PreviewCard target={msg.view}>` (right-aligned, `bubbleMax` width) BEFORE… → see `ChatView.tsx.AGENTS.md` Merges a default `fileLink` into `toolContext` once (`useMemo`) and passes it to ALL consumers incl. `ToolBurstGroup`/`CollapsedToolGroup`. See change: cleanup-import-cycles. Third pending-prompt render arm for `status=="failed"` (`data-testid="pending-prompt-failed"`, text preserved, never the emerald tick). See change: fix-optimistic-prompt-stuck-sending. Owns D7's auto-load trigger. ONE `programmaticScrollUntilRef` stamp (`SETTLE_MS` 120) is taken by EVERY programmatic scroll writer — `onChange` bottom-pin + ascent re-issue, `scrollToBottom`, `scrollToTop`, restore + its offset rAF, restore fallback, near-bottom fallback, streaming bottom-pin, the selection compensator, and `scrollToTurn` — rather than a per-writer ref list, because enumerating writers is how the previous revision failed. `handleScroll` only RECORDS (intent + restart timer) and never evaluates; evaluation runs at the settle timer's expiry, so a momentum stream evaluates once. A suppressed evaluation is DEFERRED, not consumed. `scrollToTop` sets intent because activation IS intent. Intent is cleared on issue, at mount, and on session change. Also hosts the `history-gap-live-region` (`aria-live="polite"`), OUTSIDE the virtualized list, and scopes it to AUTOMATIC loads via `autoLoadEarlier`/`lastLoadWasAutoRef`; the announced count is the RENDERED row delta, not the response event count. See change: add-tail-only-replay-window (D7, D7a). |
| `ChatViewMenu.tsx` | Discord-style ⚙ View popover mounted in chat toolbar. Edits per-session `displayPrefsOverride` via… → see `ChatViewMenu.tsx.AGENTS.md` |
| `collapse-summary.tsx` | Shared PROCESS-subcard summary primitives: `splitOverflow<T>` (pure head/overflow-tail sort-then-slice split) + `<CollapseSummary>` (chevron toggle button owning `aria-expanded`+click→onToggle). See change: stable-process-line. |
| `CollapsedToolGroup.tsx` | Renders collapsed group of repeated tool calls. Exports `CollapsedToolGroup`. → see `CollapsedToolGroup.tsx.AGENTS.md` |
| `CommandFeedbackCard.tsx` | Inline card showing slash-command execution feedback. Exports `CommandFeedbackCard`. Status map `started`/`completed`/`error` → icon + color + label. Shows `message` only on `error`. |
| `CommandInput.tsx` | Chat composer textarea + autocomplete. Exports `CommandInput`, `parseViewCommand`, `shouldWalkFileQuery`,… → see `CommandInput.tsx.AGENTS.md` `pendingPrompt` prop is now the status union, not a boolean; only `"sending"` gates the composer. See change: fix-optimistic-prompt-stuck-sending. New `modelRefreshErrors?` prop forwarded to `ModelSelector.refreshErrors`. See change: upgrade-model-selector-primitives. |
| `HistoryGapDivider.tsx` | Click-to-load interstitial disclosing a windowed replay's elided middle. Sits BETWEEN two loaded regions (the gap is bounded on both sides) — not a top-anchored "load older" header. States: A1 idle (`history-gap-count` + `history-gap-load`), A2 `history-gap-loading` (`aria-busy`), A4 `history-gap-error` + `history-gap-retry`, A5 `history-gap-unavailable` (tombstone, no retry — nothing failed, events were trimmed); divider removed entirely once filled. Every protocol `error` code collapses to ONE plain sentence — codes never reach the user. Tokens: `--text-secondary`/`--text-primary` only (`--text-muted` fails AA; `--text-tertiary` is 4.477:1 on light and is a non-text border token). Pill 44px below 480px, 32px above. See change: lazy-load-session-history. Now has TWO shapes, selected by the announced `windowShape`: `head-tail` stays a click-to-load INTERSTITIAL spliced out when drained; `tail-only` is a HEADER that auto-loads and RESOLVES TO A TERMINUS (`history-gap-session-start` / `history-gap-not-retained`) instead of disappearing — with no head above it, removing the row would leave a transcript that silently starts mid-conversation. `TerminusRow` is extracted so the state selection stays under the cognitive-complexity threshold. The auto-load `aria-live` region is deliberately NOT here: this is a virtualized row the virtualizer unmounts after a splice, so a region hosted here would not be in the DOM when its text changed — `ChatView` owns it. See change: add-tail-only-replay-window (D6). |
| `MultiAskPanel.tsx` | Grouped multi-ask panel (`data-testid="multi-ask-panel"`) for concurrently-pending free-floating asks. Vertical stack of independently-answerable cards; each reuses `getInteractiveRenderer(method)` and resolves its OWN `requestId` (no atomic submit). `method:"batch"` renders its BatchRenderer wizard in one slot. Renders null when empty. Fed by `derivePendingFreeFloating` from `ChatView`; hidden inline via `isRowVisible` while pending. See change: surface-concurrent-ask-user-prompts. |
| `MissingToolInlineError.tsx` | Inline chat error for missing shell binary. `[Install <tool> →]` flags `requestToolInstall` then navigates `/settings?tab=general`. See change: register-bash-and-tool-install-help. |
| `RawEventCard.tsx` | Collapsible card showing one raw event in the event log. Exports `RawEventCard`. → see `RawEventCard.tsx.AGENTS.md` |
| `SkillInvocationCard.tsx` | Collapsible card rendering a `<skill>` user invocation. Purple-tinted, wrench icon, default-collapsed body… → see `SkillInvocationCard.tsx.AGENTS.md` |
| `ThinkingBlock.tsx` | Exports `ThinkingBlock`. Collapsible reasoning panel; props `content`, `isStreaming`, `defaultExpanded`,… → see `ThinkingBlock.tsx.AGENTS.md` |
| `ToolBurstGroup.tsx` | Renders temporal BURST group (data from `lib/group-tool-bursts.ts`). → see `ToolBurstGroup.tsx.AGENTS.md` |
| `ToolCallStep.tsx` | Renders tool-call card. Adds `showResultBody?: boolean` prop (default `true`); when `false` hides result body… → see `ToolCallStep.tsx.AGENTS.md` |