{"_id":"@anht3889/dsh-acp-zed","name":"@anht3889/dsh-acp-zed","dist-tags":{"latest":"0.5.0"},"versions":{"0.5.0":{"name":"@anht3889/dsh-acp-zed","version":"0.5.0","description":"Interactive Agent Client Protocol server running DeepSeek Harness in Zed's Agent Panel","license":"MIT","type":"module","exports":{".":"./lib/src/app.js"},"publishConfig":{"access":"public"},"bin":{"dsh-acp-zed":"lib/bin.js"},"engines":{"node":"^22.19 || >=24"},"scripts":{"build":"tsdown","test":"vitest run","typecheck":"tsc -p tsconfig.typecheck.json --noEmit"},"dependencies":{"@agentclientprotocol/sdk":"1.4.0","@anht3889/dsh-mcp-mgmt-oauth":"0.0.1","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/cordis-plugin-group":"1.0.1","@deepseek-ai/cordis-plugin-hmr":"1.0.16","@deepseek-ai/cordis-plugin-include":"1.0.6","@deepseek-ai/cordis-plugin-loader":"1.0.2","@deepseek-ai/cordis-plugin-timer":"1.1.3","@deepseek-ai/dsh-agent":"0.1.1-rc.2","@deepseek-ai/dsh-agent-instructions":"0.1.1-rc.2","@deepseek-ai/dsh-agent-loop":"0.1.1-rc.2","@deepseek-ai/dsh-agent-loop-testkit":"0.1.1-rc.2","@deepseek-ai/dsh-agent-spine-demo":"0.1.1-rc.2","@deepseek-ai/dsh-app-boot":"0.1.1-rc.2","@deepseek-ai/dsh-attachment":"0.1.1-rc.2","@deepseek-ai/dsh-bash-sandbox":"0.1.1-rc.2","@deepseek-ai/dsh-brand":"0.1.1-rc.2","@deepseek-ai/dsh-code-runtime":"0.1.1-rc.2","@deepseek-ai/dsh-credentials-local":"0.1.1-rc.2","@deepseek-ai/dsh-fs-observation-policy":"0.1.1-rc.2","@deepseek-ai/dsh-fs-sandbox":"0.1.1-rc.2","@deepseek-ai/dsh-home-paths":"0.1.1-rc.2","@deepseek-ai/dsh-invariants":"0.1.1-rc.2","@deepseek-ai/dsh-launch-environment":"0.1.1-rc.2","@deepseek-ai/dsh-llm":"0.1.1-rc.2","@deepseek-ai/dsh-llm-deepseek":"0.1.1-rc.2","@deepseek-ai/dsh-llm-pi-ai":"0.1.1-rc.2","@deepseek-ai/dsh-mcp-client":"0.1.1-rc.2","@deepseek-ai/dsh-sandbox-local":"0.1.1-rc.2","@deepseek-ai/dsh-sandbox-policy":"0.1.1-rc.2","@deepseek-ai/dsh-scope":"0.1.1-rc.2","@deepseek-ai/dsh-session":"0.1.1-rc.2","@deepseek-ai/dsh-session-checkpoint-policy":"0.1.1-rc.2","@deepseek-ai/dsh-session-persistence":"0.1.1-rc.2","@deepseek-ai/dsh-session-persistence-jsonl":"0.1.1-rc.2","@deepseek-ai/dsh-session-query":"0.1.1-rc.2","@deepseek-ai/dsh-session-query-sqlite":"0.1.1-rc.2","@deepseek-ai/dsh-session-title":"0.1.1-rc.2","@deepseek-ai/dsh-settings":"0.1.1-rc.2","@deepseek-ai/dsh-settings-file":"0.1.1-rc.2","@deepseek-ai/dsh-skill":"0.1.1-rc.2","@deepseek-ai/dsh-subprocess-local":"0.1.1-rc.2","@deepseek-ai/dsh-system-prompt":"0.1.1-rc.2","@deepseek-ai/dsh-timeout":"0.1.1-rc.2","@deepseek-ai/dsh-tool-fs":"0.1.1-rc.2","@deepseek-ai/dsh-tool-todo":"0.1.1-rc.2","@deepseek-ai/dsh-tools":"0.1.1-rc.2","@deepseek-ai/dsh-typert-protocol":"0.1.1-rc.2","@deepseek-ai/dsh-user-approval":"0.1.1-rc.2","@deepseek-ai/schemastery":"3.18.1"},"devDependencies":{"@types/node":"^26.2.0","tsdown":"^0.22.14","tsx":"^4.23.12","typescript":"^7.0.2","vitest":"^4.1.11"},"gitHead":"65a63e110daac0036a582991468195b4b6a400cb","_id":"@anht3889/dsh-acp-zed@0.5.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-FWx/n0Ctodqzpmk3GFhw61Q4rAFLXanJB9lCCzlJ4oICoa1Gg7yjFotmuwQ7MEOW5HZgPe8LAuVbK0ErcdsqFA==","shasum":"dd52366fb4e099dd8a4f3e46ce90598c30f477fa","tarball":"https://registry.npmjs.org/@anht3889/dsh-acp-zed/-/dsh-acp-zed-0.5.0.tgz","fileCount":9,"unpackedSize":129457,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDwZkPl6xehqmBQwa46qNO06A9oT3I7q3+It9D0/KB/QQIgZ2IPA4ne41ALvzUqdMMaW9KjPyvKHYbYWeDbcwR4+/w="}]},"_npmUser":{"name":"anht3889","email":"anh.tran.3889@gmail.com"},"directories":{},"maintainers":[{"name":"anht3889","email":"anh.tran.3889@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-acp-zed_0.5.0_1787733970691_0.854874867381928"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-26T08:46:10.468Z","0.5.0":"2026-08-26T08:46:10.845Z","modified":"2026-08-26T08:46:11.583Z"},"maintainers":[{"name":"anht3889","email":"anh.tran.3889@gmail.com"}],"description":"Interactive Agent Client Protocol server running DeepSeek Harness in Zed's Agent Panel","license":"MIT","readme":"# @anht3889/dsh-acp-zed\n\nAn [Agent Client Protocol (ACP)](https://agentclientprotocol.com) server that\nruns a [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)\nagent inside Zed's **Agent Panel**. Zed spawns this process and talks to it\nover stdio JSON-RPC; the agent answers with the harness's tool loop (bash,\nfilesystem, todos), streamed deltas, permission prompts, per-session model and\nreasoning-effort switches, persisted sessions you can resume, and DeepSeek\nmodels by default — with the whole composition swappable, so other providers\nare configuration, not code.\n\n## Install and configure — step by step\n\n### Step 1. Prove the prerequisites\n\n- **Zed** (current stable); Agent Panel support ships with it.\n- **Node.js `^22.19 || >=24`**. Check: `node --version`.\n- A **DeepSeek API key**, or [another provider](#server-settings-and-custom-providers).\n\n### Step 2. Decide how Zed launches the server\n\n**Recommended: no install at all — npx runs it on demand:**\n\n```sh\nnpx -y @anht3889/dsh-acp-zed --list-models   # sanity check; prints the catalog to stderr\n```\n\nAlternatives: a global install (`npm i -g @anht3889/dsh-acp-zed`, then the\ncommand is just `dsh-acp-zed`), or a source checkout (`node /path/to/dsh-acp-zed/lib/bin.js`\nafter `pnpm build`).\n\nNote the absolute-path gotcha now: a GUI-launched Zed (Dock/Spotlight) often\ncan't see `npx` from nvm/volta. If step 3 fails to spawn, use\n`which npx` output as the absolute `command` — full detail in\n[Troubleshooting](#troubleshooting).\n\n### Step 3. Register the server in Zed\n\nCommand Palette → `zed: open settings` → add an `agent_servers` entry:\n\n```json\n{\n  \"agent_servers\": {\n    \"DeepSeek Harness\": {\n      \"type\": \"custom\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@anht3889/dsh-acp-zed\"]\n    }\n  }\n}\n```\n\n### Step 4. Pick an authentication route\n\n**Either** pass the key in Zed's env block:\n\n```json\n\"env\": { \"DEEPSEEK_API_KEY\": \"…\" }\n```\n\n**or** run the login flow once (silent prompt; saved owner-only to\n`~/.dsh/acp-zed/auth.env`, mode 600) and omit the env block:\n\n```sh\nnpx -y @anht3889/dsh-acp-zed login\n```\n\nThe env block always wins over the saved file when both exist.\n\n### Step 5. Verify outside Zed\n\n```sh\nnpx -y @anht3889/dsh-acp-zed --list-models\n```\n\nMust print the provider/model catalog to stderr and exit 0. If it fails\nhere, the message names the cause (missing config, overlay parse error,\nauth file trouble) far louder than Zed's log does.\n\n### Step 6. Use it\n\nOpen the Agent Panel from Zed's status bar, pick **DeepSeek Harness**, start a\nthread. The gear icon per thread exposes **Model** and **Thought Level** —\nswitch per session without touching settings. Threads persist, and\n`dsh-acp-zed` exposes resume via Zed's recent-threads picker. Then:\n\n- [Using the agent](#using-the-agent) — switching models/effort, resume, auth\n- [Custom providers](#server-settings-and-custom-providers) — add an OpenAI-compatible gateway,\n  Anthropic, or a self-hosted model\n\n## Using the agent\n\n### Enrolling MCP servers from the CLI\n\n`dsh-acp-zed mcp` manages the shared catalog (`~/.dsh/mcp`) that BOTH this\nbridge and the dsh web profile consume:\n\n```sh\ndsh-acp-zed mcp add http nvbug https://maas.prd.astra.nvidia.com/maas/nvbugs/mcp\n# discovers OAuth endpoints (RFC 9728/8414), registers a loopback client,\n# opens your browser (link also printed), exchanges the code, stores the\n# tokens into ~/.dsh/mcp/secrets.yaml\ndsh-acp-zed mcp add stdio tci tci-mcp\ndsh-acp-zed mcp auth nvbug     # re-run the browser dance when a refresh dies\ndsh-acp-zed mcp list           # catalog records + auth state\ndsh-acp-zed mcp remove nvbug   # record + tokens gone\n```\n\nEvery `enabled` catalog record auto-mounts into every Zed thread — no Zed\n`context_servers` entries needed at all; Zed-forwarded entries still work and\nwin on name collision (the catalog then contributes only auth).\n\nStatic-header (non-OAuth) catalog records are currently NOT attached by the\nbridge (v1 boundary): put those in Zed's `context_servers` with literal\nheaders.\n\n### MCP servers (Zed `context_servers`)\n\nZed's `context_servers` settings flow into each session as ACP `mcpServers`;\n**OAuth entries work too**: Zed authenticates OAuth servers only for its own\nnative agent and forwards a bare URL to external agents (its own source drops\n`oauth` when building the ACP entry), so the bridge resolves auth itself from\nthe dsh *web profile's* MCP catalog (`~/.dsh/mcp/servers.json` +\n`secrets.yaml`, managed by `@anht3889/dsh-mcp-mgmt-bundle`): matching entries\n(same name or URL) inherit the catalog's OAuth token — refreshed through the\ncatalog's token endpoint when expired and written back for both profiles. If\nthe refresh token is dead, stderr names it and asks you to re-authenticate in\nthe web GUI. A mounted server that yields no tools is always named on stderr.\n\neach entry mounts a `@deepseek-ai/dsh-mcp-client` connection **shared across\nall threads of the running agent** (one instance per server name — MCP\nnamespaces and their tools are app-wide), exposing its tools as\n`mcp__<server>__<tool>` to the model. Stdio and streamable-HTTP\n(`type: \"http\"`) entries work; the deprecated `sse` transport is rejected\nwith a clear error. An unreachable server soft-fails (session starts anyway;\ndetails on stderr). If you change a server's settings in `settings.json`,\nrestart the agent — the live bridge keeps the config it first mounted and\nrejects a diverging second thread with a restart-pointing error.\n\n### Skills (on by default)\n\nType `/` in a Zed thread: the slash menu lists every user-invocable skill\n(advertised via ACP `available_commands_update`, refreshed live when a skill\nfile changes). Sending `/name args` as a message invokes that skill — the\nharness claims the token and injects its body as instructions; unknown names\nstay plain text. That's the same gesture semantics as the DeepSeek Harness\nweb GUI.\n\nThe underlying stack follows the harness default (on): the model-facing\n`skill` tool is mounted, and skill docs placed in any of these roots are\ndiscovered and shown to the agent — restart not required for *content*\nchanges:\n\n- `<projectRoot>/.dsh/skills/` and `<projectRoot>/.agents/skills/` — per-project\n- `~/.dsh/skills/` and `~/.agents/skills/` — per-user\n- custom dirs via `skills.filesystem.customSkillDirs` on the acp-zed entry\n\nThe [Superpowers](https://github.com/anht3889/dsh-superpowers) pack drops in\nas a plugin: `dsh-acp-zed plugin add @anht3889/dsh-superpowers` (published;\nits `skills` inject is satisfied out of the box). To disable the stack\nentirely, patch the acp-zed entry with `skills: { enabled: false }` in the\noverlay — see `docs/zed-setup.md`.\n\n### Model and effort switching (per session)\n\nZed renders the server's session config options natively: in a thread, use\nthe select menus for the agent's session options.\n\n- **Model** — any model advertised by the current provider (the shipped\n  composition offers `deepseek-v4-flash`, `deepseek-v4-pro`, and\n  `deepseek-v4-flash-vision-exp`).\n- **Thought Level** — the current model's reasoning effort (`off`, `low`,\n  `high`, `max` for the shipped DeepSeek models). Shown only for models that\n  declare selectable efforts.\n\nChanges are per-thread and take effect from the agent's next step — you can\nswitch mid-generation and the running turn finishes on the old selection.\n\n### Resuming a thread\n\nThreads persist to `~/.dsh/acp-zed/sessions` (or `$DSH_HOME/acp-zed/sessions`)\nas you work. Zed's recent-threads picker lists them (the server implements\n`session/list` + `session/load`): pick one and the full transcript — your\nmessages, assistant replies, and completed tool calls — replays into the\nthread before you continue. Resume applies within the workspace the session\nwas recorded in: the picker shows sessions belonging to the current project.\n\n### Authentication\n\nResolution order on every launch and every `authenticate` call:\n\n1. The live `DEEPSEEK_API_KEY` environment variable (e.g. the `env` block in\n   settings), then\n2. the persisted login file `~/.dsh/acp-zed/auth.env`.\n\nIf neither has a key, prompts report auth-required and Zed surfaces the\nadvertised sign-in methods — *API key from environment* (`env`) or *Log in\nfrom the terminal* (`terminal-login`, which runs `dsh-acp-zed login` in a\nterminal window). The key is never logged, echoed, or sent anywhere but the\nDeepSeek API.\n\nTo sign out: `npx @anht3889/dsh-acp-zed logout` removes the persisted file\nand clears the in-process key cache (Zed's own logout action clears the\nrunning session's key).\n\n**Using a self-credentialed route** (headers baked in, or a keyless local\ngateway)? Add `authRequired: false` to the acp-zed overlay config — no auth\nmethods are advertised and prompts are ungated (see the worked example below).\n\n### Server settings and custom providers\n\nThe server boots a [cordis](https://github.com/deepseek-ai/deepseek-harness)\ncomposition shipped inside the package (`cordis.yml`). Two layering surfaces\nextend your installation:\n\n- **The settings document** at `~/.dsh/acp-zed/settings.yaml`, hot-reloaded:\n  a `llm-pi-ai: providers:` section declares custom provider routes (the\n  multi-provider [`@deepseek-ai/dsh-llm-pi-ai`](https://www.npmjs.com/package/@deepseek-ai/dsh-llm-pi-ai)\n  adapter ships dormant in the default composition) and they register live on\n  the next request — no restart. Credentials for them resolve through\n  `~/.dsh/acp-zed/credentials.yaml` or the environment (which always wins).\n- **The user overlay** over the shipped composition at\n  `~/.dsh/acp-zed/overlay.cordis.yml`, when present. A top-level YAML array of\n  patch entries: `- id: <entry>  config: {...}` replaces a shipped plugin's\n  config; `- insert: [...]` mounts new plugins. `!!js` expressions are\n  allowed. Overlay changes are **restart-to-apply** and a broken overlay\n  fails startup loudly with a named error.\n- **`dsh-acp-zed plugin add <npm-name-or-dir>`** is the managed path for the\n  second case: it installs into a private workspace under the harness home\n  and appends the insert block for you (see `plugin list` / `plugin remove`;\n  the full guide in `docs/zed-setup.md`).\n\nWorked example — point the bridge at an OpenAI-compatible gateway:\n\n```yaml\n# ~/.dsh/acp-zed/settings.yaml — registers live (hot reload)\nllm-pi-ai:\n  providers:\n    local-kimi:\n      displayName: Local Kimi\n      api: openai-completions\n      baseURL: http://10.78.3.34:8000/v1\n      compat: { supportsDeveloperRole: false, maxTokensField: max_tokens }\n      models:\n        - id: moonshotai/Kimi-K3\n          name: Kimi K3\n          contextWindow: 1048576\n          maxTokens: 32768\n```\n\n```yaml\n# ~/.dsh/acp-zed/overlay.cordis.yml — restart-to-apply; config REPLACES the\n# entry's whole config, so restate the shipped fields you keep (persona and\n# workspaceContext from the package's cordis.yml)\n- id: acp-zed\n  config:\n    provider: local-kimi\n    model: moonshotai/Kimi-K3\n    authRequired: false      # keyless self-hosted route: no Authenticate gate\n    workspaceContext:\n      maxBytes: 65536\n    persona: |\n      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.\n\n      Verify your work by running the code or tests. Keep answers brief and factual.\n```\n\nRestart the thread and verify the wiring outside Zed:\n\n```sh\nnpx @anht3889/dsh-acp-zed --list-models   # prints the provider/model catalog to stderr\n```\n\n(On Windows, use a `file:///C:/...` URL for `name`; plain POSIX absolute paths\nwork on macOS/Linux. `HOME` can be relocated with `$DSH_HOME`.)\n\n## Troubleshooting\n\n**\"No such file or directory\" / the agent fails to spawn.** Zed launched as a\nGUI app (Dock, Finder, Spotlight) does not read your shell profile, so `npx`\nfrom nvm/volta is often not on its PATH. Fixes:\n\n- Find the absolute path (`which npx` in a terminal) and use it as `command`:\n  ```json\n  { \"command\": \"/Users/you/.nvm/versions/node/v24.15.0/bin/npx\",\n    \"args\": [\"-y\", \"@anht3889/dsh-acp-zed\"], ... }\n  ```\n- Or launch Zed from your terminal (`zed .`), which inherits the shell's PATH\n  (the `zed` CLI installs from Zed's menu: `cli: install`).\n\nSpawn errors and the server's stderr diagnostics surface in Zed's log\n(`zed: open log`).\n\n**Every prompt demands authentication.** Neither the env var nor the login\nfile has a key — run `npx @anht3889/dsh-acp-zed login` or add the `env`\nblock. The server self-checks outside Zed:\n`npx @anht3889/dsh-acp-zed --list-models` must print the model catalog.\n\nMore: [docs/zed-setup.md](docs/zed-setup.md) — deeper setup, permission\nmodes, overlay mechanics, resume semantics, and troubleshooting.\n\n## Limitations (v1)\n\n- **No durable permission grants.** Approval prompts offer one-shot choices\n  only; there is no \"always allow\" that persists.\n- **No `mcpServers` / `additionalDirectories`.** A session requesting either\n  is rejected with an invalid-params error.\n- **No reasoning display.** The Thought Level option changes the effort sent\n  with requests, but reasoning traces are never streamed to the UI.\n- **No background tool jobs.** The generic job tools are unmounted; every\n  tool call completes in-band.\n- **Overlays are restart-to-apply.** No HMR; restart the thread (or Zed)\n  after editing the overlay or config. Only the settings document\n  (`llm-pi-ai` provider routes, credentials) hot-reloads.\n\n## Developing\n\n```sh\npnpm install\npnpm build        # tsdown → lib/\npnpm test         # vitest\npnpm typecheck    # tsc --noEmit over src/ and tests/\n```\n\nFrom a source checkout, point Zed straight at the built bin:\n\n```json\n{ \"command\": \"node\", \"args\": [\"/abs/path/to/dsh-acp-zed/lib/bin.js\"],\n  \"env\": { \"DEEPSEEK_API_KEY\": \"…\" } }\n```\n\n`dsh-acp-zed --help` prints the full CLI (usage goes to stderr; stdout is\nreserved for ACP JSON-RPC).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md","_rev":"1-ae943804f7ed270c398880e2e6b3d340"}