Remove the redundant dsh-tui-demo bin and the RESUME_SESSION_ID environment
variable, leaving dsh as the one terminal entrypoint.
The dsh-tui-demo package was a plugin (the TUI app bundle mounted by dsh's
config) plus a bin that booted a leaf cordis.yml — the same job `dsh [config]`
does. The bin, its ./bin export, its built-bin.e2e.ts, the tsdown bin entry,
and the now-unused dsh-app-boot dependency are removed; the package keeps its
plugin and invariant. demo:cordis, demo:code-mode, and the tui-agent and
cordis-agent keyless PTY smokes now launch through apps/cli/src/bin.ts with the
config as the positional argument. cli-demo/acp-demo/jsonrpc-demo keep their
bins (distinct surfaces).
RESUME_SESSION_ID was the only bridge from --resume into the shipped config;
--resume now provides the id on the boot context via ctx.provide(
RESUME_SESSION_ID_KEY, id), and the four configs read it as a bare identifier
through a quoted typeof-guarded !!js expression. The TUI resumeCommand fixtures
and docs move to `dsh --resume {session}`.
Agent Note and its Chinese pair updated; config-catalog regenerated.
5.7 KiB
Agent Note: Retire the readline front door and the repl-agent example
Status: implemented
English | 中文
Problem
The repo shipped two interactive terminal front doors: the line-oriented readline channel (@deepseek-ai/dsh-stdio) and the full-screen @deepseek-ai/dsh-tui. After the TUI landed, readline's interactive role was redundant — demo:tui superseded demo:repl as the coding-agent experience — while its remaining real role, pipes and automation, was already served better by the one-shot @deepseek-ai/dsh-cli-demo app (task in, DSH-native text/json/stream-json out, durable persistence, signal handling).
The duplication was structural, not just cosmetic: dsh-stdio-demo carried a TerminalMode (auto/readline/tui) selection seam, ~1,000 lines of readline unit tests, a readline transcript grammar ([tool call] … lines) that the CI demo smoke and two built-bin e2es grepped, and an inverted example composition where the flagship tui-agent leaf was defined as an include-patch over the repl-agent leaf it superseded.
Decision
Delete the readline front door and the repl-agent example; keep exactly three front-door archetypes: interactive TUI (TTY-only, fails loud on pipes), one-shot CLI (-p/positional task, pipes and automation), and servers (ACP / JSON-RPC).
packages/ui/stdioandexamples/repl-agentare gone.packages/examples/stdio-demois renamed@deepseek-ai/dsh-tui-demo(packages/examples/tui-demo) and always mountsdsh-tui; theTerminalMode/resolveTerminalMode/ui.modeseam is deleted. The bin refuses non-TTY streams before booting the Loader (a compose-time throw inside a Loader tree is logged per-entry, not rethrown, so a piped launch would otherwise settle into an idle UI-less process instead of exiting nonzero).examples/tui-agent/cordis.ymlnow owns the coding composition inline (the include-patch inversion is gone); its Code Mode overlay includes its own base.examples/cordis-agentmoved to the TUI app.examples/echo-agentmoved to the one-shotdsh-cli-demoapp;dsh-cli-demogained-p/--promptas the flag form of the single task (mutually exclusive with the positional).- The UI-independent with-key coding e2es (
full-loop,coding-task,resume,compaction,todo-write,code-modeand their shared harness) moved verbatim fromexamples/repl-agent/tests/toexamples/tui-agent/tests/— they assemble the stack programmatically and never touched a UI. - The SDK wizard's
stdiorun interface becametui(RunInterface = 'acp' | 'tui' | 'embed'), contributing adsh-tuientry instead ofdsh-stdio; the generatedindex.tsguards TTY beforestartSDKfor the same pre-boot fail-loud reason as the tui-demo bin.
Testing policy: PTY only for the TUI
Pipes remain the default test medium. PTY-driven subprocess tests are sanctioned only where the subject is the TUI itself: examples/tui-agent/tests/tui-keyless-smoke.e2e.ts (which gained the Code Mode overlay boot scenario, replacing repl-agent's pipe smoke as the overlay's keyless composition proof) and the minimal PTY boot smoke in examples/cordis-agent (whose front door IS the TUI). Everything else moved to pipes over the one-shot bin:
examples/echo-agent/tests/echo.e2e.tsproves the Loader boot + mock-model tool round-trip throughstream-jsonrecords instead of readline transcript lines.- The CI demo-smoke gate (
scripts/run-gates.ts, AGENTS.md) runsdemo:echo --output-format stream-json -p "echo ci smoke"and parses the records structurally. - The TUI's piped-launch refusal (nonzero exit + pointer at the one-shot CLI) is covered by the
dshTTY guard exercised inexamples/tui-agent's PTY smoke; the echo-round-trip-under-plain-Node and missing-config fail-loud proofs live incli-demo's built-bin suite. packages/context/time-context/tests/time-context.e2e.tsruns one one-shot turn; multi-turn elapsed rendering stays unit-covered in its spec.
Accepted losses
- Piped multi-turn in one process — the readline channel could script several turns over stdin; the one-shot bin runs one task per process. Multi-turn continuity is covered by
RESUME_SESSION_ID/resume e2es and the TUI's scripted PTY conversation. - Non-TTY
ask_user_question— the readline provider was the only non-TTY terminal implementation ofctx.userInteraction. A headless run whose model callsask_user_questionnow fails that tool call (no provider); the ACP bridge remains the non-terminal provider. A future headless deployment that needs it composes its own provider.
Alternatives considered
- Keep
dsh-stdioas a pipe/automation channel without the repl demo — rejected: its automation role duplicateddsh-cli-demowith a weaker contract (unstructured transcript, EOF-exit heuristics vs. one durable turn ending and format-pure output). - Rewrite the piped smokes as PTY drivers — rejected: PTY is the flakier, more complex medium and is reserved for the one surface pipes cannot prove (real TTY takeover/restore).
Consequences
- One interactive front door (TUI), one automation front door (one-shot CLI), two servers; no mode-selection seam in the terminal app.
- ~1,000 lines of readline unit tests deleted with their behavior; the readline transcript grammar is gone from all gates.
- This supersedes the packaging half of fold the stdio UI helper (the folded package is now deleted) and amends the composition described in the TUI front-door note (no
autoselection;tui-agentowns the coding composition).