Commit Graph
1027 Commits
Author SHA1 Message Date
Yichen Jiang eeab643ad9 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
2026-07-26 13:13:31 +08:00
Yichen Jiang 73e7e27799 refactor(llm): resolve model metadata together 2026-07-26 13:07:27 +08:00
_Kerman af3311e1f6 test: close per-file coverage gaps opened by the message-machine refactor
Downstream packages lost the tests that exercised their agent-loop-facing
edges when the loop was rewritten. Restore 100% per-file coverage with
behavior tests through public seams: llm-retry config validation and
cancellation races, goal replay drift/staleness/teardown edges, plan-mode
disposed-flush, workspace-context empty-change commits, api-proxy
synchronous send failures, acp-snapshot spill-path extraction and refresh
write-back, ACP injection-triggered turns, cli-demo and tui inbox
lifecycle edges, and agent-loop retry/settlement/lifecycle branches.
The only source changes are narrowly-justified v8 ignore annotations on
invariant guards and one redundant-guard removal (workspace-context).
2026-07-26 11:49:19 +08:00
Tianyi Cui 226dc7a249 docs: translate remaining READMEs 2026-07-26 05:06:39 +08:00
Tianyi Cui d60dea9f55 feat(tools): run_code description param + native-parity dispatch logging + web code-mode seam
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).
2026-07-26 02:43:34 +08:00
Turtle 61eb2014a2 Merge remote-tracking branch 'origin/master' into codex/provider-retry-policy
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
#	packages/support/llm-replay/README.md
2026-07-26 01:40:19 +08:00
Tianyi Cui 8af3d2461b Merge branch 'master' into worktree/dsh-arg-parser 2026-07-26 00:05:16 +08:00
Yichen Jiang 478376acaf Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-17-dedicated-full-screen-tui-front-door.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
2026-07-25 22:24:25 +08:00
Turtle 2243023575 Merge branch 'master' into worktree/dsh-arg-parser
Integrate the Commander adapter with master's headless rework (dsh -p now boots
through AppCLIEntry — the same cordis.yml composition as dsh web, web-observable
while it runs — via toFetchHandler(ctx.apiProxy)).

- headless.ts: keep master's AppCLIEntry-based body but take the adapter's
  pre-parsed `task` (drop the re-added parseArgs). Old startHost path and the
  now-deleted packages/host/runtime dependency are gone.
- remove the stale packages/host/runtime dir left on disk by master's deletion
  (mirrors the earlier packages/ui/acp cleanup).
2026-07-25 17:48:21 +08:00
Turtle 5345e93ceb Merge remote-tracking branch 'origin/master' into codex/provider-retry-policy
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	packages/llm/llm-retry/README.md
#	packages/llm/llm-retry/src/index.ts
#	packages/llm/llm-retry/tests/retry.spec.ts
2026-07-25 16:05:05 +08:00
Hypatia May 7cf5b08d07 Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/core-data-structures/persistence.i18n.yaml
#	packages/session-persistence/session-persistence-jsonl/src/index.ts
2026-07-25 15:43:45 +08:00
Turtle efc725b7e4 fix(llm): isolate retry policy histories 2026-07-25 15:38:58 +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
kingwl 6abb5eebc2 Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-approval-seam.md
#	.agents/notes/implemented/feature/2026-07-06-approval-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
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/acp.snapshot.ts
2026-07-25 14:37:21 +08:00
Hypatia May ddac36e46e Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/capability-seams.md
#	examples/acp-agent/composition.md
#	examples/acp-agent/cordis.yml
#	examples/acp-agent/tests/snapshots/model-switching/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/model-switching/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/permission-switching/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/permission-switching/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/plan-mode/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/plan-mode/tool-schemas.expected.json
#	packages/examples/acp-demo/README.md
#	packages/host/runtime/README.md
#	packages/support/acp-snapshot/src/normalize.ts
#	packages/support/acp-snapshot/tests/normalize.spec.ts
#	packages/ui/acp/tests/harness.ts
#	scripts/type-equiv.manifest.json
#	tsconfig.host.json
2026-07-25 14:17:24 +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
Turtle da54a61639 Merge remote-tracking branch 'origin/master' into codex/provider-retry-policy
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	packages/examples/acp-demo/README.md
#	packages/llm/llm-deepseek/README.md
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/stream-update.spec.ts
2026-07-25 13:38:09 +08:00
Turtle 2e84a1a194 Merge remote-tracking branch 'origin/master' into codex/trim-redundant-comments
# Conflicts:
#	docs/config-catalog.md
#	examples/acp-agent/tests/acp.e2e.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/config-options.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/properties.spec.ts
2026-07-25 13:36:21 +08:00
Turtle fac6c35e9a Trim redundant source comments 2026-07-25 13:02:37 +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
kingwl 933e889fb8 Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance
# Conflicts:
#	docs/event-producer-consumer.md
2026-07-25 11:01:40 +08:00
Turtle a623ed5183 test(tui): cover unbounded retry status 2026-07-25 10:54:30 +08:00
kingwl 6fa2377e34 subagent: capture overrides at delegation; stamp ahead of prompt vetoes
Review fixes (ds-review-bot on #623):

- Capture-at-delegation: the driver now reads overrideOf(parent.session)
  for both knobs synchronously before its first await, and the prompt-submit
  listener stamps those captured values — a parent switch racing the child's
  asynchronous creation belongs to the parent's future, not the child. The
  inheritOverride(parent, child) service method is split into its two halves
  (overrideOf / stampOverride) accordingly.
- Veto safety: the one-shot prompt-submit listener registers with
  prepend: true, so a veto-capable listener (a denying UserPromptSubmit
  hook) cannot close the child's first turn without the durable stamp.

Both regressions are pinned red-first in inheritance.spec.ts: the
delegation-vs-late-switch race (delegate tool flips the caller wider while
the creation transaction is pending) and a blocking prompt-submit listener
(stamp survives a promptless first turn). Service contract tests renamed to
the split API; READMEs and the bilingual Agent Note updated.
2026-07-25 10:51:25 +08:00
Turtle a193ea7092 Merge origin/master into codex/provider-retry-policy 2026-07-25 10:35:22 +08:00
Turtle b58e33268a feat(llm): add per-provider retry policies 2026-07-25 10:18:16 +08:00
Yichen Jiang 1bfca86128 feat(tui): select model reasoning effort 2026-07-25 08:32:38 +08:00
kingwl 669771097d subagent: inherit parent sandbox/approval overrides in in-process children
Per-session policy overrides (sandbox/mode, approval/policy) never crossed
the delegation boundary: a spawn child of a read-only-switched parent ran
under the wider deployment default, and a fork child missed any switch made
after its seed boundary — delegation was a bypass channel for a user's
tightening.

The in-process driver now snapshots the delegating parent's override chain
and stamps it onto the child through the canonical write paths
(SandboxPolicyService.inheritOverride / ApprovalService.inheritOverride),
anchored inside the child's first turn via a one-shot agent/prompt-submit
listener: turn-enclosed (durable), ahead of the first request (an inherited
'never' reaches the child's first system prompt), and positioned after any
stale fork-seed switch so the ordinary last-event-wins fold resolves it.
Only overrides are copied — an unswitched parent stamps nothing and the
child follows the live deployment default; both services are consumed
opportunistically, so compositions without them delegate unchanged. Nesting
composes by construction (each stamp folds the already-stamped parent log).

Evidence: inheritance.spec.ts drives scripted-model children into the real
dsh-fs-sandbox fence through the real write tool (disk-state + denial-marker
assertions; spawn, stale-seed fork, grandchild, escalation fail-closed, and
no-stamp guards), inheritOverride contract tests in both service suites, and
the recorded subagent-sandbox-inheritance ACP snapshot (read-only preset →
delegate → child denied, replayed keylessly).

See .agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md.
2026-07-25 04:06:19 +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 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
_Kerman 992cf894af refactor(agent): unify sourced message delivery 2026-07-24 22:38:50 +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
_Kerman 009d113e0e refactor(agent): trim obsolete loop surfaces 2026-07-24 21:58:07 +08:00
_Kerman 194b18a32f Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/cordis-catalog/services.md
2026-07-24 21:41:02 +08:00
_Kerman b73eb7663c refactor(agent-loop): simplify observable state machine 2026-07-24 21:18:48 +08:00
Hypatia May cbc6d81fc3 Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/architecture.i18n.yaml
2026-07-24 20:59:18 +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 51f697db50 test(tui): wait for scoped file completion
The fake terminal retains earlier autocomplete frames, so the directory follow-up assertion could pass before the scoped lookup completed. Wait for the quoted file mention to be applied before submitting.
2026-07-24 19:38:31 +08:00
Turtle f0410d592d feat(web): permission presets and approval answering for the web UI
The web host now composes the sandboxed product path (sandbox-local +
sandbox-policy behind bash-sandbox/fs-sandbox, with user-approval and
permission on top); BootHostOptions.sandbox carries the deployment
defaults (workspace-write + ask).

createApiProxy owns the approval pending registry: a ctx.approval ask
becomes an answerable approval/requested mux frame with a stable rpcId,
replayed verbatim on every mux open until settled; respond routes by the
echoed rpcId, validates the ApprovalResponsePayload audit correlation,
and broadcasts approval/resolved; the ask's abort signal withdraws the
question as cancelled.

session.permissions / session.setPermission project ctx.permission into
a protocol-owned PermissionOption select; idle switches are held
last-write-wins and
flushed into the next prompted turn (the ACP bridge's anchoring
pattern). The shared hasOpenTurn fold moved to dsh-session,
deduplicating the private copies in user-approval, the ACP bridge, and
the proxy.

Client, per the designer draft: a pending approval takes over the
composer (ApprovalPanel replaces the InputBar — amber strip,
justification headline, paired command, one-shot refuse/allow, keyed by
rpcId so a queued second approval remounts live; the resolved frame
restores the composer); the sidebar session row shows an amber
waiting-approval dot that outranks the running ring (manager-tracked
approvalId set, idempotent under mux-open replays, cleared per
connection generation, lit for uninstantiated sessions too); the
permission selector is a composer bottom-row chip over an invisible
native select, with a presentation-only title-case transform
(workspace-write renders as Workspace Write; wire names untouched). Question placeholders stay in the message flow. The
connection fixture mirrors the host behavior for keyless browser
acceptance.
2026-07-24 19:15:04 +08:00
_Kerman fb0ef82aa6 Merge remote-tracking branch 'origin/feat/send-unify' into xtr/agent-loop-message-machine
# Conflicts:
#	packages/client/runtime/src/client/sessions/fold-adapter.ts
2026-07-24 18:24:28 +08:00
Hypatia May 96c5696f80 Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/cordis-catalog/services.md
2026-07-24 17:12:03 +08:00
_Kerman 90e69a3123 refactor(agent): minimize inbox message contract 2026-07-24 17:00:42 +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
Turtle 4be3301952 fix: migrate merged-in context/message references to user/message
The master merge introduced a tui goal-restore test and the guard parent
README that still used the removed context/message event. Point both at
the coalesced plugin-sourced user/message.
2026-07-24 16:56:36 +08:00
Turtle 80bbe959a7 Merge remote-tracking branch 'origin/master' into feat/send-unify 2026-07-24 16:52:46 +08:00
Hypatia May 6be11539e2 fix: bind session authorization to observations 2026-07-24 16:40:08 +08:00
_Kerman 6945a2c37d Merge remote-tracking branch 'origin/feat/send-unify' into xtr/agent-loop-message-machine 2026-07-24 16:31:49 +08:00
Turtle bb124c2869 Merge branch 'master' into feat/send-unify 2026-07-24 16:31:00 +08:00
Tianyi Cui a88364ab66 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol 2026-07-24 16:30:03 +08:00