dsh-packycode-api 1.3.3 → 1.3.5
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/AGENTS.md +10 -6
- package/CHANGELOG.md +24 -0
- package/README.en.md +52 -22
- package/README.md +52 -22
- package/SECURITY.md +14 -5
- package/compatibility.json +6 -4
- package/docs/assets/sponsor-alipay.png +0 -0
- package/docs/assets/sponsor-wechat.png +0 -0
- package/lib/client.js +334 -0
- package/lib/index.js +4697 -2421
- package/package.json +24 -15
package/AGENTS.md
CHANGED
|
@@ -16,6 +16,8 @@ This file governs the entire `dsh-packycode-api` repository.
|
|
|
16
16
|
- Host code belongs in `src/index.js` and its sibling modules; browser UI belongs in `src/client.jsx` and is built through the client wrapper in `tsdown.config.mjs`.
|
|
17
17
|
- The route is self-contained: the plugin builds its own pi-ai provider, catalog, key ring, and balance reader. It must never require the user to edit `cordis.patch.yml` or `llm-pi-ai` provider YAML.
|
|
18
18
|
- Never introduce a silent fallback to another provider, another credential source, or an ambient `PACKY_CODE_API_KEY`. Only keys the user added through this plugin may authenticate a request.
|
|
19
|
+
- Claude requests on keys in the `cc` group go through the official Claude Code CLI (`src/claude-cli-*.js`, `src/claude-mcp-bridge.js`); every other key uses HTTP. The CLI is only a transport: it must keep all of its own tools disabled, receive DSH's tools through the MCP bridge, and leave execution, permissions and plan mode to DSH. Never let it read the user's Claude settings, login or ambient keys, and never fall back between the CLI and HTTP routes on a failure. Changing the CLI's flags, environment or the continuation logic requires `node scripts/claude-check.mjs --transport cli` with a `cc` key. The key's groups alone pick the route; do not add a user switch between CLI and HTTP.
|
|
20
|
+
- The CLI must be at least `CLAUDE_MIN_VERSION` (`src/claude-binary.js`); raise it with any new flag the transport passes. The card's update runs `claude update` only for non-npm installs. An npm install is updated with npm and `--allow-scripts=@anthropic-ai/claude-code`: on npm 12, `claude update` there reports success and leaves no native binary, and it also deletes a native `~/.local/bin/claude` in the real home. Run experiments with downloaded or old CLIs under a scratch `HOME`.
|
|
19
21
|
- The catalog declares protocols and effort levels from vendor documentation. Changing a model's `api`, `baseUrl`, or `thinkingLevelMap` requires a note in `CHANGELOG.md` and a live check.
|
|
20
22
|
- The in-plugin update installs under the profile's own pnpm release-age policy. Never pass `--config.minimumReleaseAge` or edit `minimumReleaseAgeExclude` from the plugin. Bypassing the policy leaves a lockfile entry pnpm later rejects, and pnpm then refuses every plugin install in that profile until the version is 24 hours old. pnpm records an exact version it accepts early itself; a version it holds back is reported as pending.
|
|
21
23
|
|
|
@@ -52,6 +54,10 @@ Live gateway behavior is verified with `node scripts/live-check.mjs` after a bui
|
|
|
52
54
|
|
|
53
55
|
Never reuse, move, delete, or overwrite a published npm version or Git tag. If a published version needs a correction, create a new patch version.
|
|
54
56
|
|
|
57
|
+
## Old update buttons
|
|
58
|
+
|
|
59
|
+
`latest` is what the in-plugin update button and DSH's Plugins page install, and a tag publishes straight to it (checklist step 7). From 1.3.3 on, the button keeps pnpm's 24-hour release-age policy, and pnpm records an exact version it accepts early itself. Buttons up to 1.3.2 bypass the policy, so users still on those versions install the exact version on the Plugins page once instead, as both READMEs say; releases are not spaced out or staged for them. A broken release reaches `latest` at once: deprecate it on npm and publish a fixed patch version.
|
|
60
|
+
|
|
55
61
|
## Release checklist
|
|
56
62
|
|
|
57
63
|
1. Synchronize and confirm a clean base:
|
|
@@ -91,19 +97,17 @@ Never reuse, move, delete, or overwrite a published npm version or Git tag. If a
|
|
|
91
97
|
|
|
92
98
|
5. Commit the release and push `main` without force. [`.github/workflows/publish.yml`](.github/workflows/publish.yml) must already be on the commit that will be tagged. Do not push the tag in this step.
|
|
93
99
|
|
|
94
|
-
6. Confirm the package has a GitHub Actions trusted publisher before pushing the tag: repository `BaronCyrus/dsh-packycode-api`, workflow filename `publish.yml`, environment empty
|
|
100
|
+
6. Confirm the package has a GitHub Actions trusted publisher before pushing the tag: repository `BaronCyrus/dsh-packycode-api`, workflow filename `publish.yml`, environment empty. Never request that a token, password, or one-time code be pasted into chat.
|
|
95
101
|
|
|
96
|
-
7. Create the annotated tag and push it. That push publishes to npm's `
|
|
102
|
+
7. Create the annotated tag and push it. That push publishes to npm's `latest` with GitHub OIDC. The workflow's `release` job then creates the GitHub Release from `docs/releases/v<version>.md`, attaches the tarball npm published, and marks it Latest. It is the only job with `contents: write`, and it runs no dependency code. Do not run `npm publish` locally for a release. A local publish cannot attach provenance. Do not set `NODE_AUTH_TOKEN` or a setup-node `registry-url` in the publish workflow; npm treats either as token auth and skips OIDC.
|
|
97
103
|
|
|
98
104
|
```sh
|
|
99
105
|
git tag -a v<version> -m "dsh-packycode-api v<version>"
|
|
100
106
|
git push origin v<version>
|
|
101
107
|
```
|
|
102
108
|
|
|
103
|
-
`workflow_dispatch` on the same workflow prints the OIDC identity npm will match and does not publish.
|
|
104
|
-
|
|
105
|
-
8. Confirm that both jobs of the tag's publish run succeeded. Then check that npm's `next` serves the version (`npm view dsh-packycode-api dist-tags --prefer-online`; without `--prefer-online` a cached 404 can linger) and that `gh release view v<version>` shows the notes and the `dsh-packycode-api-<version>.tgz` asset. On an OIDC `package not found` error, fix the trusted publisher and re-run the same workflow. Do not move the tag. If the tagged tree itself must change, publish a new patch version.
|
|
109
|
+
`workflow_dispatch` on the same workflow prints the OIDC identity npm will match and does not publish.
|
|
106
110
|
|
|
107
|
-
|
|
111
|
+
8. Confirm that both jobs of the tag's publish run succeeded. Then check that npm's `latest` serves the version (`npm view dsh-packycode-api dist-tags --prefer-online`; without `--prefer-online` a cached 404 can linger, and for a few minutes after a publish the tarball URL itself can answer a CDN-cached 404, so check it with a `?t=<now>` query) and that `gh release view v<version>` shows the notes and the `dsh-packycode-api-<version>.tgz` asset, with `gh release list --json tagName,isLatest` marking it Latest. On an OIDC `package not found` error, fix the trusted publisher and re-run the same workflow. Do not move the tag. If the tagged tree itself must change, publish a new patch version.
|
|
108
112
|
|
|
109
113
|
If npm published but the release job failed, re-run only that failed job. If the Release must be made by hand, attach the tarball npm serves, not a local `.artifacts` build: CI packs its own, so the local bytes differ. Fetch it with `npm pack dsh-packycode-api@<version>`, and compare its SHA-512 with the registry's `dist.integrity`. Then run `gh release create v<version> <tarball> --verify-tag --title "<the notes' title>" --notes-file <the notes' body>`. The release job leaves an existing Release unchanged.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.5
|
|
4
|
+
|
|
5
|
+
- **An outdated Claude Code CLI is caught before the request, and the CLI card updates it.** 1.3.4 always passes `--permission-prompts none`, which Claude Code added in 2.1.259 (2026-09-02). A colleague's CLI from the official installer was 2.1.223 (2026-08-05): it rejected the option at start-up, every `cc` Claude turn failed with "the installed Claude Code CLI is too old", and the card still showed it as installed. The plugin now requires 2.1.259 or later. An older detected CLI is refused before it is started, with the detected and required versions; a cached detection that looks outdated is probed again first, so a CLI updated in a terminal is used at once. The card marks such a CLI **too old** and offers **Update Claude Code CLI**. A CLI from the official installer (or any install that is not npm's) is updated with `claude update`, run with the plugin's own CLI home and without the user's `ANTHROPIC_*` / `CLAUDE_*` / `DISABLE_*` variables. An npm global install is updated by npm itself — the npm beside the CLI, which owns its prefix — with `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`. The update succeeds only when the CLI detected afterwards is new enough; otherwise the card says whether it stayed old (for example a Homebrew install), stopped running, or could not download, with the command's output. The CLI's flags and environment for requests are unchanged.
|
|
6
|
+
- **The npm install allows Claude Code's install script.** npm 12 skips install scripts unless they are allowed, and `@anthropic-ai/claude-code` places its native binary in its postinstall, so the one-click `npm install -g @anthropic-ai/claude-code` left a CLI that only printed "claude native binary not installed". The install now passes `--allow-scripts=@anthropic-ai/claude-code`, as do the commands the card and error messages suggest; npm 10.9.9 and 11.21.1 accept the option and install a working CLI. `claude update` on an npm install has the same problem on npm 12 (it reported success from 2.1.223 to 2.1.303 and left no binary), which is why npm installs are updated through npm.
|
|
7
|
+
- **The Claude route can no longer be chosen.** The key's groups alone decide: a key in `cc` always sends Claude requests through the official CLI, and every other group uses HTTP. The CLI card's "By group / Always CLI / Always HTTP" switch, the `claudeTransport` setting and its RPC are removed; a value left in a profile is ignored. Pinning HTTP sent a `cc` key's requests where the gateway refuses them as a third-party client, and pinning the CLI made other keys need one.
|
|
8
|
+
- Validation, 2026-10-19: 458 offline tests (new: the version gate before start-up, the native and npm update paths with the user's Claude variables stripped, the still-old / broken / offline outcomes, npm-install detection, the card's outdated state, update progress and failure, and the removed route switch), both rebuilt bundles and the versioned tarball. Against real CLIs in scratch homes and npm prefixes, the built manager's `update()` took a native 2.1.223 to 2.1.303 through `claude update` (49 s) and an npm 2.1.223 to 2.1.303 through npm 12.0.2 (25 s), both with `DISABLE_AUTOUPDATER=1` and a user `CLAUDE_CONFIG_DIR` in the parent environment. Live with a `cc` key: `scripts/claude-check.mjs --transport cli --cli-path <2.1.223>` was refused before start-up with the new explanation and no request; the same check passed 15 of 15 through Claude Code 2.1.295 and 5 of 5 (Haiku) through 2.1.303. `scripts/live-check.mjs` passed for all ten models, key rotation and the RPC projections. The settings card was checked through the client tests, not in DeepSeek Harness.
|
|
9
|
+
- **Both READMEs end with a Support the author section** holding the maintainer's WeChat and Alipay tip codes, the same images as Aha Tutor's. The package ships both images so the README renders them wherever the package is read.
|
|
10
|
+
- **The staging leftovers are gone.** With 1.3.3 and 1.3.4 on `latest`, the hourly schedule, the `promote` and `mark-latest` jobs, `scripts/promote-release.mjs` and its tests are removed. Releases are no longer spaced 24 hours apart for update buttons up to 1.3.2: users on those versions install the exact version on the Plugins page once, as both READMEs say. The trusted publisher no longer needs **Allow npm dist-tag**, and npm's `next` tag stays at 1.3.4.
|
|
11
|
+
- **Releases go straight to npm's `latest` again.** Staging through `next`, added in 1.3.3, protected update buttons up to 1.3.2, which still bypass pnpm's release-age policy. Tags now publish to `latest`, and the GitHub Release is marked Latest at once. 1.3.3 and 1.3.4, already on `next`, still reach `latest` through the hourly promote job once each is 25 hours old; after that the job has nothing to do and is removed.
|
|
12
|
+
- **Upgrading from 1.3.2 or earlier: install the exact version on the Plugins page.** Both READMEs now say so. Updating with an old button to a version younger than 24 hours leaves the profile refusing every plugin install, including the next update, until that version is 24 hours old; an exact-version install lets pnpm record the exception instead. With DSH's bundled pnpm 11.28.5, a profile blocked that way refused the fixed button's update to another version, and pnpm still relinked `node_modules` to it while `package.json` and the lockfile kept the old one.
|
|
13
|
+
|
|
14
|
+
## 1.3.4
|
|
15
|
+
|
|
16
|
+
- **Keys in `cc` send Claude requests through the official Claude Code CLI again; `cc-sale`, `cc-expensive`, `claude-officially` and every other group keep the native HTTP route.** PackyCode's `cc` group only serves the official client, so the route now reads the request key's groups and hands those Claude requests to this device's Claude Code CLI. The delisted `claude-sale` group is not included until it returns. Unlike the 1.2 delegation, the CLI is only the transport: it runs with all of its own tools disabled, DSH's system prompt appended to its own, and DSH's tools for the turn listed through a per-process MCP bridge on 127.0.0.1 as `mcp__dsh__<name>`. Every call the model makes is executed by DSH — permissions, sandbox, plan mode and its review, questions, todos, subagents, image generation and tool cards are the same as over HTTP — and the result answers the call the CLI is holding open. The request itself is built once for both routes (DSH history, attachments, signed thinking and tool schemas through pi-ai), and the CLI's raw stream events come back as the same Anthropic SSE stream, so usage, replay, error classification and key rotation are unchanged.
|
|
17
|
+
- **One live CLI process per conversation.** A DSH session keeps one CLI process per model: the next step's tool results and the user's next turn continue it, so its requests share one cacheable prefix. A request that does not continue it (compaction, a plan-mode switch, another key or effort) gets a process resumed from DSH's own history through a CLI transcript; a mid-turn resume uses the CLI's interrupted-turn continuation. Session titles and compaction run in one-shot processes. Idle processes stop after 20 minutes, at most eight stay alive, and all stop when the plugin unloads.
|
|
18
|
+
- **The CLI is isolated and adds no behavior of its own.** It runs with its own config home (`~/.dsh/packycode-claude-cli`), no user/project settings, CLAUDE.md, auto-memory, slash commands, session persistence, auto-update or telemetry, and with inherited `ANTHROPIC_*` / `CLAUDE_*` variables removed. Only the plugin's selected key reaches it, as `ANTHROPIC_AUTH_TOKEN`. Its own retries, model and refusal fallbacks and compaction are off: one DSH step is one API request and retries follow DSH's policy. MCP idle timeouts and auto-backgrounding are disabled so a call can wait on a user's approval or plan review (a 400-second hold was verified).
|
|
19
|
+
- **Settings → PackyCode → Claude Code CLI** is back: install status and version, a one-click npm install, the live-process counters, and the Claude route — by group (default), always CLI, or always HTTP. Every key that reaches Claude shows which route its Claude requests take. `claudeTransport` and `claudeCliPath` are volatile settings; the 1.2 `claudeCliMode` / `claudeCliCwd` and the `claude_code` delegation tool stay removed.
|
|
20
|
+
- **CLI failures say what to do, once.** A missing CLI, a broken launcher or an outdated CLI that rejects an option are explained without a status code, so DSH does not retry them twenty times. A request the official CLI sent that the gateway still refuses as a client anomaly gets its own explanation with the gateway's words; quota and invalid-key failures relayed by the CLI rotate keys exactly as over HTTP. Nothing ever switches route or provider by itself.
|
|
21
|
+
- Validation, 2026-10-17: the real Claude Code CLI 2.1.295 was probed against a local gateway for every flag and behavior relied on (MCP `_meta` tool-use ids, sequential held calls, `--resume <file>`, interrupted-turn resume, stream-json events with signature deltas, error reporting, retries off). Live with a `cc` key through the CLI: Opus, Sonnet and Haiku each passed text, a native tool roundtrip continuing the same process, image input, a Chinese title and plan mode (inventory lookup → `exit_plan_mode` → approval) — 15 of 15 checks. The full plugin wiring in `auto` read the key's groups (`cc`, …), routed Claude through the CLI and passed Haiku and Sonnet tool roundtrips; the same key pinned to HTTP still passed. Offline: tests for the route policy, transcript, tool names, MCP bridge, process lifecycle through a protocol-faithful fake CLI, plugin wiring and the settings card.
|
|
22
|
+
- **Back-to-back releases no longer hold `latest` back.** The promote job only looked at the version `next` names, so a release published before the previous one was 25 hours old reset the wait, and a day of iteration left `latest` where it was. It now promotes the newest version after `latest`, up to `next`, that has aged 25 hours, so `latest` trails the newest release by about a day. A version deprecated on npm is never promoted, which is how a broken release is held back. AGENTS.md gains a "Staged releases" section so anyone iterating knows releases go through `next` and must not be published or moved to `latest` by hand.
|
|
23
|
+
- **DSH 0.2.1 (pi-ai 1.1.0) compatibility.** DSH 0.2.1 asks the route for a key before it lists models, and lists none without one. That question now only checks the ring for a usable key: with two or more keys, listing no longer waits up to six seconds for the first group reading (which held up DSH's whole model catalog, since it lists every provider together) and no longer sends the group probes. pi-ai 1.1.0 also hands the provider a transcript whose system message declares the offered tools as `toolsAdded` instead of `context.tools`, so the one-time replay of the gateway's captured Haiku/Sonnet client-anomaly and test-message refusals stopped recognizing a first tool request; it recognizes both shapes again. Without a usable key DSH 0.2.1 shows no PackyCode models; adding, removing or auto-disabling a key refreshes its model list through DSH's credential-record event. Live on 2026-10-17 against the packages DeepSeek Harness 0.2.1-rc.2 ships, its patched pi-ai included: `scripts/live-check.mjs` passed for all ten models (Claude over HTTP), key rotation and the RPC projections, and `scripts/claude-check.mjs --transport cli` passed all 15 checks (text, tool, image, title and plan on Opus, Sonnet and Haiku).
|
|
24
|
+
- **The plugin declares and is tested on the DSH 0.2.1 host.** The peer ranges add `@deepseek-ai/cordis` 4.0.5 and `@earendil-works/pi-ai` 1.1.0, and `compatibility.json` records 0.2.1-rc.2 as the latest tested host. The development dependencies are now the packages DeepSeek Harness 0.2.1-rc.2 ships (dsh-* 0.2.1-rc.2, cordis 4.0.5, schemastery 3.18.5, pi-ai 1.1.0); the connection and chat-image tests also run on 0.2.0-rc.2 through the host fixture, and their DSH 0.1.5 rows are gone. Tests that call the provider directly now hand it the context pi-ai's own `Models` would, and the host fixtures follow 0.2.1's PTC runtime, browser-auth and Chat bundle changes.
|
|
25
|
+
- Validation, 2026-10-17: 456 offline tests on the DSH 0.2.1-rc.2 packages (0.2.0-rc.2 through the host fixture), both rebuilt bundles and the versioned tarball; the same suite also passed against the packages extracted from the desktop app. Live through the built route on those packages: `scripts/live-check.mjs` for all ten models, key rotation and the RPC projections, and `scripts/claude-check.mjs --transport cli` with a `cc` key, 15 of 15. The maintainer then tried this build in DeepSeek Harness 0.2.1-rc.2 through the linked desktop profile.
|
|
26
|
+
|
|
3
27
|
## 1.3.3
|
|
4
28
|
|
|
5
29
|
- **The update button no longer bypasses pnpm's release-age policy.** It ran `pnpm add --config.minimumReleaseAge=0`, which switched the policy off for that one install, so pnpm never recorded the early version as an exception. The next plugin install in that profile then failed with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION` on the PackyCode entry until the version was 24 hours old; a user's `dsh-chat-manager` install was refused this way. Reproduced with DSH's bundled pnpm, which ran as 11.7.0 with a 24-hour default window. The button now installs the exact version under the profile's own policy. By default pnpm installs it at once and adds `dsh-packycode-api@<version>` to the profile's `minimumReleaseAgeExclude`, and later installs pass. Under a stricter policy pnpm refuses, and the button reports the version as pending, with the time it clears, instead of failing.
|
package/README.en.md
CHANGED
|
@@ -16,7 +16,7 @@ The `PackyCode` model group ships with the plugin. No YAML edits and no separate
|
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](https://github.com/BaronCyrus/dsh-packycode-api/stargazers)
|
|
18
18
|
|
|
19
|
-
[Features](#features) · [Install](#install) · [Daily use](#daily-use) · [Models and groups](#models-and-groups) · [Update and uninstall](#update-and-uninstall)
|
|
19
|
+
[Features](#features) · [Install](#install) · [Daily use](#daily-use) · [Models and groups](#models-and-groups) · [Update and uninstall](#update-and-uninstall) · [Support](#support-the-author)
|
|
20
20
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
@@ -29,7 +29,7 @@ The `PackyCode` model group ships with the plugin. No YAML edits and no separate
|
|
|
29
29
|
| **Keys used in order** | An exhausted or rejected key is disabled and the next usable key takes over; the failed step is retried on that key |
|
|
30
30
|
| **Keys chosen by group** | Each key lists its PackyCode groups and the models they reach; when the active key's groups cannot reach the selected model (no `cc` group for Claude, say), that turn runs on a stored key whose groups can |
|
|
31
31
|
| **Visible balance** | Settings lists each key's remaining, used, limit, reset period, and a usage bar. The composer shows the active key's remaining balance |
|
|
32
|
-
| **Claude
|
|
32
|
+
| **Claude route by group** | The `cc` group only serves the official client, so Claude requests on `cc` keys go through this device's Claude Code CLI; `cc-sale`, `cc-expensive`, `claude-officially` and other groups use the plugin's HTTP route. Either way DSH runs the tools and permissions, and plan mode, attachments and the full history behave the same |
|
|
33
33
|
| **Web search through PackyCode** | Optional: DSH's `web_search` searches through PackyCode, with a DeepSeek or GPT backend, for every request or for PackyCode models only |
|
|
34
34
|
| **Image generation and editing** | Separate image keys, GPT Image 2 / 2.5 Flare / 2.5 Sunburst, model and quality settings, reference edits and original PNG storage; generation and editing verified against the gateway |
|
|
35
35
|
| **Credentials stay on the machine** | Keys live in the DSH credential file. The browser receives labels, state, and balances only |
|
|
@@ -47,10 +47,10 @@ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH se
|
|
|
47
47
|
Open the desktop application's **Plugins** page, click **Add plugin**, and enter the package name **with a version** as the **package name or address**:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
|
-
dsh-packycode-api@1.3.
|
|
50
|
+
dsh-packycode-api@1.3.5
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Choose the **official** install source, then click **Install**. `1.3.
|
|
53
|
+
Choose the **official** install source, then click **Install**. `1.3.5` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
|
|
54
54
|
|
|
55
55
|
> **Always include the version.** With a bare `dsh-packycode-api`, the install prompt shows the newest version on npm, but DSH's bundled pnpm by default installs only versions published at least 24 hours ago, so you can end up several releases behind with no sign of it in the prompt. With an exact version, pnpm installs that version and adds it to the profile's `minimumReleaseAgeExclude` itself. Afterwards, check **Current version** under **Settings → PackyCode → Plugin version**.
|
|
56
56
|
|
|
@@ -71,7 +71,7 @@ Choose a model from the `PackyCode` group. All ten models use the plugin’s HTT
|
|
|
71
71
|
|
|
72
72
|
The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
|
|
73
73
|
|
|
74
|
-
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.
|
|
74
|
+
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.5`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
|
|
75
75
|
|
|
76
76
|
For a local checkout, keep the `link:` prefix: `dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`. **Do not pass a bare path or `file:`** — that install copies the whole checkout, `node_modules` included, into the profile, where it then shadows the packages the DSH installation itself provides and the plugin looks uninstalled; see the FAQ. If you already installed that way, uninstall first and reinstall as above.
|
|
77
77
|
|
|
@@ -89,7 +89,7 @@ A profile without a browser can still use the model route. It just has no settin
|
|
|
89
89
|
|
|
90
90
|
**Read the balance.** Each key under **Accounts and keys** shows its own remaining, used, and limit (limit = remaining + used); an unlimited key shows **No quota limit**. Keys are not added up into a total. An API key can read only its own quota, not the PackyCode account's balance, so check the account balance in the PackyCode console. A key that could not be read says why on its own row; a key whose read failed this time but succeeded before keeps showing its last balance with the time it was read (the composer shows it as `≈US$…`) until DSH restarts. The composer shows the active key's remaining balance only while a PackyCode model is selected. **Refresh** bypasses the roughly 60-second cache. The default model host is `https://cf.api.fan` and the balance host is `https://www.packyapi.ai`; both can be changed under **Advanced: endpoints**. The old default, `https://www.packyapi.com`, is DNS-poisoned on mainland networks and answers `fetch failed` without a proxy; even when settings still name it, `.ai` is tried first.
|
|
91
91
|
|
|
92
|
-
**Use Claude.** Select any Claude model
|
|
92
|
+
**Use Claude.** Select any Claude model. When the key is in the `cc` group, the plugin sends the request with this device's official Claude Code CLI, so install it first under **Settings → PackyCode → Claude Code CLI** (or run `npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code`), and click **Update Claude Code CLI** there when it is too old; keys in `cc-sale`, `cc-expensive`, `claude-officially` and other groups use the plugin's HTTP route and need no CLI. Under **Accounts and keys**, every key that reaches Claude is marked “Claude via official CLI” or “Claude via HTTP”; the groups alone decide the route, and it cannot be switched by hand. On both routes DSH executes every tool under its own permissions, and plan mode, questions, todos, subagents, attachments, reasoning effort and history behave as for any other model. See “Claude Code CLI route” below.
|
|
93
93
|
|
|
94
94
|
**Web search.** DSH's `web_search` calls DeepSeek's official API by default (billed to `DEEPSEEK_API_KEY`). **Settings → PackyCode → Web search** can route it through PackyCode instead:
|
|
95
95
|
|
|
@@ -125,12 +125,25 @@ PackyCode has no dedicated search endpoint: one search is one model call with a
|
|
|
125
125
|
<summary>When a key is rotated</summary>
|
|
126
126
|
|
|
127
127
|
- **Rotates and disables the current key:** the gateway reports exhausted quota, or it rejects the key (HTTP 401 / invalid token). The harness retries the failed step, which is what actually sends it on the next key.
|
|
128
|
-
- **Passes over a key by its groups, without disabling it:** when the group reading shows the active key cannot reach this turn's model and another stored key can, the turn runs on that key
|
|
128
|
+
- **Passes over a key by its groups, without disabling it:** when the group reading shows the active key cannot reach this turn's model and another stored key can, the turn runs on that key. The active key stays active for every other model. Only evidence counts: a key whose groups are not read yet is used as before.
|
|
129
129
|
- **Does not rotate:** rate limits (429); a 400 that this gateway uses for a dead upstream channel; and a 403 that means the group accepts only the vendor's official client. The separate 403 saying the client is already authorized and should not send connectivity test messages is classified as `GATEWAY_TEST_MESSAGE`. It explains the refusal without disabling the key. Only Haiku tool context may replay it once under the bounds below.
|
|
130
130
|
- When every stored key is disabled, the request fails and says so. There is no fallback credential.
|
|
131
131
|
|
|
132
132
|
</details>
|
|
133
133
|
|
|
134
|
+
### Claude Code CLI route
|
|
135
|
+
|
|
136
|
+
PackyCode's `cc` group (“claude code专用”) only serves the official Claude Code client. The plugin hands Claude requests on keys in that group to the real Claude Code CLI on this device. **The CLI is only the transport; DSH stays the agent:**
|
|
137
|
+
|
|
138
|
+
- **DSH executes every tool.** The CLI's own Bash, Read, Edit and other tools are all off. The tools DSH offers for the turn (including `exit_plan_mode`, `ask_user_question`, todos, subagents, MCP and image generation) reach the request as `mcp__dsh__<name>` through a local MCP bridge bound to 127.0.0.1. Each call the model makes comes back to DSH, with the same permission prompts, sandbox, plan review and tool cards as over HTTP, and its result goes to the CLI that is waiting for it.
|
|
139
|
+
- **DSH's prompt and history, unchanged.** DSH's system prompt is appended to the CLI's own; the history (text, images, signed thinking, tool calls and results) is written as a CLI transcript and resumed; the reasoning effort is passed as `--effort`.
|
|
140
|
+
- **One long-lived process per conversation.** A DSH session keeps one CLI process per model: tool results and the next user turn continue it, so requests keep one cacheable prefix. After compaction, a plan-mode switch or a key change, a new process is resumed from DSH's full history; session titles and compaction use one-shot processes. A process idle for 20 minutes stops; at most 8 stay alive.
|
|
141
|
+
- **Isolated from your own Claude Code.** It runs with its own config home, `~/.dsh/packycode-claude-cli`, and never reads `~/.claude` settings, CLAUDE.md, MCP configuration or logins; only the key stored in the plugin is passed to the child. Auto-update, telemetry, auto-compaction, auto-memory and model fallback are off, and retries are left to DSH's retry policy, which rotates keys.
|
|
142
|
+
- **An outdated CLI is one click away from current.** The plugin needs Claude Code 2.1.259 or later (the first release with the `--permission-prompts` option it passes). An older CLI is stopped before the request with an explanation, and the CLI card marks it too old and offers **Update Claude Code CLI**: an install from the official installer (`~/.local/bin/claude`) runs `claude update`; an npm global install runs `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`, because npm 12 skips install scripts by default and `claude update` does not allow them on an npm install, which leaves a CLI that cannot run. Your Claude Code is only updated when you click that button.
|
|
143
|
+
- **Failures say why.** A missing CLI, an outdated CLI, and a request from the official CLI that the gateway still refuses each get their own explanation; nothing switches to another route or provider, and no key is disabled.
|
|
144
|
+
|
|
145
|
+
Known differences: starting a process takes about 0.3–1 s; when a process is resumed in the middle of a tool turn, the CLI adds “Continue from where you left off.” after the tool results, as the official client does. Requires Claude Code 2.1.259 or later (tested with 2.1.295 and 2.1.303). On Windows, Claude Code also needs Git for Windows.
|
|
146
|
+
|
|
134
147
|
### Image generation and editing
|
|
135
148
|
|
|
136
149
|
Add the dedicated key under **Settings → PackyCode → Image generation and editing → Add an image key**. This credential record is separate from conversation keys. Image calls use only the selected image key. Adding one does not start a paid test.
|
|
@@ -164,7 +177,7 @@ Live checks on 2026-10-15 passed generation and editing at `low` on all three en
|
|
|
164
177
|
| `grok-4.7` (Grok 4.7) | HTTP, Responses, text/image input; 500K context | Cannot be off; `low` / `medium` / `high` / `xhigh` | The Grok coverage read from the gateway in Settings |
|
|
165
178
|
| `gemini-4-argon` (Gemini 4 Argon) | HTTP, native Gemini streaming, text/image input; 1,048,576 context, 65,536 output | Cannot be off; `low` / `medium` / `high` | `gemini-slb` |
|
|
166
179
|
| `gemini-3.8-flash` (Gemini 3.8 Flash) | HTTP, native Gemini streaming, text/image input; 1,048,576 input, 65,536 output | Cannot be off; `low` / `medium` / `high` | `gemini-slb` |
|
|
167
|
-
| `claude-opus-5-5` |
|
|
180
|
+
| `claude-opus-5-5` | Anthropic Messages, images and native tools: through this device's Claude Code CLI for `cc` keys, HTTP otherwise | Cannot be off; `low` / `medium` / `high` / `xhigh` / `max` | Claude-group coverage reported in Settings |
|
|
168
181
|
| `claude-sonnet-5-5` | Same | Same | Same |
|
|
169
182
|
| `claude-haiku-5-5` | Same; also generates Claude session titles | Same | Same |
|
|
170
183
|
|
|
@@ -183,25 +196,27 @@ Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit
|
|
|
183
196
|
<details>
|
|
184
197
|
<summary>Protocol, group and client compatibility</summary>
|
|
185
198
|
|
|
186
|
-
-
|
|
187
|
-
- Claude requests use the live-verified CLI-compatible headers, bearer authentication, session metadata and identity system prefix while preserving DSH instructions, tool schemas, images and signed replay. The compatibility version is pinned to `2.1.295
|
|
188
|
-
- The bearer comes only from the plugin’s stored key chosen for the model. No CLI login, external configuration, ambient key or alternate provider is used.
|
|
189
|
-
-
|
|
199
|
+
- Every model uses HTTP inside the plugin, except Claude requests on `cc` keys, which this device's Claude Code CLI sends. Claude keeps `anthropic-messages`, with a base URL without `/v1`; the SDK appends `/v1/messages`. Model ids, protocols, context limits and effort mappings are unchanged. Both routes share one request builder: DSH's history, attachments, tool schemas and signed replay become a Messages request first, then HTTP or the CLI sends it, and the CLI's raw stream events are parsed by the same protocol code.
|
|
200
|
+
- Claude requests over HTTP use the live-verified CLI-compatible headers, bearer authentication, session metadata and identity system prefix while preserving DSH instructions, tool schemas, images and signed replay. The compatibility version is pinned to `2.1.295`.
|
|
201
|
+
- The bearer comes only from the plugin’s stored key chosen for the model; the CLI route passes that same key to the child as `ANTHROPIC_AUTH_TOKEN` and clears inherited `ANTHROPIC_*` / `CLAUDE_*` variables. No CLI login, external configuration, ambient key or alternate provider is used.
|
|
202
|
+
- The key's groups alone decide the route: it cannot be pinned, and a refusal never switches routes on its own. A key whose groups are not read yet uses HTTP, and a Claude request waits up to about 6 seconds for the first group reading. Client-policy refusals are explained without disabling a key. Server changes may invalidate the envelope; see [PackyCode group policy](https://docs.packyapi.ai/docs/token/).
|
|
190
203
|
- Identical Haiku and Sonnet tool requests have been both refused with the captured client-anomaly 403 and accepted. The plugin waits one second and repeats the unchanged request once for that response. Haiku also covers the captured already-authorized/test-message 403, sharing the same one-replay limit. A second refusal remains visible. Opus, plain text, ordinary official-CLI-only refusals, 429s and accepted streams do not trigger this replay. Records retain the original failures; this does not establish a repair of the gateway's internal classifier.
|
|
191
204
|
- Claude streams finish at `message_stop` without waiting for the gateway to close the HTTP body, and CRLF delimiters remain intact across network chunks. Stream errors and cancellation still surface; waiting for response headers is not counted as success.
|
|
192
|
-
- Offered DSH bash/read/write/edit/glob/grep tools use canonical CLI names such as `Bash` and `Read` over HTTP; other tools use MCP names. Only aliases declared for the current request regain their original names before DSH dispatch; unknown names never grant execution. Arguments, call IDs, results and signed history remain intact. Thinking display follows the CLI defaults: `omitted` for Haiku and `updates` with its required beta for Sonnet and Opus. Reasoning effort and output limits remain unchanged, signatures on empty thinking blocks survive replay, and explicit display options take precedence.
|
|
205
|
+
- Offered DSH bash/read/write/edit/glob/grep tools use canonical CLI names such as `Bash` and `Read` over HTTP; other tools use MCP names. Through the CLI every DSH tool is offered as `mcp__dsh__<name>`, and the end of the system prompt says the CLI's own tools are unavailable. Only aliases declared for the current request regain their original names before DSH dispatch; unknown names never grant execution. Arguments, call IDs, results and signed history remain intact. Thinking display follows the CLI defaults: `omitted` for Haiku and `updates` with its required beta for Sonnet and Opus. Reasoning effort and output limits remain unchanged, signatures on empty thinking blocks survive replay, and explicit display options take precedence.
|
|
193
206
|
- When the legacy working-directory sentence agrees with the initiating session metadata, Claude receives the exact path as a separate JSON string. Sentence punctuation stays outside the path; real trailing dots, Windows drive/UNC paths, spaces and backslashes remain intact. Commands are never trimmed or rewritten. Shell guidance prefers the current directory or `workdir`, preserving PowerShell syntax for Windows tools.
|
|
194
|
-
-
|
|
195
|
-
- The
|
|
207
|
+
- Claude turns on both routes retain the full DSH tool loop, permissions and plan mode, using host search and image tools. Claude titles use Haiku on the same route as the conversation; GPT-6 Astra and GPT-5.6 Sol titles use GPT-6.1 Sol.
|
|
208
|
+
- The 1.2 `claude_code` delegation tool and the `claudeCliMode` / `claudeCliCwd` settings do not return: the CLI is now a transport and never replaces DSH's tools with its own. `claudeCliPath` applies again and names the CLI (empty means the usual install places, then PATH). 1.3.4's `claudeTransport` is removed, and a value left in a profile is ignored. Separately installed Claude Code is only modified when you click **Update Claude Code CLI** in the CLI card.
|
|
196
209
|
- Codex Responses requests still need `prompt_cache_key`; the plugin supplies a missing session identity. Other Responses families omit it.
|
|
197
|
-
- After building, `node scripts/claude-check.mjs` checks all three Claude models on order totals, support triage, replenishment, read-only inventory tool roundtrips, product color labels and
|
|
210
|
+
- After building, `node scripts/claude-check.mjs` checks all three Claude models on order totals, support triage, replenishment, read-only inventory tool roundtrips, product color labels, Chinese titles and plan mode (read-only lookup → plan submitted with `exit_plan_mode` → approval), validating the business answers; `--transport cli` sends all of it through this device's Claude Code CLI. `node scripts/claude-stability.mjs --start --hours 6 --key-label <label>` starts a deadline- and request-budget-limited window. Invoke the same script on a schedule to sample again; `--status` reads the record. Each round records its build and scenario version. A test-message policy refusal fails that check while the other scheduled checks continue; real credential or quota failures still stop the window. Checks never change stored credentials or start DSH.
|
|
198
211
|
- For continuous dialogs, use `node scripts/claude-conversation-check.mjs --model claude-haiku-5-5 --rounds 3 --key-label <label> --output .artifacts/claude-conversation.json`. One plugin adapter handles independent sessions; each group retains six user turns and full tool history, validates arithmetic, final JSON and unexpected characters, and stops on a failure without discarding evidence. Requests default to 65 seconds and 2048 output tokens. Diagnostic overrides use `--timeout-ms` (5000–300000) and `--max-tokens` (1024–128000). `--capture-wire` records the synthetic business requests, non-authentication headers and partial stream events for exact replay, without keys. Reports include scenario and adapter lifecycle, configured limits, response-header latency and total response time. These options do not alter the plugin's runtime settings.
|
|
199
212
|
|
|
200
213
|
</details>
|
|
201
214
|
|
|
202
215
|
## Update and uninstall
|
|
203
216
|
|
|
204
|
-
**
|
|
217
|
+
> **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.3.5` on the Plugins page instead of clicking **Update plugin** in the old settings card. The old button bypasses pnpm's release-age policy: if the version it installs is less than 24 hours old, the profile refuses every other plugin install until that version is 24 hours old. After the install and a restart, the button is the fixed one, and later updates can use it.
|
|
218
|
+
|
|
219
|
+
**Update:** open **Settings → PackyCode** and, when a newer version is listed, click **Update plugin**. It installs that exact version into the owning profile with DSH's bundled pnpm and reads `package.json` back before reporting success. The install keeps pnpm's release-age policy instead of overriding it: by default pnpm installs the version at once and records it in the profile's `minimumReleaseAgeExclude`; under a stricter pnpm policy the button says when the update can run. A local `link:` checkout does not get the button. Then quit and reopen the desktop application. A page refresh does not reload the Host. Reinstalling from the **Plugins** page works too, again with the version in the package name (for example `dsh-packycode-api@1.3.5`); without it you may get a version that is merely the newest one published at least 24 hours ago.
|
|
205
220
|
|
|
206
221
|
**Coming back from a local-path install, uninstall first.** An update is a `pnpm add`: it rewrites the files inside the package directory and leaves a `node_modules` that an earlier local-path install left there. That older tree keeps shadowing the packages the DSH installation provides, so the plugin row fails to load with no visible reason. **Uninstall** runs `pnpm remove`, which deletes the package directory outright — only a reinstall after that is clean. `node scripts/install-check.mjs` reports whether a profile is in that state.
|
|
207
222
|
|
|
@@ -217,7 +232,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
217
232
|
|
|
218
233
|
Output means a leftover tree: a registry install ships no `node_modules`, so this one usually comes from an earlier local-path install (`file:`, or a bare path instead of `link:`). It sits inside the profile directory, and DSH resolves a plugin's imports from inside the profile first, so the plugin gets those old copies — for example `@deepseek-ai/schemastery` 3.18.2, which has no `Schema.volatile()`, so the module throws while it is imported. When an import fails the Loader creates no fiber for that row and no client bundle is composed either, so the model route, the RPC channel, and the settings panel all stay absent.
|
|
219
234
|
|
|
220
|
-
Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.3.
|
|
235
|
+
Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.3.5`), then quit and reopen the desktop application. Uninstall runs `pnpm remove` and deletes the whole package directory; reinstalling or clicking **Update** only rewrites files and keeps the leftover tree. Deleting that `node_modules` by hand and restarting works too.
|
|
221
236
|
|
|
222
237
|
**Right after a first install, every card in Settings shows `transport failure for /packycode-api/…: HTTP 405`?** The installed version is 1.1.6 or earlier, usually because only the bare package name was entered: the install prompt shows the newest version, but pnpm installs the newest one published at least 24 hours ago (see **Install the plugin**). Those older versions can register their settings channel only after DSH restarts and rebuilds its `connection` service. So right after a first install `/packycode-api` does not exist yet, requests fall through to the static page, and it answers 405; the model route and the settings panel itself load normally. From 1.1.7 on, a first install needs no restart. Check which version was installed:
|
|
223
238
|
|
|
@@ -231,25 +246,29 @@ Recovery: quit and reopen the desktop application, and the old version works. Th
|
|
|
231
246
|
|
|
232
247
|
**One model fails, but the key is valid?** Look at that key's groups and ✓ / ✕ under **Accounts and keys**. When its groups do not cover the model, use a key whose groups do, or add the group to the key in the PackyCode console. With such a key stored, the plugin runs that model on it automatically. A group refusal never disables a key.
|
|
233
248
|
|
|
234
|
-
**Claude reports an official-client-only or client-anomaly refusal?** This is a gateway client-policy refusal, not proof of an invalid key.
|
|
249
|
+
**Claude reports an official-client-only or client-anomaly refusal?** This is a gateway client-policy refusal, not proof of an invalid key. See whether the key is marked “Claude via HTTP” or “via official CLI”: a `cc` key always uses the CLI, and other groups use HTTP. When a request the official CLI sent is still refused, the error carries the gateway's own words (with the request id); update Claude Code (`claude update`) and retry, then send it to PackyCode support if it persists. The plugin does not disable the key or switch providers.
|
|
250
|
+
|
|
251
|
+
**“Claude Code CLI is not available”?** The key is in `cc`, which needs the CLI on this device. Under **Settings → PackyCode → Claude Code CLI** click Install, or run `npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code` and click Check again; set `claudeCliPath` for an unusual location. Otherwise use a `cc-sale` / `cc-expensive` key.
|
|
252
|
+
|
|
253
|
+
**“The installed Claude Code CLI is too old”?** This device's CLI is older than 2.1.259. Under **Settings → PackyCode → Claude Code CLI** click **Update Claude Code CLI**, then resend; or run `claude update` in a terminal (for an npm install, the npm command the card shows) and click Check again. For a Homebrew install, run `brew upgrade claude-code`.
|
|
235
254
|
|
|
236
255
|
**The balance does not match the account bill?** Settings shows only each key stored here, with its own quota, not other tokens on the same PackyCode account. An API key cannot read the account's balance; check it in the PackyCode console. A key that failed to read says so on its own row.
|
|
237
256
|
|
|
238
257
|
**The balance reads `fetch failed` from `https://www.packyapi.com`?** That host, the default through 1.0.4, is DNS-poisoned on mainland networks and only answers through a proxy, so it works on and off. The default is now `https://www.packyapi.ai`. The model list is built into the plugin and never queried from PackyCode, so it is unaffected.
|
|
239
258
|
|
|
240
|
-
**A Claude model stays on “thinking”?** Check DSH errors or diagnostics. HTTP 429/503 means gateway queueing or throttling and follows the host retry policy; client-policy refusals are explained directly.
|
|
259
|
+
**A Claude model stays on “thinking”?** Check DSH errors or diagnostics. HTTP 429/503 means gateway queueing or throttling and follows the host retry policy; client-policy refusals are explained directly. Only Claude requests on the CLI route start the local Claude Code CLI, which is stopped and reported if it prints nothing for 90 seconds.
|
|
241
260
|
|
|
242
261
|
**A rate limit disabled the key?** It should not. HTTP 429 does not rotate. Exhausted quota or HTTP 401 does; after a top-up, click **Re-enable**.
|
|
243
262
|
|
|
244
263
|
**Installing from the Plugins page fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** By default pnpm accepts only versions published at least 24 hours ago and checks the whole profile lockfile. (Entering only this plugin's bare name does not raise this error; it silently installs an older version that has passed 24 hours instead, see **Install the plugin**.) The package it names is often another plugin that was just updated, not this one. Retry once it is 24 hours old, or add the reported `name@version` under `minimumReleaseAgeExclude` in the profile's `pnpm-workspace.yaml`. Once this plugin is installed, **Update plugin** in Settings is not subject to that check.
|
|
245
264
|
|
|
246
|
-
**Do I
|
|
265
|
+
**Do I need Claude Code installed?** Only for Claude models on a `cc` key. The plugin runs it with its own config home and never touches your Claude Code login or settings; it updates the installation only when you click **Update Claude Code CLI**. Other groups and models do not need it.
|
|
247
266
|
|
|
248
267
|
**Replies stop at the output token limit (已达到输出 token 上限), or requests keep failing — how do I report it?** Open **Settings → PackyCode → Diagnostics**, pick the session (the 20 most recent, newest first, labelled with their folder name), click **Generate diagnostics** and then **Copy**, and paste the text into an [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues) or send it to the plugin author. It holds settings and numbers only: the plugin version, the session id and start time, each key's position and groups (no labels, no keys), each request's model, reasoning effort and output limit, the latest steps' token usage and finish reasons, and retry and failure codes (messages redacted and shortened). It contains no conversation text, file paths or keys. Where copying is unavailable, the text is selected instead; press ⌘C or Ctrl+C.
|
|
249
268
|
|
|
250
269
|
## Security and scope
|
|
251
270
|
|
|
252
|
-
This is a community plugin, not affiliated with or endorsed by DeepSeek or PackyCode. Model requests go to the PackyCode host you configured. Keeping credentials out of browser responses does not mean inference is local. Claude
|
|
271
|
+
This is a community plugin, not affiliated with or endorsed by DeepSeek or PackyCode. Model requests go to the PackyCode host you configured. Keeping credentials out of browser responses does not mean inference is local. Claude requests on `cc` keys are sent by a local Claude Code CLI child process: the key reaches it only through its environment, DSH's tools are offered through an MCP bridge bound to 127.0.0.1 behind a random capability, and the tools themselves still run in DSH on the host.
|
|
253
272
|
|
|
254
273
|
Keys stay in the local DSH credential file (`~/.dsh/.credentials.yaml`, owner-only as enforced by DSH). They are not written into settings, logs, or the transcript. Balance requests run only on the host, with a timeout and redirects refused.
|
|
255
274
|
|
|
@@ -275,3 +294,14 @@ Read [AGENTS.md](AGENTS.md) before agent-assisted changes or a release. Publishi
|
|
|
275
294
|
## License
|
|
276
295
|
|
|
277
296
|
[MIT](LICENSE)
|
|
297
|
+
|
|
298
|
+
## Support the author
|
|
299
|
+
|
|
300
|
+
This plugin is free and open source, and tips are entirely optional. If it saved you some hassle using PackyCode in DSH, a tip helps keep it current with new models and new DSH releases.
|
|
301
|
+
|
|
302
|
+
<table align="center">
|
|
303
|
+
<tr>
|
|
304
|
+
<td align="center"><img src="docs/assets/sponsor-wechat.png" width="200" alt="WeChat tip code"><br><b>WeChat</b></td>
|
|
305
|
+
<td align="center"><img src="docs/assets/sponsor-alipay.png" width="200" alt="Alipay payment code"><br><b>Alipay</b></td>
|
|
306
|
+
</tr>
|
|
307
|
+
</table>
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](https://github.com/BaronCyrus/dsh-packycode-api/stargazers)
|
|
18
18
|
|
|
19
|
-
[功能](#功能) · [安装](#安装) · [日常使用](#日常使用) · [模型与分组](#模型与分组) · [更新与卸载](#更新与卸载)
|
|
19
|
+
[功能](#功能) · [安装](#安装) · [日常使用](#日常使用) · [模型与分组](#模型与分组) · [更新与卸载](#更新与卸载) · [支持作者](#支持作者)
|
|
20
20
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
| **多 Key 按顺序使用** | 额度用尽或 Key 被拒绝时自动切到下一个可用 Key;失败的那一步由重试接手 |
|
|
30
30
|
| **按分组选 Key** | 每个 Key 后面列出它所在的 PackyCode 分组和能用的模型;当前 Key 的分组用不了所选模型(例如没有 cc 分组却选了 Claude)时,这一轮自动改用分组合适的 Key |
|
|
31
31
|
| **余额一眼可见** | 设置页列出每个 Key 的剩余、已用、额度、重置周期和用量条;输入框右侧显示当前 Key 的剩余额度 |
|
|
32
|
-
| **Claude
|
|
32
|
+
| **Claude 按分组选通道** | `cc` 分组只接受官方客户端,这些 Key 的 Claude 请求由本机 Claude Code CLI 发出;`cc-sale`、`cc-expensive`、`claude-officially` 等分组走插件内 HTTP。两条通道都由 DSH 执行工具、审批权限,计划模式、附件和完整对话历史完全一致 |
|
|
33
33
|
| **网页搜索可走 PackyCode** | 可选:DSH 的 `web_search` 改用 PackyCode 搜索,后端在 DeepSeek 与 GPT 之间切换;可只对 PackyCode 模型生效 |
|
|
34
34
|
| **图片生成与编辑** | 独立图片 Key,支持 GPT Image 2 / 2.5 Flare / 2.5 Sunburst、型号与质量设置、参考图编辑和 PNG 原图保存;已通过网关生图与编辑实测 |
|
|
35
35
|
| **凭据不离开本机** | Key 只存在 DSH 凭据文件里。浏览器只能看到备注、状态和余额,拿不到 Key |
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
|
-
dsh-packycode-api@1.3.
|
|
50
|
+
dsh-packycode-api@1.3.5
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
在**安装源**中选择**官方源**,然后点击**安装**。`1.3.
|
|
53
|
+
在**安装源**中选择**官方源**,然后点击**安装**。`1.3.5` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
|
|
54
54
|
|
|
55
55
|
> **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
|
|
56
56
|
|
|
@@ -71,7 +71,7 @@ dsh-packycode-api@1.3.3
|
|
|
71
71
|
|
|
72
72
|
桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
|
|
73
73
|
|
|
74
|
-
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.
|
|
74
|
+
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.5`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
|
|
75
75
|
|
|
76
76
|
本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
|
|
77
77
|
|
|
@@ -89,7 +89,7 @@ dsh-packycode-api@1.3.3
|
|
|
89
89
|
|
|
90
90
|
**看余额。** 「账户与 Key」里每个 Key 显示它自己的剩余、已用与额度(额度 = 剩余 + 已用),不限额的 Key 显示「不限额度」;多个 Key 不相加成合计。API Key 只能读到自己的额度,读不到 PackyCode 账号的总余额,账号余额请到 PackyCode 控制台查看。读失败的 Key 会在它那一行注明原因;某个 Key 这次读失败但之前读到过,会继续显示上次的余额并注明读取时间(输入框里显示为 `≈US$…`),重启 DSH 后才清空。输入框右侧只在选中 PackyCode 模型时显示当前 Key 的剩余额度。「刷新」会跳过约 60 秒的缓存。默认模型接口是 `https://cf.api.fan`,余额接口是 `https://www.packyapi.ai`,可在「高级:接口地址」里改。旧默认值 `https://www.packyapi.com` 在国内网络下 DNS 被污染、直连会 `fetch failed`,即使设置里保存的是它,插件也会先试 `.ai`。
|
|
91
91
|
|
|
92
|
-
**用 Claude。** 直接选择三个 Claude
|
|
92
|
+
**用 Claude。** 直接选择三个 Claude 模型之一。Key 在 `cc` 分组时,插件用本机的官方 Claude Code CLI 发出请求,需要先在 **设置 → PackyCode → Claude Code CLI** 一键安装(或自行 `npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code`),版本过低时在同一处点「更新 Claude Code CLI」;`cc-sale`、`cc-expensive`、`claude-officially` 等分组直接走插件内 HTTP,不需要 CLI。「账户与 Key」里每个能用 Claude 的 Key 会标出「Claude 经官方 CLI」或「Claude 经 HTTP」,通道只由分组决定,不能手动切换。无论哪条通道,工具都由 DSH 执行并按 DSH 的权限审批,计划模式、提问、待办、子代理、附件、思考档位和历史都和其它模型一样。详见下方「Claude Code CLI 通道」。
|
|
93
93
|
|
|
94
94
|
**网页搜索。** DSH 的 `web_search` 默认调用 DeepSeek 官方接口(用 `DEEPSEEK_API_KEY` 计费)。在 **设置 → PackyCode → 网页搜索** 里可以改走 PackyCode:
|
|
95
95
|
|
|
@@ -125,12 +125,25 @@ PackyCode 没有专用搜索接口:一次搜索就是一次带服务端搜索
|
|
|
125
125
|
<summary>什么时候会自动切换 Key</summary>
|
|
126
126
|
|
|
127
127
|
- **会切换并停用当前 Key:** 额度用尽(网关报额度、余额、insufficient quota 之类),或 Key 被拒绝(HTTP 401 / `无效的令牌`)。失败的那一步由 harness 重试,从而用上新 Key。
|
|
128
|
-
- **按分组改用,不停用:** 分组读数显示当前 Key 用不了这一轮的模型、而另一个 Key 能用时,这一轮直接用那个 Key
|
|
128
|
+
- **按分组改用,不停用:** 分组读数显示当前 Key 用不了这一轮的模型、而另一个 Key 能用时,这一轮直接用那个 Key。「使用中」的 Key 不变,其它模型照常用它。只在有证据时才改用:分组还没读到的 Key 照旧使用。
|
|
129
129
|
- **不会切换:** 限速(429);网关把上游渠道故障误报成 400(`当前令牌未覆盖供应商 …`);以及「只允许官方客户端」的 403。网关表示「客户端已授权,无需发送连通性测试消息」的 403 单独记为 `GATEWAY_TEST_MESSAGE`,直接说明请求被当作测试消息拒绝,不禁用 Key。仅 Haiku 工具上下文可按下方规则原样重发一次。
|
|
130
130
|
- 全部 Key 都停用时,请求失败并说明没有可用 Key,不会回退到别的凭据。
|
|
131
131
|
|
|
132
132
|
</details>
|
|
133
133
|
|
|
134
|
+
### Claude Code CLI 通道
|
|
135
|
+
|
|
136
|
+
PackyCode 的 `cc` 分组(「claude code专用」)只接受官方 Claude Code 客户端。插件把这个分组的 Key 的 Claude 请求交给本机真实的 Claude Code CLI 发出,**CLI 只负责传输,Agent 仍然是 DSH**:
|
|
137
|
+
|
|
138
|
+
- **工具全部由 DSH 执行。** CLI 自带的 Bash、Read、Edit 等工具全部关闭;DSH 本轮提供的工具(包括 `exit_plan_mode`、`ask_user_question`、待办、子代理、MCP、生图等)通过只监听 127.0.0.1 的本机 MCP 桥,以 `mcp__dsh__<工具名>` 出现在请求里。模型发起的调用交回 DSH 执行,权限审批、沙箱、计划模式的审阅界面和工具卡片都与 HTTP 通道相同,结果再交给等待中的 CLI。
|
|
139
|
+
- **提示与历史保持 DSH 原样。** DSH 的系统提示追加在 CLI 官方提示之后;历史(文字、图片、带签名的思考、工具调用与结果)由插件写成 CLI 的会话记录后续接,思考档位以 `--effort` 传入。
|
|
140
|
+
- **一个会话一个常驻进程。** 同一个 DSH 会话、同一模型复用一个 CLI 进程:工具结果和下一轮消息直接续接,请求前缀不变,网关缓存照常命中。历史被压缩、切换计划模式或换 Key 时,用 DSH 的完整历史恢复一个新进程;会话标题和压缩用一次性进程。空闲 20 分钟的进程自动结束,最多同时保留 8 个。
|
|
141
|
+
- **与你自己的 Claude Code 隔离。** 使用独立配置目录 `~/.dsh/packycode-claude-cli`,不读取 `~/.claude` 的设置、CLAUDE.md、MCP 配置和登录状态;只把插件保存的 Key 交给子进程。自动更新、遥测、自动压缩、自动记忆和模型回退都关闭,失败重试交还给 DSH 的重试策略(会按 Key 轮换)。
|
|
142
|
+
- **版本过低一键更新。** 插件需要 Claude Code 2.1.259 或更新版本(插件传入的 `--permission-prompts` 从这一版开始提供)。更旧的 CLI 在请求发出前就被拦下并说明原因,CLI 卡片标出「版本过低」并提供「更新 Claude Code CLI」:官方安装器(`~/.local/bin/claude`)装的执行 `claude update`;npm 全局安装的执行 `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`,因为 npm 12 默认不运行安装脚本,而 `claude update` 在 npm 安装上不会放行脚本,会留下一个无法运行的 CLI。只有点这个按钮时才会更新你的 Claude Code。
|
|
143
|
+
- **出错会说清原因。** 未安装 CLI、CLI 版本过旧、官方 CLI 发出的请求仍被网关拒绝,分别给出说明和下一步,不会改走其它通道或提供商,也不会停用 Key。
|
|
144
|
+
|
|
145
|
+
已知差异:新进程启动约 0.3–1 秒;在一轮工具调用中途恢复进程时,CLI 会按官方行为在工具结果后附上一句 “Continue from where you left off.”。需要 Claude Code 2.1.259 或更新版本(实测 2.1.295 与 2.1.303)。Windows 上 Claude Code 还需要 Git for Windows。
|
|
146
|
+
|
|
134
147
|
### 图片生成与编辑
|
|
135
148
|
|
|
136
149
|
在 **设置 → PackyCode → 图片生成与编辑 → 添加图片 Key** 填入专用 Key。它与「账户与 Key」里的对话 Key 分开保存;图片请求只用此处选择的 Key。添加 Key 不会自动发起付费测试。
|
|
@@ -164,7 +177,7 @@ Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具
|
|
|
164
177
|
| `grok-4.7`(Grok 4.7) | HTTP,Responses,可带图;500k 上下文 | 不能关;`low` / `medium` / `high` / `xhigh` | 以设置页从网关读取的 Grok 分组覆盖为准 |
|
|
165
178
|
| `gemini-4-argon`(Gemini 4 Argon) | HTTP,Gemini 原生流式,可带图;1,048,576 上下文,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
166
179
|
| `gemini-3.8-flash`(Gemini 3.8 Flash) | HTTP,Gemini 原生流式,可带图;1,048,576 输入,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
167
|
-
| `claude-opus-5-5` |
|
|
180
|
+
| `claude-opus-5-5` | Anthropic Messages,可带图和原生工具:`cc` 分组经本机 Claude Code CLI,其它分组走 HTTP | 不能关;`low` / `medium` / `high` / `xhigh` / `max` | 以设置页读取的 Claude 分组覆盖为准 |
|
|
168
181
|
| `claude-sonnet-5-5` | 同上 | 同上 | 同上 |
|
|
169
182
|
| `claude-haiku-5-5` | 同上;Claude 会话标题固定走它 | 同上 | 同上 |
|
|
170
183
|
|
|
@@ -183,25 +196,27 @@ Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses
|
|
|
183
196
|
<details>
|
|
184
197
|
<summary>协议、分组与客户端兼容性</summary>
|
|
185
198
|
|
|
186
|
-
-
|
|
187
|
-
- Claude 请求带上实测通过的 CLI 兼容请求头、Bearer 认证、会话元数据和身份系统提示前缀,并保留原始 DSH 系统说明、工具 schema、附件及签名回放。兼容版本固定为 `2.1.295
|
|
188
|
-
- Bearer 只来自插件保存并按模型选中的 Key
|
|
189
|
-
-
|
|
199
|
+
- 除 `cc` 分组 Key 的 Claude 请求经本机 Claude Code CLI 发出外,其余模型均在插件内通过 HTTP 调用。Claude 使用 `anthropic-messages`,base URL 不带 `/v1`;SDK 会拼出 `/v1/messages`。模型、协议、上下文和档位映射保持不变。两条通道共用同一套请求构建:DSH 历史、附件、工具 schema 和签名回放先由插件转换成 Messages 请求,再交给 HTTP 或 CLI 发送,CLI 返回的原始流事件按同一协议解析。
|
|
200
|
+
- 走 HTTP 的 Claude 请求带上实测通过的 CLI 兼容请求头、Bearer 认证、会话元数据和身份系统提示前缀,并保留原始 DSH 系统说明、工具 schema、附件及签名回放。兼容版本固定为 `2.1.295`。
|
|
201
|
+
- Bearer 只来自插件保存并按模型选中的 Key;CLI 通道把同一个 Key 以 `ANTHROPIC_AUTH_TOKEN` 交给子进程,并清除继承环境里的 `ANTHROPIC_*` / `CLAUDE_*` 变量。不读取 CLI 登录状态、外部配置或环境 Key,不切换其它提供商。
|
|
202
|
+
- 通道只由当前 Key 的分组决定,不能手动固定,也不会因为某次拒绝而自动换通道。分组还没读到时按 HTTP 发送;带 Claude 的请求会先等待最多约 6 秒的首次分组读取。客户端政策拒绝会直接说明原因,不禁用 Key。服务端规则变化可能使兼容处理失效,详见 [PackyCode 分组政策](https://docs.packyapi.ai/docs/token/)。
|
|
190
203
|
- Haiku 与 Sonnet 的工具请求都已出现「客户端异常」403 后相同请求成功的情况。插件只对这一特定响应等待 1 秒、原样重发一次;Haiku 另覆盖已捕获的「客户端已授权,无需发送测试消息」403,两种错误共用一次上限。再次拒绝仍会报错。Opus、纯文本请求、普通「只允许官方 CLI」拒绝、429 和已经开始的响应流不触发这次重发。原始失败保留在实测记录中;这不是网关内部判定已得到修复的证明。
|
|
191
204
|
- Claude 流收到 `message_stop` 后即可完成,不再等网关关闭 HTTP 连接;跨分片的 CRLF 换行保持完整。流内错误与取消仍会返回,未收到响应头的等待也不会被当作成功。
|
|
192
|
-
- DSH 的 bash/read/write/edit/glob/grep 在 HTTP 请求中使用已声明的 CLI 标准名称(如 `Bash`、`Read`),其它工具使用 MCP
|
|
205
|
+
- DSH 的 bash/read/write/edit/glob/grep 在 HTTP 请求中使用已声明的 CLI 标准名称(如 `Bash`、`Read`),其它工具使用 MCP 命名;经 CLI 时所有 DSH 工具都以 `mcp__dsh__<名称>` 提供,并在系统提示末尾说明 CLI 自带工具不可用。回到 DSH 时仅还原本次实际提供的工具名称,未知名称不会获得执行权限。工具参数、调用 id、结果和历史签名不变。思考展示采用 CLI 默认:Haiku 为 `omitted`,Sonnet / Opus 为 `updates`(附带相应 beta)。所选推理强度和输出上限不变,空思考块的签名仍完整回传;明确指定的显示模式优先。
|
|
193
206
|
- Claude 请求中的旧工作目录句式会在与当前会话元数据一致时转换为单独的 JSON 路径,避免把提示语的句号复制进路径。真实目录名中的点、Windows 盘符、UNC、空格和反斜杠保持不变;命令参数不会被自动修剪。命令工具优先使用当前目录或 `workdir`,Windows 的 PowerShell 工具保持其原有语法。
|
|
194
|
-
-
|
|
195
|
-
-
|
|
207
|
+
- 两条通道的 Claude 对话都保留完整 DSH 工具循环、权限及计划模式;网页搜索和生图使用宿主工具。会话标题由 `claude-haiku-5-5` 生成(与对话走同一条通道);GPT-6 Astra 与 GPT-5.6 Sol 的标题交给 GPT-6.1 Sol。
|
|
208
|
+
- 1.2.x 的 `claude_code` 委派工具和 `claudeCliMode`、`claudeCliCwd` 设置不再恢复:CLI 现在只是传输通道,不再用自带工具代替 DSH 执行任务。`claudeCliPath` 重新生效,用于指定 CLI 位置(留空则按常见安装位置和 PATH 查找)。1.3.4 的 `claudeTransport` 已移除,profile 里残留的值会被忽略。除非你在 CLI 卡片里点「更新 Claude Code CLI」,用户独立安装的 Claude Code 不会被改动。
|
|
196
209
|
- Codex 的 Responses 请求仍需要 `prompt_cache_key`;插件补上缺失的会话标识,其它 Responses 模型省略该字段。
|
|
197
|
-
- 构建后可用 `node scripts/claude-check.mjs` 验证三个 Claude
|
|
210
|
+
- 构建后可用 `node scripts/claude-check.mjs` 验证三个 Claude 模型的订单核算、工单归类、库存补货、只读库存查询工具回传、商品色卡标注、中文标题和计划模式(只读查询 → `exit_plan_mode` 提交计划 → 审批),并核对业务答案;加 `--transport cli` 则全部经本机 Claude Code CLI 发出。`node scripts/claude-stability.mjs --start --hours 6 --key-label <备注名>` 开始有截止时间和请求上限的采样;定时执行同一脚本继续采样,用 `--status` 查看记录。业务场景版本和每轮构建分别记录;测试消息拒绝将对应检查记为失败,其余预定检查继续,真实凭据或额度错误仍会停止整个窗口。测试不改变已保存的凭据,也不启动 DSH。
|
|
198
211
|
- 连续对话可用 `node scripts/claude-conversation-check.mjs --model claude-haiku-5-5 --rounds 3 --key-label <备注名> --output .artifacts/claude-conversation.json`:同一插件适配器处理独立会话,每组保留六轮对话和完整工具历史,检查追问中的数值一致性、最终 JSON 和异常字符;遇到失败停止该批次并保留记录。单请求默认 65 秒、输出上限 2048 token;诊断可通过 `--timeout-ms`(5000–300000)和 `--max-tokens`(1024–128000)显式调整。`--capture-wire` 记录这组模拟业务的完整请求、非认证头和中断前的流事件,用于精确重放;不记录 Key。报告包含场景版本、适配器生命周期、所用上限、首响应和完整响应耗时。这些选项不修改插件的运行参数。
|
|
199
212
|
|
|
200
213
|
</details>
|
|
201
214
|
|
|
202
215
|
## 更新与卸载
|
|
203
216
|
|
|
204
|
-
|
|
217
|
+
> **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.3.5` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
|
|
218
|
+
|
|
219
|
+
**更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.3.5`),否则装上的可能是发布满 24 小时的旧版。
|
|
205
220
|
|
|
206
221
|
**从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
|
|
207
222
|
|
|
@@ -217,7 +232,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
217
232
|
|
|
218
233
|
有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
|
|
219
234
|
|
|
220
|
-
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.3.
|
|
235
|
+
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.3.5`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
|
|
221
236
|
|
|
222
237
|
**首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
|
|
223
238
|
|
|
@@ -229,13 +244,17 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
229
244
|
|
|
230
245
|
**某个模型不可用,但 Key 是有效的?** 看「账户与 Key」里这个 Key 的分组和 ✓ / ✕:分组不覆盖这个模型时,换一个分组合适的 Key,或在 PackyCode 控制台给 Key 加上对应分组。存了分组合适的 Key 时,插件会自动用它跑这个模型。分组拒绝不会停用 Key。
|
|
231
246
|
|
|
232
|
-
**Claude 报「只接受官方 Claude Code CLI」或「客户端存在异常」?** 这是网关的客户端政策拒绝,不等于 Key
|
|
247
|
+
**Claude 报「只接受官方 Claude Code CLI」或「客户端存在异常」?** 这是网关的客户端政策拒绝,不等于 Key 失效。看这个 Key 下方标的是「Claude 经 HTTP」还是「经官方 CLI」:`cc` 分组的 Key 总是走 CLI,其它分组走 HTTP。经官方 CLI 发出的请求仍被拒时,错误里会附上网关原文(含 request id),先把 Claude Code 更新到最新版(`claude update`)再试,仍失败可发给 PackyCode 客服。插件不会因此禁用 Key 或切换提供商。
|
|
248
|
+
|
|
249
|
+
**提示「本机没有可用的 Claude Code CLI」?** 当前 Key 在 `cc` 分组,需要本机 CLI。到 **设置 → PackyCode → Claude Code CLI** 点「安装」,或在终端执行 `npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code` 后点「重新检测」;装在非常规位置时可在配置里填 `claudeCliPath`。不想装的话,换用 `cc-sale` / `cc-expensive` 分组的 Key。
|
|
250
|
+
|
|
251
|
+
**提示「本机的 Claude Code CLI 版本过旧」?** 本机 CLI 低于 2.1.259。到 **设置 → PackyCode → Claude Code CLI** 点「更新 Claude Code CLI」,完成后重发;也可以在终端执行 `claude update`(npm 安装的执行卡片上显示的 npm 命令),再点「重新检测」。Homebrew 安装的用 `brew upgrade claude-code`。
|
|
233
252
|
|
|
234
253
|
**余额对不上账号账单?** 设置页只显示这里列出的每个 Key 自己的额度,不含同账号下没添加到本插件的其它令牌。API Key 读不到账号的总余额,请到 PackyCode 控制台查看。个别 Key 读失败时会在它那一行注明。
|
|
235
254
|
|
|
236
255
|
**余额显示 `读取失败: https://www.packyapi.com: fetch failed`?** 这是 1.0.4 及更早版本的默认余额接口在国内网络下被 DNS 污染,开了代理才能连上,所以有时正常、有时失败。新版本默认改用 `https://www.packyapi.ai`。模型列表是插件内置的,不需要向 PackyCode 查询,不受影响。
|
|
237
256
|
|
|
238
|
-
**选了 Claude 模型一直显示「深度求索中」?** 查看 DSH 的错误或诊断信息。429/503
|
|
257
|
+
**选了 Claude 模型一直显示「深度求索中」?** 查看 DSH 的错误或诊断信息。429/503 表示网关排队或限流,按宿主重试策略处理;客户端政策拒绝会直接说明原因。只有走 CLI 通道的 Claude 请求会启动本机 Claude Code CLI,它在 90 秒内毫无输出会被结束并报告。
|
|
239
258
|
|
|
240
259
|
**限速之后 Key 被停用了?** 不该发生。429 不会切换 Key。额度用尽或 401 才会停用;充值后点「重新启用」。
|
|
241
260
|
|
|
@@ -243,13 +262,13 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
243
262
|
|
|
244
263
|
**网页搜索报「no stored API key's group covers …」?** 所选搜索后端的模型不在你的令牌分组里(或网关暂时把它路由到了别的供应商)。在 **设置 → PackyCode → 网页搜索** 换一个后端,或添加分组覆盖它的 Key。
|
|
245
264
|
|
|
246
|
-
|
|
265
|
+
**需要安装 Claude Code 吗?** 只有 Key 在 `cc` 分组、又要用 Claude 模型时需要。插件用独立配置目录运行它,不改动你自己的 Claude Code 登录和设置;只有你点「更新 Claude Code CLI」时才会更新这份安装。其它分组和其它模型都不需要。
|
|
247
266
|
|
|
248
267
|
**回答被截断(「已达到输出 token 上限」)、请求反复失败,怎么反馈?** 打开 **设置 → PackyCode → 诊断信息**,选出问题的会话(最近 20 个,按时间倒序,标着所在文件夹名),点「生成诊断信息」再点「复制」,把内容贴到 [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues) 或发给插件作者。内容只有设置和数字:插件版本、会话 id 与创建时间、每个 Key 的序号与分组(不含备注名和 Key 本身)、每次请求用的模型、推理档位和输出上限、最近若干步的 token 用量与结束原因,以及重试和失败的错误码(错误信息已脱敏并截短)。不含对话内容、文件路径和 Key。复制不可用时,文本会被全选,按 ⌘C 或 Ctrl+C 即可。
|
|
249
268
|
|
|
250
269
|
## 安全边界
|
|
251
270
|
|
|
252
|
-
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode
|
|
271
|
+
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。`cc` 分组的 Claude 请求由本机 Claude Code CLI 子进程发出:Key 只以环境变量交给它,DSH 工具通过只监听 127.0.0.1、带随机凭证的 MCP 桥提供,工具本身仍由 DSH 在宿主侧执行。
|
|
253
272
|
|
|
254
273
|
Key 存在本机 DSH 凭据文件(`~/.dsh/.credentials.yaml`,权限由 DSH 设为仅所有者可读),不进设置文档、日志或对话记录。余额请求只在宿主侧发出,带超时并禁止重定向。
|
|
255
274
|
|
|
@@ -275,3 +294,14 @@ pnpm run check
|
|
|
275
294
|
## License
|
|
276
295
|
|
|
277
296
|
[MIT](LICENSE)
|
|
297
|
+
|
|
298
|
+
## 支持作者
|
|
299
|
+
|
|
300
|
+
本插件免费开源,赞赏全凭心意。如果它让你在 DSH 里用 PackyCode 省了不少折腾,欢迎扫码支持,让插件持续跟上新模型和新版 DSH。
|
|
301
|
+
|
|
302
|
+
<table align="center">
|
|
303
|
+
<tr>
|
|
304
|
+
<td align="center"><img src="docs/assets/sponsor-wechat.png" width="200" alt="微信赞赏码"><br><b>微信赞赏</b></td>
|
|
305
|
+
<td align="center"><img src="docs/assets/sponsor-alipay.png" width="200" alt="支付宝收款码"><br><b>支付宝</b></td>
|
|
306
|
+
</tr>
|
|
307
|
+
</table>
|