Commit Graph

774 Commits

Author SHA1 Message Date
Turtle 5a06b9e926 fix(cli): reject default-surface flags leaked onto the web subcommand
ds-review-bot: `dsh web -p task`, `dsh web --resume s`, and `dsh --config c.yml
web` reached the web action with those values in program.opts() but the action
ignored them and served — silently dropping mode-specific inputs. The web
action now reads the parent opts and fails loud (exit 1) on a leaked
--config/-p/--resume, matching the root mode's mixing guard. Covered in
args.spec.ts.

Also (ds-review-bot): tui-demo/README documented the removed `dsh
[path-to-cordis.yml]` positional form; corrected to bare `dsh` / `dsh --config
<path>`. Agent Note + Chinese pair note the web-leak guard.
2026-07-25 17:24:39 +08:00
Turtle d616d4ca50 docs: state the shipped dsh CLI design, not the change history
Rewrite the Agent Note's Decision/Resume/front-door/Consequences sections and
its Chinese pair in present tense, dropping changelog phrasing ("X replaces an
earlier Y", "retired the env var", "which the merge brought in", "Anyone who
ran X now uses Y", "an earlier revision dispatched..."). The note now introduces
the current grammar directly; Problem and Alternatives keep the motivation and
rejected designs the format requires.
2026-07-25 16:49:45 +08:00
Turtle 9f6dbde7f6 refactor(cli): let the webserver schema own web --host/--port validation
The adapter no longer validates --host/--port or declares the allowed set:
LOOPBACK_HOST/ALL_INTERFACES_HOST leave args.ts. --host/--port are now
unvalidated pass-through overrides — the adapter only Number-coerces the port
string (the dsh-host-webserver schema wants a number). That schema
(host a 127.0.0.1/0.0.0.0 literal union, port a natural <= 65535) is the single
source of both the default (the shipped cordis.yml webserver row) and validity;
AppCLIEntry patches an explicit flag into that row, so a bad host/port fails
loud at the schema on boot (verified: `dsh web --host 9.9.9.9` and `--port abc`
both exit 1 with the schema's ValidationError).

web.ts keeps two display-only literals (the printed loopback URL, the
all-interfaces LAN-detection check), commented as mirrors of the schema, not a
source of truth. Agent Note + Chinese pair and README updated; the args spec
drops the host/port exit-code cases (now the schema's job, covered by the web
smoke on boot).
2026-07-25 16:19:02 +08:00
Turtle fca2dda37d refactor(cli): unify the arg grammar — one program, --config flag, real web subcommand
Drop the bare `dsh <config>` positional in favor of a `--config <path>` flag.
Without a root positional, `web` can be a real Commander subcommand in one
program instead of the reserved-first-token dispatch to a second parser, so
`dsh --help` lists every mode natively (no hand-pasted command text) and the
second parser + reserved-token machinery are gone.

Grammar:
  dsh                       TUI (shipped tree + ~/.dsh overlay)
  dsh --config <path>       TUI, alternate tree (demos/tests only)
  dsh --resume <id>         TUI, resume a session
  dsh -p "task"             headless one-shot
  dsh web [--host --port --dev]

`dsh` is the product front door with no positional; `--config` exists only so
demo:cordis, demo:code-mode, and the keyless PTY smokes can point the shipped
bin at an example tree. Those three sites and the /resume re-exec argv move to
`--config <path>`. The `-p` + `--config`/`--resume` mode-mixing guard and the
cordis.yml-owns-host/port-default fix are preserved.

Agent Note + Chinese pair, README, tui.ts docs updated. All 13 PTY smokes
(including code-mode via --config and the exec-replace resume handoff) green.
2026-07-25 15:47:55 +08:00
Turtle 91d86f9b21 fix(cli): let cordis.yml own the web host/port default (single source)
The merge's "always pass adapter-resolved host/port to AppCLIEntry" made the
adapter's 127.0.0.1/3080 shadow apps/cli/cordis.yml's webserver row — editing
the yml port would have had no effect, a duplicated default.

The adapter now assigns no host/port default: an absent --host/--port leaves the
field undefined (WebInvocation.host?/port?), runWeb forwards each to AppCLIEntry
only when present, and AppCLIEntry patches the webserver row only for an
explicit flag. cordis.yml is the single source of the host/port default; the
adapter still validates a flag when given. Removes the now-unused
DEFAULT_WEB_PORT; LOOPBACK_HOST/ALL_INTERFACES_HOST stay as the allowed-value
vocabulary (validation + the printed URL/LAN line).
2026-07-25 15:03:17 +08:00
Turtle 2dfd8635e8 Merge branch 'master' into worktree/dsh-arg-parser
Integrate the Commander argument adapter and dsh-front-door work with master's
config-tree `dsh web` (#601: AppCLIEntry + apps/cli/cordis.yml) and the
packages/ui/acp → packages/acp/acp relocation.

- web.ts: keep master's AppCLIEntry-based boot, but take the adapter's parsed
  (host, port, dev) instead of an internal parseArgs. The adapter's host/port
  defaults (127.0.0.1/3080) match cordis.yml, so always passing them is
  behavior-equivalent to master's "undefined keeps the yml default".
- apps/cli/package.json: master's expanded config-tree dep set + commander.
- retire-readline Agent Note: point the TUI refusal proof at
  apps/cli/tests/built-bin.e2e.ts (both languages), re-record the pair.
- READMEs reconciled (demo-bin removal + master's ACP/channel rewording).
2026-07-25 14:37:57 +08:00
Turtle 007e8fd92f refactor(cli): bail early in the arg adapter instead of returning errors as data
Address review and cut ceremony: the adapter no longer models help/version/
errors as DshInvocation members. Commander owns those under exitOverride — it
prints usage or the diagnostic and one try/catch in parseDshArgs turns the
thrown CommanderError into process.exit with the intended code. bin.ts drops its
help/version/error cases; the union is the three real modes.

Domain checks bail via command.error(print + exit 1): --prompt rejects an empty
task or a stray config/--resume, empty --resume= fails loud, and --host/--port
are validated. A repeated --resume or a flag captured as a value is Commander's
standard behavior, left alone (a bad id fails loud downstream). dsh --help
discloses web via addHelpText. Net: args.ts 185 -> 112 lines.

Also fixes review nits: built-bin e2e resolves on `close`; the /resume handoff
uses `dsh --resume=<id> -- <config>` so a config named `web` stays a positional;
and stale prose (cordis.yml comment, app-boot module doc + duplicate JSDoc,
ui/README, two feature notes, an agent-loop test name) tracks the shipped state.
Removes tui-demo's now-dead plugin-include dep and vendor/loader + app-boot
tsconfig references.
2026-07-25 14:15:25 +08:00
Tianyi Cui 8c1280fa7d Merge origin/master into fix-webplugins-watch-flake 2026-07-25 13:28:23 +08:00
Tianyi Cui d67be60933 Merge origin/master into fix-webplugins-watch-flake
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.md
#	.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.zh.md
#	packages/host/webserver/tests/web-plugins.spec.ts
2026-07-25 13:23:42 +08:00
Tianyi Cui dc9c3fb1ae Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	docs/capability-seams.md
#	docs/event-producer-consumer.md
#	tsconfig.base.json
2026-07-25 13:05:30 +08:00
Turtle 0901140b3f test(cli): cover the dsh built-bin non-TTY refusal
Removing the dsh-tui-demo bin dropped the only test of the TUI's piped-launch
refusal. Add apps/cli/tests/built-bin.e2e.ts (apps/*/tests added to the e2e
vitest include) running the built lib/bin.js under plain Node with piped stdio,
and point the refusal message at `dsh -p "task"` for automation.
2026-07-25 13:01:45 +08:00
Turtle 870fb1cafa refactor(cli): make dsh the sole terminal front door, drop RESUME_SESSION_ID
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.
2026-07-25 12:43:59 +08:00
Turtle 6cd139a25b Merge branch 'master' into worktree/dsh-arg-parser
Integrate the Commander argument adapter with master's safe session-resume
feature and dsh web --dev flag.

- args.ts: add --dev to the web parser.
- tui.ts: keep master's process.execve in-place resume handoff, but take the
  adapter's parsed (config, resume); inject the resume id through boot's
  prepare(ctx) hook via ctx.provide(RESUME_SESSION_ID_KEY, id) instead of the
  RESUME_SESSION_ID env var; rebuild the re-exec argv as `dsh --resume <id>`.
- app-boot: drop master's replaceResumeArg (no longer needed) alongside the
  already-removed parseResumeArg; add RESUME_SESSION_ID_KEY.
- the four tui-agent/cordis configs read the ctx-provided resumeSessionId via a
  typeof-guarded !!js expression, so resume needs no env var.
- web.ts: keep master's client roster and --dev watch, take parsed host/port/dev.
2026-07-25 12:04:37 +08:00
imccyu 2e27b8aeef chore(web): gate repairs for the config-tree boot round
Lint (bridge JSDoc params, service-class export shape, async invariant
listener form), regenerated doc catalogs/graphs with role classifications
for httpServer and clientModuleHost, catalog type-link exemptions for the
route/graph contracts, knip alignment (apps/cli composes via cordis.yml so
its yml-named deps are runtime edges knip cannot see; webserver's deleted
test dir), the zh side of the loading-model note brought along with its
pairing records, and coverage exclusions for the new web-transport halves
under the GUI test-lane TODO (real-composition harnesses land with that
lane).
2026-07-25 10:38:54 +08:00
imccyu db59d32c9b docs(gui): agent notes for the config-tree boot and transport layering
New note records the dsh web composition decision (flat cordis.yml, the
AppCLIEntry/AppWebEntry class pair, one declaration place per config
source, the five-way transport split) with its rejected alternatives; the
client-plugin-loading note's roster endgame and HMR sections are brought
current with what shipped.
2026-07-25 10:25:02 +08:00
Tianyi Cui 2beaa18f42 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	packages/support/acp-snapshot/README.md
2026-07-25 02:07:28 +08:00
Tianyi Cui 05ee162723 Merge remote-tracking branch 'origin/master' into fix-webplugins-watch-flake
# Conflicts:
#	packages/host/webserver/src/web-plugins.ts
#	packages/host/webserver/tests/web-plugins.spec.ts
2026-07-25 01:58:59 +08:00
Tianyi Cui 16910475ef docs(i18n): mirror ACP-automation edits into the zh pairs from master
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.
2026-07-25 01:58:42 +08:00
Tianyi Cui 2096050824 fix(webserver): registry-owned stat poll replaces fs.watchFile baseline race
The dev bundle watch missed rebuilds that landed while the registry was
constructing: fs.watchFile captures its comparison baseline with an
ASYNCHRONOUS first stat, so a write racing that window is absorbed into
the baseline and never reported. Standalone repro missed 24/400 same-tick
rewrites; the CI flake in web-plugins.spec.ts ('watch mode: a bundle
content change re-hashes the row...') was exactly this — the spec writes
immediately after createHostWebPluginRegistry returns.

The watch now polls from one registry-owned setInterval against a stat
baseline the scan itself captures synchronously, stat-before-read: a
write landing between stat and read leaves the hash newer than the
baseline (next tick re-hashes to the same rev, no spurious notify); a
write landing after the read leaves the baseline older (next tick
detects and notifies). No blind window. The poll iterates the live
table, so rescans retarget the watch for free and dispose clears one
timer. Stress: real-registry same-tick rewrite 0/600 missed (was 1/300);
spec watch tests 0/50.

New regression test pins the same-tick-as-construction write. Its
rewrite deliberately differs in size from the seed: a same-millisecond
same-size rewrite is invisible to any mtime+size poll (coarse fs
timestamps) — a stat-polling limit, not this regression. Loading-model
Agent Note updated in both languages (pair re-recorded).
2026-07-25 01:22:46 +08:00
Tianyi Cui 1d066e0f74 Fix remaining PTY and bundle watch races
Keep inherited child prompt markers bounded by the normal silence fallback. Stage web-plugin rescans atomically and retain missing watch state until a successful rebuild.
2026-07-25 00:33:33 +08:00
Tianyi Cui f9a638b8a6 Stabilize master CI across platforms 2026-07-25 00:10:37 +08:00
Tianyi Cui 440384fdb4 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.md
#	.agents/notes/implemented/architecture/2026-06-20-package-hierarchy.md
#	.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-multi-session.md
#	.agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.zh.md
#	.agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md
#	docs/architecture.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/cookbook/extension-cookbook.md
#	docs/cookbook/extension-cookbook.zh.md
#	docs/core-data-structures/approval.md
#	docs/core-data-structures/user-interaction.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	docs/testing.md
#	docs/tool-catalog.md
#	examples/acp-agent/tests/fixtures/live-mode-switching-2026-07-07.session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	packages/goal/tool-goal/README.md
#	packages/ui/acp/README.md
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-24 23:43:10 +08:00
Tianyi Cui 88f3933327 fix(docs): address Codex round-1 findings on the review-fix stack
- gen-doc-graphs still summarized the ACP demo as 'text-only'; say
  baseline-prompt and regenerate composition.md.
- The llm-catalog note claimed unit coverage for per-agent target
  isolation that no test pins directly; state the actual basis
  (agent-scoped listener installation) in both languages and re-record.
2026-07-24 22:36:06 +08:00
Tianyi Cui 5569f3f8ac docs: repair rewritten rationale and stale claims from the ACP reduction
The automation-only rewrite edited many implemented Agent Notes; several
edits replaced still-live or historical rationale instead of reframing:

- llm-model-catalog: restore the prompt/request consistency section and
  selection-ownership alternatives — installAgentLlmTarget and the TUI
  /model selector still ship that design; only the ACP wire is gone.
- plan-specific-collaboration-state, acp-multi-session, todo-write,
  ask-user-question: link the superseding automation-only note instead
  of silently rewriting the original decision or motivation; drop a
  paragraph duplicating the Web-provider facts stated two paragraphs up.
- sandbox: stop claiming unit coverage for turn-enclosed config writes
  (that mechanism left with the bridge) and retitle the commit-boundary
  paragraph accordingly.
- Fix the missing blank line before '## Consequences' in the
  plugin-command-registration pair, the JSON-RPC/Web render-intent
  consumer misattribution (the second consumer is the host/client
  runtime), stale bash_output/bash_kill names, and 'optional goals' in
  architecture.md.
- examples/acp-agent/README.md: point at the package contract instead
  of restating it; packages/ui/permission and plan-mode READMEs record
  the consumer-less preset service and the exit_plan_mode coverage gap
  under Known Limitations.
- 2026-06-19-acp-snapshot-tests: the new note defers the corpus
  migration rather than committing to it; say so.

Re-record the touched bilingual pairs.
2026-07-24 22:12:23 +08:00
Tianyi Cui 74d14f68bb fix(acp): accept baseline resource links and release a failed prompt slot
ACP v1 requires every agent to accept text AND resource_link prompt
content; the automation rewrite dropped the resource_link half of that
baseline. Restore the old bracketed-reference flattening in the codec,
reject only beyond-baseline blocks, and update the package contract and
Agent Note.

Also release the per-session prompt slot when agent.send() throws
synchronously (an agent disposed outside the bridge would otherwise
wedge the session into permanent 'already in flight' rejections),
drop the tautological version-negotiation branch, prove the scenario
env layer reaches the snapshot subprocess, pin bridge-side fail-closed
permission errors, and correct two overpromising test names.
2026-07-24 22:11:49 +08:00
Tianyi Cui 158c5e913a docs(i18n): refresh persistence docs after master merge 2026-07-24 21:27:22 +08:00
Tianyi Cui d847b48479 Merge remote-tracking branch 'origin/master' into worktree/pr343-retarget-latest-master 2026-07-24 21:21:22 +08:00
Tianyi Cui 2584f029bc Merge remote-tracking branch 'origin/master' into worktree/pr343-retarget-latest-master
# Conflicts:
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/cookbook/extension-cookbook.zh.md
2026-07-24 21:20:17 +08:00
Tianyi Cui 46dfd503e0 Merge origin/master into codex/sqlite-metadata-contracts 2026-07-24 21:07:23 +08:00
Tianyi Cui 9e691d54c0 fix(goal): normalize strict-schema fillers 2026-07-24 20:45:23 +08:00
Turtle ee5132c1e1 refactor(cli): dispatch web as a reserved token, drop parse machinery
Simplify the Commander adapter now that behavior can change: dispatch a leading
`web` token to its own parser instead of a subcommand of the root program, and
read opts()/processedArgs after parse() instead of action closures with a
mutable holder.

This removes enablePositionalOptions(), the parent-option leak guard, both
action closures, and the --resume/--prompt argParser threading. Behavior
changes: `dsh -p x web` is a headless prompt (extra positional dropped),
`dsh web -p x` fails loud (web has no -p), and a repeated --resume is natural
last-wins. The two real fail-loud invariants stay as post-parse checks: an empty
--resume= id (agent-loop treats '' as no-resume) and an empty -p task.

Trims args.spec.ts to the routing/fail-loud/help behavior that matters; the
tui-agent keyless PTY smoke still covers bin.ts dispatch end to end. Net ~114
fewer lines across adapter and tests.
2026-07-24 20:01:38 +08:00
Turtle 800bafda3b refactor(cli): parse dsh argv through one Commander adapter
Replace the dsh CLI's three hand-rolled parsing idioms (raw argv[0]/includes
dispatch in bin.ts, per-mode node:util parseArgs in headless.ts/web.ts, and the
bespoke parseResumeArg scanner in dsh-app-boot) with a single Commander adapter
in apps/cli/src/args.ts. parseDshArgs resolves argv into a discriminated
DshInvocation union; bin.ts switches on the mode and dynamic-imports the chosen
module, which now consumes already-parsed values.

- web is a real subcommand; --host uses choices and --port an argParser range
  check, moving validation into the parser.
- --resume rejects empty and repeated forms; --prompt rejects empty; a config
  positional after --prompt and a root flag placed before web fail loud.
- adds --help/--version; removes parseResumeArg from dsh-app-boot.
- new apps/cli/tests/args.spec.ts (apps/*/tests added to vitest include,
  apps/cli/tests to tsconfig.host.json); the tui-agent keyless PTY smoke covers
  bin.ts dispatch end to end unchanged.
2026-07-24 19:43:59 +08:00
Tianyi Cui 985aceaa75 Merge branch 'master' into feat/send-unify 2026-07-24 19:40:38 +08:00
Tianyi Cui f1fd9940c3 Merge commit 'de939d19b95074595910f2e53e463810094a297c' into worktree/pr345-retarget-stack 2026-07-24 19:33:08 +08:00
Tianyi Cui 86d16d15b6 Merge remote-tracking branch 'origin/master' into worktree/pr343-retarget-latest-master 2026-07-24 19:32:25 +08:00
Tianyi Cui e14bac2692 Merge branch 'master' into worktree/fix-python-sdk-nested-subagent-notifications 2026-07-24 19:17:03 +08:00
Tianyi Cui b65421431b docs(i18n): complete Agent Note translation fidelity 2026-07-24 18:38:27 +08:00
Tianyi Cui 0191a014dd docs(i18n): preserve authority constraints 2026-07-24 17:39:22 +08:00
Turtle 081bb1a8fd Merge remote-tracking branch 'origin/master' into feat/send-unify
# Conflicts:
#	packages/client/runtime/src/client/sessions/fold-adapter.ts
2026-07-24 17:17:35 +08:00
Tianyi Cui 5860950d0a Merge refreshed #344 into docs/i18n-batch-rfc 2026-07-24 17:16:38 +08:00
Tianyi Cui c62ca61ccb Merge latest master into docs/i18n-batch-core 2026-07-24 17:13:25 +08:00
Tianyi Cui bcb2bd2795 Merge refreshed #344 into docs/i18n-batch-rfc 2026-07-24 17:10:05 +08:00
07akioni 65e6a2adbe Merge branch 'master' into feat/trajectory 2026-07-24 17:06:25 +08:00
Turtle d2b2539f3e Merge remote-tracking branch 'origin/feat/send-unify' into feat/send-unify
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/architecture.md
2026-07-24 16:58:32 +08:00
Tianyi Cui b040c6a1c9 Merge latest master into docs/i18n-batch-core 2026-07-24 16:55:08 +08:00
Turtle 80bbe959a7 Merge remote-tracking branch 'origin/master' into feat/send-unify 2026-07-24 16:52:46 +08:00
Tianyi Cui f5fe71d34a docs(i18n): fix final Agent Note semantics 2026-07-24 16:36:34 +08:00
Turtle bb124c2869 Merge branch 'master' into feat/send-unify 2026-07-24 16:31:00 +08:00
ZiyaZhang 33ee34b58e fix(tui): make resume picker full-screen 2026-07-24 01:29:35 -07:00
Turtle c440217fde refactor(tui): defer cross-process resume locking 2026-07-24 01:29:35 -07:00