From e9589b523f9027ddfc5ea2f11baa42619a0e92e9 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sat, 4 Jul 2026 15:59:12 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20fix=20review=20findings=20=E2=80=94=20s?= =?UTF-8?q?upport-group=20summary=20row,=20smoke-prose=20export-shape=20cl?= =?UTF-8?q?aims?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The packages/README.md group table still described support/ as holding the stdio UI; and three prose sites credited the keyless smokes with guarding the app export shape, which a bundle without inject cannot do (a stray default boots rather than crashes) — the shape is pinned by the stdio-agent unit suite's explicit unwrapExports assertion; the smokes prove the composed tree boots. --- .../simplification/2026-07-04-fold-stdio-ui-helper.md | 2 +- examples/coding-agent/tests/keyless-smoke.e2e.ts | 7 ++++--- examples/echo-agent/tests/echo.e2e.ts | 9 +++++---- packages/README.md | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/rfc/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md b/docs/rfc/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md index 292e2dc541..599aacefac 100644 --- a/docs/rfc/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md +++ b/docs/rfc/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md @@ -10,7 +10,7 @@ The boundary bought package metadata, workspace and tsconfig references, module- ## Decision -The helper lives inside `@deepseek-ai/dsh-stdio-agent` as the in-package `stdio-chat` module (`packages/ui/stdio-agent/src/stdio-chat.ts`): `createStdioChat`, its `StdioRuntime` test seam, and its unit tests (`packages/ui/stdio-agent/tests/stdio-chat.spec.ts`, `readline.spec.ts`) moved with it, so EOF handling, rendering, disposal, and piped-vs-TTY behavior stay unit-covered under the per-file coverage gate without hijacking process globals. The module keeps the named `name`/`inject`/`Config`/`apply` export shape — the contract the app's `ctx.plugin(uiStdio, …)` mount consumes — and the keyless Loader-path smokes in `examples/echo-agent` and `examples/coding-agent` keep guarding the app's export shape end-to-end. +The helper lives inside `@deepseek-ai/dsh-stdio-agent` as the in-package `stdio-chat` module (`packages/ui/stdio-agent/src/stdio-chat.ts`): `createStdioChat`, its `StdioRuntime` test seam, and its unit tests (`packages/ui/stdio-agent/tests/stdio-chat.spec.ts`, `readline.spec.ts`) moved with it, so EOF handling, rendering, disposal, and piped-vs-TTY behavior stay unit-covered under the per-file coverage gate without hijacking process globals. The module keeps the named `name`/`inject`/`Config`/`apply` export shape — the contract the app's `ctx.plugin(uiStdio, …)` mount consumes — and the keyless Loader-path smokes in `examples/echo-agent` and `examples/coding-agent` keep proving the composed tree boots through the real Loader (the app's export SHAPE is pinned by the stdio-agent unit suite's explicit `unwrapExports` assertion, since a bundle without `inject` would boot past a stray default rather than crash). The `packages/support/ui-stdio` package is gone: manifest, tsconfig references, module-graph rows, and README rows deleted; the doc comments that named the package (the example e2e module docs, `packages/README.md`, the support and todo READMEs, [the ui group README](../../../../packages/ui/README.md)) describe the in-package module. diff --git a/examples/coding-agent/tests/keyless-smoke.e2e.ts b/examples/coding-agent/tests/keyless-smoke.e2e.ts index e079aa014b..dba8b140c7 100644 --- a/examples/coding-agent/tests/keyless-smoke.e2e.ts +++ b/examples/coding-agent/tests/keyless-smoke.e2e.ts @@ -18,9 +18,10 @@ import { afterEach, describe, expect, it } from 'vitest' * `apply()` only requires a key to be PRESENT (it does not validate it and only * uses it when a stream actually starts), so a dummy key lets the tree boot * while the absence of any prompt guarantees no network call. The value is the - * real-Loader-path guard for the app + bundle + UI plugin export shapes (a broken - * `export default` that drops `inject`/`Config` would crash here — see postmortem - * 0001), complementing coding-agent's with-key e2e suites which prove the real + * real-Loader-path guard that the composed tree boots (see postmortem 0001; + * the app carries no `inject`, so its export SHAPE is pinned by the stdio-agent + * unit suite's unwrap assertion, not by a crash here), + * complementing coding-agent's with-key e2e suites which prove the real * product. */ diff --git a/examples/echo-agent/tests/echo.e2e.ts b/examples/echo-agent/tests/echo.e2e.ts index ec02e58f5b..01bb34bff0 100644 --- a/examples/echo-agent/tests/echo.e2e.ts +++ b/examples/echo-agent/tests/echo.e2e.ts @@ -14,10 +14,11 @@ import { afterEach, describe, expect, it } from 'vitest' * This is the guard the per-file unit suite structurally cannot be: it drives * the `@deepseek-ai/dsh-stdio-agent` app plugin, the `@deepseek-ai/dsh-agent-core` * bundle it loads, the app's in-package readline UI module, AND the - * example-local `mock-llm.ts` / `echo-tool.ts` through their REAL load path, so - * a broken plugin export shape (a stray `export default` that `unwrapExports` - * would collapse, dropping `inject`/`Config`) fails here even though hand-mounted - * unit tests stay green (see docs/postmortem/0001). It needs no API key — the + * example-local `mock-llm.ts` / `echo-tool.ts` through their REAL load path + * (see docs/postmortem/0001). The app itself carries no `inject`, so a stray + * `export default` would boot rather than crash here — the export SHAPE is + * pinned by the explicit unwrap assertion in the stdio-agent unit suite; this + * smoke proves the composed tree actually runs. It needs no API key — the * `mock-echo` adapter never touches the network — so it runs in the default e2e * gate. * diff --git a/packages/README.md b/packages/README.md index da17075d36..f016f1e149 100644 --- a/packages/README.md +++ b/packages/README.md @@ -19,7 +19,7 @@ Packages are grouped by modular role at `packages///`. The group dir | [`hooks/`](hooks/README.md) | Hook bridges + the shared Claude Code / Codex wire-protocol library | Product — stable surface | | [`session-persistence/`](session-persistence/README.md) | Persistence capability family: the seam + JSONL/SQLite backends | Product — stable surface | | [`ui/`](ui/README.md) | Editor/client integration surfaces (the ACP bridge) | Product — stable surface | -| [`support/`](support/README.md) | Dev/test/example infrastructure (invariants, stdio UI, replay adapter) | Support — lower compatibility expectations | +| [`support/`](support/README.md) | Dev/test/example infrastructure (invariants, replay adapter, subagent mock) | Support — lower compatibility expectations | | [`util/`](util/README.md) | Low-level zero-dependency utilities shared across groups (the `Branded` primitive) | Support — small, stable, harness-dep-free | The split is the point: a package's group says whether it is part of the product API or support/test/example infrastructure, so release and removal decisions do not have to treat every package as an equal public contract. New packages join an existing group; adding a new top-level group is a deliberate act (extend the group READMEs and the hierarchy docs).