The shared test module was named harness.ts inside a repo whose product
IS a harness — hopelessly ambiguous. Renamed to scaffold.ts with
launchWebScaffold/WebScaffold; tsconfig plane-split entries, the seam
JSDoc/README mentions, and both Agent Note languages updated.
Both scenarios gain a Playwright interaction step over the settled
transcript (after the golden capture, so committed aria surfaces stay
untouched): replay-round-trip clicks the reasoning fold open/closed over
wire-delivered state; seeded-history expands a read tool row rebuilt from
the cold log and asserts the recorded result text appears (read rows are
expand-in-place — rowExpands routes the click to the inline fold, not the
details column). test:web 30 passed | 1 skipped.
Chinese counterpart translated per the terminology table and the
2026-07-18 TUI note's register; switcher lines added on both sides; pair
recorded. doc-sync 24/24.
testing.md gains the web browser snapshot tier entry (divergent
DSH_SNAPSHOT=... test:web commands) and names apps/web/tests/snapshots/
as the web surface's snapshot home. The GUI testing note's tier map and
lane map gain the e2e scenarios (both languages, pair re-recorded) and
drop the stale verify-session-real references (those scripts left with
the missions/ tree). packages/client/AGENTS.md check ladder covers the
wire-carriage trigger and refresh/record commands. acp-snapshot README
stops claiming the whole package is ACP-specific — its normalizers are
transport-neutral with three consumers now. vitest.web.config.ts header
carries TODO(ci-browser) with the staged-reversal pointer.
The design-study Agent Note moves proposed/ -> implemented/ rewritten in
present tense: all review decisions recorded (llm:false seam over the
placeholder-key hack, providers-mode replay, whenIdle barrier stack,
single aria golden + anchors, TUI-style inline modes over a suite
factory, scrub-only header stance, CI deferral) with re-entry triggers
under Deferred.
Design study for a deterministic, keyless browser e2e lane over the real
assembled web chain (chromium -> SSE/HTTP wire -> apiproxy -> agent loop ->
persistence), replayed through dsh-llm-replay from recorded session-log
fixtures, with aria-tree goldens plus in-process world-state assertions.
Synthesized from an OSS prior-art survey (LibreChat, ai-chatbot, lobe-chat,
OpenHands, cline, aimock...), a repo seam deep-dive, and three adversarial
critiques (doctrine, flakiness, YAGNI). Records the settled shape (no new
package, no suite factory, seed via the real persistence API, whenIdle
barrier stack, no transient-DOM assertions) and the open questions (LLM
seam, Loader-izing dsh web, header pin, golden breadth, settled signal).
- Added bilingual notes for the new session feature, detailing the transition to an empty state upon session creation.
- Updated `SessionsService` to include a `clear()` method that resets the current selection and persists the empty state.
- Enhanced the `EmptyState` component to reflect the new design, including workspace selection and input handling.
- Modified CSS styles for improved layout and visual consistency in the empty state.
- Updated tests to cover the new session clearing functionality and its effects on the UI.
- Added TrajectoryCell, TrajectoryGroupHeader, and TrajectoryTurn components for rendering trajectory steps and groups.
- Introduced bilingual support with English and Chinese translations for trajectory notes.
- Updated conversation session models to include timestamps for various message types.
- Enhanced layout logic to handle expanded assistant blocks and tool results with duration metrics.
- Added CSS styles for new components to ensure proper display and alignment.
The loading-chain RFC (2026-07-23-client-plugin-loading-model, en/zh)
states the shipped model in its final form: two package kinds (dshClient
means plugin), one module system + one plugin governor, the end-to-end
loading flow, and hot reload with its support boundary — written for a
first-time reader, no intermediate-design narration. The two 2026-07-19
GUI RFCs defer their loading-chain sections to it and drop stale
vocabulary. config-catalog regenerated for the package rename; pairing
manifest tracks the renamed pair.
- The real-browser collapse smoke tracked the old chrome: visible HARNESS
text (the wordmark svg is aria-hidden now), an 'Expand sidebar' label
(renamed 'Open sidebar'), a 300px settle (default is 280), and an
immediate focus assert (rail search defers focus past the slide). The
case now tracks the brand span, polls the deferred focus, and uses the
current labels and width.
- Tooltip treated hover and focus as one trigger: leaving with the mouse
dropped the bubble of a still-focused anchor (and vice versa). The two
triggers are tracked independently; the bubble hides only after both
clear. Spec pins both orders.
- The ui-sidebar README and the bilingual collapse note still described
the retired geometry morph; both now state the slide + crossfade
contract, the fixed-width (never-conceding) sidebar, and the rail's
whale-mark/tooltip chrome.