npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@anht3889/dsh-acp-zed

v0.5.0

Published

Interactive Agent Client Protocol server running DeepSeek Harness in Zed's Agent Panel

Readme

@anht3889/dsh-acp-zed

An Agent Client Protocol (ACP) server that runs a DeepSeek Harness agent inside Zed's Agent Panel. Zed spawns this process and talks to it over stdio JSON-RPC; the agent answers with the harness's tool loop (bash, filesystem, todos), streamed deltas, permission prompts, per-session model and reasoning-effort switches, persisted sessions you can resume, and DeepSeek models by default — with the whole composition swappable, so other providers are configuration, not code.

Install and configure — step by step

Step 1. Prove the prerequisites

  • Zed (current stable); Agent Panel support ships with it.
  • Node.js ^22.19 || >=24. Check: node --version.
  • A DeepSeek API key, or another provider.

Step 2. Decide how Zed launches the server

Recommended: no install at all — npx runs it on demand:

npx -y @anht3889/dsh-acp-zed --list-models   # sanity check; prints the catalog to stderr

Alternatives: a global install (npm i -g @anht3889/dsh-acp-zed, then the command is just dsh-acp-zed), or a source checkout (node /path/to/dsh-acp-zed/lib/bin.js after pnpm build).

Note the absolute-path gotcha now: a GUI-launched Zed (Dock/Spotlight) often can't see npx from nvm/volta. If step 3 fails to spawn, use which npx output as the absolute command — full detail in Troubleshooting.

Step 3. Register the server in Zed

Command Palette → zed: open settings → add an agent_servers entry:

{
  "agent_servers": {
    "DeepSeek Harness": {
      "type": "custom",
      "command": "npx",
      "args": ["-y", "@anht3889/dsh-acp-zed"]
    }
  }
}

Step 4. Pick an authentication route

Either pass the key in Zed's env block:

"env": { "DEEPSEEK_API_KEY": "…" }

or run the login flow once (silent prompt; saved owner-only to ~/.dsh/acp-zed/auth.env, mode 600) and omit the env block:

npx -y @anht3889/dsh-acp-zed login

The env block always wins over the saved file when both exist.

Step 5. Verify outside Zed

npx -y @anht3889/dsh-acp-zed --list-models

Must print the provider/model catalog to stderr and exit 0. If it fails here, the message names the cause (missing config, overlay parse error, auth file trouble) far louder than Zed's log does.

Step 6. Use it

Open the Agent Panel from Zed's status bar, pick DeepSeek Harness, start a thread. The gear icon per thread exposes Model and Thought Level — switch per session without touching settings. Threads persist, and dsh-acp-zed exposes resume via Zed's recent-threads picker. Then:

Using the agent

Enrolling MCP servers from the CLI

dsh-acp-zed mcp manages the shared catalog (~/.dsh/mcp) that BOTH this bridge and the dsh web profile consume:

dsh-acp-zed mcp add http nvbug https://maas.prd.astra.nvidia.com/maas/nvbugs/mcp
# discovers OAuth endpoints (RFC 9728/8414), registers a loopback client,
# opens your browser (link also printed), exchanges the code, stores the
# tokens into ~/.dsh/mcp/secrets.yaml
dsh-acp-zed mcp add stdio tci tci-mcp
dsh-acp-zed mcp auth nvbug     # re-run the browser dance when a refresh dies
dsh-acp-zed mcp list           # catalog records + auth state
dsh-acp-zed mcp remove nvbug   # record + tokens gone

Every enabled catalog record auto-mounts into every Zed thread — no Zed context_servers entries needed at all; Zed-forwarded entries still work and win on name collision (the catalog then contributes only auth).

Static-header (non-OAuth) catalog records are currently NOT attached by the bridge (v1 boundary): put those in Zed's context_servers with literal headers.

MCP servers (Zed context_servers)

Zed's context_servers settings flow into each session as ACP mcpServers; OAuth entries work too: Zed authenticates OAuth servers only for its own native agent and forwards a bare URL to external agents (its own source drops oauth when building the ACP entry), so the bridge resolves auth itself from the dsh web profile's MCP catalog (~/.dsh/mcp/servers.json + secrets.yaml, managed by @anht3889/dsh-mcp-mgmt-bundle): matching entries (same name or URL) inherit the catalog's OAuth token — refreshed through the catalog's token endpoint when expired and written back for both profiles. If the refresh token is dead, stderr names it and asks you to re-authenticate in the web GUI. A mounted server that yields no tools is always named on stderr.

each entry mounts a @deepseek-ai/dsh-mcp-client connection shared across all threads of the running agent (one instance per server name — MCP namespaces and their tools are app-wide), exposing its tools as mcp__<server>__<tool> to the model. Stdio and streamable-HTTP (type: "http") entries work; the deprecated sse transport is rejected with a clear error. An unreachable server soft-fails (session starts anyway; details on stderr). If you change a server's settings in settings.json, restart the agent — the live bridge keeps the config it first mounted and rejects a diverging second thread with a restart-pointing error.

Skills (on by default)

Type / in a Zed thread: the slash menu lists every user-invocable skill (advertised via ACP available_commands_update, refreshed live when a skill file changes). Sending /name args as a message invokes that skill — the harness claims the token and injects its body as instructions; unknown names stay plain text. That's the same gesture semantics as the DeepSeek Harness web GUI.

The underlying stack follows the harness default (on): the model-facing skill tool is mounted, and skill docs placed in any of these roots are discovered and shown to the agent — restart not required for content changes:

  • <projectRoot>/.dsh/skills/ and <projectRoot>/.agents/skills/ — per-project
  • ~/.dsh/skills/ and ~/.agents/skills/ — per-user
  • custom dirs via skills.filesystem.customSkillDirs on the acp-zed entry

The Superpowers pack drops in as a plugin: dsh-acp-zed plugin add @anht3889/dsh-superpowers (published; its skills inject is satisfied out of the box). To disable the stack entirely, patch the acp-zed entry with skills: { enabled: false } in the overlay — see docs/zed-setup.md.

Model and effort switching (per session)

Zed renders the server's session config options natively: in a thread, use the select menus for the agent's session options.

  • Model — any model advertised by the current provider (the shipped composition offers deepseek-v4-flash, deepseek-v4-pro, and deepseek-v4-flash-vision-exp).
  • Thought Level — the current model's reasoning effort (off, low, high, max for the shipped DeepSeek models). Shown only for models that declare selectable efforts.

Changes are per-thread and take effect from the agent's next step — you can switch mid-generation and the running turn finishes on the old selection.

Resuming a thread

Threads persist to ~/.dsh/acp-zed/sessions (or $DSH_HOME/acp-zed/sessions) as you work. Zed's recent-threads picker lists them (the server implements session/list + session/load): pick one and the full transcript — your messages, assistant replies, and completed tool calls — replays into the thread before you continue. Resume applies within the workspace the session was recorded in: the picker shows sessions belonging to the current project.

Authentication

Resolution order on every launch and every authenticate call:

  1. The live DEEPSEEK_API_KEY environment variable (e.g. the env block in settings), then
  2. the persisted login file ~/.dsh/acp-zed/auth.env.

If neither has a key, prompts report auth-required and Zed surfaces the advertised sign-in methods — API key from environment (env) or Log in from the terminal (terminal-login, which runs dsh-acp-zed login in a terminal window). The key is never logged, echoed, or sent anywhere but the DeepSeek API.

To sign out: npx @anht3889/dsh-acp-zed logout removes the persisted file and clears the in-process key cache (Zed's own logout action clears the running session's key).

Using a self-credentialed route (headers baked in, or a keyless local gateway)? Add authRequired: false to the acp-zed overlay config — no auth methods are advertised and prompts are ungated (see the worked example below).

Server settings and custom providers

The server boots a cordis composition shipped inside the package (cordis.yml). Two layering surfaces extend your installation:

  • The settings document at ~/.dsh/acp-zed/settings.yaml, hot-reloaded: a llm-pi-ai: providers: section declares custom provider routes (the multi-provider @deepseek-ai/dsh-llm-pi-ai adapter ships dormant in the default composition) and they register live on the next request — no restart. Credentials for them resolve through ~/.dsh/acp-zed/credentials.yaml or the environment (which always wins).
  • The user overlay over the shipped composition at ~/.dsh/acp-zed/overlay.cordis.yml, when present. A top-level YAML array of patch entries: - id: <entry> config: {...} replaces a shipped plugin's config; - insert: [...] mounts new plugins. !!js expressions are allowed. Overlay changes are restart-to-apply and a broken overlay fails startup loudly with a named error.
  • dsh-acp-zed plugin add <npm-name-or-dir> is the managed path for the second case: it installs into a private workspace under the harness home and appends the insert block for you (see plugin list / plugin remove; the full guide in docs/zed-setup.md).

Worked example — point the bridge at an OpenAI-compatible gateway:

# ~/.dsh/acp-zed/settings.yaml — registers live (hot reload)
llm-pi-ai:
  providers:
    local-kimi:
      displayName: Local Kimi
      api: openai-completions
      baseURL: http://10.78.3.34:8000/v1
      compat: { supportsDeveloperRole: false, maxTokensField: max_tokens }
      models:
        - id: moonshotai/Kimi-K3
          name: Kimi K3
          contextWindow: 1048576
          maxTokens: 32768
# ~/.dsh/acp-zed/overlay.cordis.yml — restart-to-apply; config REPLACES the
# entry's whole config, so restate the shipped fields you keep (persona and
# workspaceContext from the package's cordis.yml)
- id: acp-zed
  config:
    provider: local-kimi
    model: moonshotai/Kimi-K3
    authRequired: false      # keyless self-hosted route: no Authenticate gate
    workspaceContext:
      maxBytes: 65536
    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.

Restart the thread and verify the wiring outside Zed:

npx @anht3889/dsh-acp-zed --list-models   # prints the provider/model catalog to stderr

(On Windows, use a file:///C:/... URL for name; plain POSIX absolute paths work on macOS/Linux. HOME can be relocated with $DSH_HOME.)

Troubleshooting

"No such file or directory" / the agent fails to spawn. Zed launched as a GUI app (Dock, Finder, Spotlight) does not read your shell profile, so npx from nvm/volta is often not on its PATH. Fixes:

  • Find the absolute path (which npx in a terminal) and use it as command:
    { "command": "/Users/you/.nvm/versions/node/v24.15.0/bin/npx",
      "args": ["-y", "@anht3889/dsh-acp-zed"], ... }
  • Or launch Zed from your terminal (zed .), which inherits the shell's PATH (the zed CLI installs from Zed's menu: cli: install).

Spawn errors and the server's stderr diagnostics surface in Zed's log (zed: open log).

Every prompt demands authentication. Neither the env var nor the login file has a key — run npx @anht3889/dsh-acp-zed login or add the env block. The server self-checks outside Zed: npx @anht3889/dsh-acp-zed --list-models must print the model catalog.

More: docs/zed-setup.md — deeper setup, permission modes, overlay mechanics, resume semantics, and troubleshooting.

Limitations (v1)

  • No durable permission grants. Approval prompts offer one-shot choices only; there is no "always allow" that persists.
  • No mcpServers / additionalDirectories. A session requesting either is rejected with an invalid-params error.
  • No reasoning display. The Thought Level option changes the effort sent with requests, but reasoning traces are never streamed to the UI.
  • No background tool jobs. The generic job tools are unmounted; every tool call completes in-band.
  • Overlays are restart-to-apply. No HMR; restart the thread (or Zed) after editing the overlay or config. Only the settings document (llm-pi-ai provider routes, credentials) hot-reloads.

Developing

pnpm install
pnpm build        # tsdown → lib/
pnpm test         # vitest
pnpm typecheck    # tsc --noEmit over src/ and tests/

From a source checkout, point Zed straight at the built bin:

{ "command": "node", "args": ["/abs/path/to/dsh-acp-zed/lib/bin.js"],
  "env": { "DEEPSEEK_API_KEY": "…" } }

dsh-acp-zed --help prints the full CLI (usage goes to stderr; stdout is reserved for ACP JSON-RPC).

License

MIT — see LICENSE.