@dan-ai-studio/dshopencodego 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +156 -0
  3. package/README.md +156 -0
  4. package/cordis.patch.yml +3 -0
  5. package/lib/build-info.json +11 -0
  6. package/lib/client.js +1215 -0
  7. package/lib/index.js +2036 -0
  8. package/lib/types/adapter.d.ts +84 -0
  9. package/lib/types/adapter.js +311 -0
  10. package/lib/types/catalog/constants.d.ts +16 -0
  11. package/lib/types/catalog/constants.js +16 -0
  12. package/lib/types/catalog/contract.d.ts +26 -0
  13. package/lib/types/catalog/contract.js +131 -0
  14. package/lib/types/catalog/gateway.d.ts +20 -0
  15. package/lib/types/catalog/gateway.js +59 -0
  16. package/lib/types/catalog/index.d.ts +108 -0
  17. package/lib/types/catalog/index.js +288 -0
  18. package/lib/types/catalog/json-response.d.ts +19 -0
  19. package/lib/types/catalog/json-response.js +72 -0
  20. package/lib/types/catalog/metadata.d.ts +73 -0
  21. package/lib/types/catalog/metadata.js +259 -0
  22. package/lib/types/catalog/protocol.d.ts +65 -0
  23. package/lib/types/catalog/protocol.js +87 -0
  24. package/lib/types/catalog/reading.d.ts +41 -0
  25. package/lib/types/catalog/reading.js +68 -0
  26. package/lib/types/catalog/service.d.ts +32 -0
  27. package/lib/types/catalog/service.js +45 -0
  28. package/lib/types/config.d.ts +93 -0
  29. package/lib/types/config.js +76 -0
  30. package/lib/types/conversion/context.d.ts +55 -0
  31. package/lib/types/conversion/context.js +202 -0
  32. package/lib/types/conversion/index.d.ts +9 -0
  33. package/lib/types/conversion/index.js +7 -0
  34. package/lib/types/conversion/replay.d.ts +56 -0
  35. package/lib/types/conversion/replay.js +242 -0
  36. package/lib/types/conversion/stream.d.ts +46 -0
  37. package/lib/types/conversion/stream.js +203 -0
  38. package/lib/types/go-limits.d.ts +41 -0
  39. package/lib/types/go-limits.js +79 -0
  40. package/lib/types/index.d.ts +54 -0
  41. package/lib/types/index.js +195 -0
  42. package/lib/types/models.d.ts +90 -0
  43. package/lib/types/models.js +86 -0
  44. package/lib/types/remotes.d.ts +12 -0
  45. package/lib/types/remotes.js +28 -0
  46. package/lib/types/session-header.d.ts +36 -0
  47. package/lib/types/session-header.js +45 -0
  48. package/lib/types/usage/contract.d.ts +39 -0
  49. package/lib/types/usage/contract.js +106 -0
  50. package/lib/types/usage/index.d.ts +11 -0
  51. package/lib/types/usage/index.js +8 -0
  52. package/lib/types/usage/meter.d.ts +53 -0
  53. package/lib/types/usage/meter.js +65 -0
  54. package/lib/types/usage/service.d.ts +48 -0
  55. package/lib/types/usage/service.js +74 -0
  56. package/lib/types/usage/windows.d.ts +51 -0
  57. package/lib/types/usage/windows.js +84 -0
  58. package/package.json +147 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dan ai studio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,156 @@
1
+ # @dan-ai-studio/dshopencodego
2
+
3
+ Makes [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) work properly with an [OpenCode Go](https://opencode.ai/docs/go/) subscription: the model list comes straight from the gateway, and every inference request carries the `x-opencode-session` header the gateway requires.
4
+
5
+ [中文](README.md)
6
+
7
+ ## Why it exists
8
+
9
+ A stock DSH route to OpenCode Go has two gaps that no configuration can close:
10
+
11
+ 1. **The model list is a build-time snapshot.** DSH's `llm-pi-ai` uses the catalog pi-ai shipped with; when the gateway adds a model, you either wait for a pi-ai release or declare it by hand.
12
+ 2. **No session header.** Since 2026-09-05 Go requires a stable `x-opencode-session` on every request and answers `400 MissingSessionID` without it; `llm-pi-ai` sends only static profile headers, which cannot vary per conversation.
13
+
14
+ This plugin serves the `opencode-go` route with its own adapter and closes both gaps.
15
+
16
+ ## Install
17
+
18
+ Prerequisites: a DSH `0.1.7` release (see "Compatibility"); Node `^22.19.0 || >=24.0.0`; `dsh` and `pnpm` on PATH.
19
+
20
+ > **One owner per route**: a profile can have exactly one adapter for `opencode-go`. Remove the previous plugin (`dsh plugin --profile <p> remove @dan-ai-studio/dsh-opencode-go`) or clear any `opencode-go` provider in `llm-pi-ai` first. Otherwise the plugin logs an explicit ownership diagnostic and does not register the route — everything else keeps working.
21
+
22
+ ### Option 1: GitHub Release (recommended)
23
+
24
+ ```sh
25
+ dsh plugin --profile web add https://github.com/dan-ai-studio/dshopencodego/releases/download/v<version>/dan-ai-studio-dshopencodego-<version>.tgz
26
+ ```
27
+
28
+ Confirm the composition picked it up:
29
+
30
+ ```sh
31
+ dsh --profile web --dump-config | grep dshopencodego
32
+ ```
33
+
34
+ ### Option 2: npm (prepared, not enabled yet)
35
+
36
+ The publish workflow exists but is inert until the npm scope and `NPM_TOKEN` exist (see "Releasing"). Once enabled:
37
+
38
+ ```sh
39
+ dsh plugin --profile web add @dan-ai-studio/dshopencodego@<version>
40
+ ```
41
+
42
+ ### Option 3: build locally
43
+
44
+ ```sh
45
+ npm ci
46
+ npm run build
47
+ npm pack
48
+ dsh plugin --profile web add ./dan-ai-studio-dshopencodego-<version>.tgz
49
+ ```
50
+
51
+ > Install tarballs by **local path**. A remote tarball URL against a profile that already has a cache hits pnpm's `ERR_PNPM_MISSING_TARBALL_INTEGRITY` (see "Troubleshooting").
52
+
53
+ ### Upgrade and remove
54
+
55
+ ```sh
56
+ dsh plugin --profile web add <new tarball or package> # upgrade
57
+ dsh plugin --profile web remove @dan-ai-studio/dshopencodego # remove
58
+ ```
59
+
60
+ > pnpm silently reuses a **same-named local tarball** (`added 0`). Rename the file when reinstalling a fresh local build.
61
+
62
+ ## Configuration
63
+
64
+ Configuration lives in the profile's `cordis.patch.yml`:
65
+
66
+ ```yaml
67
+ - id: dshopencodego
68
+ name: '@dan-ai-studio/dshopencodego'
69
+ config:
70
+ enabled: true # false withdraws the route only
71
+ apiKeyEnv: OPENCODE_GO_API_KEY # default
72
+ baseURL: https://opencode.ai/zen/go/v1 # default
73
+ refreshMinutes: 60 # live catalog TTL
74
+ modelVisibility: # per-model switches (deprecated default off)
75
+ glm-5: true
76
+ modelLimits: # per-model capacity overrides
77
+ kimi-k3:
78
+ contextWindow: 262144
79
+ modelProtocols: # last resort: per-model protocol override
80
+ some-new-model: openai-responses
81
+ ```
82
+
83
+ The API key comes from the Harness credential store (reference name `OPENCODE_GO_API_KEY`), or from `export OPENCODE_GO_API_KEY=...`.
84
+
85
+ ## How a model is resolved
86
+
87
+ Four evidence levels decide how a model is called, first hit wins:
88
+
89
+ 1. **The installed pi-ai catalog entry** — protocol plus wire quirks (DeepSeek's `thinkingFormat`, for example).
90
+ 2. **models.dev's per-model `provider.npm`** — `@ai-sdk/openai` → Responses, `@ai-sdk/anthropic` → Messages, absent → Chat Completions.
91
+ 3. **Family rule** — `grok*`/`gpt*`/`muse-*` → Responses, everything else → Chat Completions.
92
+ 4. **`modelProtocols` override** — always wins.
93
+
94
+ The gateway's `/v1/models` answers only *which* models exist, never *how* to call them. Inferred decisions are labelled in the settings page; override them with `modelProtocols`.
95
+
96
+ ## The model list in the settings page
97
+
98
+ The "OpenCode Go" section shows the live gateway catalog (42+ models) with, per model:
99
+
100
+ - **context / max input / max output**, **release date**, **price per 1M tokens** (from models.dev), and **Go allowance**;
101
+ - **Go allowance** comes from OpenCode's own documentation (the "usage limits / estimated requests" tables) — **no API exposes it**. It is a transcribed table (source URL and date in the `src/go-limits.ts` header); pricing or promotion changes require updating it and shipping a release;
102
+ - filtering (by name/id, enabled-only, show-deprecated — **deprecated hidden by default**), sorting (newest first, monthly requests, input price, context, name, enabled first), and a list/table view switch.
103
+
104
+ **Default switches**: with no explicit `modelVisibility` entries at all, the **top five models by published monthly request estimate** are enabled (deprecated, unconfigurable, and training-"contributor" models never qualify). The first explicit entry switches the whole list to explicit values. The Host picker and the settings page compute this from one rule, so they never disagree.
105
+
106
+ ## Usage
107
+
108
+ - **Quota windows**: `GET /usage` reports 5-hour / weekly / monthly percentages with reset times and rate-limit flags; a failed read keeps the last reading and marks it stale, and an account or endpoint change invalidates it.
109
+ - **Actual spend**: the in-conversation button reports calls and tokens (input/output/cache-read) this process spent since it started, from the usage the provider returns on each call. The gateway publishes no per-model tokens, so the numbers are labelled for what they are instead of faking a per-model quota.
110
+
111
+ ## Compatibility
112
+
113
+ **Supported**: DSH `0.1.7` releases (including `0.1.7-alpha.1`, `0.1.7-rc.*`, and the final release). Every `@deepseek-ai/dsh-*` peer dependency declares `>=0.1.7-alpha.1 <0.1.8`.
114
+
115
+ **The mechanism (not a hard pin)**: before mounting a plugin, DSH reads its `package.json` `peerDependencies` and semver-checks each against the **running DSH version** (prereleases participate):
116
+
117
+ - all satisfied → the plugin loads;
118
+ - any mismatch → **that plugin row is disabled with a printed reason** (`Plugin … is incompatible with dsh …`), leaving other plugins untouched;
119
+ - to take the risk anyway, grant an **exact-version exemption**: `dsh plugin allow-version <pkg>@<version> --dsh-version <exact> --accept-risk` (applies only to that package and that exact runtime version).
120
+
121
+ The `engines.dsh` field is informational for readers and package managers; **DSH's compatibility gate reads only `peerDependencies`**. `@deepseek-ai/cordis` is declared separately as `4.0.2 || 4.0.3 || 4.0.4`.
122
+
123
+ **0.1.8+ or older releases**: the plugin is refused. If the seam is compatible, widen the peer range in your own build (never in DSH core), or wait for a plugin release.
124
+
125
+ ## Troubleshooting
126
+
127
+ | Symptom | Cause and fix |
128
+ |---|---|
129
+ | Log says `another adapter already owns it`; the plugin's models are missing | The `opencode-go` route is owned by the previous plugin or by an `llm-pi-ai` provider entry. Remove the owner or clear its config, then restart. |
130
+ | Settings page shows "Not configured" while requests still work | Pre-v0.1.4 builds had this defect (credential results were not unwrapped from their envelope). Upgrade. |
131
+ | Install fails with `ERR_PNPM_IGNORED_BUILDS` | A fresh profile's `pnpm-workspace.yaml` carries placeholder `allowBuilds` text; set `@google/genai` and `protobufjs` to `false` (neither needs to run scripts) and reinstall. |
132
+ | Remote tarball install fails with `ERR_PNPM_MISSING_TARBALL_INTEGRITY` | pnpm wants an integrity entry for a cached profile. Download the tarball and install by **local path**. |
133
+ | A reinstalled local tarball behaves like the old build | pnpm reuses a same-named local tarball. Rename the file and install again. |
134
+ | "The settings write was rejected" | Usually a concurrent writer (another window or process) holding the same profile. The plugin retries once automatically; if it still fails the view has reloaded — click again. |
135
+ | The usage button shows "unavailable" | An endpoint or credential change invalidated the previous reading. Fix the configuration and press Retry. It never shows `0` in place of a missing reading. |
136
+
137
+ ## Development
138
+
139
+ ```sh
140
+ npm ci
141
+ npm run typecheck # both halves: host and client
142
+ npm test # contract tests against a real local HTTP mock gateway
143
+ npm run build # emits lib/index.js and lib/client.js
144
+ ```
145
+
146
+ 148 tests across 24 files cover configuration validation, the protocol ladder, gateway and online metadata, the catalog projection, the adapter on the wire (all three protocols), Remote contracts and services, session-header invariants, usage windows and the meter, the client controller and usage pill, and both halves' mounting and registration.
147
+
148
+ ## Releasing (maintainers)
149
+
150
+ 1. **Version**: align `package.json`'s `version` with the tag you are about to push (`v<version>`); CI checks the asset name against the tag.
151
+ 2. **GitHub Release**: commit and push `main`, then push the tag. `release.yml` runs the tests, `npm pack`s, and uploads the tarball as the release asset.
152
+ 3. **npm (prepared, not enabled)**: `.github/workflows/publish-npm.yml` is manual-only and needs publish rights for the `@dan-ai-studio` scope plus the `NPM_TOKEN` repository secret. It verifies tag-versus-version, refuses to overwrite an existing version, and publishes with `--provenance`. The enablement steps live in the file header.
153
+
154
+ ## License
155
+
156
+ MIT
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # @dan-ai-studio/dshopencodego
2
+
3
+ 让 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 正常使用 [OpenCode Go](https://opencode.ai/docs/zh-cn/go/) 订阅:模型列表直接来自网关,且每个推理请求都携带网关要求的 `x-opencode-session`。
4
+
5
+ [English](README.en.md)
6
+
7
+ ## 为什么需要它
8
+
9
+ 原生 DSH 接 OpenCode Go 有两个缺口,都不是配置能补的:
10
+
11
+ 1. **模型列表是构建期快照**。DSH 的 `llm-pi-ai` 用 pi-ai 打包时生成的目录;网关新增模型后,要么等 pi-ai 发版,要么手工声明。
12
+ 2. **没有会话头**。Go 自 2026-09-05 起要求每个请求带稳定的 `x-opencode-session`,缺失即 `400 MissingSessionID`;`llm-pi-ai` 只发静态 profile headers,无法按会话取值。
13
+
14
+ 本插件为 `opencode-go` 路由提供自己的适配器,同时解决这两点。
15
+
16
+ ## 安装
17
+
18
+ 前提:DSH `0.1.7` 系列(见「兼容性」);Node `^22.19.0 || >=24.0.0`;`dsh` 与 `pnpm` 可用。
19
+
20
+ > **路由互斥**:同一个 profile 里 `opencode-go` 只能由一个适配器提供。装本插件前请先卸载旧插件(`dsh plugin --profile <p> remove @dan-ai-studio/dsh-opencode-go`),或清空 `llm-pi-ai` 配置里名为 `opencode-go` 的 provider。否则插件会记录一条明确的占用诊断,路由不会注册(其余功能照常)。
21
+
22
+ ### 方式一:GitHub Release(推荐)
23
+
24
+ ```sh
25
+ dsh plugin --profile web add https://github.com/dan-ai-studio/dshopencodego/releases/download/v<版本>/dan-ai-studio-dshopencodego-<版本>.tgz
26
+ ```
27
+
28
+ 安装后确认组合里出现该插件:
29
+
30
+ ```sh
31
+ dsh --profile web --dump-config | grep dshopencodego
32
+ ```
33
+
34
+ ### 方式二:npm(准备中)
35
+
36
+ 发布工作流已经就绪但**尚未启用**(需要 npm scope 与 `NPM_TOKEN`,见「发布」)。启用后即可:
37
+
38
+ ```sh
39
+ dsh plugin --profile web add @dan-ai-studio/dshopencodego@<版本>
40
+ ```
41
+
42
+ ### 方式三:本地构建
43
+
44
+ ```sh
45
+ npm ci
46
+ npm run build
47
+ npm pack
48
+ dsh plugin --profile web add ./dan-ai-studio-dshopencodego-<版本>.tgz
49
+ ```
50
+
51
+ > 用**本地路径**安装 tarball。把远程 tarball URL 装进一个已有缓存的 profile 会撞上 pnpm 的 `ERR_PNPM_MISSING_TARBALL_INTEGRITY`(见「故障排查」)。
52
+
53
+ ### 升级与卸载
54
+
55
+ ```sh
56
+ dsh plugin --profile web add <新版本 tarball 或包名> # 升级
57
+ dsh plugin --profile web remove @dan-ai-studio/dshopencodego # 卸载
58
+ ```
59
+
60
+ > pnpm 对**同名本地 tarball** 会静默复用旧内容(`added 0`)。升级本地构建时请改文件名再装。
61
+
62
+ ## 配置
63
+
64
+ 配置写在 profile 的 `cordis.patch.yml`:
65
+
66
+ ```yaml
67
+ - id: dshopencodego
68
+ name: '@dan-ai-studio/dshopencodego'
69
+ config:
70
+ enabled: true # false 仅撤下路由,插件保持挂载
71
+ apiKeyEnv: OPENCODE_GO_API_KEY # 默认值
72
+ baseURL: https://opencode.ai/zen/go/v1 # 默认值
73
+ refreshMinutes: 60 # 目录缓存时长
74
+ modelVisibility: # 逐模型开关(弃用模型默认关闭)
75
+ glm-5: true
76
+ modelLimits: # 逐模型容量覆盖
77
+ kimi-k3:
78
+ contextWindow: 262144
79
+ modelProtocols: # 最后兜底:逐模型协议覆盖
80
+ some-new-model: openai-responses
81
+ ```
82
+
83
+ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),也可以直接 `export OPENCODE_GO_API_KEY=...`。
84
+
85
+ ## 模型是怎么判定的
86
+
87
+ 一个模型"怎么调"由四级证据决定,先命中先赢:
88
+
89
+ 1. **内置 pi-ai 目录的精确条目**——给出协议与线怪癖(如 DeepSeek 的 `thinkingFormat`)。
90
+ 2. **models.dev 的每模型 `provider.npm`**——`@ai-sdk/openai` → Responses,`@ai-sdk/anthropic` → Messages,缺省 → Chat Completions。
91
+ 3. **家族规则**——`grok*`/`gpt*`/`muse-*` → Responses,其余 → Chat Completions。
92
+ 4. **`modelProtocols` 覆盖**——永远最高优先。
93
+
94
+ 网关的 `/v1/models` 只回答"有哪些模型",不回答"怎么调"。被推断出来的模型会在设置页标注,判错时用 `modelProtocols` 覆盖即可。
95
+
96
+ ## 设置页里的模型列表
97
+
98
+ 设置页的「OpenCode Go」分区展示网关实时目录(42 个起),并对每个模型给出:
99
+
100
+ - **上下文 / 输入 / 输出**(最大输入只有部分模型有官方数据)、**发布时间**、**单价 /1M**(来自 models.dev)、**Go 额度**;
101
+ - **Go 额度**来自 OpenCode 官方文档的「使用限制 / 预估请求数」表,**没有接口提供**,是本插件转写的数据表(见 `src/go-limits.ts` 的注释:来源 URL 与转写日期);文档调整价格或促销时需要更新该表并随发版发布。
102
+ - 筛选(按名称/ID、仅已启用、显示已弃用——**默认隐藏已弃用**)、排序(新发布优先 / 每月预估次数 / 输入单价 / 上下文 / 名称 / 已启用优先)、列表与表格两种视图。
103
+
104
+ **默认开关规则**:没人显式配置过 `modelVisibility` 时,默认启用**每月预估次数最高的 5 个**(跳过已弃用、无法配置、以及"贡献者版"这类以数据换折扣的模型);**一旦有任一显式条目,全部按显式值走**。同一规则同时作用于模型选择器与设置页,两处不会出现不同答案。
105
+
106
+ ## 用量
107
+
108
+ - **额度窗口**:`GET /usage` 返回 5 小时 / 本周 / 本月三个百分比,含重置时间与限流状态;失败时保留上次读数并标注陈旧,账号或端点变化时不保留。
109
+ - **实际消耗**:会话内按钮显示本进程自启动以来的调用次数与 token(输入/输出/缓存读),数据来自 provider 每次调用回传的 usage。网关不公布分模型 token,因此这里如实标注口径,不伪造分模型配额。
110
+
111
+ ## 兼容性
112
+
113
+ **支持**:DSH `0.1.7` 系列(含 `0.1.7-alpha.1`、`0.1.7-rc.*` 与正式版)。插件在每个 `@deepseek-ai/dsh-*` 的 `peerDependencies` 上声明 `>=0.1.7-alpha.1 <0.1.8`。
114
+
115
+ **机制(不是写死)**:DSH 在挂载插件前会读取插件 `package.json` 的 `peerDependencies`,对**运行时的 DSH 版本**逐个做 semver 判定(含预发布):
116
+
117
+ - 全部满足 → 正常加载;
118
+ - 任一不满足 → **该插件行被禁用并打印原因**(`Plugin … is incompatible with dsh …`),其他插件不受影响;
119
+ - 需要冒险时可用**精确版本豁免**:`dsh plugin allow-version <包>@<版本> --dsh-version <精确版本> --accept-risk`(只对该包与该精确版本生效)。
120
+
121
+ `package.json` 里的 `engines.dsh` 是本插件为读者/包管理器写的信息字段;**DSH 的兼容门禁只读 `peerDependencies`**,请以它为准。`@deepseek-ai/cordis` 单独声明为 `4.0.2 || 4.0.3 || 4.0.4`。
122
+
123
+ **0.1.8+ 或更早版本**:会被拒绝加载。如果 DSH 侧接口兼容,可自行放宽该插件的 peer 范围并重新构建(不改 DSH 核心);否则请等插件跟进发版。
124
+
125
+ ## 故障排查
126
+
127
+ | 现象 | 原因与处置 |
128
+ |---|---|
129
+ | 日志出现 `another adapter already owns it`,模型列表里没有本插件的模型 | `opencode-go` 路由被旧插件或 `llm-pi-ai` 配置占用。卸载占用者或清空其配置后重启。 |
130
+ | 设置页显示「未配置」但请求可用 | 旧于 v0.1.4 的构建有此缺陷(凭证结果未按信封解包),升级即可。 |
131
+ | 装包时报 `ERR_PNPM_IGNORED_BUILDS`(依赖构建脚本未批准) | 新建 profile 的 `pnpm-workspace.yaml` 里 `allowBuilds` 是占位文本;把 `@google/genai`、`protobufjs` 显式设为 `false`(二者不需要构建)后重装。 |
132
+ | 装远程 tarball 报 `ERR_PNPM_MISSING_TARBALL_INTEGRITY` | pnpm 对已有缓存的 profile 要求 lock 里有 integrity。把 tarball 下载到本地,用**本地路径**安装。 |
133
+ | 升级本地 tarball 后行为没变 | pnpm 对同名本地 tarball 会复用旧内容。改文件名再装。 |
134
+ | 设置页出现「设置写入被拒绝」 | 通常是与另一个窗口/进程并发写同一 profile;插件会自动重试一次,仍失败时界面已重载最新状态,再点一次即可。 |
135
+ | 用量按钮显示「不可用」 | 端点或凭证变化导致旧读数作废;配置正确后点「重试」。数值不会以 0 冒充。 |
136
+
137
+ ## 开发
138
+
139
+ ```sh
140
+ npm ci
141
+ npm run typecheck # host 与 client 两半
142
+ npm test # 契约测试:真实 HTTP mock 网关,断言请求头/体、目录阶梯、用量
143
+ npm run build # 产出 lib/index.js 与 lib/client.js
144
+ ```
145
+
146
+ 测试 148 个用例 / 24 个文件,覆盖配置校验、协议阶梯、网关与在线元数据、目录投影、适配器(三种协议的线上请求)、Remote 契约与服务、会话头不变量、用量窗口与计量、客户端控制器与用量组件、以及两半的挂载与登记。
147
+
148
+ ## 发布(维护者)
149
+
150
+ 1. **版本**:把 `package.json` 的 `version` 与即将打出的 tag 对齐(`v<版本>`)。CI 会校验资产名与 tag。
151
+ 2. **GitHub Release**:提交并推送 `main`,打 tag 推送。`release.yml` 会跑测试、`npm pack` 并把 tarball 作为 Release 资产上传。
152
+ 3. **npm(预留,未启用)**:`.github/workflows/publish-npm.yml` 仅手动触发,需要:npm 上的 `@dan-ai-studio` scope 权限 + 仓库 secret `NPM_TOKEN`。工作流会校验 tag 与版本一致、拒绝覆盖已发布的同版本,并使用 `--provenance` 声明构建来源。启用步骤写在文件头部注释里。
153
+
154
+ ## 许可证
155
+
156
+ MIT
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dshopencodego
3
+ name: '@dan-ai-studio/dshopencodego'
@@ -0,0 +1,11 @@
1
+ {
2
+ "clientExternals": [
3
+ "react",
4
+ "react/jsx-runtime",
5
+ "react-dom",
6
+ "@deepseek-ai/cordis",
7
+ "@deepseek-ai/dsh-client-store",
8
+ "@deepseek-ai/dsh-client-ui-slots",
9
+ "@deepseek-ai/dsh-client-ui-primitives"
10
+ ]
11
+ }