Lifts the RFC 010 § Deferred restriction that the server had to launch in the
workspace ("cwd must equal the launch directory"). An editor can now open any
project folder, and N concurrent sessions over one connection can each target a
different directory.
- packages/acp: drop the `cwd === process.cwd()` guard in validateWorkspaceParams
(keep "must be absolute" — the cwd becomes the session header / bash workdir),
and drop the persisted-cwd-vs-launch-dir check in session/load (a resumed
session keeps its original header.cwd, so its bash tools run in its workspace).
- packages/tool-bash: the missing link — default the bash workdir to the calling
agent's session cwd (`exec.agent.session.header.cwd`) via a new resolveWorkdir
helper. An explicit model `workdir` still wins; a relative one resolves against
the session cwd. This is the only correct spot for multi-session: N sessions
share one ctx.bash executor, so the workdir must come per-call from exec.agent,
not executor config. Falls back to the executor default when no session cwd is
available (preserves non-ACP behavior).
- Trust: the cwd originates from the ACP client (the user's editor) at
session/new — same trust level as the old launch dir; no new untrusted-input
path. `additionalDirectories` (scope widening / sandbox) stays rejected.
- Tests: bridge accepts any absolute cwd + records it on the header; session/load
honors the persisted cwd; bash defaults to / resolves relative against the
session cwd; two sessions with different cwds each run bash in their own dir;
non-absolute cwd still rejected. 100% per-file coverage maintained.
- Docs: RFC 010 status + § Deferred cwd bullet marked RESOLVED; acp README adds a
Per-session cwd section; tool-bash + example READMEs and e2e comments updated.
1.6 KiB
acp-agent example
The DeepSeek Harness coding agent exposed as an Agent Client Protocol (ACP) server over JSON-RPC stdio — drive it from Zed or any other ACP client.
pnpm run demo:acp # needs DEEPSEEK_API_KEY (repo-root .env or env)
This boots @deepseek-ai/dsh-acp over the shared provider/tool core (../base.yml), with agent-loop configured with no pre-created agents (ACP session/new creates them on demand) and JSONL session persistence (so session/load works).
stdout is the protocol
This example loads no stdout logger — stdout carries the JSON-RPC frames, and any other write corrupts them. Do not add @cordisjs/plugin-logger-console or a stdio UI here. Use a stderr exporter if you need logs.
Zed configuration
Add to your Zed settings.json under agent_servers:
{
"agent_servers": {
"DeepSeek Harness": {
"command": "pnpm",
"args": ["run", "demo:acp"],
"env": { "DEEPSEEK_API_KEY": "sk-…" }
}
}
}
The editor sets each session's cwd to the project it opens; the agent's bash tools run there (see the per-session cwd note in packages/acp), so the server does not need to be launched in the workspace.
MVP limitations
The bridge supports N concurrent sessions per connection, each in its own workspace cwd (RFC 011). Remaining limits: text-only prompts, additionalDirectories rejected (a session operates in its single cwd), and the tool-permission gate is deferred (TODO(rfc010-permission-gate) — tools run with the executor's full authority). See packages/acp/README.md for the full contract.