Load a per-directory local overlay in addition to the base instruction
file, matching the Claude Code AGENTS.local.md / CLAUDE.local.md
convention for git-ignored personal guidance.
- New config `localInstructionFileCandidates`, default
`['AGENTS.local.md', 'CLAUDE.local.md']`; empty disables the overlay.
The default lives in the plugin Config schema, so every front door
(TUI/ACP/headless) reads .local. files consistently.
- Per project directory the plugin loads the first-existing base
candidate, then additively the first-existing local candidate,
rendered after the base so it takes precedence within the byte budget.
- Base and local tiers get distinct scope keys via a NUL sentinel
(scopeKey/decodeScopeKey) so they never collide in the baseline map,
pending window, or version cache.
- The fixed user-global $DSH_HOME/AGENTS.md stays base-only.
Docs: README (config, lifecycle, Known Limitations), regenerated
config-catalog, and a new bilingual Agent Note cross-linked to the
owning workspace-context note. 100% per-file coverage retained.
Squashes three linearized steps (feat/tui-startup, feat/banner-reveal,
feat/remove-banner): the banner experiment converged on removing the
startup banner entirely; later commits restore it borderless and add the
brand gradient.
Squash of the linearized fix/tui-color-scheme-v2 merge and the follow-up
catalog regeneration. Renders error cause chains at every diagnostic seam
(origin/fetch-failed-diagnostics) and adds color scheme detection with a
light-terminal palette.
Delete packages/ui/stdio and examples/repl-agent; rename stdio-demo to
@deepseek-ai/dsh-tui-demo (TUI-only, refuses pipes before Loader boot).
tui-agent owns the coding composition inline; echo-agent and the CI demo
smoke move to the one-shot cli-demo bin, which gains -p/--prompt. The
UI-independent with-key e2es move verbatim to tui-agent. SDK wizard's
'stdio' interface becomes 'tui'. PTY testing stays confined to TUI
surfaces; all other subprocess tests ride pipes.
See .agents/notes/implemented/simplification/2026-07-20-retire-readline-front-door.md
Master PR #263 (scoped-layers-store): one conflict in the regenerated
docs/architecture.i18n.yaml pairing record — took master's and re-recorded
the pair over both sides' merged architecture.md/zh.md (the ctx.modes rows
merged cleanly on both).
verify-built-package-invariants ran 100+ npm-pack + plain-Node probes
serially, dominating the CI artifacts lane (~4min of a ~5min job; ~7.5min
on Windows). Each probe stages its packed view inside its own package and
spawns its own processes, so the probes are independent — run them through
the same bounded worker pool shape as publint-all, capped by
DSH_BUILT_INVARIANTS_CONCURRENCY (default availableParallelism), failures
kept in manifest order.
Measured on the gate alone: 2m07s serial -> 17s at concurrency 8.
CI lanes pin the cap to 8, matching DSH_PUBLINT_CONCURRENCY.
The master merge (windows-runtime) shifted TuiConfig's source line without
regenerating docs/config-catalog.md, and its Windows stdout pin for
workspace-edit was recorded on master without dsh-mode — the session/new
result lacked the modes advertisement and the command list lacked /mode.
Both lines carry no filesystem paths, so the POSIX pin's bytes are correct
on Windows too; graft them verbatim.
The remaining red CI on this PR head (windows coverage/static LSP failures,
the web-search live e2e) reproduces on master's own HEAD 32ccc405b and is
not a branch regression.
CI caught two gaps in the review-fix commit: the two post-next() flush
listeners were literal clones (jscpd), and the disposed-skip branch inside
them had no covering test. Extract one shared flushAfter wrapper and pin the
skip with a captured-continuation disposal test (a downstream listener
disposes the fiber mid-waterfall; the resumed wrapper appends nothing).
Four ds-review-bot findings:
- examples/tui-agent composed dsh-mode without the now-required
modes.plan.section, so the TUI leaf failed at Loader startup (the keyless
smoke only asserts the banner and missed it); graft the same deployment
plan instructions the ACP leaf carries.
- The prompt-submit and turn-continuation flushes ran before next(), so a
session/set_mode arriving while a downstream async listener (the shipped
hooks listeners' shape) awaited applied one request late; both listeners
now prepend and flush after next(), matching the request-error wrapper,
with a regression test pinning the ordering.
- An HMR unload during the exit_plan_mode review let a later approval write
into the disposed service and claim an exit whose flush could never land;
the execute path now checks the fiber lifetime after the await and fails
the call (the mode stays plan; the model re-presents).
- resolveConfig accepted empty/untrimmed mode names that list()/ACP then
advertised while the package invariant rejected their selection,
desynchronizing the picker; names are validated non-empty and trimmed at
load, the same shape the invariant enforces.
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.