Commit Graph

7248 Commits

Author SHA1 Message Date
Hypatia May
08e4f1b17c Merge remote-tracking branch 'origin/master' into fix/subagent-empty-terminal-message-output 2026-08-10 17:11:30 +08:00
Hypatia May
0a4bdd8ee8 docs(subagent): note the settlement-fold optimization condition 2026-08-10 17:06:07 +08:00
Yichen Jiang
8ae1a9d6a8 Merge remote-tracking branch 'origin/master' into fix/preset-host-plane-task-registry 2026-08-10 16:53:03 +08:00
Yichen Jiang
be7bf24169 Merge remote-tracking branch 'origin/master' into fix/preset-host-plane-task-registry 2026-08-10 16:45:13 +08:00
Yichen Jiang
cf5fbd02b8 fix(tasks-local): return the layer disposer directly and cover scoped teardown
`ScopedLayers.effect` already returns an exact `() => void`, so the inherited
`() => void dispose()` wrapper voided a void — two lint rules, four errors.

The scoped layer's own teardown had no test, which is the registry-contribution
disposal contract the testing policy requires and the only path that calls
`TaskLayer.isEmpty()`: `ScopedLayers` prunes a scope's layer when its last
contribution disposes. The new case mounts one plugin contributing both a
surface and a listener into one scope, then unloads it and observes that the
agents which joined that scope are refused again.

Refs #2141
2026-08-10 16:34:29 +08:00
Turtle
a27efdef36 docs: make technical prose concrete 2026-08-10 16:34:20 +08:00
Hypatia May
ccbaedc8a8 test(scaffold-server): expect absent lastAssistantMessage for a childless result
The subagent/end edge now encodes 'no output' as an absent field, never
an empty array; the wire projection forwards only present fields.
2026-08-10 16:29:55 +08:00
Turtle
8dc91d2c00 fix(feedback): report shared anonymous user id 2026-08-10 16:23:05 +08:00
Yichen Jiang
109059429a Merge remote-tracking branch 'origin/master' into fix/preset-host-plane-task-registry 2026-08-10 16:17:44 +08:00
Turtle
ef35c7f3b2 fix(feedback): include session id in acknowledgement 2026-08-10 16:15:29 +08:00
Yichen Jiang
d2b74744fb Merge remote-tracking branch 'origin/fix/preset-host-plane-task-registry' into fix/preset-host-plane-task-registry 2026-08-10 16:13:21 +08:00
Hypatia May
b2b0f663d5 Merge remote-tracking branch 'origin/master' into fix/subagent-empty-terminal-message-output 2026-08-10 16:13:00 +08:00
Yichen Jiang
59e759ce13 fix(tasks-local): layer control surfaces and listeners by registering scope
One host registry serves every composition in the process, so its two
service-wide collections answered per-owner questions process-wide. `start()`
asked only whether SOME surface was attached, so an agent whose own composition
loads no `tool-tasks` could start work it has no tool to collect or stop as soon
as any other preset attached one — and the answer changed depending on which
sessions happened to be open. `settle()` walked every registered listener, so a
task settling without a waiter injected one completion notice per mounted
preset into the same owner.

Both collections now sit in `ScopedLayers`, the layered-registry primitive
`tools` and `skills` already use: a registration files into its registering
context's scope, and a read unions the global layer with the owner's scope
chain. A surface or listener registered from an unscoped context lands in the
global layer and serves every owner, which is exactly the host-plane
composition's own controls, so the TUI path is unchanged without a special
case.

This supersedes the consumer-side filter in the previous commit. That filter
produced the right notices but sat in the wrong layer: it left the `start()`
gate process-wide, it could not be enforced against a producer that resolves
the registry directly, and it made a Consumer carry scope knowledge that the
other layered registries keep in the registry. `tool-tasks` is scope-agnostic
again and the `dsh-scope` edge moves to `tasks-local`.

`start()`'s refusal is now owner-relative, so its model-visible text names the
agent rather than the process. The shipped `minimal` preset keeps
`enableRunInBackground: false`, no longer as the safety boundary — the registry
owns that now — but so an agent that could never collect a task is not offered
the parameter at all.

Refs #2141
2026-08-10 16:12:41 +08:00
Hypatia May
ea47c32805 review: one fold implementation, uniform end-edge absence, partial text in tool errors, snapshot scenario
Address ds-review-bot on #2127:

- assistant-output: the rule has ONE implementation, the incremental
  AssistantOutputFold (push/pushText/collect); finalAssistantOutput folds a
  complete suffix, the SDK backend folds notification events, and the ACP
  backend folds raw chunk text into the same streamed fallback.
- subagent/end.lastAssistantMessage: 'no output' is encoded once — absent,
  never [], on both lifecycle shapes (observeRun now omits empty output).
- tool-subagent: a non-completed foreground result stays isError but appends
  the child's preserved partial text after the stop-reason headline.
- Authored keyless snapshot scenario subagent-max-tokens-partial pins the
  assembled transcript: the child's committed log carries the usage-only
  empty message and the parent's tool result carries the partial answer.
- Rule-boundary sentence (message wins over later streamed text) and the
  consumer half recorded in the Agent Note; comments trimmed to pointers.
2026-08-10 16:09:04 +08:00
CreatixChu
a44009ec35 Merge pull request #1864 from deepseek-harness/worktree/drop-create-by-name
refactor: drop the create-by-name workspace route
2026-08-10 16:01:17 +08:00
creatixchu
34c5da26b8 test: align apiproxy model harness with path-only workspaces 2026-08-10 15:53:15 +08:00
creatixchu
069f97497a Merge remote-tracking branch 'origin/master' into worktree/remove-interjection-caption
# Conflicts:
#	packages/client/ui-conversation/src/client/chat/MessageItem.module.css
#	packages/client/ui-conversation/src/client/chat/MessageItem.tsx
2026-08-10 15:50:39 +08:00
creatixchu
73527c47bd Merge remote-tracking branch 'origin/master' into worktree/drop-create-by-name 2026-08-10 15:49:49 +08:00
creatixchu
a832fc2fa5 Merge remote-tracking branch 'origin/master' into worktree/drop-create-by-name
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-25-session-list-browsing-and-manual-order.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-25-workspace-ui-product-flow.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-25-workspace-ui-product-flow.zh.md
#	.agents/notes/implemented/simplification/2026-07-31-one-route-to-add-a-workspace.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-31-one-route-to-add-a-workspace.md
#	.agents/notes/implemented/simplification/2026-07-31-one-route-to-add-a-workspace.zh.md
#	apps/cli/reference/README.i18n.yaml
#	docs/config-catalog.md
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/README.zh.md
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/src/index.ts
#	packages/host/apiproxy/tests/api-proxy-approval.spec.ts
#	packages/host/apiproxy/tests/api-proxy-blank.spec.ts
#	packages/host/apiproxy/tests/api-proxy-cold.spec.ts
#	packages/host/apiproxy/tests/api-proxy-commands.spec.ts
#	packages/host/apiproxy/tests/api-proxy-config.spec.ts
#	packages/host/apiproxy/tests/api-proxy-models.spec.ts
#	packages/host/apiproxy/tests/api-proxy-projections.spec.ts
#	packages/host/apiproxy/tests/api-proxy-question.spec.ts
#	packages/host/apiproxy/tests/api-proxy-rename.spec.ts
#	packages/host/apiproxy/tests/api-proxy-search.spec.ts
#	packages/host/apiproxy/tests/api-proxy-subagents.spec.ts
#	packages/host/apiproxy/tests/api-proxy-view.spec.ts
#	packages/host/apiproxy/tests/api-proxy-workspace.spec.ts
#	packages/todo/tool-todo/tests/projection.spec.ts
#	scripts/hero-composer-dom-continuity.mjs
2026-08-10 15:49:34 +08:00
Hypatia May
2418f44781 Merge remote-tracking branch 'origin/master' into fix/subagent-empty-terminal-message-output
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
2026-08-10 15:43:16 +08:00
Yichen Jiang
e01be02dab Merge branch 'master' into fix/preset-host-plane-task-registry 2026-08-10 15:31:20 +08:00
creatixchu
1a02b82884 Merge remote-tracking branch 'origin/master' into worktree/remove-interjection-caption 2026-08-10 15:30:10 +08:00
Yichen Jiang
37ebe87087 fix(tool-tasks): claim completion notices only for the mount's own scope
Moving the task registry to the host plane put every preset's `tool-tasks`
listener on ONE `LocalTaskService`. `settle()` computes a single snapshot and
walks every registered listener with no scope filter, and it marks `reported`
only when a waiter is present — so a task settling without a waiter reached
each mount's listener with `reported` false and every one of them injected the
same completion into the same owner. Three shipped presets carry `tool-tasks`,
and a preset file edit adds a second generation of the same mount, so an agent
read N copies of one notice as model-visible durable context.

A mount now claims an owner only when the owner's scope chain reaches the
mount's own scope. An unscoped mount is the host-plane instance that serves
every agent, which keeps the TUI composition and every existing test intact.

Registry-side ownership was the alternative: mark `reported` once the first
listener claims it. It is wrong because `onTaskDone` is not a notice-only
seam — the `dsh-tasks` invariant companion registers a validating listener —
so first-claim-wins would silence observers that are not delivering anything.

The regression test mounts two scoped `tool-tasks` over one registry and
settles an unowned-wait task, which is the only path that reaches the notice
listeners at all: the shipped-composition e2e uses `wait: true`, and a waiter
marks `reported` before settlement, so that test structurally cannot cover it.

Also corrects the standing-mounts Agent Note, which still listed `tasks-local`
among the stateful PRESET plugins.

Refs #2141
2026-08-10 15:27:10 +08:00
creatixchu
76c6e14c8b Merge remote-tracking branch 'origin/master' into codex/pr-555-ci-fix 2026-08-10 15:26:23 +08:00
creatixchu
2fea703d67 Merge remote-tracking branch 'origin/master' into codex/pr-555-ci-fix
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/client/ui-conversation/src/client/input/hub.ts
#	packages/client/ui-conversation/tests/input-bar.spec.tsx
#	packages/client/ui-conversation/tests/service-orchestration.spec.ts
2026-08-10 15:19:32 +08:00
Yichen Jiang
0be9bf312a fix(web): fold the preset frame into the session row for every client
The frame carried `agentPreset` for surfaces that label the session, but
nothing consumed it: `noteAgentPreset` ran only in the switching tab's RPC
callback, so a second connected client refetched its catalogs while its
session row — the header label's source, and the hero chip's no-op input —
kept the composition the session had replaced.

`SessionManager.handleHostEnvelope` now folds the frame like the other
session frames. Re-applying the switching tab's own frame is a no-op: the
merge lowers `blank` only and keeps the row's `updatedAt`.
2026-08-10 15:12:07 +08:00
Yichen Jiang
ec8cbd7513 Merge remote-tracking branch 'origin/master' into fix/web-slash-catalog-follows-preset 2026-08-10 15:07:15 +08:00
Yichen Jiang
02d45ed004 Merge remote-tracking branch 'origin/master' into fix/preset-host-plane-task-registry 2026-08-10 15:04:49 +08:00
Yichen Jiang
801c41fddc Merge branch 'master' into worktree/fix-windows-preset-ci 2026-08-10 14:52:19 +08:00
Yichen Jiang
f895ee22d0 Merge remote-tracking branch 'origin/master' into fix/web-slash-catalog-follows-preset
# Conflicts:
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/README.zh.md
2026-08-10 14:38:17 +08:00
Yichen Jiang
259d998455 fix(web): follow a blank session's preset switch in the slash catalog
Presets own the rows that decide what a session's `/` menu contains, but
both browser catalogs cache per session and had no invalidation edge for a
recompose: `commands/changed` is registry-wide and recomposing registers
nothing, so the menu kept serving the composition the session no longer ran.

The host stream now frames the logged `agent-preset/selected` commit as
`host/session-preset-changed`; the runtime bridges it to the typed
`session/preset-changed` event, `ui-command` soft-refreshes that session's
directory key and `ui-skill` invalidates its catalog entry.

Reaching the host on a second switch was a separate defect: the list-row
identity guard compared every summary field except `agentPreset`, and the
merge keeps the row's `updatedAt`, so a switched row looked unchanged and
served its cached instance forever. The hero chip compares the pick against
that row, so switching back to the creation-time preset sent no RPC at all.
2026-08-10 14:35:13 +08:00
Yichen Jiang
52fafa012e test(agent-presets): stabilize generation race coverage 2026-08-10 14:30:02 +08:00
Yichen Jiang
75100ad2e5 fix(agent-presets): repair Windows preset CI 2026-08-10 14:22:55 +08:00
Yichen Jiang
5d86a284e5 fix(web-app,agent-presets): keep the task registry on the host plane
`tool-bash` resolves the background-task registry with `ctx.get('tasks')`,
and it sits at the preset's top level. The registry sat inside an
entry-local `isolate: { tasks: true }` realm, which is invisible to every
sibling row outside it, while the Web surface disabled the host row — so
both lookups missed and every `run_in_background` call answered
"background tasks unavailable" with `task_output`, `task_list`, and
`task_kill` still listed in the catalog. `task_list` returning
"(no background tasks)" is what made the outage read as an empty queue
rather than a severed producer.

That is the `goals` criterion read from inside the preset: a Service a row
outside its realm READS belongs to the plane both can see. `tasks` already
keys access by owning agent (`assertAccess` compares `task.owner.id`) and
mints an independent token per `attachSurface` call, so one host instance
serves every session exactly as before presets — the per-preset-standing-mounts
note records that sharing `tasks-local` is a return to its design.

`minimal` mounts no `tool-tasks`, and the `start()` control-surface gate is
a service-wide set that another preset's controls would open for it, so its
`tool-bash` disables `run_in_background` and drops the parameter from the
schema.

Fixes #2141
2026-08-10 14:18:41 +08:00
Turtle
a7fc81d745 docs: replace front door terminology 2026-08-10 13:07:46 +08:00
creatixchu
8f0855cc9f Merge remote-tracking branch 'origin/master' into worktree/remove-interjection-caption 2026-08-10 13:05:00 +08:00
imccyu
6648ff984a Merge pull request #1817 from deepseek-harness/feat/web-queue-steer-all
feat(web): 空输入时 Ctrl/Cmd+Enter 将当前排队消息全部插话发送
2026-08-10 12:58:20 +08:00
creatixchu
c6148f0fc3 Merge remote-tracking branch 'origin/master' into worktree/remove-interjection-caption 2026-08-10 12:53:04 +08:00
Huanqi Cao
c9285753de Merge branch 'merge/1829-master' into merge/1990-1829
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
2026-08-10 12:35:32 +08:00
creatixchu
3764ce62a5 Merge remote-tracking branch 'origin/master' into codex/pr-555-ci-fix
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/client/connection/src/client/fixture.ts
#	packages/host/apiproxy/src/api-proxy.ts
2026-08-10 12:33:36 +08:00
Huanqi Cao
2a6aba0f48 Merge remote-tracking branch 'origin/master' into merge/1829-master
# Conflicts:
#	apps/cli/package.json
#	pnpm-lock.yaml
2026-08-10 12:32:14 +08:00
Huanqi Cao
ad54135d43 fix(sandbox-local): block-body the default rmTempDir fallback
The arrow shorthand implicitly returns rmSync's void, which the
no-confusing-void-expression rule forbids; the block body keeps the
fallback without the violation.
2026-08-10 12:30:39 +08:00
creatixchu
12c971d4b9 test(attachment): exclude POSIX fsync on Windows 2026-08-10 12:06:01 +08:00
Yichen Jiang
b87e2240bf Merge pull request #1543 from deepseek-harness/stack/agent-profiles-8-authoring
feat(web): author agent presets from a settings page
2026-08-10 11:55:58 +08:00
creatixchu
fb37107ca4 test(attachment): skip POSIX modes on Windows 2026-08-10 11:48:49 +08:00
Yichen Jiang
803f1fe876 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-8-authoring 2026-08-10 11:42:16 +08:00
Yichen Jiang
0d9b97bf7b docs(core): regenerate the cordis catalog for the recompose binding contract
The re-link now runs through the mount-time binding, and the method's
JSDoc says so; the generated core surface and the runtime API catalog
follow it.
2026-08-10 11:42:06 +08:00
creatixchu
52df428a10 Merge remote-tracking branch 'origin/master' into codex/pr-555-ci-fix 2026-08-10 11:28:25 +08:00
creatixchu
a3cf2617a8 docs(notes): fix review findings — translate zh note headings, point supersession at the Decision, pin caption absence 2026-08-10 11:26:37 +08:00
Yichen Jiang
2be0e6c522 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-8-authoring
# Conflicts:
#	packages/preset/agent-presets/src/index.ts
#	packages/preset/agent-presets/tests/mount.spec.ts
2026-08-10 11:25:14 +08:00