Windows-native execution foundation: PwshLocalExecutor implements the bash
executor seam over ctx.subprocess (pwsh -NoLogo -NoProfile -NonInteractive
-Command, one argv element, no quoting layer; resolvePwshPath probes
PowerShell 7 / PATH / Windows PowerShell 5.1 as a pure function), and
tool-pwsh is the minimal PowerShell-dialect model-facing tool over ctx.bash
(foreground only, managed DSH_* env, timeout/signal/exit markers, terminal
and generic presenters). Both packages carry full suites (real pwsh,
self-skipping without it) at per-file 100% coverage; vitest's Windows
exclusion narrows from packages/bash/* to the bash-requiring packages so the
pwsh suites run natively on Windows too. The CLI gains the workspace deps
and tsconfig projects without mounting either plugin; the Windows-default
roadmap is recorded as a proposed Agent Note.
glob/grep now run the @vscode/ripgrep binary via ctx.subprocess with a plain
argv vector: no system rg install, no shell layer, unconditional registration.
The load-time command -v rg probe and the bash-seam coupling are removed;
timeouts ride the cooperative exec.signal plus the seam's terminate
escalation. The fs-glob-sampling ACP snapshot executes the real packaged
binary against an mtime-pinned fixture. Adds the packaged-ripgrep-search
Agent Note, updates the roster-note facts and both shipped-composition e2es,
and regenerates the doc catalogs and third-party notices (surfacing
pre-existing manifest drift plus the new @vscode/ripgrep row; the notices
generator also learns pnpm 11's truncated virtual-store names).
`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.
Remove the duplicate model-facing list tool from this branch; directory orientation remains available through bash ls. Keep the glob sampling fix, add a real ACP composition snapshot, and narrow the decision record to the shipped bug fix.
ds-review-bot findings on the parallel bridge: sub-dispatches now run
through the registry's staged scheduler view (the loop's own seam) —
ordered prepare (pre-execute/guards) at submission-ordered start time,
only the dispatch/body stage overlapping, and a head-of-line commit
cursor running post-execute, context deferral, and the settle event in
submission order (new spec pins post order + context order under
out-of-order completion). Queued dispatches reclassify via
executionMode() immediately before starting, so a registry mutation
while queued flips them exclusive (native lazy-reclassification
semantics). Config and tool catalogs regenerated; the tool-catalog
metadata now names the start/settle pair and the scheduling contract.
run_code gains a required bash-style description parameter: presentCall
titles the card with it and moves the program to rawInput, so every
surface gets a readable label. tool/code-dispatch now logs each
sub-call's complete content/isError (the tool/result vocabulary),
replacing the bounded resultSummary and deleting the summarize/cwd
machinery — a UI renders sub-calls through the identical path as native
results. The dsh config tree mounts the worker code runtime and reads
DSH_TOOLS_MODE (temporary seam until per-session mode selection lands).
Session format stays v0 (pre-release churn). Code-mode ACP/TUI fixtures
re-recorded; TUI presenter pin refreshed; catalogs regenerated. Keyless
web smoke pins the code-mode wire contract (tools=[run_code] + SDK
prompt section).
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.
additionalProperties stays true in the published schema while execute
rejected extra keys, so generated typings and validation disagreed with
runtime behavior. The item schema now declares additionalProperties:
false — the registry's arg validation rejects extra keys with a
path-qualified violation before execute runs — and the redundant manual
check is dropped (tool catalog regenerated).
Replace send/steer/inject with one Agent.send primitive over the
(target × wakeup) matrix; followup/steer/inject become fixed-preset
alias methods on the now-abstract Agent class. Coalesce context/message
into user/message (injected context is a non-user source). Replace
agent/queued with agent/inbox/enqueue/dequeue/discard, add cancel
keepInbox, and add a FIFO-conservation invariant.
Master arrivals re-grafted onto the plan-mode surfaces:
- Package invariant runtime contracts: every package owns ./invariant —
added the dsh-mode companion (mode/set payload validation: non-empty
trimmed name), its unit spec, exports/peer wiring, and the mode group in
the tsconfig invariant paths glob.
- Interception waterfalls gained an AbortSignal parameter
(agent/prompt-submit, agent/turn-continuation) and ToolExecutionInput.signal
became required: listeners and test dispatch updated; the exit tool now
forwards exec.signal unconditionally.
- TUI question dialog: master's position/unanswered header layout kept,
the plan-review detail block re-grafted between question and answers.
- LSP capability family arrived: lsp tool joins the catalog pin, dsh-lsp
examples deps beside dsh-mode; lsp-definition snapshot refreshed with
the mode command and modes advertisement.
- docs/architecture.md and packages/README.md regenerated tables re-grafted
(ctx.modes row, mode package row) and condensed within word ceilings.
- examples/acp-agent cordis.yml: kept the deployment-owned plan instructions
(incl. the conversational-agreement sentence) beside master's routed-model
compaction comment; snapshot expected outputs refreshed keyless and noise
fixtures restored.
Rename the six model-facing tools pty_* -> terminal_* and align every
description, guidance section, ACP card title, and rendered result to
terminal terminology. Package and service internals keep their technical
PTY names (PtyService, "unknown PTY session", node-pty).
Harden the local backend teardown:
- a failed close is retryable: drop the memoized rejection so a later
terminal_close re-runs against the live process table
- service disposal clears the backend, reservation, and owner-cleanup
registries even when a close fails
- stop readiness polling before teardown so an in-flight send settles as
session_exit instead of a mis-inferred wait reason
- bound the sanitizer's pending buffer against unterminated escape runs
Update the tool catalog, package READMEs, the bilingual Agent Note, and the
acp/headless pty-tools snapshots to match.