Commit Graph

1027 Commits

Author SHA1 Message Date
Dudu-0223
e1f7eeeb95 fix(subagent): confirm steering request admission 2026-08-02 04:34:16 +08:00
Tianyi Cui
c96f48e176 fix(review): tolerate mid-teardown personal-watcher registration
CI caught a startup race the PTY smoke stages naturally: a TUI /exit typed
while watchPersonalPatches is still opening its watcher disposes the tree,
and the HMR effect registration rejects with INACTIVE_EFFECT, crashing an
app that exited exactly as asked. Return a no-op disposer for that exact
code; every other registration failure still propagates (covered both ways).
2026-08-02 01:29:04 +08:00
Tianyi Cui
b6284c8467 fix(review): audit prepared-wrapper activation and pin generated shapes
ds-review-bot round 1 on the DSH-home integration:
- generated wrappers now inject the services their manifest needs (skills/
  tools beside loader), and loadPreparedRepository rejects a wrapper fiber
  that settles anything but ACTIVE — a composition missing a required
  service fails the repository transaction instead of committing an ACTIVE
  row over a silently PENDING child (critical finding)
- the github: source ref segment excludes '#', so 'a#b' refs fail at the
  config parser with the promised syntax instead of inside pnpm
- watchPersonalPatches re-reads the include's non-patch options per refresh
  instead of a registration-time snapshot
- the TUI smoke's cache-seeded wrapper is produced by the real
  prepareDshPlugin (cache LAYOUT stays a deliberate external pin)
- new Loader integration test drives a live repositories update through
  entry.update: generation swap, old skills removed, failed candidate
  rolled back to the previous generation
2026-08-02 01:29:04 +08:00
Tianyi Cui
2448496803 feat: configure repository plugins from DSH home 2026-08-02 01:29:04 +08:00
Tianyi Cui
fd4d369907 feat(cordis): add repository package cache 2026-08-02 01:25:02 +08:00
Tianyi Cui
f941ba1b5f fix(review): label host-preparation failures and gate vendored lockfile links
ds-review-bot round 1: boot() now throws `host preparation failed` when
prepare() rejects before any config-tree entry mounts (the plugin-tree label
overstated), and the new hygiene gate verify-vendored-links pins the
linkWorkspacePackages fix — every vendored package name in pnpm-lock.yaml
must resolve to a workspace link with no registry copy alongside.
2026-08-02 01:25:01 +08:00
Tianyi Cui
2fe205f01a fix(cordis): clear omitted include patches 2026-08-02 01:25:01 +08:00
Tianyi Cui
195f7fa9af fix(cordis): make config reload transactional 2026-08-02 01:25:01 +08:00
_Kerman
0efbb7d87a Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-22-docked-web-goal-bar.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-22-docked-web-goal-bar.md
#	.agents/notes/implemented/feature/2026-07-22-docked-web-goal-bar.zh.md
#	docs/config-catalog.md
#	packages/client/ui-goal/README.i18n.yaml
#	packages/host/apiproxy/tests/api-proxy-fork.spec.ts
#	packages/ui/tui/README.i18n.yaml
2026-08-02 00:59:11 +08:00
_Kerman
6f8cbddb31 fix(approval): preserve model policy switch notices 2026-08-02 00:49:32 +08:00
_Kerman
dbdf270af0 refactor(agent): simplify inbox-driven turn admission 2026-08-02 00:27:37 +08:00
Tianyi Cui
d7289febdb Merge pull request #959 from deepseek-harness/fix/checkout-workdir-prompt
fix(prompt): distinguish checkout from workdir
2026-08-01 17:54:34 +08:00
Turtle
cb1a6c74dc Merge remote-tracking branch 'origin/master' into fix/checkout-workdir-prompt
# Conflicts:
#	packages/ui/app-boot/README.i18n.yaml
#	packages/ui/app-boot/README.md
#	packages/ui/app-boot/README.zh.md
2026-08-01 00:04:49 +08:00
Turtle
6792a12d8c Merge remote-tracking branch 'origin/master' into perf/tui-resume-scan
# Conflicts:
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/ui/tui/README.i18n.yaml
#	packages/ui/tui/tests/tui.spec.ts
2026-07-31 23:42:54 +08:00
Turtle
20e51abd4e feat: rename experimental-meta/-upgrade to meta/upgrade behind --experimental gate 2026-07-31 23:37:53 +08:00
_Kerman
1a09174987 refactor(goal): persist state with domain events 2026-07-31 22:52:18 +08:00
_Kerman
e0988abc74 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md
#	.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.zh.md
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.md
#	.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md
#	.agents/notes/implemented/feature/2026-07-27-tmux-location-context.i18n.yaml
#	.agents/notes/implemented/simplification/2026-06-20-public-agent-stop-surface.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-30-private-agent-send.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/architecture.md
#	docs/architecture.zh.md
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/compaction.i18n.yaml
#	docs/core-data-structures/core.i18n.yaml
#	docs/core-data-structures/core.md
#	docs/core-data-structures/core.zh.md
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/llm-streaming.md
#	docs/core-data-structures/llm-streaming.zh.md
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	docs/persistence-catalog.md
#	examples/acp-agent/tests/goal-snapshots/goal-session/session.expected.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/bash-spill/session.jsonl
#	examples/acp-agent/tests/snapshots/bash-tool-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/cancel-tool-calls/session.jsonl
#	examples/acp-agent/tests/snapshots/cancel/session.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	examples/acp-agent/tests/snapshots/empty-response-retry/session.jsonl
#	examples/acp-agent/tests/snapshots/error-finish/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-edit/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-glob-sampling/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-policy-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-read-window/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-read/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-write-overwrite/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-write/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-invalid-matcher/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-deny/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-stop-continue/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-invalid-matcher/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-pretool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-stop-continue/session.jsonl
#	examples/acp-agent/tests/snapshots/lsp-definition/session.jsonl
#	examples/acp-agent/tests/snapshots/multi-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/packed-chunks/session.jsonl
#	examples/acp-agent/tests/snapshots/parallel-tool-calls/session.jsonl
#	examples/acp-agent/tests/snapshots/pty-tools/session.jsonl
#	examples/acp-agent/tests/snapshots/repeat-tool-guard/session.jsonl
#	examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl
#	examples/acp-agent/tests/snapshots/session-sandbox-root/session.jsonl
#	examples/acp-agent/tests/snapshots/session-title-after-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/todo-write/session.jsonl
#	examples/acp-agent/tests/snapshots/tool-call-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/web-fetch/session.jsonl
#	examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl
#	examples/acp-agent/tests/snapshots/workflow-run/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-edit/session.jsonl
#	examples/headless-agent/tests/semantic-checkpoint-snapshots/tool-outcome-unknown/session.expected.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/goal-tools/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/missing-credential/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/provider-retry/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/pty-tools/session.jsonl
#	examples/headless-agent/tests/snapshots/pty-tools/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/ralph-loop/stream-json.expected.jsonl
#	examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl
#	examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/parent.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/bash-tool/notifications.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/bash-tool/session.jsonl
#	examples/jsonrpc-agent/tests/snapshots/persistent-tools/notifications.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/persistent-tools/session.jsonl
#	examples/jsonrpc-agent/tests/snapshots/subagent-spawn/notifications.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.1.jsonl
#	examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.jsonl
#	examples/jsonrpc-agent/tests/snapshots/text-turn/notifications.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/text-turn/session.jsonl
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/src/client/sessions/request-inspection.ts
#	packages/compact/compact-basic/README.i18n.yaml
#	packages/compact/compact-basic/README.md
#	packages/compact/compact-basic/README.zh.md
#	packages/compact/compact-basic/src/index.ts
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/context/tmux-context/README.i18n.yaml
#	packages/context/tmux-context/tests/tmux-context.spec.ts
#	packages/context/workspace-context/tests/workspace-context.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent/README.i18n.yaml
#	packages/core/agent/README.md
#	packages/core/agent/README.zh.md
#	packages/core/agent/src/types.ts
#	packages/core/session/README.i18n.yaml
#	packages/core/session/README.md
#	packages/core/session/README.zh.md
#	packages/fs/tool-str-replace-editor/tests/tools.spec.ts
#	packages/goal/command-goal/tests/command-goal.spec.ts
#	packages/goal/goal/tests/goal.spec.ts
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/README.zh.md
#	packages/host/apiproxy/src/api/index.ts
#	packages/host/apiproxy/tests/api-proxy-workspace.spec.ts
#	packages/llm/llm/README.i18n.yaml
#	packages/llm/llm/README.md
#	packages/llm/llm/README.zh.md
#	packages/llm/llm/src/index.ts
#	packages/pty/pty-local/tests/index.spec.ts
#	packages/pty/pty-local/tests/local.spec.ts
#	packages/pty/pty/tests/service.spec.ts
#	packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts
#	packages/pty/tool-bash-persistent/tests/tools.spec.ts
#	packages/pty/tool-pty/tests/loader-composition.spec.ts
#	packages/pty/tool-pty/tests/tools.spec.ts
#	packages/session-persistence/session-checkpoint-policy/tests/crash-recovery.e2e.ts
#	packages/skill/tool-skill/tests/tool-skill.spec.ts
#	packages/tasks/tasks-local/tests/tasks.spec.ts
#	packages/ui/tui/README.i18n.yaml
#	packages/ui/tui/tests/tui.spec.ts
#	packages/ui/user-approval/src/index.ts
#	packages/ui/user-approval/tests/approval.spec.ts
2026-07-31 22:16:40 +08:00
Turtle
54e541d33f fix(app-boot): drop the unreachable timer guard on the fail-loud release path
The timeout promise's executor runs synchronously while the race is
constructed, so the timer is always assigned; the undefined check was a
dead branch the per-file coverage gate rejected.
2026-07-31 22:14:43 +08:00
_Kerman
afedf18ccf fix inbox lifecycle downstream contracts 2026-07-31 22:00:39 +08:00
Turtle
b4f1675360 docs(app-boot): correct the pre-fix capture claim and pin the exit seam contract
The PTY capture does continue past the terminal-takeover bytes with the
fatal diagnostic; only the reset never follows. State that precisely in
both notes.

Document on FailLoudProcess.exit that callers treat it as the end of the
run, matching how the release path already relies on it.
2026-07-31 20:37:16 +08:00
Turtle
b35b06396d fix(app-boot): keep the fail-loud exit fatal while the terminal is released
Review of the previous commit found two defects in the release path, both
reproduced against the implementation:

- The timeout guarding a never-settling release was unref'ed. An
  unhandledRejection listener suppresses Node's default fatal exit, so with
  nothing else referenced the process reached an empty event loop and exited
  0 on the very failure it was reporting. Keep the timer referenced and clear
  it once the race settles.

- The handler uninstalled itself before awaiting the release. A second
  concurrent rejection then became uncaught and killed the process
  mid-teardown, stranding exactly the terminal state this restores. Replace
  the uninstall with a latch: the first rejection is the reported one, and
  later rejections (teardown's own included) fall through to the pending exit.

Add the PTY regression the fake-process tests cannot express: boot the shipped
tree over a fixture whose llm-pi-ai providers value is list-shaped, expect exit
1, and assert the captured bytes carry both the diagnostic and ESC[?2004l.
Against the pre-fix source the stream ends at ESC[?2004h ESC[>7u ESC[?u ESC[c
with no reset and the case fails, so it pins the actual bug.

Split the two-shape formatting test into one install per case; a latched
handler reports once by design.
2026-07-31 20:37:16 +08:00
Turtle
70f37206d2 fix(app-boot): release the terminal before a fatal load exit
A dsh launch whose config failed validation returned the user to a broken
shell: typing was invisible and the next command was mangled by a stray
Device Attributes reply (1;2;4cecho ...).

The Loader mounts entries concurrently, so ui-tui can already hold the
terminal (raw mode, bracketed paste, keyboard protocol, plus an in-flight
DA query) when a sibling entry rejects on its own config. installFailLoud
wrote its diagnostic and exited immediately, so nothing disposed the tree
and ProcessTerminal.stop() never ran.

Give installFailLoud an optional release teardown, awaited between the
diagnostic and the exit and bounded by FAIL_LOUD_RELEASE_TIMEOUT_MS. The
TUI launcher passes one that disposes the root context, reaching the same
shutdown() the /exit path already uses (drainInput() + ui.stop()). The
context is captured in boot()'s prepare hook because the rejection arrives
while boot() is still in flight.

Bins that pass no release keep the previous behavior exactly.
2026-07-31 20:37:16 +08:00
Turtle
dc88440dad Merge remote-tracking branch 'origin/master' into codex/experimental-cli-command-names
# Conflicts:
#	apps/cli/README.i18n.yaml
#	packages/ui/tui/README.i18n.yaml
2026-07-31 20:18:15 +08:00
Turtle
60a0bcd358 feat(cli): mark meta and upgrade commands experimental 2026-07-31 20:16:19 +08:00
_Kerman
8e88b17c9f fix pre-step lifecycle regressions 2026-07-31 19:40:59 +08:00
Tianyi Cui
7d04e4654a Merge remote-tracking branch 'origin/master' into worktree/pr1018-todo-retarget-20260731
# Conflicts:
#	apps/cli/README.i18n.yaml
#	packages/ui/tui/README.i18n.yaml
2026-07-31 19:23:34 +08:00
_Kerman
fcc2b5e282 refactor agent pre-step inbox lifecycle 2026-07-31 19:21:16 +08:00
Tianyi Cui
3aa98ba609 Merge remote-tracking branch 'origin/master' into worktree/pr1018-todo-retarget-20260731
# Conflicts:
#	apps/cli/README.i18n.yaml
#	apps/cli/README.md
#	apps/cli/README.zh.md
2026-07-31 19:17:50 +08:00
hypatiamay
dcc9e50f84 Merge pull request #1026 from deepseek-harness/feat/compaction-progress-visibility
feat(tui): show live compaction progress
2026-07-31 19:17:43 +08:00
Turtle
a942c726f5 fix(tui): abort the resume scan with its overlay
Review findings from ds-review-bot: closing the loading picker now
aborts the scan through the AbortSignal both query methods accept, a
signal-ignoring backend's late settlement is dropped by a staleness
check, one catch spans listing and projection so a projection failure
closes the overlay instead of stranding the loading placeholder,
setCandidates clears a stale still-loading error, and the batch
comment no longer overstates the win as scaling with session count.
2026-07-31 18:57:24 +08:00
Turtle
6472533845 Merge remote-tracking branch 'origin/master' into perf/tui-resume-scan 2026-07-31 18:32:43 +08:00
Tianyi Cui
20cb7e7360 Merge latest master into manual compaction 2026-07-31 17:58:30 +08:00
Tianyi Cui
6e26f9fd83 Merge latest master into manual compaction
# Conflicts:
#	apps/cli/README.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/compact/compact-basic/README.i18n.yaml
#	packages/pty/pty-local/tests/index.spec.ts
2026-07-31 17:57:11 +08:00
NI0317
c4d88bc25e Merge latest origin/master into feature/tui-first-run-welcome
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-31 17:49:03 +08:00
NI0317
346d1e4c74 fix(tui): address onboarding review feedback 2026-07-31 17:47:07 +08:00
Turtle
ef201014d0 Merge remote-tracking branch 'origin/master' into codex/dsh-home-path
# Conflicts:
#	packages/ui/app-boot/README.i18n.yaml
#	packages/ui/app-boot/README.md
#	packages/ui/app-boot/README.zh.md
#	packages/ui/app-boot/src/index.ts
2026-07-31 17:40:48 +08:00
Turtle
9146c97d13 review: order detailsDialogWidth consistently across the parallel config lists 2026-07-31 17:35:37 +08:00
imccyu
499a6e9c85 Merge pull request #1028 from deepseek-harness/pr/dump-config
feat(cli): dsh --dump-config / --dump-default-config print the composed config tree
2026-07-31 17:06:55 +08:00
Turtle
885f1ed1ac refactor(config): centralize DSH home paths 2026-07-31 16:49:55 +08:00
Turtle
27ab6ee05e docs: regenerate cordis catalog and re-record TUI README pairing 2026-07-31 16:44:25 +08:00
Turtle
5b144238a2 feat(tui): /details Tab toggles apply immediately
Drop the pending state and confirm step: Tab cycles the highlighted
entry and applies at once, so the transcript behind the dialog is the
live preview; Enter/Esc/Ctrl+C just close.
2026-07-31 16:44:25 +08:00
Turtle
f13003df75 feat(tui): two-entry /details selector with Tab cycling
DetailsDialog now shows one entry per dimension (Tool cards, Reasoning)
seeded with the current values; Tab cycles the highlighted entry's
pending value (rendered as current -> pending), Enter applies every
changed dimension in one confirm, Esc/Ctrl+C cancels.
2026-07-31 16:44:25 +08:00
Turtle
2c98f35a86 feat(tui): bare /details opens a keyboard selector
DetailsDialog is a centered SelectList over the five transcript-detail
states (three tool-card phases, reasoning shown/hidden); it preselects
the current phase, marks both current values, applies on Enter, and
cancels on Esc/Ctrl+C. Width is the new detailsDialogWidth config key.
The argument grammar is unchanged and shares the same setters.
2026-07-31 16:44:07 +08:00
Turtle
3899a26c87 feat(tui): /details command sets card visibility and reasoning display
/details reports the transcript detail state bare, jumps tool cards to
collapsed|expanded|hidden, and sets or toggles reasoning blocks, sharing
the closure state behind Ctrl+O/Ctrl+R via setToolsVisibility/setReasoning.

Also fixes a replay defect the reasoning rebuild exposed: rebuildTranscript
reused a settled StreamingAssistantComponent for a later assistant/message
of the same step, overwriting the earlier content; the settled check now
lives in renderEvent for both live and replay paths (untrusted-controls
re-recorded with the previously dropped content present).
2026-07-31 16:44:07 +08:00
Turtle
b7ee38fef0 feat(tui): open the /resume picker immediately with a loading state
The selector overlay opens as soon as the command dispatches: the
picker renders a loading placeholder over an undefined candidate set,
owns terminal input from its first frame, answers Enter with a
still-loading error, and cancels on Escape exactly like the loaded
list. The finished scan swaps rows in through setCandidates without
replacing the overlay; a scan failure closes it and keeps the existing
notice.
2026-07-31 16:39:33 +08:00
Turtle
ce0aa90c1e feat(cli): dsh --dump-config / --dump-default-config print the composed tree
dsh --dump-config and dsh web --dump-config compose the shipped base,
the surface overlay, and the --config or personal overlay — exactly the
layers that surface boots — and print the entry list as YAML without
booting; --dump-default-config stops at the surface overlay so the two
outputs diff to precisely the user layer's effect.

The dump shares the mounting code: the vendored include exports its
patch algorithm as applyEntryPatches() and its !!js dialect as
entryListSchema (logged in vendor/README.md), dsh-app-boot's
renderConfigDump() composes and renders through both (and now imports
the dialect instead of duplicating it), and the CLI adds a thin
dump-config mode. !!js expressions print verbatim; unmatched patches
warn on stderr; boot-only flags are rejected alongside the dump flags.

(cherry picked from commit 1fdbebfa8a5dc7df840d53666320064a7e3dae59)
2026-07-31 16:20:54 +08:00
Turtle
651417e01c test(tui): pin the folded-snapshot clock so replay is keyless-deterministic 2026-07-31 16:12:05 +08:00
Turtle
0c9e529f74 feat(tui): hidden mode folds a turn's assistant steps into one message
The Ctrl+O hidden phase keeps one Assistant header per turn: the first
step with visible text/reasoning owns it, later steps render as
headerless continuations, and bodiless (tool-only) steps render
nothing. Leaving hidden restores per-step headers. Pure TUI
presentation; the session log is unchanged.
2026-07-31 16:12:05 +08:00
Turtle
3c08ca3606 perf(tui): open the /resume selector from one batch projection
The selector called readSession per listed session under an unbounded
Promise.all: each call re-listed the whole persistence store (O(N^2)
listings), decompressed and parsed the complete log, replay-validated
every event, and deep-cloned it up to three times, only to derive one
row's title, activity time, turn label, route, and goal phase. On a
real 185-session / 87 MB store the selector took tens of seconds.

Candidate rows now come from one projectSessions batch over borrowed
logs; a rejected projection degrades to the same disabled unreadable
row. Preflight still replay-validates the single chosen session through
readSession, which is already live-preferred, so its redundant live
shortcut is gone.
2026-07-31 16:09:17 +08:00
imccyu
abc77e707e Merge remote-tracking branch 'origin/feat/manual-compact-single-lock' into feat/compaction-progress-visibility 2026-07-31 15:51:17 +08:00