Commit Graph
33 Commits
Author SHA1 Message Date
Turtle 6baa030594 feat(cli): dsh CLI with personal config overlays from ~/.config/dsh 2026-07-22 14:29:28 +08:00
Turtle a2f17d71ed fix(vendor/include): config hot-reload keeps the last good tree and its patches 2026-07-22 14:29:28 +08:00
Turtle a409f8b4ba feat(tui): detect terminal color scheme and apply light-optimised palette
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.
2026-07-22 14:29:27 +08:00
Turtle 0c9a4d7c28 Retire the readline front door and the repl-agent example
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
2026-07-22 14:29:27 +08:00
Turtle e97290ba9e docs(telemetry): state anonymous id as per-harness-home, not per-machine
The consolidated resolver scopes the anonymous id to $DSH_HOME rather
than the machine. Update the module contract, README, and Agent Note to
say per-harness-home explicitly instead of over-claiming a machine-global
identity, and record why DSH_HOME scoping is the intended single-root
meaning rather than a regression.
2026-07-21 15:57:17 +08:00
Turtle fac3fc090f fix(paths): treat empty DSH_HOME as unset; isolate telemetry env test
Review fixes for #462:
- resolveDshHome now treats an empty or whitespace-only $DSH_HOME as
  unset, so a blank override never resolves the home to cwd via
  resolve(''). Restores the guard telemetry's old resolver carried.
- The default-env telemetry test asserts only that globalConfigDir()
  returns an absolute path, so a machine DSH_HOME without a .dsh suffix
  cannot break it.
2026-07-21 14:43:38 +08:00
Turtle a0268d2509 fix(compact-basic): replay conversation prefix so summarization reuses KV cache
Automatic compaction fires mid-conversation, right after the loop warmed
the provider's KV cache with the last routed request. The default
summarizer then issued a separate request whose prefix shared nothing
with that warm request — a bespoke summarizer system prompt followed by
the older history flattened to one rendered transcript string — so a
differing first token invalidated the entire cached prefix and every
compaction re-processed the whole replayed history twice.

Move the compaction directive from the FRONT (a fresh system prompt) to
the END (a trailing user message), and replay the last routed request's
own system prompt, tools, message prefix, and shadowed-region messages
verbatim via session.requestHeader() + deriveEventMessage. The auxiliary
call is now a genuine prefix-extension of the warm request, so the
provider reuses the cached tokens up to the trailing instruction.

SummarizationInput carries the replayed prefix instead of a flat string;
the now-unused renderTranscript/renderContentBlocks path is removed with
its spec. Cache reuse is best-effort (head compaction guarantees a hit;
a mid-range compaction or a differently-routed summarizer forgoes it),
correctness is not.
2026-07-21 13:55:22 +08:00
Turtle 92e0d0e04f refactor(paths): collapse harness home resolution into one resolver
Delete @deepseek-ai/dsh-home and make dsh-paths the sole owner of the
single-root harness home ($DSH_HOME || ~/.dsh). Migrate tool-bash,
skill-local, and agent-spine-demo off dsh-home, and fold telemetry's
divergent globalConfigDir onto the shared resolver, dropping its second
XDG/APPDATA policy and the deepseek-harness namespace so the anonymous
id lives under the harness home. Add dshHomeDisplay() for symbolic
user-facing paths, replacing workspace-context's bespoke check.
2026-07-21 13:52:00 +08:00
Turtle dd57d3009d test(sandbox): decouple the probe-timeout test from the racy default budget
The earlier fix only widened the vitest timeout, but the real race is the
patient probe reading the 1s launcher under the 5000ms *default* probe budget:
under a full parallel run spawnSync blocks the worker and fork/exec latency can
push the launcher's wall-clock past 5000ms, so the patient probe wrongly reads
unusable and the assertion fails. Give the patient probe a generous explicit
15000ms budget (still far below its 1s launcher runtime margin) so only the
250ms impatient probe races the launcher; keep a 30s vitest timeout above the
patient budget.
2026-07-21 10:07:03 +08:00
Turtle bdbd22bb97 Merge remote-tracking branch 'origin/master' into fix/tui-color-scheme-v2
Resolve conflicts:
- packages/ui/tui/src/index.ts: keep the color-scheme detection block; drop the
  obsolete static autocomplete list (master moved to refreshCommandAutocomplete).
- docs/config-catalog.md: regenerate (tui Config source line shifted to :104).
2026-07-21 10:06:49 +08:00
Turtle a205ba4c29 test(sandbox): give the probe-timeout test headroom over vitest's default
`bounds the default probes` runs a real launcher that sleeps 1s under the
5000ms default probe budget, all wrapped in vitest's 5000ms default test
timeout. The blocking spawnSync races that wrapper and tips over under the
load spike of a full parallel run — a pre-existing, load-sensitive flake
(noted as unrelated in this PR's original description). Give the test an
explicit 20s timeout so its bounded subprocess work never races the default.
2026-07-21 09:42:12 +08:00
Turtle f81d382230 fix(tui): make color-scheme detection fully covered and race-free
The color-scheme detection block left packages/ui/tui/src/index.ts below
the 100% per-file coverage gate on three counts: the .then callback's
`scheme === undefined` branch was reachable only via the 2s query
timeout, the .catch only via a query-write failure, and the
`editor.borderColor` assignment inside applyColorScheme was dead code —
the next line's setStatus() immediately reassigns editor.borderColor.

Register the scheme listener before firing the startup query so the
query's own reply is delivered through the listener (the same path as
later theme switches), which removes the redundant .then re-application
and its uncoverable undefined branch, and closes the theoretical window
where a synchronous reply lands before the listener exists. Drop the
dead editor.borderColor line. Cover the rest: a same-scheme report
(early return) and a terminal that throws on the query write (the
swallowed .catch).
2026-07-20 22:17:35 +08:00
Turtle aa7e8ea728 Merge branch 'master' into fix/tui-color-scheme-v2 2026-07-20 21:13:57 +08:00
Turtle 734bd40bb6 docs: regenerate config catalog after stacking on #425 2026-07-20 19:03:15 +08:00
Turtle 6889878bc5 Merge remote-tracking branch 'origin/fetch-failed-diagnostics' into fix/tui-color-scheme-v2 2026-07-20 18:58:41 +08:00
Turtle a3243abeda Merge branch 'master' into translate-skill-subagent 2026-07-20 18:58:12 +08:00
Turtle a661f5c8f3 test(tui): prove color scheme detection switches palette ANSI codes 2026-07-20 17:24:29 +08:00
Turtle 3a1b500cef fix(tui): detect terminal color scheme and apply light-optimised palette 2026-07-20 17:24:29 +08:00
Turtle ed784cfdce Render error cause chains at every diagnostic seam
A TUI run against an unreachable endpoint failed with only 'fetch failed':
undici wraps transport failures in a bare TypeError whose diagnosis lives
on .cause, and every diagnostic seam rendered only error.message. The
readline front door additionally rendered failed turns as pure silence.

- dsh-llm: new errorChain(value) renders the full cause chain and
  AggregateError members with circular/hostile-coercion containment.
- llm-deepseek: pre-response transport failures throw LlmError('NETWORK')
  naming the endpoint and chaining the fetch TypeError; aborts keep their
  DOMException so the loop still classifies them as cancellation.
- agent-loop: durable turn/end error messages and logger warnings render
  through errorChain; local renderThrown copies removed.
- ui-stdio: failure turn/end reasons now render ([turn failed <code>],
  [turn aborted], [turn rejected], output-token-limit); startup-failure
  logs use errorChain.
- ui-tui: agent/error notices and the startup-failure line use errorChain.
2026-07-20 17:24:29 +08:00
Turtle 85fbf122a9 docs: regenerate event-producer matrix after master merge 2026-07-20 17:22:50 +08:00
Turtle ccb1d09850 Merge remote-tracking branch 'origin/master' into fetch-failed-diagnostics
# Conflicts:
#	docs/event-producer-consumer.md
2026-07-20 17:21:43 +08:00
Turtle f593ef5ab5 fix(session): drop the <context> envelope and project context verbatim
context/message previously defaulted to a <context source="…">…</context>
wrapper. No model is trained on a <context> tag either, and message
framing does not belong on the session surface: the surface projects the
durable log, and a caller that wants a frame formats its own content —
which the one heavy producer (workspace-context) already does with its own
<system-reminder> frame, opting out via 'raw'. The tag only added
machinery — ContextEnvelope plus an envelope field threaded through
InjectOptions, HookContext, the context/message event, and the agent-loop
inject/additionalContexts plumbing.

context/message now projects its content verbatim as a user-role message,
sharing one deriveEventMessage case with user/message and steering/message.
ContextEnvelope and every envelope field are removed; context/message.meta
still carries durable, model-hidden JSON state. Regenerated catalogs and
website API; refreshed the three affected keyless snapshots (envelope field
only; timestamps unchanged).

Broadens and renames the steering Agent Note to cover both envelope
removals as one decision.

Agent Note: .agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.md
2026-07-20 16:22:20 +08:00
Turtle b25b78fd02 fix(session): project steering messages as plain user content
steering/message previously rendered inside a <steering source="…">
envelope like context/message. No model is trained on a <steering> tag,
so the framing is arbitrary markup the model was never taught to read;
recorded transcripts show it treating the instruction as third-party
metadata and refusing it. Framing also does not belong on the session
surface — a caller that wants a frame formats its own content. It now
projects verbatim as a plain user-role message; the <context> envelope is
untouched and renderTagged becomes context-only.

Agent Note: .agents/notes/implemented/simplification/2026-07-20-unwrap-steering-message-projection.md
2026-07-20 15:51:27 +08:00
Turtle aeb48cc5f3 Render error cause chains at every diagnostic seam
A TUI run against an unreachable endpoint failed with only 'fetch failed':
undici wraps transport failures in a bare TypeError whose diagnosis lives
on .cause, and every diagnostic seam rendered only error.message. The
readline front door additionally rendered failed turns as pure silence.

- dsh-llm: new errorChain(value) renders the full cause chain and
  AggregateError members with circular/hostile-coercion containment.
- llm-deepseek: pre-response transport failures throw LlmError('NETWORK')
  naming the endpoint and chaining the fetch TypeError; aborts keep their
  DOMException so the loop still classifies them as cancellation.
- agent-loop: durable turn/end error messages and logger warnings render
  through errorChain; local renderThrown copies removed.
- ui-stdio: failure turn/end reasons now render ([turn failed <code>],
  [turn aborted], [turn rejected], output-token-limit); startup-failure
  logs use errorChain.
- ui-tui: agent/error notices and the startup-failure line use errorChain.
2026-07-20 12:35:10 +08:00
Turtle 4ce2202721 Bound the delegation section with a header so "skip this section" is well-defined 2026-07-20 11:56:08 +08:00
Turtle 33fadcf08d Drop the draft-PR requirement; delegation is just: use a subagent 2026-07-20 11:46:16 +08:00
Turtle 4d037613b1 Drop worktree/branch mechanics from the delegation instruction; just use a subagent 2026-07-20 11:31:27 +08:00
Turtle f2206a3f28 Address review: fix exception path, recursion stop, terminology, anchor, description 2026-07-20 10:55:03 +08:00
Turtle 3a20b4c551 dsh-translate-docs: delegate translation writing to a subagent worktree with a draft PR 2026-07-20 10:48:58 +08:00
Turtle 7f91a05ed7 docs: add TUI screenshots 2026-07-17 17:13:41 +08:00
Turtle 87e25ef1fe fix(tui): make the color palette theme-agnostic
The palette used absolute 256-color indices (`38;5;252`, `48;5;236`, …)
that terminals never remap to the active scheme: near-white body text
vanished on light backgrounds and fixed dark bubble fills put default
foreground text on dark blocks. Rebuild it from the standard 16-color
ANSI foregrounds plus SGR attributes, keep body text on the terminal
default foreground, replace filled background bubbles with foreground-only
left-gutter bars, and use reverse video for the active selection so every
grouping reads on any color scheme.
2026-07-17 16:50:53 +08:00
Turtle 12b7ac67ba fix(ui): surface declarative startup failures 2026-07-17 16:44:25 +08:00
Turtle 1119c537d0 feat(ui): add dedicated TUI package
Move the interactive pi-tui front door into @deepseek-ai/dsh-tui while keeping @deepseek-ai/dsh-stdio line-oriented for pipes. Select the terminal package in the demo app, preserve logger ownership, and cover the production Loader composition with a PTY smoke test.
2026-07-17 12:01:37 +08:00