@eddyskywalker/dsh-chatgpt-subscription 0.36.1 → 0.37.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/CHANGELOG.md +48 -0
- package/README.md +23 -3
- package/lib/client.js +340 -47
- package/lib/client.js.map +1 -1
- package/lib/index.js +3088 -54
- package/lib/types/client/common/ComposerQuotaBadge.d.ts +7 -0
- package/lib/types/client/common/ComposerQuotaBadge.d.ts.map +1 -1
- package/lib/types/client/locales-ru/opendesign.d.ts.map +1 -1
- package/lib/types/client/locales-ru/progress-updates.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +4 -4
- package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts +6 -0
- package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts.map +1 -1
- package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -1
- package/lib/types/client/opendesign/locales.d.ts +54 -0
- package/lib/types/client/opendesign/locales.d.ts.map +1 -1
- package/lib/types/client/opendesign/styles.d.ts +5 -0
- package/lib/types/client/opendesign/styles.d.ts.map +1 -1
- package/lib/types/client/progress-updates/locales.d.ts +17 -2
- package/lib/types/client/progress-updates/locales.d.ts.map +1 -1
- package/lib/types/client/progress-updates/settings-binding.d.ts +13 -3
- package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -1
- package/lib/types/client/progress-updates/settings-section.d.ts +5 -5
- package/lib/types/client/progress-updates/settings-section.d.ts.map +1 -1
- package/lib/types/client/progress-updates/styles.d.ts.map +1 -1
- package/lib/types/host/claude/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/client.d.ts +103 -0
- package/lib/types/host/opendesign/client.d.ts.map +1 -1
- package/lib/types/host/opendesign/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/types.d.ts +31 -0
- package/lib/types/host/opendesign/types.d.ts.map +1 -1
- package/lib/types/host/progress-updates/index.d.ts +5 -0
- package/lib/types/host/progress-updates/index.d.ts.map +1 -1
- package/lib/types/host/progress-updates/prompt.d.ts +37 -3
- package/lib/types/host/progress-updates/prompt.d.ts.map +1 -1
- package/lib/types/host/progress-updates/tool.d.ts.map +1 -1
- package/lib/types/host/proxy-manager.d.ts +63 -1
- package/lib/types/host/proxy-manager.d.ts.map +1 -1
- package/lib/types/host/widget-board/line-contracts.d.ts +192 -0
- package/lib/types/host/widget-board/line-contracts.d.ts.map +1 -0
- package/lib/types/host/widget-board/line-quota.d.ts +284 -0
- package/lib/types/host/widget-board/line-quota.d.ts.map +1 -0
- package/lib/types/host/widget-board/line-registry.d.ts +402 -0
- package/lib/types/host/widget-board/line-registry.d.ts.map +1 -0
- package/lib/types/host/widget-board/provider.d.ts +140 -0
- package/lib/types/host/widget-board/provider.d.ts.map +1 -0
- package/lib/types/index.d.ts +10 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/opendesign-contracts.d.ts +47 -0
- package/lib/types/shared/opendesign-contracts.d.ts.map +1 -1
- package/package.json +2 -1
- package/widgets/line-flip/index.html +58 -0
- package/widgets/line-flip/main.js +1102 -0
- package/widgets/line-flip/style.css +729 -0
- package/widgets/line-flip/widget.json +555 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.37.0 - 2026-10-23
|
|
6
|
+
- **[progress-updates] 进展更新补上「开局」与「收尾」两条硬要求**
|
|
7
|
+
- **现象**:任务开始和结束都没有进展条目,整场只在被催到的时候冒出两三条;面板看着像「只有出结论才有动静」。
|
|
8
|
+
- **根因**:整条链路只折叠模型显式调用 `progress_update` 的事件(`projection.apply` 对其它名字的 `tool/call`、`tool/ptc-dispatch` 原样返回),没有任何从工具活动自动推导的路径;而模型侧唯一的正向纠偏是「8 轮催促」,它在 `tools/post-execute` 上从 0 数到 8 才响,结构上不可能在 t=0 触发;收尾时模型输出的是最终答复正文而不是工具调用,`post-execute` 不触发,于是也没有收口那一条。实测本会话日志:三条进展分别紧跟三次催促(seq 86→94、160→168、252→260),首条出现在第 8 轮之后,`turn/end`(seq 347)之前的 87 个事件里一条都没有。
|
|
9
|
+
- **改法**:`prompt.ts` 的引导词把「开局(第一批工具调用之前)」与「收尾(最终答复之前)」提成两条硬要求,原来的「任务早期」条目降级为「计划真的变了才补」;`tool.ts` 的工具描述在首句后同步一句书挡要求——描述是模型每次调用都会读到、离调用最近的一段文本。催促阈值不动默认值(仍是 8,`NUDGE_THRESHOLD` 是测试守着的冻结契约),本机在 profile 配置里设成 4。
|
|
10
|
+
- **验证**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件 / 4586 passed / 8 skipped / 0 failed(工具描述的子串断言一条没改);`npm run build` 通过,`lib/index.js` 里能搜到新文案。
|
|
11
|
+
- **留档**:结构层面的锚点(`agent/pre-step` 做开局、`agent/turn-stopping` + `steer` 做收尾)这次刻意没做,纯文本仍是软约束,模型可以不照做。
|
|
12
|
+
- **[progress-updates] 提示词整段转英文,并新增「输出语言」设置(auto / 中文 / English)**
|
|
13
|
+
- **现象**:进展更新的系统提示词是中文的,而工具描述本来就是英文——同一件事两套语言;用户也无法指定进展本身用哪种语言写。
|
|
14
|
+
- **改法(提示词)**:`prompt.ts` 的 `PROGRESS_GUIDANCE` 整段换成英文,与工具描述统一措辞。新增 `ProgressUpdateLanguage = 'auto' | 'zh' | 'en'` 与 `PROGRESS_LANGUAGE_DIRECTIVES`:把「标题与正文用哪种语言写」做成一句追加在引导词末尾的指令——`auto` 跟随对话语言(日、俄等其它语言自动跟随),`zh`/`en` 明确压过对话语言。**「指令用英文」与「输出用中文」是两件互不影响的事**,这正是把语言单独拆成一个开关的原因。
|
|
15
|
+
- **改法(设置)**:宿主 `Config` 新增 `progressUpdatesLanguage`(`z.union([z.const('auto'), z.const('zh'), z.const('en')])` + `default('auto')` + `volatile()`,与另两个字段同一套:保存即生效、不重挂插件行);`resolveProgressUpdatesSettings` 用白名单校验,配置里写了个不认识的字符串等于没写(退回 auto),而不是把它原样拼进提示词。设置页从三行变四行,第三行是原生 `<select>`(`data-dsh-part="settings-language"`),三个选项就是 schema 的三个取值;中/英/俄三份字典同时补齐(俄语里语言名用 Китайский,因为 `russian-locale.test.tsx` 明令俄语包里不许出现 CJK)。
|
|
16
|
+
- **测试**:`progress-updates-apply` 新增「语言指令追加在引导词末尾」(含活引用就地换值,单实例守卫下读一次卸一次)与「未知取值退回 auto」;`live-ref-and-route` 补 schema 默认值;`progress-updates-client` 新增「下拉写的是 progressUpdatesLanguage,选项就是三个取值」,行数断言 3→4,控件禁用态补一条;中文断言同步换成英文。9 个进展更新测试文件 150 例全绿。
|
|
17
|
+
- **验证**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件 / 4590 passed / 8 skipped / 0 failed;`npm run build` 通过。
|
|
18
|
+
- **[opendesign] 额度卡终于有进度条了:吃的是控制台同源的 Design Plan 窗口(5 小时 / 7 天),不是钱包余额**
|
|
19
|
+
- **现象**:OpenDesign 线路的卡与设置页只有金额(「可用余额 $1.50」),没有任何百分比进度条;而 OpenDesign 控制台的计费卡明明画着「Design Plan · 5 小时额度 剩余 90%」「7 天额度 剩余 81%」两条带重置倒计时的进度条。
|
|
20
|
+
- **根因(两层)**:一是**读错了面**。插件一直只读 `/billing/summary` 与 `/wallet/balance`——前者给套餐档位与「还剩多少 credits」,后者给钱包余额,**两者都没有「这一期一共给了多少」**,所以「已用/总量」这个分母根本不存在,代码里那句「本卡不发明一个总数去除」是对的。二是**真源在另一个端点**:从控制台 SPA 的 bundle 反查出 `GET {amr}/workspaces/{workspaceId}/billing/coding-plan-usage`(带 `x-vela-workspace-id`),返回 `{ tier, eligible, windows: [{ policyId, durationSeconds, remainingCredits, limitCredits, resetsAt }] }`;控制台自己的过滤逻辑是 `durationSeconds === 604800`(7 天)加 go 档的 `18000`(5 小时),百分比就是 `remainingCredits / limitCredits`。该路径实测存在(未鉴权 401;此前猜的 `/billing/windows`、`/billing/coding-plan`、`/billing/preflight` 全是 404),工作区 id 来自 `GET {amr}/workspaces`。
|
|
21
|
+
- **改法(宿主)**:新增 `fetchWorkspaceId()` 与 `fetchCodingPlanUsage()`(绝不 throw,非 200 把 `HTTP <status>: <code|message>` 作为数据返回,`coding_plan_configuration_unavailable` 原样透传;窗口解析严格——`policyId` 非空、`durationSeconds` 正整数、`limitCredits > 0`、两个金额都是整数字符串、`resetsAt` 为 null 或可解析 ISO,**不合格的窗口丢弃而不是补**)。`/usage` 变成三路并行(钱包 / 账单 / 额度窗口),工作区 id **每个请求只解析一次**并复用(失败也复用、不重试,两个账号实测只发 1 次 `/workspaces`,避免每个账号各撞一次同一个 401)。DTO 新增 `OpenDesignCodingPlanDto` 与 `OpenDesignUsageAccountDto.codingPlan`(失败也带 `error`,因为「空列表」与「这条线路没有窗口」是两句话)。看板缩放器把这批窗口变成 `line-card` 的普通 `quota.windows`:`usedPercent = (limit − remaining)/limit`、`windowMinutes = durationSeconds/60`、`label` 留空让卡片自己按分钟说「5 小时 / 7 天」,`credits` 继续只放钱包余额。
|
|
22
|
+
- **改法(界面)**:设置页每个窗口一行——名称 + 「已用 x% · 剩余 y%」+ `role="progressbar"` 进度条 + 「{时间} 重置」;读不到或该工作区未配置时只写一句弱化说明,绝不画 0% 的假条。输入框徽标在有窗口时显示最窄窗口的「剩余 90%」并带一条细进度条,tooltip 列出所有窗口;没有窗口则逐字退回原来的 `$余额`(其他线路的徽标 DOM 有专门用例守着,一个节点都没变)。看板卡复用既有窗口行,自动得到「5 小时 / 7 天」两行、两条 meter、百分比与倒计时。
|
|
23
|
+
- **一次被推翻的口径(留档)**:中途曾按「累计消耗占比 = 已消耗 ÷(已消耗 + 剩余)」做过一版,用户指出套餐本身有独立额度后废弃——那条式的分母会随充值漂移,且与「本期用了多少」不是同一件事。全部改动已回退,最终口径只有一套:窗口的 `limit − remaining`。
|
|
24
|
+
- **测试**:`test/opendesign-routes.test.ts` 31 例(workspace 解析的数组/包装/无 id/401、窗口读取的两窗口与坏窗口丢弃、拒绝码作为数据、每请求只解析一次工作区、钱包在额度读取失败时不丢)、`test/widget-board-lines.test.ts` 57 例(两窗口 → 300/10080 分钟、已用 10/19%、`resetsAt` 毫秒、`label` 为空、钱包仍在;读不到时 windows 为空且原因进 error)、`test/opendesign-section.test.tsx` 17 例与 `test/composer-quota-badge.test.tsx` 10 例(每窗口一条 bar 与 aria 值、失败/未配置不画条、徽标有窗口显示剩余%、无窗口退回余额且零新节点)。
|
|
25
|
+
- **验证(含实机结论)**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件通过 / 2 skipped、4578 passed / 8 skipped / 0 failed;`npm run build` 通过。
|
|
26
|
+
**实机 2026-10-22(真实 Go 账号,三次重启逐步定位)**:① 首版拿 `/workspaces` 列表找不到 id → 改成「先 `/workspaces/current` 再列表兜底」,实机确认 `activeWorkspaceId` 能解析;② 解析通了以后 coding-plan 端点回 `HTTP 401: unauthenticated`;③ 按序轮试三种凭据形状(`Bearer vela_ctrl_…` / `Bearer sk-amr-…` / `x-api-key: sk-amr-…`)**全部 401**。
|
|
27
|
+
**结论**:该端点只认控制台浏览器会话,插件持有的 key 一律不放行;官方 CLI 能读到同样窗口是用它自己的 `vela login` 会话。因此设置页把这种情况与「工作区未配置」分开,显示「额度窗口仅在 OpenDesign 控制台可见」;看板卡只写一句原因、不画 0% 假条。读取路径保留(上游哪天放开 key 或换到有会话能力的调用方即自动生效),失败时的 error 会带尝试记录,便于日后一眼判断。
|
|
28
|
+
- **[proxy] 代理不再劫持回环与本机网关,Linux 也能自动发现系统代理;代理卡文案改成“全部供应线路”**
|
|
29
|
+
- **现象**:把某条线路的 baseURL 指向本机网关(例如本地转发在 `http://127.0.0.1:9090`)时,请求会被塞进系统代理——`ProxyAgent` 只认一个 `dispatcher`,既不看 `NO_PROXY` 也不对回环地址做豁免,而本机代理工具(Clash/Mihomo)通常用 fake-ip DNS 拒掉或转回自己,于是出现“直接 curl 通、插件一路 400 / ECONNREFUSED”。同一处还有第二个洞:`auto` 模式在 Linux 上完全不探测,`detectSystemProxy` 只有 win32(注册表)与 darwin(`scutil`)两个分支,Linux 用户桌面配了系统代理也永远读到 `null`,只能靠环境变量。
|
|
30
|
+
- **改法(旁路)**:`createFetch` 解析出活动代理后先过一遍旁路判定——`isLoopbackHostname`(整个 `127.0.0.0/8`、`::1`、`localhost`、`*.localhost`)无条件直连;再按标准语义匹配 `NO_PROXY`/`no_proxy`(`*`、精确主机、域名后缀、`host:port`,不支持 CIDR)。列表与代理同源读取:进程环境变量优先、其次 `$DSH_HOME/.env`,`ProxyManager.getNoProxyList()` 与系统代理共用 5 秒 TTL,读取抛错一律当作“没有列表”——不会反向把代理从所有线路上摘掉。旁路命中走 `baseFetch`,与“没有代理”是同一条路径,流式、超时与诊断包裹都不受影响。
|
|
31
|
+
- **改法(Linux)**:`detectSystemProxy` 新增 `platform === 'linux'` 分支,`parseLinuxSystemProxy` 读 GNOME `gsettings` 的 `org.gnome.system.proxy mode|https|http|socks`,优先 https → http → socks,输出 `http://` 或 `socks5://`;PAC(`auto`)与关闭(`none`)返回 `null` 并继续回落环境变量,对既有平台零变化。第三个参数是读取器测试缝,缺省才是真正的 `gsettings`。
|
|
32
|
+
- **改法(文案)**:`proxyModeHint` 与 `proxyDirectHint` 三份语言包(中/英/俄)改成“本插件的全部供应线路”,并写明登录、令牌续期、模型目录与配额读取同样经过这条代理;README 的代理段落同步补上按平台的探测方式、旁路规则与 `NO_PROXY` 语义。旧文案只说“GPT 与 Antigravity(Gemini)共用”,在 12 条线路的时代早已不成立。
|
|
33
|
+
- **测试**:`test/proxy-manager.test.ts` 新增 22 例(42 例全绿)——回环无论列表怎么写都直连;`*`/后缀/精确主机/`host:port`/带 scheme 与路径的条目;无法解析的目标不旁路;`ProxyManager` 在代理生效时把回环与 `NO_PROXY` 主机交给 `baseFetch`(含 `Request` 入参);未列名主机仍走代理;TTL 缓存与抛错读取器;GNOME 解析(https 优先、socks 回落、`auto`/`none`/缺端口/IPv6 括号);`detectSystemProxy` 的 linux 分支与环境变量回落。
|
|
34
|
+
- **验证**:`npm run typecheck` 三工程 0 错误;`npx vitest run test/proxy-manager.test.ts` 42/42;全量 `npm test` 277 文件通过 / 2 skipped,4557 passed / 8 skipped / 0 failed;`npm run build` 通过。
|
|
35
|
+
- **[board] 组件看板上一张卡看一条线路:`line-flip`,一条线路一张会翻面的卡**
|
|
36
|
+
- **形态**:看板插件在宿主上发布 cordis 服务 `widgetBoard`(apiVersion 3)。本插件在 `apply` 顶部无条件接线,经 `ctx.inject(['widgetBoard'])` 注册一个组件目录(`widgets/`,随包发布)、一个数据源(`line-card`)与三个能力(`line-refresh` / `line-account-switch` / `line-account-strategy`)。看板缺席时整段是 no-op;注册失败只 warn,绝不影响插件装载;卸载时一次 `handle.dispose()` 全撤。
|
|
37
|
+
- **一张卡一条线路**:`widgets/line-flip` 在 `props.line` 里写线路 id(`codex`、`claude`、`kimi-code`、`minimax-code`、`antigravity`、`command-code`、`glm-coding-plan`、`step-code`、`qoder`、`cline-pass`、`opendesign`),`line-card` 就照着它读那一条线路:正面是额度窗口的已用百分比、进度条与重置倒计时,背面是这条线路的号池、当前账号与三档轮换 chip。刷新、切号、改策略都走能力(`widget.action` 拿不到返回值),并用能力返回值重画。同一份组件摆多张就是多条线路,加一条线路只需在 `src/index.ts` 的 `lines.pools` 里加一行。
|
|
38
|
+
- **单位**:各线路在 wire 上的时间表示并不统一(codex 是 Unix **秒**,antigravity / cline-pass 是 ISO 字符串,其余是**毫秒**),换算在 `src/host/widget-board/line-quota.ts` 的每线 normalizer 里各做一次,卡片数据一律毫秒,且不按数量级猜单位。
|
|
39
|
+
- **命名**:看板 manifest 的 `source`/`capabilities` 只接受 `[a-z][a-z0-9.-]{1,39}(?::…)?`,带 scope 的包名进不去,所以注册用的 provider 取 `dsh-chatgpt-subscription`,与 manifest 逐字相同才能解析;`test/widget-board.test.ts` 现在照着真实注册结果,逐条比对 `widgets/*/widget.json` 的 `source` 与 `capabilities`。
|
|
40
|
+
- **数据源与能力都不声明 permission**:它们只读本机线路自己的 `GET /status`、只写本插件持有的号池文档,不跑命令、不访问组件指定的主机,没有需要人批准的东西。
|
|
41
|
+
- **测试**:`test/widget-board.test.ts`(11 例)只测仍然存在的边界——组件目录注册(provider 名、apiVersion 透传、id 语法)、看板缺席是 no-op、注册失败只 warn、卸载时 dispose(含迟到的注册被退回)、无 capabilities 的看板只注册数据源、没有线路注册表时不注册任何东西,以及 manifest 与注册 id 的逐字对齐。
|
|
42
|
+
- **验证**:`npm run typecheck` 三个工程 0 错误;`npx vitest run test/widget-board.test.ts test/widget-board-lines.test.ts` 42 例全绿(11 + 31);全量 `npx vitest run` 277 文件通过 / 2 skipped,4519 passed / 8 skipped / 0 failed。
|
|
43
|
+
|
|
44
|
+
## 0.36.2 - 2026-10-22
|
|
45
|
+
- **[claude] 设置卡不再拿一枚已死的 access token 请求上游:status / 额度 / 测试连接 / 目录刷新统一走号池续期,托管账号闲置一夜后不再诱导用户重新登录(#66)**
|
|
46
|
+
- **现象**:Claude 订阅的 access token 只有约 8 小时寿命。卡片上的「令牌到期」、额度读取与「测试连接」在托管(managed)账号闲置一夜后全部出错——到期时间显示为过去时间、额度区报错、连接测试失败,看起来像「登录每天失效」,用户于是每天重新登录一次;而重登只是把到期时间刷成新的 8 小时,第二天照旧。
|
|
47
|
+
- **根因**:续期只发生在模型请求路径(`adapter` → `pool.getEffectiveAccount()` → `freshAccount()`,由 `claudeNeedsRefresh()` 在到期前 5 分钟内触发)。`/claude/api` 的 `status`、`quota`、`connection/test`、`catalog/refresh` 则直接用 `activeAccount()` 从号池读出的**存储值**请求上游,从不续期:卡片永远只看到「最后一枚被存下来的 access token」,8 小时后必然过期。相邻的 Kimi Code 线路早有 `effectiveCredentials()` 解决此事,Claude 线路缺这一段。
|
|
48
|
+
- **改法**:`registerClaudeRoutes()` 新增与 Kimi 同形的 `effectiveCredentials(target)` —— 无 pool 或无 `target.id` 时返回存储凭据,否则经 `pool.getFreshCredential(target.id, fetchFn)` 续期,续期失败时回落存储凭据(卡片仍能渲染账号列表,真实原因由那次请求报告)。四条卡片路径统一改用它;`status` 先续期、再读额度、再构建响应,所以 `accounts[].expiresAt`(读自号池行,续期会写回)就是续期后的新值。`readStatus()` 增加可选第二参,让额度读取、catalog 加载与 `accounts[]` 描述同一枚已消费的凭据。
|
|
49
|
+
- **不变量**:adopted(Claude Code 快照)仍然永不刷新——号池对 adopted 恒不续期、并在发网络请求前就拒绝,正好落进上面的回落分支,卡片只展示快照自身的 `authStatus`;只有续期被上游**拒绝**(`refreshFailureStatus` 仅对 `ClaudeUnauthorizedError` 写入)时,账号行才显示「需重新登录」,临时网络失败不会把账号标死。单飞由号池内核 `freshAccount()` 负责,同一枚 refresh token 不会被花两次,路由层没有另做互斥。
|
|
50
|
+
- **测试**:`test/claude-routes.test.ts` 新增 `describe('credential renewal on the card paths')`(6 例,注入假 refresh seam 与记录 `Authorization` 的 fetch double,全程无网络)——`GET /status` 恰好续期 1 次且池内 `expiresAt` 变未来、不写 `authStatus`、usage 请求带新 bearer、`accounts[].expiresAt` 与池内一致、`quotaError: null`;`POST /quota` 同理;`connection/test` 与 `catalog/refresh` 分别以新 bearer 请求 `/v1/messages` 与 `/v1/models`;过期 adopted 快照刷新 0 次且仍渲染 `authStatus='expired'`;卡片与模型请求并发、两次卡片轮询并发都只续期一次。反向验证:把 `routes.ts` 退回基线后 6 条中 5 条失败(adopted 那条按设计通过)。
|
|
51
|
+
- **验证**:`npm run typecheck` 三个工程 0 错误;全量 `npm test` 275 文件通过 / 1 跳过,4477 passed / 7 skipped / 0 failed;`npm run build` 通过。
|
|
52
|
+
- **已知边界**:卡片路径的续期与模型请求共用同一续期入口,因此一次续期失败(例如离线)会让下一次状态轮询再次尝试续期;这与模型请求路径的既有行为一致,未在路由层另加冷却。
|
|
5
53
|
## 0.36.1 - 2026-10-22
|
|
6
54
|
- **[cline-pass] 额度不再只在手动刷新时动:状态读取按 TTL 在答背后刷新,设置卡与输入框徽标 60 秒自动更新**
|
|
7
55
|
- **现象**:Cline Pass 设置页打开后额度数字就定住了——同一次会话里消耗掉的部分,要重新打开页面或点一次「刷新额度」才会反映;输入框旁的额度徽标同样停在首次读到的数字。
|
package/README.md
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
- [本机登录](#本机登录)
|
|
26
26
|
- [安全边界](#安全边界)
|
|
27
27
|
- [插件路由](#插件路由)
|
|
28
|
+
- [组件看板卡片(dsh-widget-board)](#组件看板卡片dsh-widget-board)
|
|
28
29
|
- [开发与验证](#开发与验证)
|
|
29
30
|
- [故障排查](#故障排查)
|
|
30
31
|
|
|
@@ -347,7 +348,11 @@ npx @deepseek-ai/dsh plugin --profile web add "link:C:\absolute\path\to\dsh-chat
|
|
|
347
348
|
|
|
348
349
|
DSH 模型选择器应显示 **“Codex(ChatGPT 订阅)”**。GPT-6 系列与 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)。
|
|
349
350
|
|
|
350
|
-
**设置 → Codex 订阅 → 网络代理**
|
|
351
|
+
**设置 → Codex 订阅 → 网络代理** 是本插件**全部供应线路共用**的一份代理设置(ChatGPT、Claude、Antigravity、Kimi Code、MiniMax Code、Command Code、Ollama、GLM Coding Plan、Step、Cline Pass、Qoder、OpenDesign),可选择系统代理(自动检测)、自定义代理或直连。各线路的模型生成、登录与令牌交换/续期、账号信息、项目发现、配额与模型目录查询,以及插件自带的工具与网页抓取,都使用此设置;修改后对后续请求生效,无需重启 DSH。
|
|
352
|
+
|
|
353
|
+
系统代理自动检测按平台分流:Windows 读注册表(同一份输出里的 `ProxyEnable`/`ProxyServer`)、macOS 读 `scutil --proxy`、Linux 读 GNOME 的 `gsettings`(`org.gnome.system.proxy` 的 mode/host/port;PAC 模式不支持,因为代理只能经代理端口转发,无法施用自动代理脚本);都拿不到时回落到 `HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY` 环境变量与 `$DSH_HOME/.env`。
|
|
354
|
+
|
|
355
|
+
代理生效时,**回环地址**(整个 `127.0.0.0/8`、`::1`、`localhost`)与 **`NO_PROXY` / `no_proxy` 列表**里的主机仍然直连——把某条线路的 baseURL 指向本机网关(例如 `http://127.0.0.1:9090`)时不会被塞进代理。`NO_PROXY` 与代理同源读取(进程环境变量优先,其次 `$DSH_HOME/.env`),支持 `*`、域名后缀(`example.com` 与 `.example.com` 都匹配子域)以及 `host:port`;不支持 CIDR。浏览器中的授权页面使用浏览器自己的网络设置。
|
|
351
356
|
|
|
352
357
|
已经用官方 Codex CLI 登录过的用户可以跳过第 3 步的 OAuth:**设置 → 订阅服务 → ChatGPT**,在账号池卡片里点「登录」**旁边**的「导入本机 Codex CLI 登录」即可(见「本机登录」)。
|
|
353
358
|
|
|
@@ -1064,9 +1069,9 @@ OAuth 是默认入口;「使用 API Key」按钮保留为兼容回退,部署
|
|
|
1064
1069
|
| POST | `/models/visibility`、`/models/visibility-all` | 单个/批量隐藏 |
|
|
1065
1070
|
| POST | `/models/context-window` | 单模型上下文窗口覆盖 |
|
|
1066
1071
|
| POST | `/catalog/refresh` | 用号池里可用的 Key 同步实时目录;目录真的变了才通知模型选择器重建 |
|
|
1067
|
-
| GET\|POST | `/usage` | 读取每个 OAuth
|
|
1072
|
+
| GET\|POST | `/usage` | 读取每个 OAuth 账号的钱包余额、账单摘要(套餐、credits、周期)与 **Design Plan 额度窗口**(5 小时 / 7 天,各自的 limit 与剩余;工作区 id 每个请求只解析一次);三路相互独立,失败作为数据显示,绝不标记账号 |
|
|
1068
1073
|
|
|
1069
|
-
协议事实与未验证项的完整证据记录见 `docs/opendesign-line-plan.md`:设备授权的创建与轮询响应是**实测**的,批准后的字段名来自上游 issue #8870;钱包与账单摘要在真实订阅账号上实测过,对话链路仍未与真实 Key
|
|
1074
|
+
协议事实与未验证项的完整证据记录见 `docs/opendesign-line-plan.md`:设备授权的创建与轮询响应是**实测**的,批准后的字段名来自上游 issue #8870;钱包与账单摘要在真实订阅账号上实测过,对话链路仍未与真实 Key 联调。**额度窗口**走控制台自己的 `GET /api/v1/workspaces/{workspaceId}/billing/coding-plan-usage`(带 `x-vela-workspace-id`)。**实测结论(2026-10-22,真实 Go 账号)**:该端点只认控制台会话,插件持有的三种凭据形状——`Bearer vela_ctrl_…`、`Bearer sk-amr-…`、`x-api-key: sk-amr-…`——**全部 401**;工作区 id 本身能正常解析,所以不是地址问题。因此设置页显示「额度窗口仅在 OpenDesign 控制台可见」,看板卡只写一句原因、绝不画 0% 的条;读取逻辑保留,上游哪天放开 key 就会自动生效。
|
|
1070
1075
|
|
|
1071
1076
|
## 本机登录
|
|
1072
1077
|
|
|
@@ -1160,6 +1165,21 @@ Antigravity 的 Gemini 用量以流结束时的上游累计计数为准,缓存
|
|
|
1160
1165
|
|
|
1161
1166
|
状态响应只包含脱敏 email、套餐、账号 ID 后四位、token 到期时间和额度 DTO。
|
|
1162
1167
|
|
|
1168
|
+
## 组件看板卡片(dsh-widget-board)
|
|
1169
|
+
|
|
1170
|
+
装了 `dsh-widget-board` 的 Host 上,本插件往组件库里放一张卡片 `line-flip`(**线路额度**):**一条线路一张卡**,同一份组件摆多张、每张在 `props.line` 里写自己那条线路,不需要额外配置。
|
|
1171
|
+
|
|
1172
|
+
| 卡片 | 数据源 | 能力 |
|
|
1173
|
+
| --- | --- | --- |
|
|
1174
|
+
| **线路额度** `line-flip` | `dsh-chatgpt-subscription:line-card`(60 秒轮询,读 `props.line` 指的那一条线路) | `dsh-chatgpt-subscription:line-refresh`(让这条线路向上游强制读一次额度,等它返回)、`dsh-chatgpt-subscription:line-account-switch`、`dsh-chatgpt-subscription:line-account-strategy` |
|
|
1175
|
+
|
|
1176
|
+
- 卡片自己会翻面:正面是这条线路的额度窗口、进度条与重置倒计时;背面是它的号池、当前账号与三档轮换策略(顺序 / 轮询 / 粘住)。`props.line` 取 `codex`、`claude`、`kimi-code`、`minimax-code`、`antigravity`、`command-code`、`glm-coding-plan`、`step-code`、`qoder`、`cline-pass`、`opendesign` 之一,想看哪条线路就摆哪一张。
|
|
1177
|
+
- 注册走看板发布的 `widgetBoard` 服务(注册时带服务自己报的 `apiVersion` 协商),组件目录 `widgets/` 随包发布;看板没装时这段什么都不做,看板拒绝注册时只记一条 warn,不影响插件装载;卸载时一次 `handle.dispose()` 把组件目录、数据源与能力一起撤掉。
|
|
1178
|
+
- 数据源与三个能力都**不声明 `permission`**:它们只读本机这条线路自己的 `GET /status`、只写本插件持有的号池文档,不跑命令、不访问卡片指定的主机,所以不会弹授权按钮。
|
|
1179
|
+
- 数据源与能力名都以 `dsh-chatgpt-subscription:` 为前缀(**不带** `@eddyskywalker/` 的 scope):看板 manifest 的 id 正则不接受 `@` 与 `/`,带 scope 的名字在 manifest 里根本写不出来。
|
|
1180
|
+
- 卡片里的时间戳一律是**毫秒**:各条线路在 wire 上的单位并不统一(codex 是 Unix 秒,antigravity / cline-pass 是 ISO 字符串,其余是毫秒),换算在 `src/host/widget-board/line-quota.ts` 里每条线路各做一次,卡片不按数量级猜单位。
|
|
1181
|
+
- 插件更新后要**重启一次 Host**:看板没有插件热重载,新的组件目录只在装载时进组件库。
|
|
1182
|
+
|
|
1163
1183
|
## 开发与验证
|
|
1164
1184
|
|
|
1165
1185
|
```sh
|