master's locale rollout renders the details Output section title through
t('details.output') (输出 under the zh seat the test uses). The spec still
asserted the English 'Output' literal and failed. Match the sibling
terminal-card suite's localized assertion.
master's locale rollout made `t` a required prop on GenericToolCardProps and
the details slot; the web-card spec predates it. Supply the makeTranslate seat
the sibling suites use.
The base (feat/search-presenter) renamed the search result view's discriminant
from `kind` to `shape` and removed the view's `content` field (a UI without a
card now falls back to the raw tool/result content). Adapt the web consumer:
- searchCardModel switches on `result.shape`; SearchBlock's own `kind` prop is
mapped from it.
- The truncation recovery footer reads the block's raw `content` (where the
`Full … stored at …` locator now lives) instead of the removed view content.
- Fixture grep/glob views use `shape` and drop `content`; the recovery footer
rides the raw tool/result text.
- Tests and the bilingual Agent Note follow the rename and the recovery source.
The base's ReadResultView now requires `offset` (persisted so an empty window
still knows its start). The connection fixture's read sample and read-card.spec's
resultRead helper supply it (the window's first line, 41).
Address the ds-review-bot findings on the search card:
- searchCardModel dropped the result view's `content`, so a capped search's
`Full … stored at: <locator>` recovery footer vanished from the UI (the card
replaces the raw text). Thread it through as `SearchCardModel.recovery` and
render it below the card at all three sites, only when truncated.
- SearchRow's fallback body was gated on `state === 'error'`, so a settled
non-error call with no card (a successful nested run_code sub-dispatch, a
legacy generic result) showed only its summary with content lost. Widen it to
any settled call with `search === null`.
- searchCardModel trusted the `files`/`paths` shape the host wire schema only
string-checks; a malformed known-kind frame would crash SearchBlock. Validate
the full shape and fall to the generic path on mismatch.
- SearchBlock's restored tail file header added a row without consuming a tail
slot, exceeding maxLines by one and overstating the hidden count. Make it
consume a slot so the visible count holds at maxLines and `hidden` stays exact.
Correct the fixture JSDoc (now genuinely exceeds the row cap) and the Agent Note
recovery-text claim, sync the ui-conversation bilingual README with the search
row, and add an assembled keyless snapshot (apps/web/tests/search-card.snapshot.ts)
that pins the grep card's shape from the built bundles.
The coverage lane caught a regression in the prior commit: FileMutationRow now
passes the tool's raw path to the injected openFile (which resolves against cwd
in apply.ts), but diff-card.spec still asserted the row pre-resolved. Assert on
the raw path instead. Also fix the built-boot diff assertion to match on the
line body and footer text — the `+ ` prefix is a CSS ::before, absent from
textContent.
Top-level read samples in read-card.spec use the read tool's real file_path
schema key (web_fetch keeps its own path key); the Input-JSON assertion follows.
The LANGS/LANG_ALIASES JSDoc no longer claims the TypeScript grammar embeds
JSX/TSX — shiki's TS grammar tokenizes JSX approximately, an accepted trade to
keep one JS-family boot grammar.
Every expandable tool row shares one interaction (whole-row toggle,
icon-to-chevron hover preview) and one expanded body: an IN/OUT
gutter-labeled card with per-section 150px scroll caps and sticky labels.
toolRowModel derives result output and the error first line, terminalFailed
surfaces a failing exit as the collapsed row's red dot, a hover Inspect
pill jumps to the call's trajectory record through a one-shot store
handoff, and the chat view keeps its scroll offset across view switches.
grep/glob return no presentResult on an error result, so an errored search had
no card and the keyed SearchRow showed only a red dot — the model-facing error
text (bad pattern, missing path, a nested run_code dispatch with no card) was
nowhere on screen. Add an error-text arm mirroring the file-mutation and read
rows. Added tests for the text arm and its name/code fallback. The unknown-kind
fallback in search-card-model is already guarded (returns null → generic path).
- webCardModel returns null for an unknown web `kind` (wire from a newer host)
instead of drawing it as a malformed fetch, matching the unknown-`card` and
terminal-model wire-boundary default.
- Fixture WEB_SEARCH_RESULT/WEB_FETCH_RESULT and the source type derive from the
contract's ToolResultView via Extract, so a new contract field fails at the
type level rather than drifting silently.
- built-boot smoke asserts the web_search/web_fetch turns render their keyed
WebRow cards, giving the registration and wire projection an assembled check.
- DetailsPanel comment no longer claims the card omits content for search.
- ui-primitives README inline-Chinese limitation now lists WebBlock's controls.
Complete the stalled review pass: drop the unused useMemo import (rows flatten
inline), add SearchBlock to the ui-primitives README (both languages) with a
Search results section, and re-record the doc pairings. Search card behavior
and tests unchanged (313 pass).