将 Command Code 接入 DSH,提供模型目录、推理请求、图片输入和账户用量查看能力。
$ dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
这个插件把 Command Code 接入 DSH,让你可以在 DSH 的模型选择器中浏览并使用 Command Code 提供的模型。它还提供独立的设置页、账户用量查看和按套餐整理模型列表的功能。
commandcode 模型提供方,把 DSH 的对话、工具调用和流式输出转换为 Command Code 请求。/commandcode 命令和设置页的账户卡片查看请求数、花费、Token、额度、时间窗口限制和订阅信息。@deepseek-ai/dsh-llm、@deepseek-ai/dsh-settings、@deepseek-ai/dsh-credentials、Reactsrc/index.ts;模型请求与目录适配位于 src/adapter.ts,浏览器入口位于 src/client/index.ts。适合希望在 DSH 中使用 Command Code 账号和模型、并在同一个模型选择器里查看套餐与图片能力的用户。对于需要了解账户额度、请求花费或 5 小时/每周窗口用量的用户,也可以直接使用设置页或 /commandcode 命令查看。
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH 相关运行时 | ^0.1.0-rc.6 peer 依赖 | 需要 DSH 的 LLM、凭据、设置、客户端连接等服务;插件包声明了对应 peer 依赖。 |
| Node.js | >=22 | package.json 的 engines 字段要求。 |
| React | ^18.2.0 | Web 设置页使用 React 渲染。 |
| 平台 | 跨平台 | package.json 未声明 os 或 cpu 限制。 |
| 原生模块 | 无 | 未声明 node-pty、node:sqlite 等原生模块依赖。 |
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
apiKeyEnv | 字符串 | 指定从 DSH 凭据服务或启动环境读取 API key 的名称。设置页保存 key 时也使用这个引用。 | COMMANDCODE_API_KEY |
apiKey | 字符串 | 直接写入插件组合配置的 API key;适合由宿主配置注入,优先级高于凭据引用。 | 未设置 |
apiBase | 字符串 | Command Code API 的基础地址,便于使用默认地址以外的服务端点。 | https://api.commandcode.ai |
workingDir | 字符串 | 作为项目工作目录信息提交给 Command Code;留空时使用 DSH 进程当前目录。 | 当前工作目录 |
modelsCachePath | 字符串 | 保存模型目录缓存的位置,网络暂时不可用时用于回退显示。 | ~/.commandcode/models-cache.json |
requestTimeoutMs | 数字 | 等待生成请求收到响应首字节的最长时间。 | 60000 毫秒 |
streamIdleTimeoutMs | 数字 | 流式响应连续无数据时,超过该时间就判定连接失效。 | 300000 毫秒 |
filterModelsByPlan | 布尔值 | 控制模型选择器是否隐藏超出账户订阅套餐的模型;关闭后显示完整目录。 | true |
Q: 这个插件需要 API key 吗?
A: 模型目录可以在没有 key 时浏览,但发送请求和查看账户用量需要可用的 Command Code API key。插件会先检查直接配置,再通过 DSH 凭据服务解析;没有凭据服务时才读取启动环境,最后回退到 ~/.commandcode/auth.json。
Q: 支持哪些图片输入?
A: 只有源码登记为 Vision 的模型接受图片,并且 DSH 需要启用附件服务。文本模型不会偷偷丢弃图片,而是返回不支持内容的错误。
Q: 为什么模型列表里没有某个模型?
A: 默认的模型选择器会按照账户订阅套餐隐藏超出权限的模型。账单查询失败、套餐未知或存在按需余额时会失败开放;关闭 filterModelsByPlan 也能显示完整目录,但服务端仍可能返回套餐权限错误。
Q: 长时间思考时请求中断怎么办?
A: 默认等待首字节 60 秒,并允许流空闲 300 秒。网络较慢或模型长时间不输出时,可以在设置页调大 requestTimeoutMs 或 streamIdleTimeoutMs;请求连接失败、限流和部分服务端错误会按 DSH 默认策略重试。
Q: 为什么请求返回 MODEL_NOT_IN_PLAN?
A: 这表示所选模型不在当前 Command Code 套餐中。可以改选当前套餐包含的模型,或调整账户套餐;模型列表中的套餐标记只用于提示,服务端才是最终权限来源。
Q: 支持 stop 序列吗?
A: 不支持。Command Code 的请求格式没有 stop 字段,带有该选项的请求会明确返回不支持选项错误。
Q: 设置页显示未配置,但请求仍然成功,为什么?
A: 可能是 key 来自官方 CLI 登录文件 ~/.commandcode/auth.json,而不是 DSH 凭据库。把 key 保存到设置页后,设置页可以准确显示已配置状态。
Q: 卸载插件会删除 API key 吗?
A: 不会。卸载命令只移除插件包和它的配置层,DSH 凭据库及 ~/.commandcode/auth.json 中的 key 会保留。
入门 — 安装插件后主要通过“设置 → Command Code”填写 API key 和连接参数,再从模型选择器选择模型;需要根据套餐或网络情况调整选项时再查看高级配置。
stop 序列;带有该选项的请求会返回 UNSUPPORTED_OPTION。~/.commandcode/auth.json 作为最后兜底,不读取 pi/OMP 等其他工具的认证文件。English | 简体中文
Unofficial DeepSeek Harness LLM provider plugin for Command Code, ported from pi-commandcode-provider (MIT). It registers a commandcode provider whose requests are translated to Command Code's Provider API (POST /alpha/generate, reverse-engineered by the pi plugin, command-code@1.26.0).
This is a community integration. You need your own Command Code account and API key or subscription, and Command Code's terms apply. This project is not affiliated with Command Code, Inc.
dsh plugin add, plus a commandcode provider route with a live catalog (GET {apiBase}/provider/v1/models, cached at ~/.commandcode/models-cache.json).llm-commandcode section and apply to the very next request, no restart.config.apiKey → credential ref apiKeyEnv (default COMMANDCODE_API_KEY) → launch environment → the official CLI auth file (~/.commandcode/auth.json, from command-code login).KNOWN_PLANS), an active deal or FREE badge (KNOWN_DEALS, expiry-aware so lapsed discounts hide themselves), the current peak/off-peak state (Peak/Half) for time-of-day-priced models, an Image marker for Vision models, and the context window (1M / 256K / 262K) — e.g. "Go · 50% off · Image · 1M", "Go · Half · 1M". The list is sorted by plan tier (Go → GOAT → Pro → Provider/Max), so the models your plan can use lead the picker.filterModelsByPlan: false in the llm-commandcode settings section) to always list every model.KNOWN_EFFORTS, matching command-code@1.26.0); reasoning models without effort levels still think automatically, exactly like the official CLI.UNSUPPORTED_CONTENT) rather than dropping them.
Command Code API keys never expire. The easiest path is the official CLI (Node.js 22+):
npm i -g command-code@latest
cmd login # macOS/Linux; native Windows: cmdc login
cmd login opens a browser to authenticate; the key is written to ~/.commandcode/auth.json — picked up automatically as a last-resort fallback. Alternatively create a key in the browser (Command Code Studio) and paste it into Settings → Command Code, or export COMMANDCODE_API_KEY="user_...".
The bare name dsh-commandcode-provider is taken by an unrelated package, so this plugin is published as @mars-sea/dsh-commandcode-provider:
dsh plugin --profile web add @mars-sea/dsh-commandcode-provider
# Pin a release tag (recommended — readable and immutable)
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.2
# Or pin any exact commit by its SHA
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#<full-commit-sha>
The #<ref> suffix pins one exact revision (pnpm git-dependency syntax). Without it the install tracks the default branch, so a later push can silently change what you get.
A git install fetches sources, so the package's prepare script builds lib/ after install. pnpm ≥10 blocks that script by default — run the add, then copy the exact package key pnpm prints into ~/.dsh/profiles/web/pnpm-workspace.yaml:
allowBuilds:
'@mars-sea/dsh-commandcode-provider@github:Mars-Sea/dsh-commandcode-provider#<full-commit-sha>': true
and re-run the add.
npm install
npm run build # git/tarball installs do this via `prepare` automatically
dsh plugin --profile web add /path/to/dsh-commandcode-provider
After changing src/, re-run npm run build and restart the app.
dsh plugin add links the package into the profile (pnpm records it under the true package name @mars-sea/dsh-commandcode-provider), appends that name to dsh.profile.bundles, and activates the cordis.patch.yml layer:
- insert:
- id: llm-commandcode
name: "@mars-sea/dsh-commandcode-provider"
config:
apiKeyEnv: COMMANDCODE_API_KEY
The patch name must be the full package specifier, quoted — the loader imports it as a module from the profile's node_modules, where pnpm only links the scoped name. A bare name fails with ERR_MODULE_NOT_FOUND and crashes the app on boot; an unquoted @mars-sea/... fails YAML parsing (see Troubleshooting).
Verify the composed layer, then (re)start the web app:
dsh --profile web --dump-config # shows a "# == @mars-sea/dsh-commandcode-provider" layer
dsh web # or restart your running instance
The patch layer is read from the installed package at every boot, so updating the package brings the fixed row automatically — no need to hand-edit cordis.patch.yml unless you copied it into your own profile layer.
# npm: always the latest published release
dsh plugin --profile web update @mars-sea/dsh-commandcode-provider
# GitHub (pinned): point at the new tag — no uninstall needed, pnpm swaps it in place
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.2
# local checkout: pull, rebuild, restart
git -C /path/to/dsh-commandcode-provider pull
npm run build --prefix /path/to/dsh-commandcode-provider
dsh web
Then restart the web app. Verify with dsh --profile web --dump-config — the layer should show name: '@mars-sea/dsh-commandcode-provider'.
updatesays "Already up to date" but the version did not move (pnpm ≥ 11)? pnpm 11'sminimumReleaseAgesupply-chain policy can refuse a freshly published version. Pin the exact version instead:dsh plugin --profile web add @mars-sea/dsh-commandcode-provider@0.2.2(orpnpm config set minimumReleaseAge 0 --location projectinside the profile directory).
Upgrading from ≤0.1.6 (or a broken hand-edited profile): if you copied the old patch row into your profile's own
cordis.patch.yml, that copy still wins over the bundle layer — fix it toname: "@mars-sea/dsh-commandcode-provider"or remove it (see Troubleshooting).
To uninstall instead:
dsh plugin --profile web remove @mars-sea/dsh-commandcode-provider(the scoped name — pnpm records the dependency under its real name). Your API key in the dsh credential store and~/.commandcode/auth.jsonare left untouched.
After restart: Settings → Command Code shows the dedicated page — enter your API key and click Save (the badge flips to 已配置/Configured once the Host holds it). Settings → Models shows a Command Code card; the model picker lists the live catalog under commandcode. Send a message with a model your plan includes — deepseek/deepseek-v4-flash works on entry-level plans, and open-weight models (DeepSeek/Qwen/Kimi/MiniMax) generally do, while frontier models (Claude/GPT/Gemini/Grok) may require Pro/Max plans or on-demand usage.
The plugin registers a /commandcode slash command (requires the dsh commands service, present in the standard web profile) showing your account state from the official account endpoints:
/commandcode (or /commandcode status)

Each endpoint degrades independently — a temporary failure of one leaves the rest visible and notes the failure inline.
Settings → Command Code is the primary surface: an API-key field (stored in $DSH_HOME/.credentials.yaml via the credentials service; write-only, reports whether a key is set), plus API base URL, working directory, and request/stream timeout fields, all written to the llm-commandcode section. The catalog is browsable without a key. The working directory is optional — leave it blank and the placeholder shows the process cwd it resolves to.
Once a key is configured, the page header shows a live Account usage card — the same account, spend, credit, and window-limit facts as /commandcode, plus your subscription plan badge and billing period end — fetched Host-side (the key never leaves it) and rendered natively:
The same knobs live in $DSH_HOME/settings.yaml (per-request overrides, no restart):
llm-commandcode:
apiKeyEnv: COMMANDCODE_API_KEY # credential reference resolved per request
apiBase: https://api.commandcode.ai
workingDir: /path/to/project # reported to the API (project slug, config block)
modelsCachePath: ~/.commandcode/models-cache.json
requestTimeoutMs: 60000 # max wait for the first response byte (default 60s)
streamIdleTimeoutMs: 300000 # stream stall before treated as dead (default 300s — generous, so long-thinking models are not cut off)
The composition-entry config (cordis.patch.yml) accepts the same keys; a literal apiKey there takes precedence over the credential reference.
Command Code API request to .../alpha/generate failed with retries — a transport-layer failure: fetch() never got an HTTP response (a 401/403/429 would say "API error"). Since 0.1.8 the message names the real root cause (ECONNREFUSED, ENOTFOUND, CERT_HAS_EXPIRED, socket hang up, …). Common causes: a required proxy (Node's fetch/undici ignores HTTP_PROXY/HTTPS_PROXY — configure a dispatcher or whitelist api.commandcode.ai), connection reset/throttled (firewall, GFW-style interference, unstable Wi-Fi), TLS interception (corporate MITM), or a transient blip retry recovers from.requestTimeoutMs (60s) with no first byte, and treats a stream stalling past streamIdleTimeoutMs (300s by default) as dead. Both surface as TIMEOUT with the stall duration; tune the knobs for slow-but-stable networks.streamIdleTimeoutMs in the llm-commandcode section or on the settings page.ERR_MODULE_NOT_FOUND: Cannot find package 'dsh-commandcode-provider' — the patch row's name is the bare name, but pnpm only links the scoped name. Fix the row to name: "@mars-sea/dsh-commandcode-provider" — note the quotes (an unquoted @-prefixed scalar fails YAML parsing) — then restart.MODEL_NOT_IN_PLAN (403) — the model isn't in your plan. Pick an open-weight model or upgrade; the error names the model and links the docs.MISSING_CREDENTIAL — no key anywhere. Store one via the settings page, export COMMANDCODE_API_KEY, set config.apiKey, or run command-code login. The route and catalog stay browsable without a key.~/.commandcode/auth.json (the cmd login fallback), not the credential store. Paste it into the card once; both coexist fine.maxTokens can be exhausted before visible text. Normal.allowBuilds errors on dsh plugin add from git — copy the exact package key pnpm printed into pnpm-workspace.yaml and re-run (see Install).KNOWN_IMAGE_MODELS in src/adapter.ts). Text-only models throw UNSUPPORTED_CONTENT; Command Code's own CLI's client-side VISION fallback is not reproduced here — switch to a Vision model instead. Image input also requires the dsh attachment service.dsh-host-apiproxy's selectModel) refuses model-unavailable and cannot be relaxed from the plugin side. This bundle makes the message friendlier via its client half: it rewrites the rejection to "当前会话已包含图片,而模型 <model> 不支持图片输入;请选择支持图片的模型,或先移除会话中的图片。" (the error code and details pass through unchanged). Select a model the picker marks Image, remove the images first, or use an image-routing bundle (e.g. @deepseek-ai/dsh-llm-image-routing).stop sequences (the wire format has none): requests carrying one throw UNSUPPORTED_OPTION./alpha/generate requires your key.This plugin operates entirely within your dsh profile and your Command Code account. Local files: reads ~/.commandcode/auth.json only as a last-resort key fallback; reads/writes ~/.commandcode/models-cache.json; reads your key from $DSH_HOME/.credentials.yaml via the standard credential seam (never logged). Network: GET {apiBase}/provider/v1/models (public catalog) and POST {apiBase}/alpha/generate (your requests, authenticated), the body including your configured workingDir. No telemetry — the only outbound host is the Command Code API (api.commandcode.ai by default, configurable via apiBase).
Disable without removing: edit your profile's cordis.patch.yml and comment out (or remove) the llm-commandcode row, or set disabled: true, then restart.
Uninstall completely:
dsh plugin --profile web remove @mars-sea/dsh-commandcode-provider
This removes the bundle dependency and its layer; your API key in the dsh credential store and ~/.commandcode/auth.json are left untouched.
npm install
npm run typecheck # tsc --noEmit
npm run build # tsdown -> lib/
MIT — see LICENSE. Portions ported from pi-commandcode-provider (MIT).