2026-07-05 01:25:58 +08:00
<!-- Generated by scripts/gen - doc - graphs.ts - do not edit by hand.
Run `pnpm run gen-doc-graphs` to regenerate. -->
2026-07-24 01:40:25 +08:00
# ACP Automation App Composition
2026-07-05 01:25:58 +08:00
2026-07-24 22:36:06 +08:00
The ACP demo exposes fresh baseline-prompt agent sessions to programmatic clients over JSON-RPC stdio, with no stdout logger, human UI, or pre-created agent.
2026-07-05 01:25:58 +08:00
```mermaid
flowchart LR
cfg["examples/acp-agent< br / > cordis.yml"]
plugin_acp_llm_deepseek["llm-deepseek< br /> @deepseek -ai/dsh-llm-deepseek"]
cfg --> plugin_acp_llm_deepseek
2026-07-14 01:09:44 +08:00
plugin_acp_sandbox["sandbox< br /> @deepseek -ai/dsh-sandbox-local"]
cfg --> plugin_acp_sandbox
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
plugin_acp_sandbox_policy["sandbox-policy< br /> @deepseek -ai/dsh-sandbox-policy"]
cfg --> plugin_acp_sandbox_policy
refactor(subprocess): rename the process seam to subprocess and address review
Review feedback (tianyicui): 'process' is a poor service name. The family is
now packages/subprocess/ — @deepseek-ai/dsh-subprocess (ctx.subprocess,
abstract SubprocessService, Subprocess* vocabulary) and
@deepseek-ai/dsh-subprocess-local (LocalSubprocessService) — renamed
throughout code, compositions, docs (en+zh, pairs re-recorded), catalogs,
and gates. 'subprocess' is the precise term for managed OS children (the
Python-stdlib sense), avoids colliding with Node's global process object,
and reads as one system beside dsh-subagent-subprocess.
ds-review-bot findings addressed:
- kill() on a settled handle is now a no-op (no signal to a possibly-reused
pgid, no referenced grace timer delaying exit); pinned by a spy test.
- The moved DshEnvironmentKey/DshEnvironment/CollectedOutput types get
drift-checked type-equiv blocks on the new subprocess.md page, restoring
their manifest registration.
- subprocess.md is registered in the core.md sub-page index (en+zh).
2026-07-26 12:43:14 +08:00
plugin_acp_subprocess["subprocess< br /> @deepseek -ai/dsh-subprocess-local"]
cfg --> plugin_acp_subprocess
2026-07-14 01:09:44 +08:00
plugin_acp_bash["bash< br /> @deepseek -ai/dsh-bash-sandbox"]
2026-07-05 01:25:58 +08:00
cfg --> plugin_acp_bash
2026-07-14 01:09:44 +08:00
plugin_acp_approval["approval< br /> @deepseek -ai/dsh-user-approval"]
cfg --> plugin_acp_approval
2026-07-15 15:57:57 +08:00
plugin_acp_acp_agent["acp-agent< br /> @deepseek -ai/dsh-acp-demo"]
2026-07-05 01:25:58 +08:00
cfg --> plugin_acp_acp_agent
2026-07-15 15:57:57 +08:00
plugin_acp_acp_agent --> bundle_agent_core["@deepseek -ai/dsh-agent-spine-demo"]
2026-07-05 01:25:58 +08:00
plugin_acp_acp_agent --> bundle_jsonl["@deepseek -ai/dsh-session-persistence-jsonl"]
2026-07-24 01:40:25 +08:00
plugin_acp_acp_agent --> frontdoor_acp["@deepseek -ai/dsh-acp< br /> automation-only JSON-RPC stdio< br /> fresh sessions created by client"]
2026-07-05 01:25:58 +08:00
bundle_agent_core --> spine_llm["ctx.llm"]
bundle_agent_core --> spine_sessions["ctx.sessions"]
bundle_agent_core --> spine_tools["ctx.tools + tool-bash"]
bundle_agent_core --> spine_loop["ctx.agents + ctx.agentLoop"]
2026-07-20 11:47:17 +08:00
plugin_acp_token_meter["token-meter< br /> @deepseek -ai/dsh-token-meter"]
cfg --> plugin_acp_token_meter
2026-07-15 16:42:32 +08:00
plugin_acp_compact_basic["compact-basic< br /> @deepseek -ai/dsh-compact-basic"]
cfg --> plugin_acp_compact_basic
2026-07-05 01:25:58 +08:00
plugin_acp_subagent["subagent< br /> @deepseek -ai/dsh-subagent"]
cfg --> plugin_acp_subagent
plugin_acp_subagent_spawn["subagent-spawn< br /> @deepseek -ai/dsh-subagent-spawn"]
cfg --> plugin_acp_subagent_spawn
plugin_acp_subagent_fork["subagent-fork< br /> @deepseek -ai/dsh-subagent-fork"]
cfg --> plugin_acp_subagent_fork
feat(subagent): continuable background subagents
Implement the continuable background subagents RFC: a durable child
session with a series of Task-backed activations, each disposing its
run before the Task settles.
- dsh-subagent: rename SubagentRun.sendMessage to strict steer, drop
run-level resume, add SubagentProvider.resume dispatch via
SubagentService.resume, the continuation start field, and the
versioned model-hidden subagent/descriptor session event.
- dsh-subagent-inprocess/-spawn/-fork: publish the control-allocated
child id, append the descriptor inside the initial turn, implement
cold resume from the child's own transcript under the live parent
scope, and strict running-only steer.
- dsh-subagent-control (new): SubagentControlService owning stable
child ids, descriptor snapshot/fold/authorization, Task-backed
activation with settle-then-dispose ordering, the process-local
active-run association, and steer-or-resume sendMessage routing.
- dsh-tool-subagent: background route branches on the provider's
resume capability (continuable via the control service; one-shot
task for ACP), returning both child and task ids.
- dsh-tool-subagent-control (new): the globally named send_message
tool rendering steered/started routes.
Keyless coverage spans Task ownership and disposal ordering, running
delivery, cold follow-up, descriptor rejection and rollback, known-id
reconstruction, kill during lookup, admission races, and a new
subagent-continuable ACP snapshot scenario.
2026-07-23 17:07:38 +08:00
plugin_acp_tool_subagent_control["tool-subagent-control< br /> @deepseek -ai/dsh-tool-subagent-control"]
cfg --> plugin_acp_tool_subagent_control
2026-07-26 02:32:34 +08:00
plugin_acp_tool_subagent_list_agents["tool-subagent-list-agents< br /> @deepseek -ai/dsh-tool-subagent-control/list-agents"]
cfg --> plugin_acp_tool_subagent_list_agents
2026-07-31 22:45:21 +08:00
plugin_acp_tool_subagent_report["tool-subagent-report< br /> @deepseek -ai/dsh-tool-subagent-report"]
cfg --> plugin_acp_tool_subagent_report
2026-07-05 01:25:58 +08:00
plugin_acp_tool_subagent["tool-subagent< br /> @deepseek -ai/dsh-tool-subagent"]
cfg --> plugin_acp_tool_subagent
plugin_acp_tool_subagent_fork["tool-subagent-fork< br /> @deepseek -ai/dsh-tool-subagent"]
cfg --> plugin_acp_tool_subagent_fork
2026-07-09 19:06:55 +08:00
plugin_acp_workflow_workerthread["workflow-workerthread< br /> @deepseek -ai/dsh-workflow-workerthread"]
cfg --> plugin_acp_workflow_workerthread
2026-07-06 03:14:07 +08:00
plugin_acp_tool_workflow["tool-workflow< br /> @deepseek -ai/dsh-tool-workflow"]
cfg --> plugin_acp_tool_workflow
2026-07-20 00:51:19 +08:00
plugin_acp_tool_ralph["tool-ralph< br /> @deepseek -ai/dsh-tool-ralph"]
cfg --> plugin_acp_tool_ralph
2026-07-05 01:25:58 +08:00
plugin_acp_tool_todo["tool-todo< br /> @deepseek -ai/dsh-tool-todo"]
cfg --> plugin_acp_tool_todo
2026-07-08 14:24:20 +08:00
plugin_acp_repeat_tool_guard["repeat-tool-guard< br /> @deepseek -ai/dsh-repeat-tool-guard"]
cfg --> plugin_acp_repeat_tool_guard
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
plugin_acp_fs_sandbox["fs-sandbox< br /> @deepseek -ai/dsh-fs-sandbox"]
cfg --> plugin_acp_fs_sandbox
2026-07-05 01:25:58 +08:00
plugin_acp_fs_policy["fs-policy< br /> @deepseek -ai/dsh-fs-policy"]
cfg --> plugin_acp_fs_policy
plugin_acp_tool_fs["tool-fs< br /> @deepseek -ai/dsh-tool-fs"]
cfg --> plugin_acp_tool_fs
plugin_acp_hooks_claude["hooks-claude< br /> @deepseek -ai/dsh-hooks-claude"]
cfg --> plugin_acp_hooks_claude
plugin_acp_hooks_codex["hooks-codex< br /> @deepseek -ai/dsh-hooks-codex"]
cfg --> plugin_acp_hooks_codex
```
| Plugin id | Package / module |
| --- | --- |
| `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` |
2026-07-14 01:09:44 +08:00
| `sandbox` | `@deepseek-ai/dsh-sandbox-local` |
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
| `sandbox-policy` | `@deepseek-ai/dsh-sandbox-policy` |
refactor(subprocess): rename the process seam to subprocess and address review
Review feedback (tianyicui): 'process' is a poor service name. The family is
now packages/subprocess/ — @deepseek-ai/dsh-subprocess (ctx.subprocess,
abstract SubprocessService, Subprocess* vocabulary) and
@deepseek-ai/dsh-subprocess-local (LocalSubprocessService) — renamed
throughout code, compositions, docs (en+zh, pairs re-recorded), catalogs,
and gates. 'subprocess' is the precise term for managed OS children (the
Python-stdlib sense), avoids colliding with Node's global process object,
and reads as one system beside dsh-subagent-subprocess.
ds-review-bot findings addressed:
- kill() on a settled handle is now a no-op (no signal to a possibly-reused
pgid, no referenced grace timer delaying exit); pinned by a spy test.
- The moved DshEnvironmentKey/DshEnvironment/CollectedOutput types get
drift-checked type-equiv blocks on the new subprocess.md page, restoring
their manifest registration.
- subprocess.md is registered in the core.md sub-page index (en+zh).
2026-07-26 12:43:14 +08:00
| `subprocess` | `@deepseek-ai/dsh-subprocess-local` |
2026-07-14 01:09:44 +08:00
| `bash` | `@deepseek-ai/dsh-bash-sandbox` |
| `approval` | `@deepseek-ai/dsh-user-approval` |
2026-07-15 15:57:57 +08:00
| `acp-agent` | `@deepseek-ai/dsh-acp-demo` |
2026-07-20 11:47:17 +08:00
| `token-meter` | `@deepseek-ai/dsh-token-meter` |
2026-07-15 16:42:32 +08:00
| `compact-basic` | `@deepseek-ai/dsh-compact-basic` |
2026-07-05 01:25:58 +08:00
| `subagent` | `@deepseek-ai/dsh-subagent` |
| `subagent-spawn` | `@deepseek-ai/dsh-subagent-spawn` |
| `subagent-fork` | `@deepseek-ai/dsh-subagent-fork` |
feat(subagent): continuable background subagents
Implement the continuable background subagents RFC: a durable child
session with a series of Task-backed activations, each disposing its
run before the Task settles.
- dsh-subagent: rename SubagentRun.sendMessage to strict steer, drop
run-level resume, add SubagentProvider.resume dispatch via
SubagentService.resume, the continuation start field, and the
versioned model-hidden subagent/descriptor session event.
- dsh-subagent-inprocess/-spawn/-fork: publish the control-allocated
child id, append the descriptor inside the initial turn, implement
cold resume from the child's own transcript under the live parent
scope, and strict running-only steer.
- dsh-subagent-control (new): SubagentControlService owning stable
child ids, descriptor snapshot/fold/authorization, Task-backed
activation with settle-then-dispose ordering, the process-local
active-run association, and steer-or-resume sendMessage routing.
- dsh-tool-subagent: background route branches on the provider's
resume capability (continuable via the control service; one-shot
task for ACP), returning both child and task ids.
- dsh-tool-subagent-control (new): the globally named send_message
tool rendering steered/started routes.
Keyless coverage spans Task ownership and disposal ordering, running
delivery, cold follow-up, descriptor rejection and rollback, known-id
reconstruction, kill during lookup, admission races, and a new
subagent-continuable ACP snapshot scenario.
2026-07-23 17:07:38 +08:00
| `tool-subagent-control` | `@deepseek-ai/dsh-tool-subagent-control` |
2026-07-26 02:32:34 +08:00
| `tool-subagent-list-agents` | `@deepseek-ai/dsh-tool-subagent-control/list-agents` |
2026-07-31 22:45:21 +08:00
| `tool-subagent-report` | `@deepseek-ai/dsh-tool-subagent-report` |
2026-07-05 01:25:58 +08:00
| `tool-subagent` | `@deepseek-ai/dsh-tool-subagent` |
| `tool-subagent-fork` | `@deepseek-ai/dsh-tool-subagent` |
2026-07-09 19:06:55 +08:00
| `workflow-workerthread` | `@deepseek-ai/dsh-workflow-workerthread` |
2026-07-06 03:14:07 +08:00
| `tool-workflow` | `@deepseek-ai/dsh-tool-workflow` |
2026-07-20 00:51:19 +08:00
| `tool-ralph` | `@deepseek-ai/dsh-tool-ralph` |
2026-07-05 01:25:58 +08:00
| `tool-todo` | `@deepseek-ai/dsh-tool-todo` |
2026-07-08 14:24:20 +08:00
| `repeat-tool-guard` | `@deepseek-ai/dsh-repeat-tool-guard` |
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
| `fs-sandbox` | `@deepseek-ai/dsh-fs-sandbox` |
2026-07-05 01:25:58 +08:00
| `fs-policy` | `@deepseek-ai/dsh-fs-policy` |
| `tool-fs` | `@deepseek-ai/dsh-tool-fs` |
| `hooks-claude` | `@deepseek-ai/dsh-hooks-claude` |
| `hooks-codex` | `@deepseek-ai/dsh-hooks-codex` |
2026-07-05 02:54:01 +08:00
Source config: [`examples/acp-agent/cordis.yml` ](cordis.yml ).
Maintenance mode: hybrid: the leaf plugin list is parsed from its `cordis.yml` ; app package expansion is curated from package source.