dsh-packycode-api 1.3.8 → 1.4.0
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 +1 -1
- package/CHANGELOG.md +53 -0
- package/README.en.md +29 -27
- package/README.md +29 -27
- package/SECURITY.md +8 -8
- package/lib/client.js +35 -5
- package/lib/index.js +4581 -3375
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -16,7 +16,7 @@ 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
|
|
19
|
+
- Claude sessions on keys in the `cc` group are carried out by the official Claude Code CLI as the agent (`src/claude-cli-*.js`, `src/claude-agent-tools.js`, `src/claude-permission-mode.js`); every other key uses HTTP with DSH's own agent. PackyCode's `cc` group judges each request's content, so the CLI runs with its own system prompt and tools: never append DSH's system prompt, never attach DSH's tools (both are refused as a client anomaly), and never disguise DSH's agent as Claude Code to get past the check. Its tool calls reach DSH as calls of the agent-scoped `claude_code` mirror tool, and ExitPlanMode as DSH's own `exit_plan_mode`. Every permission prompt the CLI sends must be answered by DSH's approval under the session's permission preset, every plan by DSH's plan review and every question by DSH's question UI; the plugin never allows a prompt by itself. Never let it read the user's Claude settings, login or ambient keys, or a project's `.claude/settings.json`, hooks or `.mcp.json`, and never fall back between the CLI and HTTP routes on a failure. Changing the CLI's flags, environment, the step and continuation logic, or the permission mapping requires `node scripts/claude-check.mjs --transport cli` with a `cc` key, and its summary must count no client-anomaly refusals. The key's groups pick the route: `cc` takes the CLI, the other Claude groups take HTTP, and a key whose groups are not read yet takes the CLI, because a `cc` key over HTTP is always refused. A turn that starts on the CLI finishes there (`turn/start` decides and attaches the mirror tool, reading the session's own model pick, not `agent.options`). Do not add a user switch between CLI and HTTP. Only the user's own messages reach the CLI (`src/claude-user-text.js`); never forward DSH's runtime or time context, skill catalog, `AGENTS.md` or notices. Resolve the DSH services an agent uses through its preset (`agentPresets.serviceFor`): on the Web surface plan mode lives in the preset's realm and the plugin's own `ctx.get` does not see it.
|
|
20
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`.
|
|
21
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.
|
|
22
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.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
- **Claude sessions on `cc` keys are carried out by Claude Code itself, which ends the "客户端存在异常" refusals.** PackyCode's `cc` group judges each request's content, not the program that sends it. From 1.3.4 the official CLI carried DSH's own agent: its tools were off (`--tools ""`), DSH's system prompt ("You are an AI agent powered by DeepSeek Harness…") was appended, and DSH's tools were attached over a local MCP bridge. Users got 本轮运行失败 "我们检测到您的客户端存在异常…请避免任何基于我方 API 二次分发的 API 转接接入", and updating the CLI did not help.
|
|
6
|
+
- The cause was measured on 2026-10-25 with the same `cc` key, machine and CLI. `scripts/claude-check.mjs --transport cli` failed 7 of 15 checks on 1.3.9; every client-anomaly refusal carried DSH tools.
|
|
7
|
+
- Launched directly, with its own prompt and tools as paseo runs it, the CLI had 0 of 79 requests refused. With only DSH's prompt appended, 4 of 7 were refused; with the 1.3.9 shape, every run was refused at its first request. The plugin's environment variables alone refused none, and CLI 2.1.310 changed nothing.
|
|
8
|
+
- Now the CLI runs with its own system prompt and tools, nothing of DSH's appended or attached. It gets `--permission-prompt-tool stdio`, `--setting-sources user`, `--strict-mcp-config` with no servers and its own session record (`--session-id` / `--resume <id>`). Each API request it makes is one DSH step, replayed as that step's SSE stream as before.
|
|
9
|
+
- **Claude Code's tool calls are DSH tool calls of the mirror tool `claude_code`.** Each turn decides its route when it starts and registers the tool in the agent's own scope for a turn of a PackyCode Claude model that goes to the CLI; any other turn withdraws it. The model is the session's own pick in the model picker (DSH's `modelSelection` projection), not the agent's creation options. DSH shows Bash as a terminal card and edits as diffs. The CLI executes the call itself; the mirror waits for its result and shows it.
|
|
10
|
+
- Deciding at the turn's start matters because DSH lists a step's tools before it calls the model, and Auto review refuses a call of a tool the step did not list ("the pending native tool schema is missing or ambiguous").
|
|
11
|
+
- **DSH answers Claude Code's permission prompts.** When the CLI asks about a call, the mirror call's `tools/pre-execute` returns `ask`, so DSH's own approval prompt opens on that card, and a refusal reaches the CLI with DSH's reason. Under the `auto` preset the call is left to Auto review, which asks the user when it refuses. A call the CLI allows by itself (reads, read-only commands) needs no answer. A prompt about a call DSH was never shown (a subagent's) goes to DSH's approval without a card. The CLI's permission mode follows the session:
|
|
12
|
+
- plan mode → `plan`;
|
|
13
|
+
- `workspace-write` → `acceptEdits`;
|
|
14
|
+
- `read-only` and `auto` → `default`;
|
|
15
|
+
- `danger-full-access` with approval `never` → `bypassPermissions`.
|
|
16
|
+
A change is sent to the live process with `set_permission_mode`.
|
|
17
|
+
- **Plans and questions go to DSH's own UI.** Claude Code's ExitPlanMode becomes DSH's `exit_plan_mode`, and the plan is read from the plan file the CLI wrote in its home's `plans` directory. Approval answers ExitPlanMode with a `setMode` update to the preset's mode, so implementation does not stop at the next edit. "Keep planning" sends the user's feedback back, and Claude Code stays in plan mode. If Claude Code enters plan mode itself, DSH's plan mode follows. DSH's plan mode, like every service the bridge uses, is resolved through the agent's preset (`agentPresets.serviceFor`): on the desktop app's Web surface it lives in the session's preset realm, where the plugin's own `ctx.get('planMode')` sees nothing. ExitPlanMode becomes the plan review only while the CLI is in plan mode; outside it Claude Code refuses its own call at once, and DSH shows that as an ordinary `claude_code` call. AskUserQuestion is put to DSH's question service (`userQuestions.ask`) and its answers return as the tool's `answers`. That service is used rather than the `ask_user_question` tool because headless profiles do not register the tool.
|
|
18
|
+
- **One Claude Code session per DSH session.** A live process continues the response it last served: the tool calls DSH has dealt with, the user's next message, or a plan review.
|
|
19
|
+
- **Restart:** after an idle stop, a DSH restart, or another model, effort or key, a new process resumes the same Claude Code session by id. A response cut off mid-stream is remembered, so the next request still resumes. `dsh-sessions.json` maps DSH sessions to Claude Code sessions by ids and fingerprints only.
|
|
20
|
+
- **Unfamiliar history:** an edited message, a fork, a conversation from another model, or a session from 1.3.x starts a new Claude Code session. Its transcript is written from DSH's history: mirrored calls become Claude Code's own calls, and calls of DSH's own tools become text.
|
|
21
|
+
- **Notes:** a user note beside DSH's tool results stops the request the CLI had already sent (`interrupt`), and the note goes in as its next message. The response DSH asked for is then the one that read the note.
|
|
22
|
+
- **Cancellation:** stopping DSH's turn stops Claude Code's turn too.
|
|
23
|
+
- **Compaction:** DSH's compaction of a cc session is answered with a local summary. Claude Code compacts its own context, and its compaction request is not taken for a DSH step.
|
|
24
|
+
- **Self-started turns:** a turn Claude Code starts on its own (a scheduled prompt) is interrupted, because DSH could not show it.
|
|
25
|
+
- **Only the user's own messages reach Claude Code.** DSH adds model-visible messages for its own agent to every turn: the runtime context (working directory, DSH's file policy), a time sample at each step, its skill catalog, the project's `AGENTS.md`, and notices about approval, plan mode and model changes. On the CLI route the request keeps only the texts of DSH messages whose source is the user's (`user`, a `schedule` they wrote, a `session-reference`, an `agent-message`); a turn left with nothing (a goal's next step) keeps its words. `src/claude-user-text.js` holds the list.
|
|
26
|
+
- **Routing when a key's groups are unknown, and issue #3.** A key whose groups are not read yet now takes the CLI instead of HTTP: a `cc` key over HTTP is always refused, while every Claude group serves the official client. A turn that starts on the CLI finishes there, even if the reading arrives during it, because Claude Code may be waiting for its tool results; the next turn follows the groups.
|
|
27
|
+
- A reading that could not reach a key is tried again after 30 seconds (`FAILED_GROUP_RETRY_MS`) instead of after the 10-minute TTL. A Claude request waits for the reading only when its own key has no groups in it. Opening a session starts a reading.
|
|
28
|
+
- The group probe also understands the single-group refusal, `分组 cc-sale 下模型 <id> 无可用渠道(distributor)` (503), and the older `当前分组 <name> 下对于模型 …`. Before, a single-group key's groups stayed unread ([#3](https://github.com/BaronCyrus/dsh-packycode-api/issues/3), reported for a `cc-sale` key).
|
|
29
|
+
- With no CLI installed, a key whose groups are unread is told so, and that a key outside `cc` moves to HTTP once they are read.
|
|
30
|
+
- **Session titles** run in a one-shot `-p` process with no tools and no session record. DSH's title rules go into the user message instead of being appended to Claude Code's prompt. A request that offers no tools is no agent's step either (Auto review asking with the session's model, another plugin's call): it gets the same one-shot answer, its instructions and question as the user's words, without the title framing.
|
|
31
|
+
- **The client-anomaly explanation no longer says to update the CLI.** It says the cc group judged the request's content, that a resend may pass, and that a refusal that keeps happening goes to PackyCode support with the gateway's words, or calls for a cc-sale / cc-expensive / claude-officially key.
|
|
32
|
+
- **What changes for users in cc sessions:** commands and edits run directly on the device, outside DSH's sandbox, gated by the approvals above. DSH's own tools (subagents, todos, jobs, image generation, DSH's search, goals and schedules) are not available, and Claude Code uses its own. A project's `CLAUDE.md` applies; DSH's `AGENTS.md` is not injected. Approvals are one-time only. Under `auto`, read-only calls Claude Code allowed itself are reviewed after the fact. Other groups are unchanged.
|
|
33
|
+
- **The CLI stays isolated.** It keeps its own home, gets only the plugin's key and has inherited Claude variables stripped. It now also never reads a project's `.claude/settings.json`, hooks or `.mcp.json`, so a repository cannot redirect the endpoint or run hooks with the key. Auto-memory, background tasks, auto-update and telemetry are off. Its retries and fallbacks are still off: one step is one request, and DSH's policy retries and rotates keys. A process that ends mid-step is reported as a 502 that DSH retries, and the retry resumes the session; it is not reported as a CLI that cannot start.
|
|
34
|
+
- **The minimum CLI stays 2.1.259.** 2.1.259 and 2.1.295 both took every flag and control message the plugin uses, driven through the plugin's session module against a scripted local gateway. The local MCP bridge (`src/claude-mcp-bridge.js`) and the DSH system-prompt note are removed. AGENTS.md, SECURITY.md and both READMEs describe the new route.
|
|
35
|
+
- **`scripts/claude-check.mjs --transport cli` now runs `scripts/claude-agent-check.mjs`.** In a scratch directory Claude Code reads a file and computes, edits one (approved), deletes one (refused), plans and implements after review, asks a question, reads an image and names a session. The files and answers are checked, and client-anomaly and anti-abuse refusals are counted.
|
|
36
|
+
- Validation, 2026-10-26:
|
|
37
|
+
- **Offline:** 535 tests, both rebuilt bundles and the versioned tarball. New tests cover the CLI arguments and environment, the permission mapping, fingerprints, continuation, plan answers, history conversion, cards, approval reasons and question answers. A fake Claude Code agent with stdio permission prompts covers approve and refuse, auto-run calls, full access, plan mode with approval and with feedback, questions, notes, resume by id, a rebuilt session, titles, compaction, gateway failures, a failure between steps, cancellation, and a missing or outdated CLI. Tests added after the desktop check cover: unread groups taking the CLI and HTTP taking over once they are read; a turn that stays on the CLI; the single-group refusal; the 30-second retry; only the user's messages reaching Claude Code, with no note made of DSH's time sample; plan mode read through the agent's preset and switched on a live process; ExitPlanMode outside plan mode; tool-less requests; and the missing-CLI message for unread groups.
|
|
38
|
+
- **Host spike:** in a headless DSH 0.2.1-rc.3 profile with a scripted model, a scoped tool registered mid-stream was executed in the same step. `ask` opened an approval carrying the card's `callId`, a rejected call did not run, `exit_plan_mode` reviewed and approved, and headless had no `ask_user_question`.
|
|
39
|
+
- **Headless DSH end to end:** 0.2.1-rc.3 with the packed plugin, CLI 2.1.295 and a `cc` key. Ten tasks all ended as expected:
|
|
40
|
+
- a read-only lookup;
|
|
41
|
+
- an edit approved under `read-only` (the file changed);
|
|
42
|
+
- an `rm -rf` refused (the files stayed);
|
|
43
|
+
- plan mode with one "keep planning" and then approval (the plan file was revised, and `CHANGELOG.md` was written without another prompt);
|
|
44
|
+
- a question answered through the question service;
|
|
45
|
+
- a new DSH process with `--session-id` resuming the same Claude Code session;
|
|
46
|
+
- under `auto` with DSH's official auto review, jev-latest allowed an edit, and medium-risk deletes were refused and then refused by the user.
|
|
47
|
+
- **Live, with that key:** `node scripts/claude-check.mjs --transport cli` passed 21 of 21 checks (7 kinds × Opus, Sonnet, Haiku) with 53 requests: 0 client-anomaly, 0 anti-abuse. Its steps now offer DSH-like tools, as DSH's always do. `node scripts/live-check.mjs` passed every other model, key rotation, the failure classification, both auto-review reviewers and the RPC projections; grok-4.7 was refused by the gateway as not covered by the key's groups (`grok-officially` no longer serves it, and the group reading shows ✗).
|
|
48
|
+
- **Desktop app,** DSH 0.2.1-rc.3 with the maintainer's profile, CLI 2.1.295 and that key, in a scratch workspace: a Read card, an approval allowed and one rejected, `/plan` reviewed and then implemented (Write of the plan, review, Edit under `acceptEdits`, an approved command), a question in DSH's question UI, and the same Claude Code session resumed after a DSH restart. The check found the four problems fixed above: a first request after start-up sent over HTTP while the group reading was slow behind a local proxy, `/plan` never reaching Claude Code on the Web surface (Claude Code edited files while DSH showed the plan review), DSH's context messages forwarded to the CLI (64K tokens for a one-file read, and a time sample taken for a note), and the mirror tool missing from each turn's first step in a session created on another model. Auto review was not switched on there, because enabling it needs the user's risk confirmation; it was covered headless.
|
|
49
|
+
|
|
50
|
+
## 1.3.9
|
|
51
|
+
|
|
52
|
+
- **The update button tells an install source that has not synced the new version, and one it cannot reach, from a plain failure.** The card reads the latest version from npm itself, while DSH's pnpm downloads it from the profile's own install source, and right after a release that source can lag: npmmirror, which listed 1.3.7 15 seconds after npm, still answered 1.3.7 36 minutes after 1.3.8 was published, and npm's CDN can serve a 404 for a new tarball for a few minutes. An update on another machine then failed with only "更新失败,请重试,或在插件页重新安装。" The plugin now reads pnpm's output with the codes DSH's own plugin manager reads. When the source has no such version or tarball of this package yet (`ERR_PNPM_NO_MATCHING_VERSION`, `ERR_PNPM_FETCH_404`, `ETARGET`, `E404`), the card shows a note to update again in a few minutes, adding that a regional mirror can take longer. When pnpm could not reach the source (`ERR_PNPM_META_FETCH_FAIL`, `ERR_PNPM_FETCH_5xx`, or Node's `ENOTFOUND`, `ECONNREFUSED`, `ECONNRESET`, `ETIMEDOUT`, `EAI_AGAIN`), or the install hung past its 3-minute bound, the card shows an alert to check the network or proxy. Both name the source's host when pnpm names it; its path, credentials and pnpm's output stay host-side. Another package's 404 and any other failure keep the old message. The install source is not switched.
|
|
53
|
+
- **An install stopped by its bound or by a cancel reports why.** Node reports a spawn's abort as its own `AbortError` before the process closes, so the bound's "timed out" never reached the update; it now does.
|
|
54
|
+
- Validation, 2026-10-22: 515 offline tests (new: real pnpm 11.28.5 output read as syncing or unreachable with only the host, another package's 404 and unknown output as neither; the update's `failed` outcomes; a pnpm that hangs, started through the real spawn, ending at the bound as unreachable while a cancel stays a cancel; the card's note and alert), both rebuilt bundles and the versioned tarball. With DSH's bundled pnpm 11.28.5 and the plugin's `update()` against scratch profiles holding 1.3.7: on npmjs it installed 1.3.8 (4.7 s); on npmmirror, still without 1.3.8, it returned `syncing` with `registry.npmmirror.com` in 0.9 s; on a closed local port it returned `unreachable` once pnpm's own retries were spent (70 s); on an address that never answers it returned `unreachable` at a 20-second bound (the default is 180 s), with `package.json` and the lockfile unchanged and no pnpm left running. Every failed profile kept 1.3.7. The card was checked through the client tests, not in DeepSeek Harness.
|
|
55
|
+
|
|
3
56
|
## 1.3.8
|
|
4
57
|
|
|
5
58
|
- **DSH's official 自动审查 can review with jev-latest or DeepSeek Flash.** DSH ships an experimental "自动授权审查" plugin (`@deepseek-ai/dsh-experimental-auto-review`, row `auto-review`, off by default). Switched on, it adds 自动审查 to the composer's permission menu and reviews every tool call of a session in that mode with one hand-built `llm.stream` request on the session's own model. The plugin now listens on DSH's `llm/stream` waterfall, which every model request passes. It recognizes that request by its fixed `REVIEW_POLICY` system prompt and four-section message, and answers it with the reviewer chosen under Settings → PackyCode → 自动审查 (`autoReviewModel`: `jev-latest` by default, `deepseek-flash`, or `session` to leave it alone). What is reviewed, the policy, asking the user, final denials in children, and refusing a call whose review failed all stay the official plugin's. Every other request goes on untouched. The plugin registers no permission preset and no tool gate of its own.
|
package/README.en.md
CHANGED
|
@@ -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 route by group** | The `cc` group only serves the official client, so Claude
|
|
32
|
+
| **Claude route by group** | The `cc` group only serves the official client, so Claude sessions on `cc` keys are carried out by this device's Claude Code itself, with its own system prompt and tools, while DSH shows every tool call and handles permissions, plan review and questions; `cc-sale`, `cc-expensive`, `claude-officially` and other groups use the plugin's HTTP route with DSH's own agent |
|
|
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
|
| **Auto review on your model** | With DSH's built-in “Auto authorization review” switched on, the permission menu's Auto review can review each tool call with jev-latest or DeepSeek Flash; the rules and outcomes stay the official ones |
|
|
@@ -48,10 +48,10 @@ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH se
|
|
|
48
48
|
Open the desktop application's **Plugins** page, click **Add plugin**, and enter the package name **with a version** as the **package name or address**:
|
|
49
49
|
|
|
50
50
|
```text
|
|
51
|
-
dsh-packycode-api@1.
|
|
51
|
+
dsh-packycode-api@1.4.0
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Choose the **official** install source, then click **Install**. `1.
|
|
54
|
+
Choose the **official** install source, then click **Install**. `1.4.0` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
|
|
55
55
|
|
|
56
56
|
> **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**.
|
|
57
57
|
|
|
@@ -72,7 +72,7 @@ Choose a model from the `PackyCode` group. All ten models use the plugin’s HTT
|
|
|
72
72
|
|
|
73
73
|
The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
|
|
74
74
|
|
|
75
|
-
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.
|
|
75
|
+
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.0`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
|
|
76
76
|
|
|
77
77
|
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.
|
|
78
78
|
|
|
@@ -86,11 +86,11 @@ A profile without a browser can still use the model route. It just has no settin
|
|
|
86
86
|
|
|
87
87
|
**Switch keys.** Keys are used in the order they were added. **Use this key** picks the preferred key, effective from the next turn; **Rename** changes its label (at most 60 characters, empty names are refused); **Re-enable** puts a disabled key back after a top-up or replacement.
|
|
88
88
|
|
|
89
|
-
**See groups.** Under **Accounts and keys**, each key lists its PackyCode groups (hover for the group's description) and which models they reach: ✓ yes, ◐ partly, ✕ no. The groups come from the gateway itself (its refusal of a model id it cannot route names the token's groups
|
|
89
|
+
**See groups.** Under **Accounts and keys**, each key lists its PackyCode groups (hover for the group's description) and which models they reach: ✓ yes, ◐ partly, ✕ no. The groups come from the gateway itself (its refusal of a model id it cannot route names the token's groups, as “已选分组=[…]”, or for a single-group key as “分组 … 下模型 … 无可用渠道”; nothing is billed), matched against PackyCode's public model-group table. Check Claude group coverage per model; do not assume `cc-sale` serves all three models; GPT needs `codex` / `codex-sale`; DeepSeek needs `deepseek-officially` / `deepseek-sale`.
|
|
90
90
|
|
|
91
91
|
**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.
|
|
92
92
|
|
|
93
|
-
**Use Claude.** Select any Claude model. When the key is in the `cc` group, the
|
|
93
|
+
**Use Claude.** Select any Claude model. When the key is in the `cc` group, the session is carried out by 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 or a newer version is out; 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 decide the route, and it cannot be switched by hand. Until a key's groups are read, it uses the CLI. Over HTTP, DSH executes every tool, and plan mode, questions, todos, subagents, attachments, reasoning effort and history behave as for any other model; through the CLI, Claude Code does the work itself — see “Claude Code CLI route” below for the differences.
|
|
94
94
|
|
|
95
95
|
**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:
|
|
96
96
|
|
|
@@ -134,16 +134,18 @@ PackyCode has no dedicated search endpoint: one search is one model call with a
|
|
|
134
134
|
|
|
135
135
|
### Claude Code CLI route
|
|
136
136
|
|
|
137
|
-
PackyCode's `cc` group (“claude code专用”) only serves the official Claude Code client
|
|
137
|
+
PackyCode's `cc` group (“claude code专用”) only serves the official Claude Code client, and it judges each request's content, not the program that sends it: from 1.3.4 to 1.3.9 the CLI carried DSH's system prompt and tools, which the gateway refuses as a “client anomaly”. From 1.4.0, Claude sessions on these keys are **carried out by Claude Code as the agent**, with DSH as the interface and the gatekeeper — the way tools such as paseo use the official CLI:
|
|
138
138
|
|
|
139
|
-
- **
|
|
140
|
-
- **
|
|
141
|
-
- **
|
|
142
|
-
- **
|
|
143
|
-
- **
|
|
144
|
-
- **
|
|
139
|
+
- **Claude Code uses its own prompt and tools.** DSH's system prompt is not appended and DSH's tools are not attached; Claude Code reads and writes files, runs commands and runs subagents itself, directly on this device. A project's `CLAUDE.md` applies as usual. What DSH adds for its own agent (`AGENTS.md`, the runtime and time context, its skill catalog, and notices about approval, plan mode or a model change) is not passed to Claude Code; it receives only the messages you send.
|
|
140
|
+
- **Every tool call is a DSH tool card.** Commands show as terminal cards and edits as diffs, with the output Claude Code actually got (the tool is named `claude_code`).
|
|
141
|
+
- **DSH decides permissions.** When Claude Code asks for permission, the session's permission preset applies: under `workspace-write` (the default) edits inside the working directory go ahead and anything else that needs permission (a command that is not read-only, for example) shows DSH's approval prompt; under `read-only` edits ask too; under `auto` Auto review decides and asks you when it refuses; under `danger-full-access` nothing asks. A refusal reaches Claude Code with its reason.
|
|
142
|
+
- **Plan mode and questions happen in DSH.** After `/plan`, Claude Code enters its own plan mode, writes the plan to a file and submits it; DSH shows it in its own plan review, approval continues under the preset, and “keep planning” sends your feedback back for revision. Claude Code's questions appear in DSH's question UI.
|
|
143
|
+
- **One Claude Code session per DSH session.** A DSH session keeps one long-lived CLI process; after it idles out (20 minutes), DSH restarts, or the model or key changes, the next request resumes Claude Code's own saved session. After an edited message, a fork, or a switch from another model, a new Claude Code session starts from DSH's history. When you add a note while Claude Code is working, the plugin stops its current request and gives it the note as its next message. Compaction DSH starts is answered with a local summary; Claude Code compacts its own context itself.
|
|
144
|
+
- **Isolated from your own Claude Code.** It runs with its own config home, `~/.dsh/packycode-claude-cli`, and reads neither `~/.claude` settings and logins nor a project's `.claude/settings.json`, hooks or `.mcp.json`; only the key stored in the plugin is passed to the child. Auto-update, telemetry, auto-memory, background tasks and model fallback are off, and retries are left to DSH's retry policy, which rotates keys.
|
|
145
|
+
- **An outdated CLI is one click away from current.** The plugin needs Claude Code 2.1.259 or later (tested from that release on with the permission prompts and mode switches the plugin uses). 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. When the CLI works but is not the latest release, the card names the new version and offers the same button: the plugin reads `latest` of `@anthropic-ai/claude-code` from npm on this device (the same version as the native installer's `latest` channel), at most once every 30 minutes, and again when you click Check again; without an answer it offers nothing. Your Claude Code is only updated when you click that button.
|
|
146
|
+
- **Failures say why.** A missing CLI, an outdated CLI, and a request the gateway still refuses as a client anomaly each get their own explanation; nothing switches to another route or provider, and no key is disabled.
|
|
145
147
|
|
|
146
|
-
|
|
148
|
+
**What differs from DSH running the tools:** commands and edits are run by Claude Code directly on this device, outside DSH's sandbox, gated only by the permissions above; DSH's own tools (subagents, todos, background jobs, image generation, DSH's search, goals and schedules, and so on) are not available in these sessions, and Claude Code uses its own equivalents (its WebSearch may be refused by PackyCode); DSH's file-changes panel does not record Claude Code's edits; approvals are one-time only. Under `auto`, read-only calls Claude Code allows itself are reviewed as well. Claude Code's session records and plan files are kept in `~/.dsh/packycode-claude-cli/`. Starting a process takes about 0.3–1 s. Requires Claude Code 2.1.259 or later (tested with 2.1.259, 2.1.295 and 2.1.310). On Windows, Claude Code also needs Git for Windows.
|
|
147
149
|
|
|
148
150
|
### Image generation and editing
|
|
149
151
|
|
|
@@ -153,7 +155,7 @@ The image card shows each image key's remaining, used and limit, its reset perio
|
|
|
153
155
|
|
|
154
156
|
Choose the image model and quality, then click **Create image** in a PackyCode conversation or explicitly request `packycode_image_generate`. Attach references and describe changes to use `/v1/images/edits`; new images use `/v1/images/generations`. The image model is independent of the conversation model and other image plugins can coexist.
|
|
155
157
|
|
|
156
|
-
Claude generates and edits images through DSH’s `packycode_image_generate`, with the same separate image key, preferences and balance cache as other models. Saved images from older CLI-backed sessions remain viewable without regeneration.
|
|
158
|
+
Claude generates and edits images through DSH’s `packycode_image_generate`, with the same separate image key, preferences and balance cache as other models. Saved images from older CLI-backed sessions remain viewable without regeneration. Claude sessions on `cc` keys are carried out by Claude Code itself and cannot use this tool.
|
|
157
159
|
|
|
158
160
|
**Image visible in tool details but unavailable in the final answer:** a standalone main-chat gallery remains visible when reasoning/tool details are collapsed, including PTC child calls. Reopening an existing conversation restores the gallery from its saved attachments without regenerating or spending image quota. An old invalid Markdown image link to a host path does not affect this gallery.
|
|
159
161
|
|
|
@@ -225,7 +227,7 @@ The card shows whether DSH's plugin is on, how many reviews this plugin answered
|
|
|
225
227
|
| `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 |
|
|
226
228
|
| `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` |
|
|
227
229
|
| `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` |
|
|
228
|
-
| `claude-opus-5-5` | Anthropic Messages, images and native tools:
|
|
230
|
+
| `claude-opus-5-5` | Anthropic Messages, images and native tools: this device's Claude Code CLI as the agent for `cc` keys, HTTP otherwise | Cannot be off; `low` / `medium` / `high` / `xhigh` / `max` | Claude-group coverage reported in Settings |
|
|
229
231
|
| `claude-sonnet-5-5` | Same | Same | Same |
|
|
230
232
|
| `claude-haiku-5-5` | Same; also generates Claude session titles | Same | Same |
|
|
231
233
|
|
|
@@ -248,27 +250,27 @@ DeepSeek Flash uses the gateway's Responses endpoint (`/api/pricing` lists `open
|
|
|
248
250
|
<details>
|
|
249
251
|
<summary>Protocol, group and client compatibility</summary>
|
|
250
252
|
|
|
251
|
-
- Every model uses HTTP inside the plugin, except Claude
|
|
253
|
+
- Every model uses HTTP inside the plugin, except Claude sessions on `cc` keys, which this device's Claude Code CLI carries out. 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. Through the CLI, pi-ai still turns DSH's request into a Messages request, but only what is new in it — the user's next message, or tool calls DSH has dealt with — reaches Claude Code; each API request Claude Code makes is one DSH step, its raw stream events are parsed by the same protocol code, and its tool calls become `claude_code` or `exit_plan_mode`.
|
|
252
254
|
- 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`.
|
|
253
255
|
- 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.
|
|
254
|
-
- The key's groups
|
|
256
|
+
- The key's groups 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 the CLI: a `cc` key is always refused over HTTP, while every Claude group serves the official client; once the reading shows another group, HTTP takes over. A Claude request waits up to about 6 seconds for the key's groups; a key whose reading failed is read again after about 30 seconds, and opening a session starts a reading early. A turn that starts on the CLI finishes there, and the next turn follows the groups. 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/).
|
|
255
257
|
- 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.
|
|
256
258
|
- 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.
|
|
257
|
-
- 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
|
|
259
|
+
- 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, DSH's tools are not sent to Claude Code. 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.
|
|
258
260
|
- 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.
|
|
259
261
|
- 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.
|
|
260
|
-
- The 1.2 `
|
|
262
|
+
- The 1.2 `claudeCliMode` / `claudeCliCwd` settings do not return: Claude Code's permissions follow the session's DSH permission preset, and its working directory is the session's. The tool named `claude_code` is now the mirror tool that shows Claude Code's tool calls in cc sessions; only the plugin uses it, and it is not the 1.2 delegation tool. `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.
|
|
261
263
|
- Codex Responses requests still need `prompt_cache_key`; the plugin supplies a missing session identity. Other Responses families omit it.
|
|
262
|
-
- 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`
|
|
264
|
+
- 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` runs the cc route's checks instead (`scripts/claude-agent-check.mjs`): in a scratch directory Claude Code reads a file and computes, edits one (approved), deletes one (refused), plans and then implements after review, asks a question, reads an image and names a session, and the files and answers are checked, with the gateway's client-anomaly and anti-abuse refusals counted. `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.
|
|
263
265
|
- 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.
|
|
264
266
|
|
|
265
267
|
</details>
|
|
266
268
|
|
|
267
269
|
## Update and uninstall
|
|
268
270
|
|
|
269
|
-
> **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.
|
|
271
|
+
> **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.4.0` 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.
|
|
270
272
|
|
|
271
|
-
**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.
|
|
273
|
+
**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. The newer version is read from npm, while pnpm downloads it from the profile's own install source: right after a release that source (a regional mirror in particular) may not have it yet, and the button asks you to update again in a few minutes; when the source cannot be reached, it asks you to check the network or proxy. 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.4.0`); without it you may get a version that is merely the newest one published at least 24 hours ago.
|
|
272
274
|
|
|
273
275
|
**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.
|
|
274
276
|
|
|
@@ -284,7 +286,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
284
286
|
|
|
285
287
|
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.
|
|
286
288
|
|
|
287
|
-
Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.
|
|
289
|
+
Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.4.0`), 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.
|
|
288
290
|
|
|
289
291
|
**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:
|
|
290
292
|
|
|
@@ -298,9 +300,9 @@ Recovery: quit and reopen the desktop application, and the old version works. Th
|
|
|
298
300
|
|
|
299
301
|
**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.
|
|
300
302
|
|
|
301
|
-
**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.
|
|
303
|
+
**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. The cc group judges whether a request comes from Claude Code itself; from 1.4.0 cc sessions are carried out by Claude Code and are normally accepted. If one is still refused, resend it; if it keeps happening, send the gateway's own words from the error (with the request id) to PackyCode support, or use a `cc-sale` / `cc-expensive` / `claude-officially` key. Updating the Claude Code CLI does not help with this refusal. The plugin does not disable the key or switch providers.
|
|
302
304
|
|
|
303
|
-
**“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.
|
|
305
|
+
**“Claude Code CLI is not available”?** The key is in `cc`, which needs the CLI on this device. When the message says the key's groups are not read yet, the group reading failed for now (common on an unstable network or proxy): resend shortly, and a key outside `cc` moves to HTTP once its groups are read. 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.
|
|
304
306
|
|
|
305
307
|
**“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`.
|
|
306
308
|
|
|
@@ -320,7 +322,7 @@ Recovery: quit and reopen the desktop application, and the old version works. Th
|
|
|
320
322
|
|
|
321
323
|
## Security and scope
|
|
322
324
|
|
|
323
|
-
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
|
|
325
|
+
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 sessions on `cc` keys are carried out by a local Claude Code CLI child process: the key reaches it only through its environment, and its tools (reading and writing files, running commands and so on) run directly on this device, outside DSH's sandbox; calls that need permission are decided by you or Auto review under the session's permission preset, and nothing asks under `danger-full-access`.
|
|
324
326
|
|
|
325
327
|
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.
|
|
326
328
|
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
| **多 Key 按顺序使用** | 额度用尽或 Key 被拒绝时自动切到下一个可用 Key;失败的那一步由重试接手 |
|
|
30
30
|
| **按分组选 Key** | 每个 Key 后面列出它所在的 PackyCode 分组和能用的模型;当前 Key 的分组用不了所选模型(例如没有 cc 分组却选了 Claude)时,这一轮自动改用分组合适的 Key |
|
|
31
31
|
| **余额一眼可见** | 设置页列出每个 Key 的剩余、已用、额度、重置周期和用量条;输入框右侧显示当前 Key 的剩余额度 |
|
|
32
|
-
| **Claude 按分组选通道** | `cc` 分组只接受官方客户端,这些 Key 的 Claude
|
|
32
|
+
| **Claude 按分组选通道** | `cc` 分组只接受官方客户端,这些 Key 的 Claude 会话由本机 Claude Code 自己完成:它用自己的系统提示词和工具做事,DSH 显示每次工具调用,并负责授权、计划审阅和提问;`cc-sale`、`cc-expensive`、`claude-officially` 等分组走插件内 HTTP,由 DSH 自己的 agent 执行 |
|
|
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
|
| **自动审查可换模型** | 开启 DSH 自带的「自动授权审查」后,权限菜单里的「自动审查」可改用 jev-latest 或 DeepSeek Flash 审查每次工具调用,审查规则和处理方式保持官方原样 |
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
|
|
49
49
|
|
|
50
50
|
```text
|
|
51
|
-
dsh-packycode-api@1.
|
|
51
|
+
dsh-packycode-api@1.4.0
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
在**安装源**中选择**官方源**,然后点击**安装**。`1.
|
|
54
|
+
在**安装源**中选择**官方源**,然后点击**安装**。`1.4.0` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
|
|
55
55
|
|
|
56
56
|
> **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
|
|
57
57
|
|
|
@@ -72,7 +72,7 @@ dsh-packycode-api@1.3.8
|
|
|
72
72
|
|
|
73
73
|
桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
|
|
74
74
|
|
|
75
|
-
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.
|
|
75
|
+
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.0`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
|
|
76
76
|
|
|
77
77
|
本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
|
|
78
78
|
|
|
@@ -86,11 +86,11 @@ dsh-packycode-api@1.3.8
|
|
|
86
86
|
|
|
87
87
|
**换 Key。** Key 按添加顺序使用。点「切到此 Key」指定优先使用的 Key,下一轮就生效;「重命名」改备注(最多 60 字,不能为空);充值或更换后点「重新启用」。
|
|
88
88
|
|
|
89
|
-
**看分组。** 「账户与 Key」里每个 Key 下面列出它所在的 PackyCode 分组(鼠标悬停可看分组说明),以及能用哪些模型:✓ 可用、◐ 部分可用、✕ 不可用。分组由网关自己报出(对一个不存在的模型 id
|
|
89
|
+
**看分组。** 「账户与 Key」里每个 Key 下面列出它所在的 PackyCode 分组(鼠标悬停可看分组说明),以及能用哪些模型:✓ 可用、◐ 部分可用、✕ 不可用。分组由网关自己报出(对一个不存在的模型 id 的拒绝里会写明「已选分组」,单分组的 Key 则是「分组 … 下模型 … 无可用渠道」,不产生费用),再对照 PackyCode 公开的模型分组表。Claude 的分组覆盖要按具体模型确认,不能假定 `cc-sale` 支持全部三个型号;GPT 需要 `codex` / `codex-sale`;DeepSeek 需要 `deepseek-officially` / `deepseek-sale`。
|
|
90
90
|
|
|
91
91
|
**看余额。** 「账户与 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`。
|
|
92
92
|
|
|
93
|
-
**用 Claude。** 直接选择三个 Claude 模型之一。Key 在 `cc`
|
|
93
|
+
**用 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」,通道由分组决定,不能手动切换;分组还没读到时先走 CLI。经 HTTP 时工具由 DSH 执行,计划模式、提问、待办、子代理、附件、思考档位和历史都和其它模型一样;经 CLI 时由 Claude Code 自己执行,差别见下方「Claude Code CLI 通道」。
|
|
94
94
|
|
|
95
95
|
**网页搜索。** DSH 的 `web_search` 默认调用 DeepSeek 官方接口(用 `DEEPSEEK_API_KEY` 计费)。在 **设置 → PackyCode → 网页搜索** 里可以改走 PackyCode:
|
|
96
96
|
|
|
@@ -134,16 +134,18 @@ PackyCode 没有专用搜索接口:一次搜索就是一次带服务端搜索
|
|
|
134
134
|
|
|
135
135
|
### Claude Code CLI 通道
|
|
136
136
|
|
|
137
|
-
PackyCode 的 `cc` 分组(「claude code专用」)只接受官方 Claude Code
|
|
137
|
+
PackyCode 的 `cc` 分组(「claude code专用」)只接受官方 Claude Code 客户端,而且按请求内容判断是不是 Claude Code 自己在工作:1.3.4–1.3.9 借 CLI 发出的是 DSH 的系统提示词和工具,会被判为「客户端存在异常」。从 1.4.0 起,这些 Key 的 Claude 会话**由 Claude Code 自己当 agent**,DSH 负责界面和把关,和 paseo 等工具使用官方 CLI 的方式一样:
|
|
138
138
|
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
139
|
+
- **Claude Code 用自己的提示词和工具。** 不追加 DSH 的系统提示词,也不挂 DSH 的工具;读写文件、执行命令、子代理都由 Claude Code 自己完成,在本机直接执行。项目里的 `CLAUDE.md` 照常生效。DSH 为自己的 agent 附加的内容(`AGENTS.md`、运行环境、时间、技能列表,以及审批、计划模式、换模型的提示)不会交给 Claude Code,它只收到你自己发的消息。
|
|
140
|
+
- **每次工具调用都是一张 DSH 工具卡片。** 命令显示为终端卡片,改文件显示为 diff,结果是 Claude Code 实际执行后的输出(工具名为 `claude_code`)。
|
|
141
|
+
- **授权交给 DSH。** Claude Code 请求授权时,按会话的权限预设处理:`workspace-write`(默认)下工作目录内的文件修改直接进行,其它需要授权的操作(例如非只读命令)弹出 DSH 的授权提示;`read-only` 下修改文件也要授权;`auto` 下交给自动审查,审查拒绝时再问你;`danger-full-access` 下不询问。拒绝的理由会原样告诉 Claude Code。
|
|
142
|
+
- **计划模式和提问也在 DSH 里完成。** `/plan` 后 Claude Code 进入它自己的计划模式,把计划写成文件再提交;DSH 用自己的计划审阅界面展示,批准后按预设继续,选「继续规划」时你的反馈会交给它修改。Claude Code 向你提问时,问题出现在 DSH 的提问界面。
|
|
143
|
+
- **一个 DSH 会话对应一个 Claude Code 会话。** 同一个 DSH 会话复用一个常驻 CLI 进程;进程空闲 20 分钟结束、DSH 重启、换模型或换 Key 后,用 Claude Code 自己保存的会话记录续接。编辑过历史消息、分叉会话或从别的模型切过来时,用 DSH 的历史新开一个 Claude Code 会话。你在 Claude Code 工作时插话,插件会停下它当前的请求,把这句话作为下一条消息交给它。DSH 发起的历史压缩在本地生成摘要,Claude Code 自己的上下文由它自己压缩。
|
|
144
|
+
- **与你自己的 Claude Code 隔离。** 使用独立配置目录 `~/.dsh/packycode-claude-cli`,不读取 `~/.claude` 的设置和登录状态,也不读项目里的 `.claude/settings.json`、hooks 和 `.mcp.json`;只把插件保存的 Key 交给子进程。自动更新、遥测、自动记忆、后台任务和模型回退都关闭,失败重试交还给 DSH 的重试策略(会按 Key 轮换)。
|
|
145
|
+
- **版本过低一键更新。** 插件需要 Claude Code 2.1.259 或更新版本(实测从这一版起支持插件用到的授权请求和权限模式切换)。更旧的 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。CLI 能用但不是最新版时,卡片也会提示新版本并提供同一个按钮:插件在本机读取 npm 上 `@anthropic-ai/claude-code` 的 `latest`(与官方安装器的 `latest` 通道是同一版本),30 分钟内最多读一次,点「重新检测」立即重读;读不到时不提示。只有点这个按钮时才会更新你的 Claude Code。
|
|
146
|
+
- **出错会说清原因。** 未安装 CLI、CLI 版本过旧、请求仍被网关判为客户端异常,分别给出说明和下一步,不会改走其它通道或提供商,也不会停用 Key。
|
|
145
147
|
|
|
146
|
-
|
|
148
|
+
**和 DSH 自己执行相比的差别:** 命令和文件修改由 Claude Code 在本机直接执行,不经过 DSH 的沙箱,只受上面的授权把关;DSH 自己的工具(子代理、todo、后台任务、生图、DSH 搜索、目标和定时任务等)在这些会话里不可用,Claude Code 用它自己的同类工具(它的 WebSearch 可能被 PackyCode 拒绝);DSH 的文件改动面板不记录 Claude Code 的修改;授权只有单次允许。`auto` 预设下,Claude Code 自己放行的只读操作也会被审查一次。Claude Code 的会话记录和计划文件保存在 `~/.dsh/packycode-claude-cli/`。新进程启动约 0.3–1 秒。需要 Claude Code 2.1.259 或更新版本(实测 2.1.259、2.1.295 与 2.1.310)。Windows 上 Claude Code 还需要 Git for Windows。
|
|
147
149
|
|
|
148
150
|
### 图片生成与编辑
|
|
149
151
|
|
|
@@ -153,7 +155,7 @@ PackyCode 的 `cc` 分组(「claude code专用」)只接受官方 Claude Cod
|
|
|
153
155
|
|
|
154
156
|
选择请求型号与质量后,可在 PackyCode 对话里点 **创建图片** 补充描述,或明确要求使用 `packycode_image_generate`。上传参考图后描述修改要求会调用 `/v1/images/edits`;新图调用 `/v1/images/generations`。图片型号独立于对话型号,其他插件的图片工具仍可并存。
|
|
155
157
|
|
|
156
|
-
Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具生图、编辑图片并回传会话,使用独立的图片 Key、设置和余额缓存。旧版 CLI 会话已经保存的图片仍可查看,无需重新生成。
|
|
158
|
+
Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具生图、编辑图片并回传会话,使用独立的图片 Key、设置和余额缓存。旧版 CLI 会话已经保存的图片仍可查看,无需重新生成。 `cc` 分组的 Claude 会话由 Claude Code 自己执行,用不了这个工具。
|
|
157
159
|
|
|
158
160
|
**详情里有图、主聊天却显示「图片无法预览」:** 图片结果会在主聊天单独展示,收起思维链或工具详情时仍可见,包括 PTC 嵌套调用。修复版重新打开历史对话也会用已保存的附件补出图片卡片,无需再次生图;模型回复里遗留的无效本机路径图片链接不影响这张卡片。
|
|
159
161
|
|
|
@@ -225,7 +227,7 @@ DSH 自带一个实验性插件「自动授权审查」,默认关闭。开启
|
|
|
225
227
|
| `grok-4.7`(Grok 4.7) | HTTP,Responses,可带图;500k 上下文 | 不能关;`low` / `medium` / `high` / `xhigh` | 以设置页从网关读取的 Grok 分组覆盖为准 |
|
|
226
228
|
| `gemini-4-argon`(Gemini 4 Argon) | HTTP,Gemini 原生流式,可带图;1,048,576 上下文,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
227
229
|
| `gemini-3.8-flash`(Gemini 3.8 Flash) | HTTP,Gemini 原生流式,可带图;1,048,576 输入,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
228
|
-
| `claude-opus-5-5` | Anthropic Messages,可带图和原生工具:`cc`
|
|
230
|
+
| `claude-opus-5-5` | Anthropic Messages,可带图和原生工具:`cc` 分组由本机 Claude Code CLI 当 agent,其它分组走 HTTP | 不能关;`low` / `medium` / `high` / `xhigh` / `max` | 以设置页读取的 Claude 分组覆盖为准 |
|
|
229
231
|
| `claude-sonnet-5-5` | 同上 | 同上 | 同上 |
|
|
230
232
|
| `claude-haiku-5-5` | 同上;Claude 会话标题固定走它 | 同上 | 同上 |
|
|
231
233
|
|
|
@@ -248,27 +250,27 @@ DeepSeek Flash 走网关的 Responses 接口(`/api/pricing` 列出 `openai-res
|
|
|
248
250
|
<details>
|
|
249
251
|
<summary>协议、分组与客户端兼容性</summary>
|
|
250
252
|
|
|
251
|
-
- 除 `cc` 分组 Key 的 Claude
|
|
253
|
+
- 除 `cc` 分组 Key 的 Claude 会话由本机 Claude Code CLI 完成外,其余模型均在插件内通过 HTTP 调用。Claude 使用 `anthropic-messages`,base URL 不带 `/v1`;SDK 会拼出 `/v1/messages`。模型、协议、上下文和档位映射保持不变。经 CLI 时,插件仍由 pi-ai 把 DSH 的请求转换成 Messages 格式,但只把其中的新内容(用户的新消息、DSH 处理完的工具调用)交给 Claude Code;Claude Code 每发一次 API 请求就是 DSH 的一步,它的原始流事件按同一协议解析,其中的工具调用改写成 `claude_code` 或 `exit_plan_mode`。
|
|
252
254
|
- 走 HTTP 的 Claude 请求带上实测通过的 CLI 兼容请求头、Bearer 认证、会话元数据和身份系统提示前缀,并保留原始 DSH 系统说明、工具 schema、附件及签名回放。兼容版本固定为 `2.1.295`。
|
|
253
255
|
- Bearer 只来自插件保存并按模型选中的 Key;CLI 通道把同一个 Key 以 `ANTHROPIC_AUTH_TOKEN` 交给子进程,并清除继承环境里的 `ANTHROPIC_*` / `CLAUDE_*` 变量。不读取 CLI 登录状态、外部配置或环境 Key,不切换其它提供商。
|
|
254
|
-
-
|
|
256
|
+
- 通道由当前 Key 的分组决定,不能手动固定,也不会因为某次拒绝而自动换通道。分组还没读到时按 CLI 发送:`cc` 分组的 Key 走 HTTP 一定被拒,而官方客户端各个 Claude 分组都接受,读到分组后其它分组再改走 HTTP。带 Claude 的请求会先等待最多约 6 秒读取分组;读取失败的 Key 约 30 秒后重读,会话打开时也会提前读一次。一轮对话从 CLI 开始,就在 CLI 上做完,下一轮再按分组选。客户端政策拒绝会直接说明原因,不禁用 Key。服务端规则变化可能使兼容处理失效,详见 [PackyCode 分组政策](https://docs.packyapi.ai/docs/token/)。
|
|
255
257
|
- Haiku 与 Sonnet 的工具请求都已出现「客户端异常」403 后相同请求成功的情况。插件只对这一特定响应等待 1 秒、原样重发一次;Haiku 另覆盖已捕获的「客户端已授权,无需发送测试消息」403,两种错误共用一次上限。再次拒绝仍会报错。Opus、纯文本请求、普通「只允许官方 CLI」拒绝、429 和已经开始的响应流不触发这次重发。原始失败保留在实测记录中;这不是网关内部判定已得到修复的证明。
|
|
256
258
|
- Claude 流收到 `message_stop` 后即可完成,不再等网关关闭 HTTP 连接;跨分片的 CRLF 换行保持完整。流内错误与取消仍会返回,未收到响应头的等待也不会被当作成功。
|
|
257
|
-
- DSH 的 bash/read/write/edit/glob/grep 在 HTTP 请求中使用已声明的 CLI 标准名称(如 `Bash`、`Read`),其它工具使用 MCP 命名;经 CLI
|
|
259
|
+
- DSH 的 bash/read/write/edit/glob/grep 在 HTTP 请求中使用已声明的 CLI 标准名称(如 `Bash`、`Read`),其它工具使用 MCP 命名;经 CLI 时 DSH 的工具不发给 Claude Code。回到 DSH 时仅还原本次实际提供的工具名称,未知名称不会获得执行权限。工具参数、调用 id、结果和历史签名不变。思考展示采用 CLI 默认:Haiku 为 `omitted`,Sonnet / Opus 为 `updates`(附带相应 beta)。所选推理强度和输出上限不变,空思考块的签名仍完整回传;明确指定的显示模式优先。
|
|
258
260
|
- Claude 请求中的旧工作目录句式会在与当前会话元数据一致时转换为单独的 JSON 路径,避免把提示语的句号复制进路径。真实目录名中的点、Windows 盘符、UNC、空格和反斜杠保持不变;命令参数不会被自动修剪。命令工具优先使用当前目录或 `workdir`,Windows 的 PowerShell 工具保持其原有语法。
|
|
259
261
|
- 两条通道的 Claude 对话都保留完整 DSH 工具循环、权限及计划模式;网页搜索和生图使用宿主工具。会话标题由 `claude-haiku-5-5` 生成(与对话走同一条通道);GPT-6 Astra 与 GPT-5.6 Sol 的标题交给 GPT-6.1 Sol。
|
|
260
|
-
- 1.2.x 的 `
|
|
262
|
+
- 1.2.x 的 `claudeCliMode`、`claudeCliCwd` 设置不再恢复:Claude Code 的权限由会话的 DSH 权限预设决定,工作目录就是会话目录。名为 `claude_code` 的工具现在是 cc 会话里显示 Claude Code 工具调用的镜像工具,只由插件使用,不是 1.2.x 的委派工具。`claudeCliPath` 重新生效,用于指定 CLI 位置(留空则按常见安装位置和 PATH 查找)。1.3.4 的 `claudeTransport` 已移除,profile 里残留的值会被忽略。除非你在 CLI 卡片里点「更新 Claude Code CLI」,用户独立安装的 Claude Code 不会被改动。
|
|
261
263
|
- Codex 的 Responses 请求仍需要 `prompt_cache_key`;插件补上缺失的会话标识,其它 Responses 模型省略该字段。
|
|
262
|
-
- 构建后可用 `node scripts/claude-check.mjs` 验证三个 Claude 模型的订单核算、工单归类、库存补货、只读库存查询工具回传、商品色卡标注、中文标题和计划模式(只读查询 → `exit_plan_mode` 提交计划 → 审批),并核对业务答案;加 `--transport cli`
|
|
264
|
+
- 构建后可用 `node scripts/claude-check.mjs` 验证三个 Claude 模型的订单核算、工单归类、库存补货、只读库存查询工具回传、商品色卡标注、中文标题和计划模式(只读查询 → `exit_plan_mode` 提交计划 → 审批),并核对业务答案;加 `--transport cli` 则改跑 cc 通道的检查(`scripts/claude-agent-check.mjs`):在临时目录里让 Claude Code 自己读文件计算、改文件(授权批准)、删文件(授权拒绝)、计划审阅后实施、提问、看图和起标题,核对文件和答案,并统计网关的「客户端异常」和「反滥用」拒绝次数。`node scripts/claude-stability.mjs --start --hours 6 --key-label <备注名>` 开始有截止时间和请求上限的采样;定时执行同一脚本继续采样,用 `--status` 查看记录。业务场景版本和每轮构建分别记录;测试消息拒绝将对应检查记为失败,其余预定检查继续,真实凭据或额度错误仍会停止整个窗口。测试不改变已保存的凭据,也不启动 DSH。
|
|
263
265
|
- 连续对话可用 `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。报告包含场景版本、适配器生命周期、所用上限、首响应和完整响应耗时。这些选项不修改插件的运行参数。
|
|
264
266
|
|
|
265
267
|
</details>
|
|
266
268
|
|
|
267
269
|
## 更新与卸载
|
|
268
270
|
|
|
269
|
-
> **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.
|
|
271
|
+
> **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.4.0` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
|
|
270
272
|
|
|
271
|
-
**更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm
|
|
273
|
+
**更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。新版本号是从 npm 读到的,pnpm 却从 profile 配置的安装源下载:刚发布的版本,安装源(尤其是国内镜像)可能还没同步到,这时按钮会提示过几分钟再更新;连不上安装源时,会提示检查网络或代理。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.4.0`),否则装上的可能是发布满 24 小时的旧版。
|
|
272
274
|
|
|
273
275
|
**从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
|
|
274
276
|
|
|
@@ -284,7 +286,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
284
286
|
|
|
285
287
|
有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
|
|
286
288
|
|
|
287
|
-
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.
|
|
289
|
+
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.4.0`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
|
|
288
290
|
|
|
289
291
|
**首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
|
|
290
292
|
|
|
@@ -296,9 +298,9 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
296
298
|
|
|
297
299
|
**某个模型不可用,但 Key 是有效的?** 看「账户与 Key」里这个 Key 的分组和 ✓ / ✕:分组不覆盖这个模型时,换一个分组合适的 Key,或在 PackyCode 控制台给 Key 加上对应分组。存了分组合适的 Key 时,插件会自动用它跑这个模型。分组拒绝不会停用 Key。
|
|
298
300
|
|
|
299
|
-
**Claude 报「只接受官方 Claude Code CLI」或「客户端存在异常」?** 这是网关的客户端政策拒绝,不等于 Key 失效。看这个 Key 下方标的是「Claude 经 HTTP」还是「经官方 CLI」:`cc` 分组的 Key 总是走 CLI,其它分组走 HTTP
|
|
301
|
+
**Claude 报「只接受官方 Claude Code CLI」或「客户端存在异常」?** 这是网关的客户端政策拒绝,不等于 Key 失效。看这个 Key 下方标的是「Claude 经 HTTP」还是「经官方 CLI」:`cc` 分组的 Key 总是走 CLI,其它分组走 HTTP。cc 分组按请求内容判断是不是 Claude Code 自己在工作;1.4.0 起 cc 会话由 Claude Code 自己完成,正常不会被拒。偶尔仍被拒时重发一次;反复出现时,把错误里的网关原文(含 request id)发给 PackyCode 客服,或改用 `cc-sale` / `cc-expensive` / `claude-officially` 分组的 Key。更新 Claude Code CLI 不能解决这个拒绝。插件不会因此禁用 Key 或切换提供商。
|
|
300
302
|
|
|
301
|
-
**提示「本机没有可用的 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。
|
|
303
|
+
**提示「本机没有可用的 Claude Code CLI」?** 当前 Key 在 `cc` 分组,需要本机 CLI。提示里写着「插件还没读到当前 Key 的分组」时,是分组读取暂时失败(网络或代理不稳时常见):稍后重发即可,不在 `cc` 分组的 Key 读到分组后会自动改走 HTTP。到 **设置 → PackyCode → Claude Code CLI** 点「安装」,或在终端执行 `npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code` 后点「重新检测」;装在非常规位置时可在配置里填 `claudeCliPath`。不想装的话,换用 `cc-sale` / `cc-expensive` 分组的 Key。
|
|
302
304
|
|
|
303
305
|
**提示「本机的 Claude Code CLI 版本过旧」?** 本机 CLI 低于 2.1.259。到 **设置 → PackyCode → Claude Code CLI** 点「更新 Claude Code CLI」,完成后重发;也可以在终端执行 `claude update`(npm 安装的执行卡片上显示的 npm 命令),再点「重新检测」。Homebrew 安装的用 `brew upgrade claude-code`。
|
|
304
306
|
|
|
@@ -320,7 +322,7 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
320
322
|
|
|
321
323
|
## 安全边界
|
|
322
324
|
|
|
323
|
-
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。`cc` 分组的 Claude
|
|
325
|
+
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。`cc` 分组的 Claude 会话由本机 Claude Code CLI 子进程完成:Key 只以环境变量交给它;它的工具(读写文件、执行命令等)在本机直接执行,不经过 DSH 的沙箱,需要授权的操作按会话的权限预设交给你或自动审查决定,`danger-full-access` 预设下不询问。
|
|
324
326
|
|
|
325
327
|
Key 存在本机 DSH 凭据文件(`~/.dsh/.credentials.yaml`,权限由 DSH 设为仅所有者可读),不进设置文档、日志或对话记录。余额请求只在宿主侧发出,带超时并禁止重定向。
|
|
326
328
|
|