@mars-sea/dsh-commandcode-provider 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/LICENSE +1 -7
- package/NOTICE +10 -0
- package/README.md +57 -95
- package/README.zh-CN.md +57 -94
- package/assets/screenshots/model-picker.png +0 -0
- package/assets/screenshots/usage-dashboard.png +0 -0
- package/lib/client.js +666 -10
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.js +26 -3
- package/lib/index.js.map +1 -1
- package/package.json +26 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.2.3] - 2026-08-16
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **`streamIdleTimeoutMs` default raised from 120s to 300s.** The stream idle watchdog used to kill a generation that produced no events for 120s, but frontier reasoning models (xhigh/max effort) can legitimately stay silent for minutes while thinking — the official CLI sets no idle cap at all. An aggressive cap turned long thinking into a spurious `TIMEOUT`, which dsh-llm-retry then retried, surfacing to users as "stuck, then reconnecting". The new 300s default keeps the dead-connection protection (a truly stalled socket still fails instead of hanging) without cutting off legitimate long thinking. Tune `streamIdleTimeoutMs` in the `llm-commandcode` settings section or on the settings page for your workload.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **In-band stream `error` events are now classified like the official CLI, so transient server-side drops get retried instead of failing the turn.** The adapter previously threw every stream `error` event as `PROVIDER_STREAM_ERROR`, which is outside the harness default retryable set — a server blip that the official CLI recovers from (e.g. "Upstream stream ended before terminal chunk") failed the whole turn. Now the adapter mirrors command-code's `readStreamErrorEvent`/`isStreamErrorRetryable`: an error that is explicitly non-retryable, carries a terminal marker (`premium_credits_exhausted`, `model_not_in_plan`, `insufficient credits`), or reports a non-retryable HTTP status stays `PROVIDER_STREAM_ERROR`; everything else is thrown as `SERVER`, which the default retry policy retries.
|
|
16
|
+
|
|
17
|
+
## [0.2.2] - 2026-08-16
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **A dedicated "Command Code" settings page** (Settings → **Command Code**, a top-level nav entry at the same level as General / Models / Plugins) where you can configure the provider **entirely from the web UI**: an **API-key field** (write-only, stored through the dsh credentials service under the `COMMANDCODE_API_KEY` reference the plugin resolves, with a configured/unconfigured badge) plus the **API base URL**, **working directory**, and **request/stream timeouts** (written to the `llm-commandcode` settings namespace, effective on the next request — no restart). The browser half registers a `settings.section` entry (`id: commandcode`) from the bundle's client plugin; the controller is covered by new unit tests in `tests/settings.test.ts`.
|
|
22
|
+
- **The working-directory field is now genuinely optional in the settings page**: the page reads the Host process cwd (`host.describe().cwd`) and shows it as the field's placeholder, so a blank field visibly resolves to the process working directory — nothing to configure unless you want to pin a specific path. The page hints this in both languages.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **The API key could not actually be configured from the Models page for this provider.** The Models page renders an unknown-adapter-family card for `commandcode` and disables its editor (submit is blocked when `layout === 'unknown'`), so the card's key field could not save. The new dedicated settings page is the working surface for the key (and the connection knobs); the Models card remains as a status/reflection of the provider.
|
|
27
|
+
|
|
7
28
|
## [0.2.1] - 2026-08-16
|
|
8
29
|
|
|
9
30
|
### Fixed
|
package/LICENSE
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026
|
|
4
|
-
|
|
5
|
-
This plugin is a port of pi-commandcode-provider (Copyright (c) 2025 patlux,
|
|
6
|
-
MIT), which reverse-engineered the Command Code Provider API. Command Code is
|
|
7
|
-
a product of Command Code, Inc.; this project is not affiliated with or
|
|
8
|
-
endorsed by it, and your use of the Command Code service is governed by
|
|
9
|
-
Command Code's own terms.
|
|
3
|
+
Copyright (c) 2026 Mars-Sea
|
|
10
4
|
|
|
11
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/NOTICE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
dsh-commandcode-provider
|
|
2
|
+
Copyright (c) 2026 Mars-Sea
|
|
3
|
+
|
|
4
|
+
This software incorporates portions ported from pi-commandcode-provider
|
|
5
|
+
(Copyright (c) 2025 Pat Woz), licensed under the MIT License, which
|
|
6
|
+
reverse-engineered the Command Code Provider API.
|
|
7
|
+
|
|
8
|
+
Command Code is a product of Command Code, Inc.; this project is not
|
|
9
|
+
affiliated with or endorsed by it, and your use of the Command Code service
|
|
10
|
+
is governed by Command Code's own terms.
|
package/README.md
CHANGED
|
@@ -2,25 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [简体中文](./README.zh-CN.md)
|
|
4
4
|
|
|
5
|
+
[](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin)
|
|
6
|
+
[](https://github.com/Mars-Sea/dsh-commandcode-provider/stargazers)
|
|
7
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
8
|
+
[](https://github.com/Mars-Sea/dsh-commandcode-provider/pulls)
|
|
5
9
|
[](https://github.com/Mars-Sea/dsh-commandcode-provider/actions/workflows/ci.yml)
|
|
6
10
|
[](https://opensource.org/licenses/MIT)
|
|
7
11
|
[](https://www.npmjs.com/package/@mars-sea/dsh-commandcode-provider)
|
|
8
12
|
|
|
9
|
-
Unofficial [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/) LLM provider plugin for **Command Code**, ported from [pi-commandcode-provider](https://github.com/patlux/pi-commandcode-provider) (MIT). It registers a `commandcode`
|
|
13
|
+
Unofficial [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/) LLM provider plugin for **Command Code**, ported from [pi-commandcode-provider](https://github.com/patlux/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`).
|
|
10
14
|
|
|
11
15
|
> 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.
|
|
12
16
|
|
|
13
17
|
## What you get
|
|
14
18
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- **
|
|
19
|
-
- **Reasoning-effort support** for
|
|
20
|
-
- **
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
- **Image input for Vision-capable models**: models the official registry lists with Vision (e.g. `claude-sonnet-5`, `gpt-5.4`, `google/gemini-3.5-flash`, …) accept attached images, resolved through the dsh attachment service and sent in the official Command Code wire format. Text-only models (e.g. `deepseek/deepseek-v4-flash`, `zai-org/GLM-5.3`) refuse images loudly rather than silently dropping them.
|
|
19
|
+
- **Plugin bundle** installable into any dsh profile with `dsh plugin add`, plus a **`commandcode` provider route** with a live catalog (`GET {apiBase}/provider/v1/models`, cached at `~/.commandcode/models-cache.json`).
|
|
20
|
+
- **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-commandcode` section and apply to the very next request, no restart.
|
|
21
|
+
- **API key resolution order**: `config.apiKey` → credential ref `apiKeyEnv` (default `COMMANDCODE_API_KEY`) → launch environment → the official CLI auth file (`~/.commandcode/auth.json`, from `command-code login`).
|
|
22
|
+
- **Model-picker annotations**: every model shows the **minimum plan** that includes it (`KNOWN_PLANS`), an **active deal** or `FREE` badge (`KNOWN_DEALS`, expiry-aware so lapsed discounts hide themselves), an **`Image`** marker for Vision models, and the **context window** (`1M` / `256K` / `262K`) — e.g. *"Go · 50% off · Image · 1M"*. The list is **sorted by plan tier** (Go → GOAT → Pro → Provider/Max), so the models your plan can use lead the picker.
|
|
23
|
+
- **Reasoning-effort support** for models the official catalog marks as such (`KNOWN_EFFORTS`, matching `command-code@1.26.0`); reasoning models without effort levels still think automatically, exactly like the official CLI.
|
|
24
|
+
- **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.
|
|
25
|
+
|
|
26
|
+
<img src="assets/screenshots/model-picker.png" alt="Model picker with plan, deal, image and context annotations" width="250">
|
|
24
27
|
|
|
25
28
|
## Getting an API key
|
|
26
29
|
|
|
@@ -31,13 +34,13 @@ npm i -g command-code@latest
|
|
|
31
34
|
cmd login # macOS/Linux; native Windows: cmdc login
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
`cmd login` opens a browser to authenticate;
|
|
37
|
+
`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](https://commandcode.ai/studio/auth/cli)) and paste it into **Settings → Command Code**, or `export COMMANDCODE_API_KEY="user_..."`.
|
|
35
38
|
|
|
36
39
|
## Install
|
|
37
40
|
|
|
38
41
|
### From npm (recommended)
|
|
39
42
|
|
|
40
|
-
The
|
|
43
|
+
The bare name `dsh-commandcode-provider` is taken by an unrelated package, so this plugin is published as **`@mars-sea/dsh-commandcode-provider`**:
|
|
41
44
|
|
|
42
45
|
```sh
|
|
43
46
|
dsh plugin --profile web add @mars-sea/dsh-commandcode-provider
|
|
@@ -47,12 +50,12 @@ dsh plugin --profile web add @mars-sea/dsh-commandcode-provider
|
|
|
47
50
|
|
|
48
51
|
```sh
|
|
49
52
|
# Pin a release tag (recommended — readable and immutable)
|
|
50
|
-
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.
|
|
53
|
+
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.2
|
|
51
54
|
# Or pin any exact commit by its SHA
|
|
52
55
|
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#<full-commit-sha>
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
The `#<ref>` suffix pins
|
|
58
|
+
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.
|
|
56
59
|
|
|
57
60
|
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`:
|
|
58
61
|
|
|
@@ -61,21 +64,21 @@ allowBuilds:
|
|
|
61
64
|
'@mars-sea/dsh-commandcode-provider@github:Mars-Sea/dsh-commandcode-provider#<full-commit-sha>': true
|
|
62
65
|
```
|
|
63
66
|
|
|
64
|
-
and re-run the `add`.
|
|
67
|
+
and re-run the `add`.
|
|
65
68
|
|
|
66
69
|
### From a local checkout
|
|
67
70
|
|
|
68
71
|
```sh
|
|
69
72
|
npm install
|
|
70
|
-
npm run build # git
|
|
73
|
+
npm run build # git/tarball installs do this via `prepare` automatically
|
|
71
74
|
dsh plugin --profile web add /path/to/dsh-commandcode-provider
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
After changing `src/`, re-run `npm run build` and restart the app.
|
|
75
78
|
|
|
76
79
|
### What the install does
|
|
77
80
|
|
|
78
|
-
`dsh plugin add` links the package into the profile (pnpm records
|
|
81
|
+
`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:
|
|
79
82
|
|
|
80
83
|
```yaml
|
|
81
84
|
- insert:
|
|
@@ -85,7 +88,7 @@ A local path install links the checkout as-is, so after changing `src/` re-run `
|
|
|
85
88
|
apiKeyEnv: COMMANDCODE_API_KEY
|
|
86
89
|
```
|
|
87
90
|
|
|
88
|
-
The `name`
|
|
91
|
+
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](#troubleshooting)).
|
|
89
92
|
|
|
90
93
|
Verify the composed layer, then (re)start the web app:
|
|
91
94
|
|
|
@@ -96,77 +99,50 @@ dsh web # or restart your running instance
|
|
|
96
99
|
|
|
97
100
|
## Updating
|
|
98
101
|
|
|
99
|
-
The
|
|
100
|
-
|
|
101
|
-
Update according to how you installed it:
|
|
102
|
+
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.
|
|
102
103
|
|
|
103
104
|
```sh
|
|
104
|
-
#
|
|
105
|
+
# npm: always the latest published release
|
|
105
106
|
dsh plugin --profile web update @mars-sea/dsh-commandcode-provider
|
|
106
107
|
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
# and the bundle layer is re-read from the installed package on next boot)
|
|
110
|
-
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.1
|
|
108
|
+
# GitHub (pinned): point at the new tag — no uninstall needed, pnpm swaps it in place
|
|
109
|
+
dsh plugin --profile web add github:Mars-Sea/dsh-commandcode-provider#v0.2.2
|
|
111
110
|
|
|
112
|
-
#
|
|
111
|
+
# local checkout: pull, rebuild, restart
|
|
113
112
|
git -C /path/to/dsh-commandcode-provider pull
|
|
114
113
|
npm run build --prefix /path/to/dsh-commandcode-provider
|
|
115
114
|
dsh web
|
|
116
115
|
```
|
|
117
116
|
|
|
118
|
-
Then restart the web app
|
|
117
|
+
Then restart the web app. Verify with `dsh --profile web --dump-config` — the layer should show `name: '@mars-sea/dsh-commandcode-provider'`.
|
|
119
118
|
|
|
120
|
-
> **`update` says "Already up to date" but the version did not move (pnpm ≥ 11)?** pnpm 11's `minimumReleaseAge` supply-chain policy can refuse
|
|
121
|
-
>
|
|
122
|
-
> ```sh
|
|
123
|
-
> dsh plugin --profile web add @mars-sea/dsh-commandcode-provider@0.1.9
|
|
124
|
-
> ```
|
|
125
|
-
>
|
|
126
|
-
> `add` with an explicit version installs it (and moves your spec to `^0.1.9`). If you trust your registry you can also disable the gate with `pnpm config set minimumReleaseAge 0 --location project` inside the profile directory (or delete the `minimumReleaseAgeExclude` entry pnpm wrote into `pnpm-workspace.yaml`).
|
|
119
|
+
> **`update` says "Already up to date" but the version did not move (pnpm ≥ 11)?** pnpm 11's `minimumReleaseAge` supply-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` (or `pnpm config set minimumReleaseAge 0 --location project` inside the profile directory).
|
|
127
120
|
|
|
128
|
-
> **Upgrading from ≤0.1.6** (or a broken hand-edited profile):
|
|
121
|
+
> **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 to `name: "@mars-sea/dsh-commandcode-provider"` or remove it (see [Troubleshooting](#troubleshooting)).
|
|
129
122
|
|
|
130
|
-
> **To uninstall instead
|
|
123
|
+
> **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.json` are left untouched.
|
|
131
124
|
|
|
132
125
|
## Verify it works
|
|
133
126
|
|
|
134
|
-
After restart
|
|
127
|
+
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.
|
|
135
128
|
|
|
136
129
|
## Usage dashboard
|
|
137
130
|
|
|
138
|
-
The plugin registers a `/commandcode` slash command (requires the dsh `commands` service, present in the standard web profile)
|
|
131
|
+
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:
|
|
139
132
|
|
|
140
133
|
```text
|
|
141
134
|
/commandcode (or /commandcode status)
|
|
142
135
|
```
|
|
143
136
|
|
|
144
|
-
|
|
137
|
+

|
|
145
138
|
|
|
146
|
-
|
|
147
|
-
📊 Command Code 用量 (mars-sea)
|
|
148
|
-
|
|
149
|
-
── 请求 ──────────────────────────────
|
|
150
|
-
💬 请求 992 次 / 失败 0 成功率 100%
|
|
151
|
-
💰 花费 $1.4446 ($1.44 credits)
|
|
152
|
-
🔤 Token 205.3M 入 / 808.8K 出
|
|
153
|
-
|
|
154
|
-
── 信用 ──────────────────────────────
|
|
155
|
-
💳 月额度 $8.54 (已购 $0.00 / 赠送 $0.00)
|
|
156
|
-
└ ██████████ 100%
|
|
157
|
-
|
|
158
|
-
── 窗口用量 ──────────────────────────
|
|
159
|
-
⏱ 5 小时 $0.18 / $3.00
|
|
160
|
-
└ █░░░░░░░░░ 重置 8/15/2026, 2:39:36 PM
|
|
161
|
-
📅 每周 $1.46 / $6.00
|
|
162
|
-
└ ██░░░░░░░░ 重置 8/21/2026, 7:10:57 PM
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Each endpoint degrades independently: a temporary failure of one (e.g. the credits endpoint) leaves the rest visible and notes the failure inline.
|
|
139
|
+
Each endpoint degrades independently — a temporary failure of one leaves the rest visible and notes the failure inline.
|
|
166
140
|
|
|
167
141
|
## Configure
|
|
168
142
|
|
|
169
|
-
|
|
143
|
+
**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.
|
|
144
|
+
|
|
145
|
+
The same knobs live in `$DSH_HOME/settings.yaml` (per-request overrides, no restart):
|
|
170
146
|
|
|
171
147
|
```yaml
|
|
172
148
|
llm-commandcode:
|
|
@@ -175,59 +151,45 @@ llm-commandcode:
|
|
|
175
151
|
workingDir: /path/to/project # reported to the API (project slug, config block)
|
|
176
152
|
modelsCachePath: ~/.commandcode/models-cache.json
|
|
177
153
|
requestTimeoutMs: 60000 # max wait for the first response byte (default 60s)
|
|
178
|
-
streamIdleTimeoutMs:
|
|
154
|
+
streamIdleTimeoutMs: 300000 # stream stall before treated as dead (default 300s — generous, so long-thinking models are not cut off)
|
|
179
155
|
```
|
|
180
156
|
|
|
181
|
-
The composition-entry config (`cordis.patch.yml`
|
|
157
|
+
The composition-entry config (`cordis.patch.yml`) accepts the same keys; a literal `apiKey` there takes precedence over the credential reference.
|
|
182
158
|
|
|
183
159
|
## Troubleshooting
|
|
184
160
|
|
|
185
|
-
- **`Command Code API request to .../alpha/generate failed`
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
-
|
|
191
|
-
- **
|
|
192
|
-
-
|
|
193
|
-
- **`
|
|
194
|
-
- **The Models page card shows "not configured" but requests work** — the key came from `~/.commandcode/auth.json` (the `cmd login` fallback), not the dsh credential store. Paste it into the card once to make the card show as configured; both coexist fine.
|
|
195
|
-
- **A reasoning model returns no visible text on short requests** — reasoning models (e.g. `deepseek/deepseek-v4-*`) consume output tokens on reasoning first; a small `maxTokens` can be exhausted before any visible text. This is normal.
|
|
196
|
-
- **`allowBuilds` errors on `dsh plugin add` from git** — copy the exact package key pnpm printed (with the commit hash) into `pnpm-workspace.yaml` and re-run (see [Install](#from-github)).
|
|
161
|
+
- **`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.
|
|
162
|
+
- **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 past `streamIdleTimeoutMs` (300s by default) as dead. Both surface as `TIMEOUT` with the stall duration; tune the knobs for slow-but-stable networks.
|
|
163
|
+
- **"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 `streamIdleTimeoutMs` in the `llm-commandcode` section or on the settings page.
|
|
164
|
+
- **Boot crash: `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.
|
|
165
|
+
- **`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.
|
|
166
|
+
- **`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.
|
|
167
|
+
- **Models card shows "not configured" but requests work** — the key came from `~/.commandcode/auth.json` (the `cmd login` fallback), not the credential store. Paste it into the card once; both coexist fine.
|
|
168
|
+
- **A reasoning model returns no visible text on short requests** — it consumes output tokens on reasoning first; a small `maxTokens` can be exhausted before visible text. Normal.
|
|
169
|
+
- **`allowBuilds` errors on `dsh plugin add` from git** — copy the exact package key pnpm printed into `pnpm-workspace.yaml` and re-run (see [Install](#from-github)).
|
|
197
170
|
|
|
198
171
|
## Notes & limitations
|
|
199
172
|
|
|
200
|
-
- **Image input is model-gated**: only models the official
|
|
201
|
-
- **Switching to a text-only model in an image-bearing session is rejected by dsh itself** — a harness-level guard (`dsh-host-apiproxy`'s `selectModel`
|
|
202
|
-
- **No `stop` sequences
|
|
203
|
-
- Reasoning blocks are **not replayed** into later turns (matches the official CLI
|
|
204
|
-
-
|
|
205
|
-
- The model catalog endpoint is public; requests to `/alpha/generate` require the key above.
|
|
173
|
+
- **Image input is model-gated**: only models the official registry lists with Vision accept images (see `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**.
|
|
174
|
+
- **Switching to a text-only model in an image-bearing session is rejected by dsh itself** — a harness-level guard (`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`).
|
|
175
|
+
- **No `stop` sequences** (the wire format has none): requests carrying one throw `UNSUPPORTED_OPTION`.
|
|
176
|
+
- Reasoning blocks are **not replayed** into later turns (matches the official CLI); only tool calls with a paired tool result are replayed.
|
|
177
|
+
- The catalog endpoint is public; `/alpha/generate` requires your key.
|
|
206
178
|
|
|
207
179
|
## Permissions & privacy
|
|
208
180
|
|
|
209
|
-
This plugin operates entirely within your dsh profile and your Command Code account.
|
|
210
|
-
|
|
211
|
-
- **Local files**
|
|
212
|
-
- Reads `~/.commandcode/auth.json` (the official CLI login) **only** as a last-resort key fallback.
|
|
213
|
-
- Reads/writes `~/.commandcode/models-cache.json` (model catalog cache).
|
|
214
|
-
- Reads your API key from the dsh credential store (`$DSH_HOME/.credentials.yaml`) via the standard credential seam — the key is never logged or sent anywhere but the Command Code API.
|
|
215
|
-
- **Network**
|
|
216
|
-
- `GET {apiBase}/provider/v1/models` — public model catalog (no key required).
|
|
217
|
-
- `POST {apiBase}/alpha/generate` — the model requests themselves, authenticated with your key.
|
|
218
|
-
- The request body includes the `workingDir` (project path) you configure (defaults to the process cwd), sent as Command Code's `config.workingDir`.
|
|
219
|
-
- **No telemetry**: no analytics, no tracking, no third-party endpoints. The only outbound hosts are the Command Code API (`api.commandcode.ai` by default, configurable via `apiBase`).
|
|
181
|
+
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`).
|
|
220
182
|
|
|
221
183
|
## Disabling / uninstalling
|
|
222
184
|
|
|
223
|
-
- **Disable**
|
|
185
|
+
- **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.
|
|
224
186
|
- **Uninstall** completely:
|
|
225
187
|
|
|
226
188
|
```sh
|
|
227
189
|
dsh plugin --profile web remove @mars-sea/dsh-commandcode-provider
|
|
228
190
|
```
|
|
229
191
|
|
|
230
|
-
This removes the bundle dependency and its layer
|
|
192
|
+
This removes the bundle dependency and its layer; your API key in the dsh credential store and `~/.commandcode/auth.json` are left untouched.
|
|
231
193
|
|
|
232
194
|
## Development
|
|
233
195
|
|