Files
deepseek-harness/examples/acp-agent
Tianyi Cui 6d37b6c33d fix(acp): server crashed on connect — drop export default, read optional service cwd-independently
Two independent bugs made the ACP server crash the moment an editor (Zed)
connected, despite 178 green unit tests at 100% coverage:

1. `session/new` threw `cannot get property "agents" without inject`. Root
   cause: a stray `export default apply` made the cordis Loader's
   `unwrapExports` (`exports.default ?? exports`) collapse the module to the
   bare `apply` function, discarding the sibling `inject`/`name`/`Config`
   named exports. The plugin fiber was built with empty `inject`, so every
   `ctx.<service>` read in `apply` threw at load. Fix: remove the default
   export so the Loader uses the namespace.

2. `session/load` threw `cannot get property "sessionPersistence" without
   inject`. `AgentLoop.resume` read `this.ctx.sessionPersistence` (a service
   it deliberately does NOT inject); the property proxy's ancestor-only fiber
   walk fails through the bridge's traceable shadow. Fix: read it via
   `this.ctx.get('sessionPersistence', false)`, the topology-independent
   global-store lookup.

Why the suite missed both: every test mounted the plugin by hand
(`ctx.plugin({name,inject,apply})`), bypassing `unwrapExports` entirely, and
the only test driving these RPCs was key-gated (skipped in CI). Added a no-key
`session/new` e2e that boots the real example through the real Loader — it
fails loudly on bug #1 without an API key. Set `TSX_TSCONFIG_PATH` in the e2e
spawn so the subprocess resolves workspace `paths` from a temp cwd (it was
silently falling back to a stale built `lib/`).

Docs: post-mortem 0001; AGENTS.md "line coverage is not behavior coverage" +
with-key/smoke-test philosophy; packages/AGENTS.md plugin-export-shape and
ctx.get rules; dsh-code-review SKILL checks.
2026-06-18 03:12:37 +08:00
..

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 loggerstdout 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-…" }
    }
  }
}

Run from the repo root (the MVP requires the server's launch directory to be the workspace — see the cwd note in packages/acp).

MVP limitations

The bridge is the RFC 010 MVP: single session per connection (RFC 011 lifts this), text-only prompts, cwd must equal the launch directory, 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.