Commit Graph
73 Commits
Author SHA1 Message Date
Turtle f290a8b851 refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.

- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
  web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
  patches never cross an include boundary. Precedence: base < surface <
  (--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
  test tree never inherits the user's route; new `--config-replace` boots a file
  as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
  configure or disable it. Upstream built the id index once before the patch
  loop, leaving every surface-only row — the whole TUI front door — silently
  unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
  dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
  TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
  examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay

Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.

Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 21:15:42 +08:00
imccyu 66d650e4fb refactor: simplify sidebar logics 2026-07-29 14:52:41 +08:00
Tianyi Cui 9161d9bf32 Merge branch 'master' into worktree/fix-test-mock-server-bin 2026-07-29 01:08:07 +08:00
Tianyi Cui c3d9f132e8 test(snapshot): canonicalize generated cwd tokens 2026-07-28 23:46:01 +08:00
Tianyi Cui 84d0d92cfb test(snapshot): normalize temporary workspace paths 2026-07-28 21:32:49 +08:00
Yichen Jiang 9236f24bcd fix(llm): stop exposing the mock server binary 2026-07-28 18:21:11 +08:00
Tianyi Cui 9c78a7df33 test(snapshot): share identical header sidecars 2026-07-28 17:26:03 +08:00
Tianyi Cui f2c0021941 docs(notes): aggressive archive sweep of low-value decision records
Archive 21 implemented triplets whose shipped decisions are complete and
whose bodies no longer guide future work (one-off UI chrome, generator
applications whose scripts are self-explanatory, superseded implementation
detail, process history owned by current contracts/skills). Delete 4
rejected triplets whose premises are obsolete: the DeepReadonly proposal
(dev-invariants note now carries the alternative inline), the collapse
tool-owned presentation proposal (superseded by the shipped render-intent
union), retire-mid-turn-steering (steering is now load-bearing across
plan-mode/apiproxy/TUI), and single-session-ACP (automation-only ACP
resolved the question; multi-session isolation is pinned by tests).

Repair every inbound link: retarget intentional historical citations to
archived paths, replace decision-current citations with the surviving
authority, and fix the stale example-execute-over-tsx pointer in
pnpm-workspace.yaml. Re-record pairing sidecars and seal the archive
manifest (append-only; existing seals unchanged).
2026-07-28 00:00:51 +08:00
Tianyi Cui 194ea6bdf0 docs(test): correct execa process-tree claims 2026-07-27 18:03:21 +08:00
Tianyi Cui d897dcc7ea Merge remote-tracking branch 'origin/master' into worktree/pr682-retarget-20260727
# Conflicts:
#	.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml
2026-07-27 17:55:56 +08:00
Tianyi Cui 77a85f9b1a Merge remote-tracking branch 'origin/master' into worktree/fix-ci-timing-flakes-20260727 2026-07-27 15:53:08 +08:00
Tianyi Cui 9c53cd7d07 test: stabilize timing-sensitive terminal checks 2026-07-27 15:33:36 +08:00
Yichen Jiang 21aeff3029 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml
#	docs/config-catalog.md
#	docs/core-data-structures/session.i18n.yaml
#	scripts/type-equiv.manifest.json
2026-07-27 13:35:10 +08:00
Tianyi Cui cbb266dc2d Merge remote-tracking branch 'origin/master' into nih-imp-execa
# Conflicts:
#	.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml
#	apps/web/tests/scaffold.ts
#	packages/session-persistence/session-checkpoint-policy/tests/crash-recovery.e2e.ts
#	packages/support/acp-snapshot/README.i18n.yaml
2026-07-27 06:31:17 +08:00
Tianyi Cui 7a3c71161c Merge remote-tracking branch 'origin/master' into worktree/packed-chunks-default-rfc
# Conflicts:
#	.agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.i18n.yaml
#	docs/testing.i18n.yaml
#	packages/support/acp-snapshot/README.i18n.yaml
2026-07-27 03:31:33 +08:00
Tianyi Cui 4ff496c65c feat(session): default JSONL writes to packed rows 2026-07-26 23:44:52 +08:00
Tianyi Cui a8a1ada183 docs: move execa Agent Note to implemented; update inbound links and README contracts
- proposed/testing -> implemented/testing with the lifecycle rewrite
  (Proposal->Decision in present tense, Acceptance criteria + Risks
  folded into Consequences); zh counterpart mirrored and both pairs
  re-recorded.
- the rejected NIH-audit roll-up pair now links the implemented/ path.
- loader-smoke README: captured output is bounded by execa's default
  100 MB maxBuffer, no longer unbounded.
- acp-snapshot README: harness.ts now also imports vitest (vi.waitFor),
  so the vitest-run-only constraint names both modules.
- jsonrpc keyless smoke: raise the invalid-env case's subprocess
  deadline to 25s (the 9s pick starved a cold tsx boot on slow NFS).
2026-07-26 23:10:38 +08:00
Tianyi Cui 98980900d0 Merge origin/master into worktree/archive-agent-notes-20260726
# Conflicts:
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.md
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.zh.md
2026-07-26 23:07:21 +08:00
Tianyi Cui 37140bf823 docs(notes): archive low-value decision records 2026-07-26 23:06:00 +08:00
Tianyi Cui e2882f486b fix(review): harden web replay verification
Validate replay sidecars and cross-copy failure facts, make browser console tripwires and macOS temp paths deterministic, and wait for asynchronous TUI resume details. Keep the owning docs, translations, and generated catalog aligned.
2026-07-26 22:38:33 +08:00
Tianyi Cui f8342b0a8e test(web): cover the settings surface and workspace management
Two new keyless scenarios for the functionality master gained since this
lane's base (#644 websettings, #643 workspace browser rework), both zero
model calls:

- settings-chrome: the modal shell (sidebar-foot trigger aria states,
  role=dialog, aria-current section switch to the deliberately empty
  Models, Escape + close-button paths, dialog aria golden); the Appearance
  row as the REAL theme gesture — retiring lifecycle-chrome's
  TODO(web-theme-gesture): clicking 深色 runs aria-pressed -> persisted
  dsh.theme -> body[data-ds-dark-theme] -> alias-token flip, survives
  reload, and 'system' follows the emulated OS scheme both ways; the
  Language row switches the settings-scoped copy to English (dsh.locale
  persisted, survives reload) and restores zh. Intentional reloads tear
  the SSE stream, so the spec drains exactly its own reconnect warnings —
  the tripwire still fails on unexpected connection loss.
- workspace-management: create-by-name twice through the region-header
  dialog (host-durable via ctx.workspace.list()); rename end to end —
  hover-revealed row menu (the button is display:none until the row
  hovers), duplicate-name pre-check (inline role=alert + disabled primary
  before any wire call), then workspace.rename through the real RPC,
  row update, host durability, reload survival; the flat 'In one list'
  view (section label flips, group headers drop, dsh.workspace.view
  persists across reload, grouped restored); the session hover card
  (dwell to open, closes on pointer leave). The one session row reuses
  seeded-history's committed seed — no new recording. Deliberately not
  driven: the inert menu rows and drag reorder (deferred in the note
  with re-entry triggers).

Agent Note gains scenarios 8-9 and the drag-reorder deferred item in both
languages; llm-replay README's zh side catches up with the { patches }
paragraph; pairings re-recorded.
2026-07-26 20:38:36 +08:00
Yichen Jiang eeab643ad9 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
2026-07-26 13:13:31 +08:00
Tianyi Cui ea1d8d06b3 test(web): pin every scenario end-state with an aria golden
Every spec now commits at least one golden and the interactive ones one
per distinct end-state (nine new .expected.md):

- live-interactions: cancel.expected.md (frozen partial + 已停止 marker),
  error-auth.expected.md (the prompt bubble alone — the committed artifact
  of the web-error-surface gap, the diff that flips when error rendering
  lands), retry.expected.md (indistinguishable from a clean completion —
  retries are deliberately invisible in the transcript).
- question-composer: answered.expected.md (the question resolved into its
  tool round trip plus the final reply, takeover gone) beside the existing
  waiting-state golden.
- steering: mid-steer.expected.md pins the accepted-but-INVISIBLE state
  (the loop drains steering only at the step boundary, so no interjection
  bubble exists while the question still blocks — if the client ever
  renders pending steers eagerly, this golden flips first) and
  settled.expected.md the badged bubble plus obeying reply.
- navigation-panes: waterfall.expected.md and details-open.expected.md
  (tool-name header, Input args, Output result) beside the trajectory one.
- lifecycle-chrome: reloaded.expected.md — rendering the same settled
  transcript from persistence alone IS the recovery claim.

Fixture inventories extended to the new closed sets; the Agent Note's
expected-outputs policy updated in both languages (per-end-state goldens
for interactive scenarios), pairing re-recorded.
2026-07-26 12:45:44 +08:00
Tianyi Cui cbb5fc7a51 test(web): lifecycle & chrome scenarios — workspace flow, reload recovery, dark mode
One tiny recorded text turn drives three whole-page concerns:

- workspace flow over the real wire: the empty-state hero's first send
  materializes a real Workspace + Session (the jsdom workspace-flow suite
  pins this state machine over the fixture client; this scenario pins it
  through HTTP RPC + SSE + the gateway). Durable proof: the session
  header's cwd is the create-by-name target <workspaceRoot>/workspace.
  Adds the hero waiting-state aria golden.
- reload recovery: collapse the sidebar (persisted dsh.layout.panels),
  page.reload, and the surface comes back whole from persistence alone —
  layout collapsed, selection restored (dsh.sessions.current), the
  recorded turn re-rendered from session.history with zero model calls
  (the drained replay cursor makes any stray request fail loud at close).
- dark mode: no product control flips the theme yet, so the scenario
  drives the ThemeService's entire DOM contract — body[data-ds-dark-theme]
  — and pins the shipped cascade: the alias token flips, a painted surface
  repaints, and removing the attribute restores the light sample exactly.
  TODO(web-theme-gesture) upgrades to a real settings control; no theme
  golden per the lane's scope ruling (aria is color-blind).

Agent Note scenario list extended in both languages; pairing re-recorded.
2026-07-26 06:08:08 +08:00
Tianyi Cui 4964e9c729 test(web): navigation & panes scenarios over one rich seeded session
One two-turn seed (turn 1: bash + two parallel reads in a single assistant
message; turn 2: a markdown-heavy reply) rendered cold through the
seeded-history pattern — zero model calls — serving four surfaces:

- sidebar search: client-side title filter; asserted only after the durable
  title lands with the attach baseline (a cold SessionSummary carries no
  title — search matches the displayTitle the user sees). Negative query
  empties the tree, positive narrows to the match + its force-expanded
  group, clear restores.
- Trajectory tab: turn sections, the step group's tool mix ('bash read×2'),
  and a view-area aria golden.
- Waterfall tab: span stats header + one lane per span. The P-I fold counts
  a turn-0 prologue span (only assistant/steering nodes carry a turn
  number) — pinned as-is; real spans are P-III per the view's ledger.
- details column: the bash toolview row routes click to openDetails;
  open/closed is asserted on the frame's data-details-collapsed attribute
  because close collapses the grid column to width 0 without unmounting
  the subtree (hidden, not absent, is the contract).

Agent Note scenario list extended in both languages; pairing re-recorded.
2026-07-26 05:15:47 +08:00
Tianyi Cui 07770f90f9 Merge remote-tracking branch 'origin/master' into web-e2e-interactions
# Conflicts:
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.md
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.zh.md
#	apps/web/tests/scaffold.ts
2026-07-26 04:10:37 +08:00
Tianyi Cui 96c67df835 docs(notes): extend the web e2e lane note with the live-interaction scenarios
Both languages: the three new scenarios (live-interactions overrides,
question-composer takeover, wire-level steering), the product-delta list
({ patches } override form, the carried-failure fix, the llm-retry row),
two new Deferred items (web error surface, composer steering gesture),
and de-hardcoded scenario counts; pairing re-recorded.
2026-07-26 04:07:49 +08:00
Tianyi Cui 674d916ef8 Merge branch 'master' into worktree/llm-mock-fault-server 2026-07-26 00:45:44 +08:00
Tianyi Cui f1577d620e test(web): harden replay scaffold lifecycle 2026-07-26 00:33:46 +08:00
Yichen Jiang badf7d1c63 fix(llm-mock-server): harden fault boundaries 2026-07-25 22:45:58 +08:00
Yichen Jiang 5446714177 Merge branch 'master' into worktree/llm-mock-fault-server 2026-07-25 22:27:29 +08:00
Tianyi Cui ee25ccf38b Merge remote-tracking branch 'origin/master' into web-e2e-lane
# Conflicts:
#	vitest.web.config.ts
2026-07-25 18:19:22 +08:00
Tianyi Cui 8a7bb03aab fix(persistence): reconcile project session layout 2026-07-25 15:11:17 +08:00
Tianyi Cui fb17d5ec49 Merge remote-tracking branch 'origin/master' into web-e2e-lane
# Conflicts:
#	docs/config-catalog.md
#	docs/testing.i18n.yaml
#	docs/testing.md
#	docs/testing.zh.md
#	packages/host/runtime/src/start.ts
#	packages/support/acp-snapshot/README.md
2026-07-25 14:20:19 +08:00
Yichen Jiang 83cccd7ffc feat(llm): add scriptable mock fault server 2026-07-25 08:20:51 +08:00
Tianyi Cui 16910475ef docs(i18n): mirror ACP-automation edits into the zh pairs from master
Master's i18n batches added Chinese counterparts to ~50 docs this PR
edits in English. Bring each zh side along with the minimal edits
covering the en diff (recorded-hash diffs, not re-translations),
reunite the stream-workflow-progress pair under rejected/ with its
manifest entry, re-record all pairing hashes, and regenerate the
event/persistence/tool catalogs and doc graphs over the merged tree.
2026-07-25 01:58:42 +08:00
Tianyi Cui 440384fdb4 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.md
#	.agents/notes/implemented/architecture/2026-06-20-package-hierarchy.md
#	.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-multi-session.md
#	.agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.zh.md
#	.agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md
#	docs/architecture.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/cookbook/extension-cookbook.md
#	docs/cookbook/extension-cookbook.zh.md
#	docs/core-data-structures/approval.md
#	docs/core-data-structures/user-interaction.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	docs/testing.md
#	docs/tool-catalog.md
#	examples/acp-agent/tests/fixtures/live-mode-switching-2026-07-07.session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	packages/goal/tool-goal/README.md
#	packages/ui/acp/README.md
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-24 23:43:10 +08:00
Tianyi Cui 8a7472d11d Merge remote-tracking branch 'origin/master' into web-e2e-lane
# Conflicts:
#	docs/testing.md
2026-07-24 23:11:00 +08:00
Tianyi Cui 13345fdadc docs(i18n): re-record web e2e note pair after the scaffold rename
The rename commit edited both sides of the bilingual pair but missed the
re-record; the pairing gate compares blob hashes and went red.
2026-07-24 22:46:04 +08:00
Tianyi Cui 6d3c25f494 refactor(web-e2e): rename harness -> scaffold; add interaction coverage
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.
2026-07-24 22:18:19 +08:00
Tianyi Cui 5569f3f8ac docs: repair rewritten rationale and stale claims from the ACP reduction
The automation-only rewrite edited many implemented Agent Notes; several
edits replaced still-live or historical rationale instead of reframing:

- llm-model-catalog: restore the prompt/request consistency section and
  selection-ownership alternatives — installAgentLlmTarget and the TUI
  /model selector still ship that design; only the ACP wire is gone.
- plan-specific-collaboration-state, acp-multi-session, todo-write,
  ask-user-question: link the superseding automation-only note instead
  of silently rewriting the original decision or motivation; drop a
  paragraph duplicating the Web-provider facts stated two paragraphs up.
- sandbox: stop claiming unit coverage for turn-enclosed config writes
  (that mechanism left with the bridge) and retitle the commit-boundary
  paragraph accordingly.
- Fix the missing blank line before '## Consequences' in the
  plugin-command-registration pair, the JSON-RPC/Web render-intent
  consumer misattribution (the second consumer is the host/client
  runtime), stale bash_output/bash_kill names, and 'optional goals' in
  architecture.md.
- examples/acp-agent/README.md: point at the package contract instead
  of restating it; packages/ui/permission and plan-mode READMEs record
  the consumer-less preset service and the exit_plan_mode coverage gap
  under Known Limitations.
- 2026-06-19-acp-snapshot-tests: the new note defers the corpus
  migration rather than committing to it; say so.

Re-record the touched bilingual pairs.
2026-07-24 22:12:23 +08:00
Tianyi Cui 8f97f95d7b docs(i18n): bilingual pair for the web e2e lane Agent Note
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.
2026-07-24 21:06:54 +08:00
Tianyi Cui 2cd37e2765 docs(testing): web e2e lane docs + Agent Note to implemented
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.
2026-07-24 19:57:27 +08:00
Tianyi Cui c0eacae2ba docs(i18n): align Agent Note terminology 2026-07-24 13:57:16 +08:00
Tianyi Cui e819a586b0 refactor(acp): reduce bridge to automation protocol 2026-07-24 01:40:25 +08:00
Tianyi Cui 86940da524 docs(i18n): refresh Agent Notes after parent merge 2026-07-23 19:48:00 +08:00
Tianyi Cui 3b390334d3 Merge branch 'worktree/pr344-retarget-stack' into worktree/pr345-retarget-stack 2026-07-23 19:33:30 +08:00
Tianyi Cui cecd0fedf5 docs(i18n): normalize seam consumer terminology 2026-07-23 17:48:50 +08:00
Tianyi Cui a4d6c302f6 docs(i18n): align turn and step terminology 2026-07-23 14:37:01 +08:00
Tianyi Cui d5f5517ec0 docs(i18n): address Agent Note review feedback 2026-07-23 01:11:59 +08:00