dsh-commandcode-provider
Curated pickmars-sea/dsh-commandcode-provider
Unofficial DeepSeek Harness LLM provider plugin for Command Code: live model catalog, reasoning-effort support, Models-page card. Ported from pi-commandcode-provider (MIT).
39
stars
3
forks
MIT
License
2026-08-14
Created
2026-08-16
Last push
README
dsh-commandcode-provider
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.
What you get
- Plugin bundle installable into any dsh profile with
dsh plugin add, plus acommandcodeprovider route with a live catalog (GET {apiBase}/provider/v1/models, cached at~/.commandcode/models-cache.json). - Dedicated "Command Code" settings page (Settings → Command Code) with an API-key field and connection knobs (API base, working directory, request/stream timeouts). The key is stored through the dsh credentials service; connection fields land in the
llm-commandcodesection and apply to the very next request, no restart. - API key resolution order:
config.apiKey→ credential refapiKeyEnv(defaultCOMMANDCODE_API_KEY) → launch environment → the official CLI auth file (~/.commandcode/auth.json, fromcommand-code login). - Model-picker annotations: every model shows the minimum plan that includes it (
KNOWN_PLANS), an active deal orFREEbadge (KNOWN_DEALS, expiry-aware so lapsed discounts hide themselves), the current peak/off-peak state (Peak/Half) for time-of-day-priced models, anImagemarker 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. - Reasoning-effort support for models the official catalog marks as such (
KNOWN_EFFORTS, matchingcommand-code@1.26.0); reasoning models without effort levels still think automatically, exactly like the official CLI. - Image input for Vision-capable models (sent in the official wire format via the dsh attachment service); text-only models refuse images loudly (
UNSUPPORTED_CONTENT) rather than dropping them.
<img src="assets/screenshots/model-picker.png" alt="Model picker with plan, deal, image and context annotations" width="250">
Getting an API key
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_...".
Install
From npm (recommended)
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
From GitHub
# 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.
From a local checkout
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.
What the install does
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
Updating
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.
Verify it works
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.
Usage dashboard
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.
Configure
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.
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.
Troubleshooting
Command Code API request to .../alpha/generate failedwith 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'sfetch/undici ignoresHTTP_PROXY/HTTPS_PROXY— configure a dispatcher or whitelistapi.commandcode.ai), connection reset/throttled (firewall, GFW-style interference, unstable Wi-Fi), TLS interception (corporate MITM), or a transient blip retry recovers from.- A long generation stops mid-stream — since 0.1.8 the adapter aborts after
requestTimeoutMs(60s) with no first byte, and treats a stream stalling paststreamIdleTimeoutMs(300s by default) as dead. Both surface asTIMEOUTwith the stall duration; tune the knobs for slow-but-stable networks. - "Reconnects" when a reasoning model thinks for a long time — the stream idle watchdog used to default to 120s, which is shorter than a frontier reasoning model's silent thinking phase (xhigh/max effort can stay quiet for minutes, and the official CLI sets no idle cap at all). Since 0.2.3 the default is 300s; if you still hit spurious timeouts on very long thinking, raise
streamIdleTimeoutMsin thellm-commandcodesection or on the settings page. - Boot crash:
ERR_MODULE_NOT_FOUND: Cannot find package 'dsh-commandcode-provider'— the patch row'snameis the bare name, but pnpm only links the scoped name. Fix the row toname: "@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, setconfig.apiKey, or runcommand-code login. The route and catalog stay browsable without a key.- Models card shows "not configured" but requests work — the key came from
~/.commandcode/auth.json(thecmd loginfallback), not the credential store. Paste it into the card once; both coexist fine. - A reasoning model returns no visible text on short requests — it consumes output tokens on reasoning first; a small
maxTokenscan be exhausted before visible text. Normal. allowBuildserrors ondsh plugin addfrom git — copy the exact package key pnpm printed intopnpm-workspace.yamland re-run (see Install).
Notes & limitations
- Image input is model-gated: only models the official registry lists with Vision accept images (see
KNOWN_IMAGE_MODELSinsrc/adapter.ts). Text-only models throwUNSUPPORTED_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. - Switching to a text-only model in an image-bearing session is rejected by dsh itself — a harness-level guard (
dsh-host-apiproxy'sselectModel) refusesmodel-unavailableand 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 marksImage, remove the images first, or use an image-routing bundle (e.g.@deepseek-ai/dsh-llm-image-routing). - No
stopsequences (the wire format has none): requests carrying one throwUNSUPPORTED_OPTION. - Reasoning blocks are not replayed into later turns (matches the official CLI); only tool calls with a paired tool result are replayed.
- The catalog endpoint is public;
/alpha/generaterequires your key.
Permissions & privacy
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).
Disabling / uninstalling
-
Disable without removing: edit your profile's
cordis.patch.ymland comment out (or remove) thellm-commandcoderow, or setdisabled: true, then restart. -
Uninstall completely:
dsh plugin --profile web remove @mars-sea/dsh-commandcode-providerThis removes the bundle dependency and its layer; your API key in the dsh credential store and
~/.commandcode/auth.jsonare left untouched.
Development
npm install
npm run typecheck # tsc --noEmit
npm run build # tsdown -> lib/
Community & feedback
- <img src="https://cdn.simpleicons.org/github/111827" width="16" alt="GitHub" /> GitHub Repository
- <img src="https://cdn.simpleicons.org/github/111827" width="16" alt="Releases" /> GitHub Releases
- <img src="https://cdn.simpleicons.org/npm/111827" width="16" alt="npm" /> npm Package
- <img src="https://cdn.simpleicons.org/discourse/111827" width="16" alt="Linux.do" /> Linux.do 社区
License
MIT — see LICENSE. Portions ported from pi-commandcode-provider (MIT).
More in Integrations & Sharing
dsh-interconnect
by chinesezjc
Cross-instance message/event handoff plugins for DSH (interconnect service + tools)
dsh-notifier
by thewolfwalker
Unified notification push plugin for DeepSeek Harness (DSH): one minimal notify() API, 8 channel adapters (telegram/dingtalk/feishu/wxpusher/pushplus/serverchan/bark/webhook), dual trigger (auto session events + agent tool).
dsh-lark
by omdsh-dev
Lark/Feishu IM bot 通道:聊天驱动 agent,回复与审批以消息/卡片返回;凭据可用 !!js process.env.… 注入 patch;要求 Node ^22.19\
dsh-im
by xmanrui
Connect IM bots to DeepSeek Harness by scanning QR codes (supports Feishu, Weixin, DingTalk, and more).
