@eddyskywalker/dsh-chatgpt-subscription 0.3.5 → 0.3.7

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
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.6 - 2026-09-17
6
+
7
+ - **修 preset 在部分 harness 上被判 broken**(有人反馈「装了却选不到」):dispatch preset 有一行挂载 `@deepseek-ai/dsh-tool-present`,而该包从 harness 0.1.5-alpha.2 才发布,更早的安装上这一行无法解析——roster 会把整个 preset 判为 `broken`,而 broken 的 preset 既不可选也不可复制(文件其实已经同步进 `<dshHome>/.agent-presets/`,失败发生在挂载判定那一层)。现在同步时按当前安装调和:行里的包名对当前安装不提供的,就给该行补一个 `disabled: true`(roster 会跳过 disabled 行;harness 升级到提供该包的版本后,下次启动自动恢复启用)。候选写成显式清单(目前只有 `dsh-tool-present` 一项),而不是「凡是解析不到的行都禁用」——解析器整体失灵时那样会把 preset 掏空,故障比它修掉的更隐蔽。新增 5 条用例,拿真实 preset 跑四种包集,按 roster 自己的规则断言没有挂不上的行。
8
+ - **peer 下限抬到 `^0.1.2-alpha.5`**:0.1.1-rc.2 既没有 preset 需要的 `present` 工具,`agent-tool-presentation` 的 `mode` 枚举那时也还写作 `code`(0.1.2-rc.1 起才是 `ptc`),preset 在那里同样挂不上。当初把 0.1.1-rc.2 圈进范围的 `@deepseek-ai/dsh-client-runtime` 已在 0.1.2 停发,抬下限不损失真实支持。
9
+ - `presets/dispatch/agent.cordis.yml` 补上缺失的结尾换行——`.editorconfig` 要求 `insert_final_newline`,它是仓库里唯一违反该约定的文件。
10
+ - **修生成图片不显示**:`CodexImageToolView` 通过 `conversation.resolveImage` 取图,而该服务在 harness 0.1.2 就改名成了 `uiConversation.imageUrl`,此后所有版本的生成图片都渲染不出来(代码里是 `as unknown as` 强转,编译期查不出来)。现在按可用性依次取 `uiConversation.imageUrl`、`conversation.resolveImage`,都不可用时返回失败的 Promise,卡片显示既有的「图片加载失败」文案。
11
+ - **兼容 harness 0.1.6 的改名**:DSH 0.1.6 把 workflow 引擎的包名从 `@deepseek-ai/dsh-workflow-worker-thread` 改成 `@deepseek-ai/dsh-workflow-ptc`,而 preset 行名指向不存在的包会让整个 preset 被判为 broken、既不可选也不可复制。`src/host/preset-sync.ts` 现在在同步时探测当前安装能解析哪个名字(`import.meta.resolve`):旧名仍在就保留,否则把行里的包名改写成新名;两个都不能解析时不改写(改名只会掩盖试过哪个)。同一份 preset 因此在 0.1.5 与 0.1.6 上都能挂载。新增 `reconcilePackageNames` / `resolvesFromHere` / `rewritePresetFile` 与 9 条用例,覆盖「改写后的目标树仍然幂等」「安装换代后改回来」「只处理 `.yml` / `.yaml`」。
12
+ - **开发与测试基线移到 harness 0.1.5-rc.2**(npm 上 `@deepseek-ai/dsh` 的 `latest`,也就是用户实际在跑的版本):此前 `package-lock.json` 把整棵依赖树钉在 0.1.1-rc.2,测试从来没跑在用户运行的版本上——「生成图片不显示」这条就是这样漏掉的。重新生成锁文件后 dsh 全家族(27 个包)落在 0.1.5-rc.2,`peerDependencies` 相应补上 `^0.1.6-alpha.1`。peer 与 dev 从此分工明确:peer 声明支持的世代,dev 只声明构建与测试所对的那一版。
13
+ - 客户端类型换到 0.1.2 之后的新家:`@deepseek-ai/dsh-client-runtime` 自 0.1.2 起不再发布。`ClientContext` 改从 `@deepseek-ai/cordis` 取,`ctx.slots` 的声明改由 `@deepseek-ai/dsh-client-ui-renderer/client` 提供(新增该依赖),`SnapshotStore` 改为在 `src/client/store.ts` 声明共用结构(只用 `getSnapshot` / `subscribe` 两个成员),`package.json` 的 peer、dev 与 `dsh.client.inject` 移除该包。客户端产物仍然只 `require` `react` / `react/jsx-runtime`。
14
+ - 测试跟随三处 API 改名:`mode: 'code'` → `'ptc'`(`ToolRuntime` 的装配枚举)、`CallId` → `ToolCallId`(现由 `@deepseek-ai/dsh-llm/brand` 导出)、`settingsNamespace()` → 直接用 `PREFERENCES_NAMESPACE`(该函数已从 `@deepseek-ai/dsh-settings` 移除)。
15
+ - `test/package-integrity.test.ts` 的不变量由「peer 与 dev 逐字相同」改为「dev 的每一段范围都必须出现在对应 peer 的范围里」。原写法要求两处完全一致,而 peer 现在要覆盖两个世代、dev 只能对其中一个编译,subset 才是这条检查真正要表达的事。
16
+ - 修 README 里与实际不符的说明:`maxDepth` 默认值(0.1.5 及以前取 preset 行、默认 3;0.1.6 起取 `subagent` 服务设置、默认 1)、不存在的「DSH 插件市场」安装路径、Subagent 卡片的位置,以及构建与测试所对的基线版本。
17
+
5
18
  - **调度模式 Agent Preset 随包分发**:新增 `presets/dispatch/`(基于 PTC 模式的编排 preset:R0 复杂度分诊 → L2 任务的澄清访谈 → 规划 → 派发 → 审查 → 验收;子代理必须显式指定模型且落在「子代理」设置白名单内;选择不可用时按 DSH 默认行为降级)与 `src/host/preset-sync.ts`。DSH 只能从配置根、内置 `agent-presets` 包的 `presets/`、以及 `<dshHome>/.agent-presets` 发现 preset,插件包无法自行注册根目录,因此采用「包内随附 + 启动时同步到 home」的方式(与 `@linxin666/dsh-liangshen` 同一机制)。同步幂等、只处理本包自己的 id、绝不触碰用户手写的 preset,失败只记 warn 不阻断插件加载;新增 `config.syncAgentPresets`(默认 `true`)可关闭。包根通过向上查找最近的 `package.json` 定位,兼容 `src/` 与打包后的 `lib/` 两种布局(写死 `../presets/` 在两种布局下会解析到不同目录);复制逐条目实现,规避 Node 22 + Windows 上 `fs.cpSync` 遇到非 ASCII 路径直接崩进程的问题(nodejs/node#54476)。新增 `test/preset-sync.test.ts`(8 条)覆盖首次同步、幂等跳过、内容变更重写与多余文件清理、不触碰非本插件目录、retire 与保留、源目录缺失。`package.json` 的 `files` 增加 `presets`、`exports` 增加 `./presets/*`,`npm pack --dry-run` 确认三个 preset 文件随包发布。
6
19
 
7
20
  - **子代理必须写明模型**:授权守卫不再只拒绝「写明且不在白名单内」的路由,而是要求带有允许列表的会话里每次委派都成对给出 `provider` + `model`。此前不写路由的调用会让子代理继承父级模型(设置卡白名单形同虚设,子代理总是跑在主模型上);现在缺省与只写一半都会被拒绝,拒绝理由里给出全部已授权路由并提示先用 `list_subagent_models` 查询。只读取公开接口(`ctx.tools.guard` + 会话日志 + 设置文档),不修改 DSH 本体。
package/README.md CHANGED
@@ -71,7 +71,7 @@
71
71
 
72
72
  - 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;
73
73
  - 子代理的模型与思考深度沿用 DSH 自身设置:**设置 → Subagent** 卡片授权 Agent 可以为子代理挑选的模型(来自 DSH 已接入的全部 Provider,包含本插件的 Codex / Antigravity),新 Agent 的默认路由由 DSH 的 `agent-default-model` 设置提供;
74
- - 最大嵌套深度是 DSH 子代理工具的装配配置(preset 中 `tool-subagent` `maxDepth`,默认 3;`provider-managed` 表示把预算交给进程外提供方),不在本插件设置内;
74
+ - 最大嵌套深度不在本插件设置内,由 DSH 侧决定:0.1.5 及以前是 preset 中 `tool-subagent` 行的 `maxDepth`(默认 3),0.1.6 起改由 `subagent` 服务的设置项提供(默认 1);`provider-managed` 表示把预算交给进程外提供方;
75
75
  - 6 Astra 与 5.6 Sol / Terra / Luna 默认使用 272K 有效上下文;订阅侧 6 Astra 可配置最高 872K,5.6 系列最高 1M,用于 DSH 压缩与溢出判断;其他模型保持目录声明值;
76
76
  - 可访问的进度条、窄窗口/200% 缩放布局、深浅主题与 reduced-motion。
77
77
 
@@ -99,7 +99,7 @@
99
99
  - Windows 或 Linux;
100
100
  - Windows:系统需提供 Windows PowerShell,以使用 CurrentUser DPAPI;
101
101
  - Linux:Host 用户必须拥有可写的 `~/.dsh`(或 `$DSH_HOME`),凭据文件会强制使用 `0600`、目录使用 `0700`;
102
- - 已安装 DSH
102
+ - 已安装 DSH:peer 范围覆盖 0.1.2-alpha.5 及以后的 0.1.x(含 0.1.5-rc.2 与 0.1.6-alpha)。构建与测试以 **0.1.5-rc.2** 为基线(npm 上 `@deepseek-ai/dsh` 的 `latest`,也就是用户实际在跑的版本)。0.1.1-rc.2 不再声明支持——它既没有 preset 用到的 `present` 工具,`mode` 枚举那时也还写作 `code`;0.1.6 把 workflow 引擎改了包名,插件在 preset 同步时按当前安装自动适配(见下);
103
103
  - Node.js 与 npm。
104
104
 
105
105
  ## 安装
@@ -117,11 +117,13 @@ dsh plugin --profile web add @eddyskywalker/dsh-chatgpt-subscription
117
117
  npx @deepseek-ai/dsh plugin --profile web add @eddyskywalker/dsh-chatgpt-subscription
118
118
  ```
119
119
 
120
- ### 方式 2:通过 DSH 插件市场安装
120
+ ### 方式 2:在 DSH 界面里安装
121
121
 
122
- 1. 打开 DSH 界面中的 **插件市场** / **Plugin Market**;
123
- 2. 搜索 `@eddyskywalker/dsh-chatgpt-subscription` 或 `dsh-chatgpt-subscription`;
124
- 3. 点击 **安装**。
122
+ DSH 没有插件市场;Web 界面的 **Plugins** 页提供按包名安装的入口(底层与 `dsh plugin add` 相同):
123
+
124
+ 1. 打开侧栏的 **Plugins** 页;
125
+ 2. 在添加插件的输入框里填 `@eddyskywalker/dsh-chatgpt-subscription` 并安装;
126
+ 3. 重启 `dsh web`。
125
127
 
126
128
  ### 方式 3:本地开发调试(源码软链接)
127
129
 
@@ -147,7 +149,7 @@ npx @deepseek-ai/dsh plugin --profile web add "link:C:\absolute\path\to\dsh-chat
147
149
  3. 完成 ChatGPT 登录;
148
150
  4. 执行 **测试连接**。
149
151
 
150
- DSH 模型选择器应显示 **“Codex(ChatGPT 订阅)”**。6 Astra 与 GPT-5.6 系列的有效上下文窗口在“Codex 订阅 → 增强功能”中配置。子代理的模型与思考深度由 DSH 自身的设置决定(**设置 → Subagent** 卡片授权的模型清单,以及 `agent-default-model` 的默认路由);最大嵌套深度由 DSH preset 中 `tool-subagent` 的 `maxDepth` 决定。
152
+ DSH 模型选择器应显示 **“Codex(ChatGPT 订阅)”**。6 Astra 与 GPT-5.6 系列的有效上下文窗口在“Codex 订阅 → 增强功能”中配置。子代理的模型与思考深度由 DSH 自身的设置决定(Subagent 卡片授权的模型清单,以及 `agent-default-model` 的默认路由;该卡片 0.1.5 及以前在「设置」页,0.1.6 起在 **Plugins** 页);最大嵌套深度由 DSH 侧决定(0.1.5 及以前取 preset 中 `tool-subagent` 的 `maxDepth`,默认 3;0.1.6 起取 `subagent` 服务的设置,默认 1)。
151
153
 
152
154
  **设置 → Codex 订阅 → 网络代理** 同时控制 GPT 与 Antigravity(Gemini)的 Host 请求,可选择系统代理(自动检测)、自定义代理或直连。Gemini 模型生成、网页登录后的令牌交换、令牌刷新、账号信息、项目发现、配额与模型目录查询均使用此设置;修改后对后续请求生效,无需重启 DSH。浏览器中的 Google 授权页面使用浏览器自己的网络设置。
153
155
 
@@ -189,6 +191,7 @@ DSH 模型选择器应显示 **“Codex(ChatGPT 订阅)”**。6 Astra 与 G
189
191
  同步在每个 profile 启动时执行一次(幂等):
190
192
 
191
193
  - 目标树与包内副本逐字节相同时跳过,有差异时整体重写,并把包内已删除的多余文件清理掉;
194
+ - **行里的包名按运行环境改写**:preset 要挂载 `@deepseek-ai/dsh-workflow-worker-thread`,而 harness 0.1.6 把它改名成了 `@deepseek-ai/dsh-workflow-ptc`,指向不存在的包会让整个 preset 被判为 broken、既不可选也不可复制。同步时用 `import.meta.resolve` 探测当前安装能解析哪个名字(旧名仍在就保留,否则改写成新名;两个都不可用时不改写,因为改名只会掩盖试过哪个),所以同一份 preset 在 0.1.5 与 0.1.6 上都能挂载;
192
195
  - 只处理本包自己的 preset id(`BUNDLED_PRESET_IDS`),**绝不改动用户手写的 preset 或其它插件的 preset**;
193
196
  - 包内已不再随附的旧 id 会从目标根目录移除(retire);
194
197
  - 同步失败(例如 home 只读)只记一条 warn,不会导致插件加载失败——preset 是便利项,不是本插件提供的核心能力。
package/lib/client.js CHANGED
@@ -5179,9 +5179,20 @@ window.__ModuleLoader__.load({
5179
5179
  inject: (sessionId) => ({ loadImage: imageLoader(ctx, sessionId) })
5180
5180
  }, CodexImageToolView));
5181
5181
  }
5182
+ /**
5183
+ * Resolve one session-authorized image URL.
5184
+ *
5185
+ * Harness 0.1.2 moved this from `resolveImage` on `conversation` to `imageUrl`
5186
+ * on `uiConversation`, so both shapes stay supported.
5187
+ */
5182
5188
  function imageLoader(ctx, sessionId) {
5183
- const conversation = ctx.conversation;
5184
- return (attachment) => conversation.resolveImage(sessionId, attachment);
5189
+ const current = ctx.get("uiConversation");
5190
+ const currentResolve = current?.imageUrl?.bind(current);
5191
+ if (currentResolve !== void 0) return (attachment) => currentResolve(sessionId, attachment);
5192
+ const legacy = ctx.get("conversation");
5193
+ const legacyResolve = legacy?.resolveImage?.bind(legacy);
5194
+ if (legacyResolve !== void 0) return (attachment) => legacyResolve(sessionId, attachment);
5195
+ return () => Promise.reject(/* @__PURE__ */ new Error("no client service resolves an image URL"));
5185
5196
  }
5186
5197
  //#endregion
5187
5198
  exports.apply = apply;