# The plan-acp-agent plugin tree: the coding agent served over the Agent # Client Protocol WITH session modes composed — the plan-mode RFC's live # composition. The editor's mode picker (session/set_mode) switches the # session between `default` and `plan`; in plan mode the model works under # the plan guidance section with bash clamped to a read-only sandbox by plan # mode's `access` cap, and leaves through the user-reviewed exit_plan_mode # tool (the review rides the same elicitation flow as ask_user_question). # # CRITICAL: this tree loads NO stdout logger and NO hmr — stdout is reserved # for the ACP JSON-RPC protocol (a property of @deepseek-ai/dsh-acp-demo, # same as examples/acp-agent). # # Requires DEEPSEEK_API_KEY (and optionally DEEPSEEK_BASE_URL) — the # dsh-acp-demo bin loads the gitignored repo-root .env first (on STDERR only). # The DeepSeek adapter. - id: llm-deepseek name: '@deepseek-ai/dsh-llm-deepseek' config: apiKey: !!js process.env.DEEPSEEK_API_KEY baseURL: !!js process.env.DEEPSEEK_BASE_URL models: - deepseek-v4-flash # The ACP server app: the agent-core spine + JSONL persistence + the ACP # bridge (which advertises the mode picker and answers the plan review). - id: acp-agent name: '@deepseek-ai/dsh-acp-demo' config: model: deepseek-v4-flash # Keep this example's prompt fixed to its explicit persona; workspace # instructions are demonstrated by a separate composition. workspaceContext: false # Persistence root: $DSH_SNAPSHOT_SESSIONS_ROOT when the snapshot harness # sets it (so a record run's logs land where the harness harvests them), # else the local ./.sessions default. persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions' persona: | You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug. Verify your work by running the code or tests. Keep answers brief and factual. # Session modes (ctx.modes — the shipped `plan` definition, no overrides): # the mode/set vocabulary, the mode section, the exit_plan_mode tool, and # plan's read-only `access` cap on the sandbox stack below. The ACP bridge # above reads it opportunistically and advertises the picker. - id: mode name: '@deepseek-ai/dsh-mode' # The sandbox stack: the platform-runner provider (bwrap → per-platform # Landlock launcher → Seatbelt, functionally probed), then the confined bash # executor. workspace-write is the day-to-day default; plan mode's `access` # cap clamps every call to read-only while it is in force — which is exactly # what keeps the bash tools AVAILABLE in plan mode: exploration commands run, # a write is denied by the sandbox. The cap and the session's own # sandbox-mode knob compose at read time (neither writes the other), so a # knob switched during plan re-emerges intact on exit. NOTE: the workspace # root is CONFIG-FIXED for the executor's lifetime (the launch dir here), # while each ACP session has its own cwd — a per-session root is config-phase # future work in the sandbox RFC. - id: sandbox name: '@deepseek-ai/dsh-sandbox-local' - id: bash name: '@deepseek-ai/dsh-bash-sandbox' config: mode: workspace-write workspaceRoot: !!js process.cwd() # The approval seam (ctx.approval — mechanism only, no config): the confined # executor makes tool-bash advertise the escalation fields, and this seam is # what lets an escalating retry actually reach the editor as a # session/request_permission prompt. In plan mode the `access` cap denies # escalation outright — the widened step belongs in the plan. - id: approval name: '@deepseek-ai/dsh-user-approval' # The model-facing ask_user_question tool: the plan section tells the model # to raise a blocking decision to the user while planning; the review and # the questions ride the same elicitation flow. - id: tool-ask-user name: '@deepseek-ai/dsh-tool-ask-user' # Filesystem capability stack: local provider, read-before-write/edit policy # gate, then the model-facing read/write/edit tools. Plan mode restrains # these by guidance only (the section says changes belong in the plan) — the # enforced boundary in plan is the bash sandbox clamp above. - id: fs-local name: '@deepseek-ai/dsh-fs-local' config: cwd: !!js process.cwd() - id: fs-policy name: '@deepseek-ai/dsh-fs-policy' - id: tool-fs name: '@deepseek-ai/dsh-tool-fs' # The model-facing todo_write tool — the model tracks its plan while # exploring. - id: tool-todo name: '@deepseek-ai/dsh-tool-todo'