dsh-packycode-api 1.2.6 → 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.8
4
+
5
+ - **Diagnostics for request problems.** Settings → PackyCode gains a **Diagnostics** card (诊断信息). A user who hits "已达到输出 token 上限" or repeated failures picks the session (the 20 most recent top-level sessions, newest first, labelled by local start time, the workspace folder's base name and whether it is open), clicks **Generate diagnostics** and then **Copy**, and sends the text to the plugin author. Without a clipboard API the text is selected for a manual copy. The host builds the text from DSH's session history over two new RPC endpoints, `diagnostics/sessions` and `diagnostics/session`, in format `packycode-diagnostics/1`. It holds the plugin version; the session id, start time and live state; each stored key by position with its groups and reachable models; the logged request settings (provider, model, reasoning effort, `maxTokens`, and whether DSH's adapter supplied that ceiling); the steps that ended at the output limit; the latest steps' token usage and finish reasons; turn endings; retries and failed attempts with their codes; and the compaction count. Error messages are redacted and cut to 160 characters. Conversation text, reasoning, titles, tool arguments and results, paths, key labels and keys never enter it. An invalid session id or a runtime without session history is refused with its own message.
6
+ - **Claude session titles come back as plain text in the user's language.** A Claude session's title runs on `claude-haiku-5-5` inside the Claude Code CLI, where DSH's title rules are only an appendix to the CLI's own system prompt and the user's text arrives as English framing around a JSON array. For a short message such as 在吗, the title came back as English or as raw JSON (`{"title": "Casual greeting check-in"}`). The CLI title prompt now ends by restating the rules: the bare title, not JSON or quoted, in the messages' language, named outright when the text is Chinese, Japanese or Korean. Only the CLI's last text block is read as the reply, so narration before a tool call is never taken for the title. The reply is then unwrapped from a code fence, a JSON object's `title` or a JSON string, a "Title:"/"标题:" label, or wrapping quotes before DSH reads it. A reply that holds no usable title yields no text, so DSH keeps its first-message fallback: several lines (live, Haiku once wrote its thinking on one line and the title on another), a placeholder such as 对话标题 / "Session title", or an empty wrapper. HTTP models' titles and delegated turns are unchanged.
7
+ - README: an FAQ entry on reporting truncated replies and failing requests with the Diagnostics card, and a note on how Claude-session titles are restated and unwrapped.
8
+ - Validation, 2026-10-15: 437 offline tests (10 new for diagnostics, 5 for titles), both rebuilt bundles and the versioned tarball. A browser replay of the built settings page showed the session picker, the generated text and, where the clipboard refused the write, the select-all fallback. Titles were replayed live through the built CLI adapter with DSH 0.2.0-rc.2's exact title request (system prompt, JSON framing, 64-token cap) and a `cc` key. Before the fix, 在吗 came back as `Greeting Check-In` and as `{"title": "Session greeting check"}`. After it, ten titles for 在吗, 你好, 你饿吗, hi and a Chinese repository question all came back as plain text, Chinese for Chinese messages, for about $0.08. No DSH restart.
9
+
10
+ ## 1.2.7
11
+
12
+ - **Image keys can be renamed.** Settings → PackyCode → Image generation and editing gains the same **Rename** action as conversation keys, through a new `images/keys/rename` endpoint on the image key ring (`packycode-api/image-keys`). Both cards share one rename form: the name becomes a text field, Enter or **Save** stores it, Escape or **Cancel** keeps the old one, and only the key id and the new label reach the host.
13
+ - **One quota hover for both key rings.** The PackyCode quota beside the model picker now uses the same component as the image-key quota: the help cursor marks it, and hovering or focusing it shows the same lines — which quota it is, the current key, its account, remaining, used and total quota, and when it was read or that the last read failed. The composer figure's details open leftward so they stay inside the composer.
14
+ - **Registration invite in Settings.** While no conversation key is stored, **Accounts and keys** shows PackyCode's registration invite link (`https://www.packyapi.ai/register?aff=Im3l`) under the empty-state note. It is a new-window link, which DSH desktop hands to the system browser (a web profile opens a tab). It appears only after the host has answered the status read and disappears as soon as any key is stored.
15
+ - **README: install with an exact version.** The Plugins page's install prompt shows the newest npm version, but DSH's bundled pnpm 11 resolves a bare `dsh-packycode-api` to the newest version published at least 24 hours ago (`minimumReleaseAge`). During the 1.1.x/1.2.x release burst a first install therefore landed on 1.1.1 or 1.1.5, whose settings channel needed a DSH restart and answered every call with HTTP 405 until then. The install guide now always enters `dsh-packycode-api@<version>` (pnpm then adds it to `minimumReleaseAgeExclude` itself), the FAQ explains the 405 symptom with a version check and the recovery, and the README links the registration invite for readers without a key.
16
+ - Validation, 2026-10-15: 422 offline tests (6 new for key rename and the shared quota hover, 4 for the invite), both rebuilt bundles and the versioned tarball. The first-install 405 was reproduced against the DSH 0.2.0-rc.2 runtime in an isolated `DSH_HOME`: a Plugins-page install of the bare name prompted 1.2.6, installed 1.1.5 and answered HTTP 405 until restart, while `dsh-packycode-api@1.2.6` installed 1.2.6 and answered at once. A browser replay of the built settings page showed the invite in light and dark themes and no invite with a stored key. No DSH restart, paid request or live gateway call.
17
+
3
18
  ## 1.2.6
4
19
 
5
20
  - Clicking black space around a large image now closes the preview, including the canvas inside the full-size dialog. The image hit area fits its actual displayed dimensions instead of covering letterboxing; image clicks, download controls and error notices keep the viewer open.
package/README.en.md CHANGED
@@ -41,23 +41,25 @@ The `PackyCode` model group ships with the plugin. No YAML edits and no separate
41
41
 
42
42
  ## Install
43
43
 
44
- You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH setup, see the [official instructions](https://github.com/deepseek-ai/deepseek-harness#run).
44
+ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH setup, see the [official instructions](https://github.com/deepseek-ai/deepseek-harness#run). No API key yet? You can register with PackyCode and apply for one through [this invite link](https://www.packyapi.ai/register?aff=Im3l).
45
45
 
46
46
  ### 1. Install the plugin
47
47
 
48
- Open the desktop application's **Plugins** page, click **Add plugin**, and enter this as the **package name or address**:
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
51
+ dsh-packycode-api@1.2.8
52
52
  ```
53
53
 
54
- Choose the **official** install source, then click **Install**. To pin a version, enter `dsh-packycode-api@1.2.6`.
54
+ Choose the **official** install source, then click **Install**. `1.2.8` 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
- A **first install requires no DSH restart**: open **Settings → PackyCode** and add a key immediately. When updating an already loaded older version, follow the restart guidance in the **Plugin version** card.
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
+
58
+ A **first install requires no DSH restart**: open **Settings → PackyCode** and add a key immediately. This holds from 1.1.7 on; earlier versions need one restart after a first install, see the FAQ. When updating an already loaded older version, follow the restart guidance in the **Plugin version** card.
57
59
 
58
60
  ### 2. Add a key
59
61
 
60
- Open **Settings → PackyCode**. Paste the API key under **Add a key**. A label is optional and only distinguishes keys. Click **Add**.
62
+ Open **Settings → PackyCode**. Paste the API key under **Add a key**. A label is optional and only distinguishes keys. Click **Add**. Until a key has been added, **Accounts and keys** shows the same registration invite link, which opens in the system browser; it disappears once a key is stored.
61
63
 
62
64
  > Do not paste a key into a public issue, chat, or screenshot. The plugin does not read `PACKY_CODE_API_KEY` from the environment, and it does not silently switch to another provider when a request fails.
63
65
 
@@ -70,7 +72,7 @@ Choose a model from the `PackyCode` group. `deepseek-flash`, `gpt-6.1-sol`, `gpt
70
72
 
71
73
  The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
72
74
 
73
- **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.6`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
75
+ **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.8`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
74
76
 
75
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.
76
78
 
@@ -202,7 +204,7 @@ Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit
202
204
  - The reasoning block opens with `▸ 启动 Claude Code CLI…` and then shows the CLI's version and model once it is up. When the gateway throttles or is busy (429, 503 `账号并发排队已满` / per-account wait queue full, and similar), the CLI retries up to 10 times on its own; each retry now shows as `↻ 网关返回 HTTP 503,CLI 自动重试 n/10` instead of looking hung. When the retries run out, the turn says PackyCode's Claude upstream is busy, not that the key is bad. A CLI that prints nothing for 2 minutes after starting is stopped and reported.
203
205
  - The conversation and its images reach the CLI over stdin (`--input-format stream-json`), not argv: a Windows command line is length-limited and cannot carry an image. Images in the conversation are sent to Claude as images, at the HTTP route's request size (at most 2048×2048, about 1 MiB each; at most 20 images and 20 MiB per turn, dropping the oldest first). An image left out is named with its read-only local copy, which the CLI can open with Read.
204
206
  - Every run carries `--append-system-prompt` (the delegation note). In `-p` mode the official CLI introduces itself as "You are Claude Code, Anthropic's official CLI for Claude …" when it has appended instructions and as "You are a Claude agent, built on Anthropic's Claude Agent SDK." when it has none; the latter was refused upstream as not coming from the official CLI (403 `only accepts requests from the official Claude Code CLI`). That is the official CLI's own behavior; the plugin does not rewrite its system prompt.
205
- - While the session model is a Claude model, titles are generated with `claude-haiku-5-5`, read-only, in a temporary directory, instead of a full Opus turn.
207
+ - While the session model is a Claude model, titles are generated with `claude-haiku-5-5`, read-only, in a temporary directory, instead of a full Opus turn. Inside the CLI, DSH's title rules are only an appendix to the CLI's own system prompt, and a very short message such as 在吗 used to come back as English JSON (`{"title": "Casual greeting check-in"}`). The prompt therefore ends by restating them: the bare title as plain text, in the language of the messages (Chinese, Japanese and Korean are named by their script). A reply that still arrives in JSON, a code fence, quotes or after a "Title:" label is unwrapped before DSH reads it. A reply of several lines (the model wrote out its thinking or an explanation, so the title line cannot be told) or a bare placeholder such as "Session title" yields no title, and DSH keeps its default title from the first message.
206
208
  - While the session model is `gpt-6-astra`, titles are generated with `gpt-6.1-sol` (same Codex group); the turns themselves stay on Astra. Other models title their own sessions.
207
209
  - The `claude_code` tool can delegate one task to the local CLI while the session model is `gpt-6.1-sol`, `gpt-6-astra`, or `deepseek-flash`. The requested `mode` cannot exceed what the session preset allows. While the session is in plan mode the delegation plans too, and returns the plan text to the parent model.
208
210
  - An effort level the model does not support is rejected before the request is sent. Do not edit a model's effort map casually.
@@ -211,7 +213,7 @@ Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit
211
213
 
212
214
  ## Update and uninstall
213
215
 
214
- **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. 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 `dsh-packycode-api` from the **Plugins** page does the same job.
216
+ **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. 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.2.8`); without it you may get a version that is merely the newest one published at least 24 hours ago.
215
217
 
216
218
  **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.
217
219
 
@@ -227,7 +229,15 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
227
229
 
228
230
  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.
229
231
 
230
- Recovery: **uninstall** the plugin on the **Plugins** page, **install** `dsh-packycode-api` again, 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.
232
+ Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.2.8`), 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.
233
+
234
+ **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:
235
+
236
+ ```sh
237
+ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.json
238
+ ```
239
+
240
+ Recovery: quit and reopen the desktop application, and the old version works. Then click **Check for updates** → **Update plugin** under **Settings → PackyCode → Plugin version** (it installs the exact latest version and is not subject to the 24-hour rule), and restart once more.
231
241
 
232
242
  **Web search says "no stored API key's group covers …"?** The search backend's model is not in your token groups (or the gateway currently routes it to another supplier). Pick the other backend under **Settings → PackyCode → Web search**, or add a key whose group covers it.
233
243
 
@@ -243,17 +253,19 @@ Recovery: **uninstall** the plugin on the **Plugins** page, **install** `dsh-pac
243
253
 
244
254
  **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**.
245
255
 
246
- **Installing from the Plugins page fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** pnpm refuses packages published less than 24 hours ago and checks the whole profile lockfile. 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.
256
+ **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.
247
257
 
248
258
  **The CLI is installed, but Claude still fails?** A host launched from Finder or the Start menu usually has a shorter `PATH` than a terminal. The plugin also checks the official install location, common package-manager directories, and `npm prefix -g`. If it still cannot find the binary, set `claudeCliPath` or click **Check again**. After a Host change or a reinstall, quit and reopen the desktop application.
249
259
 
260
+ **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.
261
+
250
262
  ## Security and scope
251
263
 
252
264
  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 models also start the official CLI on this device.
253
265
 
254
266
  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
267
 
256
- Use [Issues](https://github.com/BaronCyrus/dsh-packycode-api/issues) for ordinary bugs. Never include a key, token, or credential-file contents. See [SECURITY.md](SECURITY.md).
268
+ Use [Issues](https://github.com/BaronCyrus/dsh-packycode-api/issues) for ordinary bugs; for a failing request, attach the text from the **Diagnostics** card. Never include a key, token, or credential-file contents. See [SECURITY.md](SECURITY.md).
257
269
 
258
270
  ## Local development
259
271
 
package/README.md CHANGED
@@ -41,23 +41,25 @@
41
41
 
42
42
  ## 安装
43
43
 
44
- 先准备好 **DeepSeek Harness** 和 **PackyCode(PackyAPI)的 API Key**。尚未安装 DSH,可查看 [DSH 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。
44
+ 先准备好 **DeepSeek Harness** 和 **PackyCode(PackyAPI)的 API Key**。尚未安装 DSH,可查看 [DSH 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。还没有 API Key 的,可以通过[这个邀请链接](https://www.packyapi.ai/register?aff=Im3l)注册 PackyCode 申请。
45
45
 
46
46
  ### 1. 安装插件
47
47
 
48
- 打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入:
48
+ 打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
49
49
 
50
50
  ```text
51
- dsh-packycode-api
51
+ dsh-packycode-api@1.2.8
52
52
  ```
53
53
 
54
- 在**安装源**中选择**官方源**,然后点击**安装**。需要固定版本时填入 `dsh-packycode-api@1.2.6`。
54
+ 在**安装源**中选择**官方源**,然后点击**安装**。`1.2.8` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
55
55
 
56
- 首次安装后**无需重启 DSH**,可直接打开**设置 → PackyCode** 添加 Key。更新已加载的旧版时,按「插件版本」卡片的重启提示操作。
56
+ > **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
57
+
58
+ 首次安装后**无需重启 DSH**,可直接打开**设置 → PackyCode** 添加 Key。这适用于 1.1.7 及以后的版本;更早的版本首次安装后要重启一次,见「常见问题」。更新已加载的旧版时,按「插件版本」卡片的重启提示操作。
57
59
 
58
60
  ### 2. 添加 Key
59
61
 
60
- 打开 **设置 → PackyCode**,在「添加 Key」里粘贴 API Key。备注可选,用来区分多个 Key。点「添加」。
62
+ 打开 **设置 → PackyCode**,在「添加 Key」里粘贴 API Key。备注可选,用来区分多个 Key。点「添加」。还没有添加过 Key 时,「账户与 Key」里会显示同一个注册邀请链接,点击后在系统浏览器中打开;添加 Key 之后就不再显示。
61
63
 
62
64
  > 不要把 Key 粘贴到公开 Issue、聊天记录或截图里。插件不会读取环境变量 `PACKY_CODE_API_KEY`,也不会在失败时偷偷改用别的 provider。
63
65
 
@@ -70,7 +72,7 @@ dsh-packycode-api
70
72
 
71
73
  桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
72
74
 
73
- **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.6`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
75
+ **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.8`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
74
76
 
75
77
  本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
76
78
 
@@ -202,7 +204,7 @@ Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses
202
204
  - 思考区第一行是「▸ 启动 Claude Code CLI…」,CLI 起来后显示版本和模型。网关限流或繁忙(429、503 `账号并发排队已满` 等)时,CLI 会自己重试最多 10 次,每次重试都会显示成 `↻ 网关返回 HTTP 503,CLI 自动重试 n/10`,不再像卡住。重试用完仍失败时,会说明是 PackyCode 的 Claude 上游繁忙,不是 Key 的问题。CLI 启动后 2 分钟内没有任何输出会被停止并报告原因。
203
205
  - 对话记录和图片通过 stdin 交给 CLI(`--input-format stream-json`),不走命令行参数:Windows 命令行长度有上限,而且命令行带不了图片。对话里的图片会以图片形式发给 Claude(与 HTTP 路由相同的压缩规格:每张不超过 2048×2048、约 1 MiB;一回合最多 20 张、合计 20 MiB,超出时先舍弃最早的)。没随消息发出的图片会写明本机只读副本的路径,CLI 需要时可以用 Read 读取。
204
206
  - 每次运行都带 `--append-system-prompt`(委派说明)。在 `-p` 模式下,官方 CLI 有追加说明时会以 "You are Claude Code, Anthropic's official CLI for Claude …" 自我介绍,没有时是 "You are a Claude agent, built on Anthropic's Claude Agent SDK.";后者曾被上游当成非官方 CLI 拒绝(403 `only accepts requests from the official Claude Code CLI`)。这是官方 CLI 自己的行为,插件没有改写它的系统提示词。
205
- - 会话跑在 Claude 模型上时,生成标题改用 `claude-haiku-5-5`,只读、临时目录,避免为起标题跑一整轮 Opus。
207
+ - 会话跑在 Claude 模型上时,生成标题改用 `claude-haiku-5-5`,只读、临时目录,避免为起标题跑一整轮 Opus。DSH 的标题要求在 CLI 里只是追加在它自己系统提示词后面的一段,「在吗」这类很短的消息曾被起成 `{"title": "Casual greeting check-in"}` 这样的英文 JSON。所以插件会在提示词末尾再强调一次:只回标题纯文本,用消息原文的语言(中文、日文、韩文按文字直接点名)。回复里仍带 JSON、代码块、引号或「Title:」前缀时,插件会先剥掉再交给 DSH。如果回复有好几行(模型把思考或解释也写了出来,分不清哪行是标题),或者只是「对话标题」这类占位词,就不给标题,DSH 会保留按首条消息生成的默认标题。
206
208
  - 会话跑在 `gpt-6-astra` 上时,标题改由 `gpt-6.1-sol` 生成(同一个 Codex 分组);对话本身仍然用 Astra。其它模型的标题由会话模型自己生成。
207
209
  - 另有 `claude_code` 工具:当前模型是 `gpt-6.1-sol`、`gpt-6-astra` 或 `deepseek-flash` 时,可以把一个任务委派给本机 Claude Code。请求的 `mode` 不会超过会话权限允许的上限;会话处于计划模式时,这个委派也只规划,并把计划正文交回父模型。
208
210
  - 声明了模型不支持的推理档位会被 harness 在发请求前拒绝,不要随手改档位映射。
@@ -211,7 +213,7 @@ Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses
211
213
 
212
214
  ## 更新与卸载
213
215
 
214
- **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装 `dsh-packycode-api`。
216
+ **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.2.8`),否则装上的可能是发布满 24 小时的旧版。
215
217
 
216
218
  **从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
217
219
 
@@ -227,7 +229,15 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
227
229
 
228
230
  有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
229
231
 
230
- 修复:到**插件**页**卸载**本插件,再重新**安装** `dsh-packycode-api`,然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
232
+ 修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.2.8`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
233
+
234
+ **首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
235
+
236
+ ```sh
237
+ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.json
238
+ ```
239
+
240
+ 处理:完全退出并重新打开桌面应用,旧版即可正常使用。然后在 **设置 → PackyCode → 插件版本** 点「检查更新」→「更新插件」(它会固定安装最新版,不受 24 小时规则限制),再重启一次。
231
241
 
232
242
  **某个模型不可用,但 Key 是有效的?** 看「账户与 Key」里这个 Key 的分组和 ✓ / ✕:分组不覆盖这个模型时,换一个分组合适的 Key,或在 PackyCode 控制台给 Key 加上对应分组。存了分组合适的 Key 时,插件会自动用它跑这个模型。分组拒绝不会停用 Key。
233
243
 
@@ -241,19 +251,21 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
241
251
 
242
252
  **限速之后 Key 被停用了?** 不该发生。429 不会切换 Key。额度用尽或 401 才会停用;充值后点「重新启用」。
243
253
 
244
- **插件页安装报 `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** pnpm 默认拒绝发布不满 24 小时的包,并且会检查 profile 里的整个 lockfile。报错里点名的往往是另一个刚更新过的插件,不是本插件。等它发布满 24 小时再重试,或把报错里的 `包名@版本` 加到 profile 目录 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 下。已安装本插件后,设置页的「更新插件」不受这个限制。
254
+ **插件页安装报 `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** pnpm 默认只接受发布满 24 小时的版本,并且会检查 profile 里的整个 lockfile。(只填本插件的包名不会报这个错,而是悄悄装上满 24 小时的旧版,见「安装插件」。)报错里点名的往往是另一个刚更新过的插件,不是本插件。等它发布满 24 小时再重试,或把报错里的 `包名@版本` 加到 profile 目录 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 下。已安装本插件后,设置页的「更新插件」不受这个限制。
245
255
 
246
256
  **网页搜索报「no stored API key's group covers …」?** 所选搜索后端的模型不在你的令牌分组里(或网关暂时把它路由到了别的供应商)。在 **设置 → PackyCode → 网页搜索** 换一个后端,或添加分组覆盖它的 Key。
247
257
 
248
258
  **装了 CLI 还是不能用 Claude?** 从 Finder 或开始菜单启动时,`PATH` 往往比终端短。插件会再查官方安装位置、常见包管理器目录和 `npm prefix -g`。仍找不到就在设置里填 `claudeCliPath`,或点「重新检测」。改的是 Host 或重新安装了插件时,要完全退出并重启桌面应用。
249
259
 
260
+ **回答被截断(「已达到输出 token 上限」)、请求反复失败,怎么反馈?** 打开 **设置 → PackyCode → 诊断信息**,选出问题的会话(最近 20 个,按时间倒序,标着所在文件夹名),点「生成诊断信息」再点「复制」,把内容贴到 [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues) 或发给插件作者。内容只有设置和数字:插件版本、会话 id 与创建时间、每个 Key 的序号与分组(不含备注名和 Key 本身)、每次请求用的模型、推理档位和输出上限、最近若干步的 token 用量与结束原因,以及重试和失败的错误码(错误信息已脱敏并截短)。不含对话内容、文件路径和 Key。复制不可用时,文本会被全选,按 ⌘C 或 Ctrl+C 即可。
261
+
250
262
  ## 安全边界
251
263
 
252
264
  本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。Claude 模型还会在本机启动官方 CLI。
253
265
 
254
266
  Key 存在本机 DSH 凭据文件(`~/.dsh/.credentials.yaml`,权限由 DSH 设为仅所有者可读),不进设置文档、日志或对话记录。余额请求只在宿主侧发出,带超时并禁止重定向。
255
267
 
256
- 普通问题请提交 [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues)。不要附带 Key、令牌或凭据文件内容。更多说明见 [SECURITY.md](SECURITY.md)。
268
+ 普通问题请提交 [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues),请求出错时可附上「诊断信息」卡片生成的内容。不要附带 Key、令牌或凭据文件内容。更多说明见 [SECURITY.md](SECURITY.md)。
257
269
 
258
270
  ## 本地开发
259
271