@dan-ai-studio/dshopencodego 0.1.14 → 0.1.15

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/README.en.md CHANGED
@@ -120,7 +120,7 @@ The gateway's `/v1/models` answers only *which* models exist, never *how* to cal
120
120
 
121
121
  ## The model list in the settings page
122
122
 
123
- The "OpenCode Go" section shows the live gateway catalog (42+ models) with, per model:
123
+ The "OpenCode Go" section shows the live gateway catalog (the count follows the gateway) with, per model:
124
124
 
125
125
  - **context / max input / max output**, **release date**, **price per 1M tokens** (from models.dev), and **Go allowance**;
126
126
  - **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;
@@ -152,7 +152,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
152
152
 
153
153
  | Binding layer | Declared | Enforced by |
154
154
  | --- | --- | --- |
155
- | `peerDependencies` (15 `@deepseek-ai/dsh-*` packages) | all `>=0.1.7-alpha.1 <0.1.8` | **DSH's gate, at plugin load time** |
155
+ | `peerDependencies` (17 `@deepseek-ai/dsh-*` packages) | all `>=0.1.7-alpha.1 <0.1.8` | **DSH's gate, at plugin load time** |
156
156
  | `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | the same gate |
157
157
  | `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | informational only; DSH never reads it |
158
158
  | `engines.node` | `^22.19.0 \|\| >=24.0.0` | the package manager |
@@ -161,7 +161,7 @@ The `engines.dsh` field is informational for readers and package managers; **DSH
161
161
 
162
162
  Things to keep in mind when maintaining this:
163
163
 
164
- - **Required versus optional peers**: six of the fifteen are marked `optional` (`dsh-api-remotes`, `dsh-client-locale`, `dsh-client-store`, `dsh-client-ui-model-selection`, `dsh-client-ui-settings`, `dsh-client-ui-slots`). The nine that actually block loading are `dsh-llm`, `dsh-typert-protocol`, `dsh-attachment`, `dsh-brand`, `dsh-credentials`, `dsh-fs`, `dsh-launch-environment`, `dsh-settings`, and `dsh-timeout`. `dsh-llm` is the heaviest coupling — more than twenty imports across the source.
164
+ - **Required versus optional peers**: six of the eighteen are marked `optional` (`dsh-api-remotes`, `dsh-client-locale`, `dsh-client-store`, `dsh-client-ui-model-selection`, `dsh-client-ui-settings`, `dsh-client-ui-slots`). The twelve that actually block loading are `cordis`, `dsh-attachment`, `dsh-brand`, `dsh-client-ui-conversation`, `dsh-client-ui-renderer`, `dsh-credentials`, `dsh-fs`, `dsh-launch-environment`, `dsh-llm`, `dsh-timeout`, `dsh-typert-protocol`, and `dsh-typert-registry`. `dsh-llm` is the heaviest coupling — more than twenty imports across the source.
165
165
  - **Declared range ≠ verified range**: `0.1.7-alpha.1` and `alpha.2` fall inside the declaration but were never verified here. What was verified is `0.1.7-rc.1` (the dev-dependency baseline) and `0.1.7-rc.2` (daily use).
166
166
  - **The upper bound is a tracking line**: `<0.1.8` means that the moment DSH ships `0.1.8`, this plugin must ship a new release in the same window or every user loses the plugin. After changing a range, `npm test` is the verification (local mock gateway, no network, no tokens) — ranges follow what the interfaces declare, and are never "measured" with live probes.
167
167
  - **Peer coverage is now guarded both ways**: `dsh-typert-registry`, `dsh-client-ui-conversation`, and `dsh-client-ui-renderer` were imported by the source but absent from `peerDependencies`, invisible to the gate; they are declared now, and `tests/peer-coverage.spec.ts` asserts both directions — anything the source imports must be declared, and anything declared but unreached must be removed (`dsh-settings` went that way: the settings form is actually provided by `dsh-client-ui-settings`).
package/README.md CHANGED
@@ -120,7 +120,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
120
120
 
121
121
  ## 设置页里的模型列表
122
122
 
123
- 设置页的「OpenCode Go」分区展示网关实时目录(42 个起),并对每个模型给出:
123
+ 设置页的「OpenCode Go」分区展示网关实时目录(数量随网关发布变化),并对每个模型给出:
124
124
 
125
125
  - **上下文 / 输入 / 输出**(最大输入只有部分模型有官方数据)、**发布时间**、**单价 /1M**(来自 models.dev)、**Go 额度**;
126
126
  - **Go 额度**来自 OpenCode 官方文档的「使用限制 / 预估请求数」表,**没有接口提供**,是本插件转写的数据表(见 `src/go-limits.ts` 的注释:来源 URL 与转写日期);文档调整价格或促销时需要更新该表并随发版发布。
@@ -152,7 +152,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
152
152
 
153
153
  | 绑定层 | 声明 | 谁在把关 |
154
154
  | --- | --- | --- |
155
- | `peerDependencies`(15 个 `@deepseek-ai/dsh-*`) | 均为 `>=0.1.7-alpha.1 <0.1.8` | **DSH 加载时的真门禁** |
155
+ | `peerDependencies`(17 个 `@deepseek-ai/dsh-*`) | 均为 `>=0.1.7-alpha.1 <0.1.8` | **DSH 加载时的真门禁** |
156
156
  | `@deepseek-ai/cordis` | `4.0.2 \|\| 4.0.3 \|\| 4.0.4` | 同一门禁 |
157
157
  | `engines.dsh` | `>=0.1.7-alpha.1 <0.1.8` | 仅信息字段,DSH 不读 |
158
158
  | `engines.node` | `^22.19.0 \|\| >=24.0.0` | 包管理器 |
@@ -161,7 +161,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
161
161
 
162
162
  维护时需要注意:
163
163
 
164
- - **必选与可选之分**:15 个 peer 中 6 个标了 `optional`(`dsh-api-remotes`、`dsh-client-locale`、`dsh-client-store`、`dsh-client-ui-model-selection`、`dsh-client-ui-settings`、`dsh-client-ui-slots`);真正卡住加载的是 9 个——`dsh-llm`、`dsh-typert-protocol`、`dsh-attachment`、`dsh-brand`、`dsh-credentials`、`dsh-fs`、`dsh-launch-environment`、`dsh-settings`、`dsh-timeout`。其中 `dsh-llm` 是最重的一处耦合(源码 import 二十余处)。
164
+ - **必选与可选之分**:18 个 peer(17 个 `dsh-*` 加框架 `cordis`)中 6 个标了 `optional`(`dsh-api-remotes`、`dsh-client-locale`、`dsh-client-store`、`dsh-client-ui-model-selection`、`dsh-client-ui-settings`、`dsh-client-ui-slots`);真正卡住加载的是 12 个——`cordis`、`dsh-attachment`、`dsh-brand`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer`、`dsh-credentials`、`dsh-fs`、`dsh-launch-environment`、`dsh-llm`、`dsh-timeout`、`dsh-typert-protocol`、`dsh-typert-registry`。其中 `dsh-llm` 是最重的一处耦合(源码 import 二十余处)。
165
165
  - **名义范围 ≠ 实测范围**:`0.1.7-alpha.1`、`alpha.2` 落在声明范围内,但本项目没有验证过;实际验证过的是 `0.1.7-rc.1`(开发依赖基线)与 `0.1.7-rc.2`(日常使用)。
166
166
  - **上界就是跟版线**:`<0.1.8` 意味着 DSH 一旦发布 `0.1.8`,本插件必须同批发新版,否则所有用户加载失败。调整范围后用 `npm test` 验证即可(本地 mock 网关,零网络零 token)——范围以接口声明为准,不要用线上探测来"测"出一个范围。
167
167
  - **peer 覆盖已双向守住**:`dsh-typert-registry`、`dsh-client-ui-conversation`、`dsh-client-ui-renderer` 曾被源码 import 却未声明、门禁管不到,现已补进 `peerDependencies`;`tests/peer-coverage.spec.ts` 双向断言——源码用到的必须声明,声明了却没人用的必须删(`dsh-settings` 就这样被移除:设置表单实际由 `dsh-client-ui-settings` 提供)。
package/lib/client.js CHANGED
@@ -454,7 +454,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
454
454
  style.textContent = ".d7lz0W_root{color:var(--dsw-alias-label-primary);flex-direction:column;gap:1.25rem;display:flex}.d7lz0W_title{margin:0;font-size:1.05rem}.d7lz0W_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.8rem}.d7lz0W_warn{color:var(--dsw-alias-state-warn-primary);margin:0;font-size:.8rem}.d7lz0W_ok{color:var(--dsw-alias-state-success-primary);font-size:.8rem}.d7lz0W_block{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:.6rem;flex-direction:column;gap:.5rem;padding:.85rem;display:flex}.d7lz0W_row{flex-wrap:wrap;align-items:center;gap:.5rem;display:flex}.d7lz0W_row>strong{margin-right:auto}.d7lz0W_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);min-width:10rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;flex:14rem;padding:.35rem .5rem;font-size:.85rem}.d7lz0W_button{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;padding:.35rem .7rem;font-size:.8rem}.d7lz0W_button:disabled{color:var(--dsw-alias-state-idle-primary);cursor:default}.d7lz0W_number{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:5rem;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_select{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:.35rem;padding:.25rem .4rem;font-size:.8rem}.d7lz0W_list{flex-direction:column;display:flex}.d7lz0W_item{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-start;gap:.5rem;padding:.45rem .15rem;display:flex}.d7lz0W_item input[type=checkbox]{accent-color:var(--dsw-alias-brand-primary);margin-top:.15rem}.d7lz0W_itemBody{flex-direction:column;gap:.15rem;min-width:0;display:flex}.d7lz0W_itemMain{flex-wrap:wrap;align-items:baseline;gap:.6rem;display:flex}.d7lz0W_itemMeta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:.75rem;font-size:.75rem;display:flex}.d7lz0W_itemModalities{color:var(--dsw-alias-label-secondary);font-size:.75rem}.d7lz0W_name{color:var(--dsw-alias-label-primary)}.d7lz0W_mono{color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.d7lz0W_badge{color:var(--dsw-alias-brand-primary)}";
455
455
  document.head.appendChild(style);
456
456
  }
457
- var section_default = { "itemBody": "d7lz0W_itemBody", "root": "d7lz0W_root", "input": "d7lz0W_input", "name": "d7lz0W_name", "title": "d7lz0W_title", "list": "d7lz0W_list", "badge": "d7lz0W_badge", "warn": "d7lz0W_warn", "itemModalities": "d7lz0W_itemModalities", "block": "d7lz0W_block", "mono": "d7lz0W_mono", "row": "d7lz0W_row", "itemMeta": "d7lz0W_itemMeta", "button": "d7lz0W_button", "select": "d7lz0W_select", "number": "d7lz0W_number", "item": "d7lz0W_item", "ok": "d7lz0W_ok", "hint": "d7lz0W_hint", "itemMain": "d7lz0W_itemMain" };
457
+ var section_default = { "warn": "d7lz0W_warn", "itemMeta": "d7lz0W_itemMeta", "hint": "d7lz0W_hint", "input": "d7lz0W_input", "badge": "d7lz0W_badge", "name": "d7lz0W_name", "itemBody": "d7lz0W_itemBody", "itemMain": "d7lz0W_itemMain", "mono": "d7lz0W_mono", "button": "d7lz0W_button", "row": "d7lz0W_row", "root": "d7lz0W_root", "list": "d7lz0W_list", "title": "d7lz0W_title", "item": "d7lz0W_item", "itemModalities": "d7lz0W_itemModalities", "ok": "d7lz0W_ok", "select": "d7lz0W_select", "block": "d7lz0W_block", "number": "d7lz0W_number" };
458
458
 
459
459
  // src/client/Section.tsx
460
460
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -635,7 +635,7 @@ var SectionController = class {
635
635
  this.set({ saving: false });
636
636
  }
637
637
  }
638
- /** Narrow or reorder the model table; a view preference, never a write. */
638
+ /** Narrow or reorder the model list; a view preference, never a write. */
639
639
  setFilter(patch) {
640
640
  this.set({ filter: { ...this.state.filter, ...patch } });
641
641
  }
@@ -950,7 +950,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
950
950
  style.textContent = ".mMNkkW_root{align-items:center;display:inline-flex;position:relative}.mMNkkW_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;border-radius:999px;padding:.35rem .6rem;font-size:.8rem;line-height:1}.mMNkkW_trigger:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.mMNkkW_panel{z-index:20;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-overlay);width:18rem;color:var(--dsw-alias-label-primary);border-radius:.6rem;flex-direction:column;gap:.6rem;padding:.75rem .85rem;display:flex;position:absolute;bottom:calc(100% + .5rem);right:0;box-shadow:0 8px 24px #0000002e}.mMNkkW_window{flex-direction:column;gap:.25rem;display:flex}.mMNkkW_row{justify-content:space-between;gap:.5rem;font-size:.85rem;display:flex}.mMNkkW_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:.75rem}.mMNkkW_progress{width:100%;height:.35rem;accent-color:var(--dsw-alias-brand-primary)}.mMNkkW_limited{color:var(--dsw-alias-state-warn-primary);font-size:.75rem}.mMNkkW_warning{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-label-primary);border-radius:.4rem;padding:.4rem .5rem;font-size:.75rem}.mMNkkW_retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:.35rem;align-self:flex-start;padding:.25rem .5rem;font-size:.75rem}.mMNkkW_local{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:.2rem;padding-top:.5rem;display:flex}";
951
951
  document.head.appendChild(style);
952
952
  }
953
- var pill_default = { "trigger": "mMNkkW_trigger", "limited": "mMNkkW_limited", "panel": "mMNkkW_panel", "retry": "mMNkkW_retry", "local": "mMNkkW_local", "hint": "mMNkkW_hint", "progress": "mMNkkW_progress", "warning": "mMNkkW_warning", "row": "mMNkkW_row", "root": "mMNkkW_root", "window": "mMNkkW_window" };
953
+ var pill_default = { "progress": "mMNkkW_progress", "window": "mMNkkW_window", "limited": "mMNkkW_limited", "retry": "mMNkkW_retry", "panel": "mMNkkW_panel", "local": "mMNkkW_local", "hint": "mMNkkW_hint", "warning": "mMNkkW_warning", "trigger": "mMNkkW_trigger", "root": "mMNkkW_root", "row": "mMNkkW_row" };
954
954
 
955
955
  // src/client/UsagePill.tsx
956
956
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -1133,7 +1133,11 @@ function apply(ctx) {
1133
1133
  scope.slots.inject("settings.section", () => scope.slots.register({
1134
1134
  name: "settings.section",
1135
1135
  id: "dshopencodego",
1136
- order: 20,
1136
+ // After the product rows. The built-ins run -10 (account) through 20
1137
+ // (agent presets); sharing 20 with `agent-presets` left the pair ordered
1138
+ // by registration timing, which drifts between boots. The host's own
1139
+ // tests use 1000 for "last".
1140
+ order: 1e3,
1137
1141
  label: () => translate("nav"),
1138
1142
  inject: () => ({
1139
1143
  controller,
@@ -77,8 +77,13 @@ export interface OpencodeGoConfig {
77
77
  */
78
78
  retryPolicy?: RetryPolicyConfig;
79
79
  }
80
- /** Plain resolved values used by the adapter. */
81
- export declare const PlainConfig: z<OpencodeGoConfig>;
80
+ /**
81
+ * Plain resolved values used by the adapter.
82
+ *
83
+ * The input side is a partial on purpose: a profile writes only the fields it
84
+ * overrides, and the schema's own defaults fill the rest.
85
+ */
86
+ export declare const PlainConfig: z<Partial<OpencodeGoConfig>, OpencodeGoConfig>;
82
87
  /** 0.1.7's Loader retains these references when profile fields change. */
83
88
  export type LiveConfig = {
84
89
  [K in keyof OpencodeGoConfig]-?: {
@@ -44,7 +44,12 @@ const fields = {
44
44
  modelProtocols: z.dict(z.string()).default({}),
45
45
  retryPolicy: RetryPolicySchema,
46
46
  };
47
- /** Plain resolved values used by the adapter. */
47
+ /**
48
+ * Plain resolved values used by the adapter.
49
+ *
50
+ * The input side is a partial on purpose: a profile writes only the fields it
51
+ * overrides, and the schema's own defaults fill the rest.
52
+ */
48
53
  export const PlainConfig = z.object(fields);
49
54
  /** Runtime schema for {@link OpencodeGoConfig}; every field stays live. */
50
55
  export const Config = z.object(Object.fromEntries(Object.entries(fields).map(([key, schema]) => [key, schema.volatile()])));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dan-ai-studio/dshopencodego",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "OpenCode Go provider for DeepSeek Harness: live gateway catalog, per-conversation session header, usage",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -55,8 +55,9 @@
55
55
  },
56
56
  "scripts": {
57
57
  "build": "node scripts/build.mjs",
58
- "typecheck": "tsc -p tsconfig.host.json --noEmit && tsc -p tsconfig.client.json --noEmit",
58
+ "typecheck": "tsc -p tsconfig.host.json --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
59
59
  "test": "vitest run",
60
+ "test:coverage": "vitest run --coverage",
60
61
  "test:watch": "vitest",
61
62
  "prepare": "npm run build",
62
63
  "prepack": "npm run build"
@@ -130,6 +131,7 @@
130
131
  "@types/node": "^22.20.0",
131
132
  "@types/react": "~18.3.1",
132
133
  "@types/react-dom": "~18.3.0",
134
+ "@vitest/coverage-v8": "^4.1.11",
133
135
  "esbuild": "^0.28.2",
134
136
  "jsdom": "^29.0.0",
135
137
  "lightningcss": "^1.32.0",