@eddyskywalker/dsh-chatgpt-subscription 0.36.2 → 0.38.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +32 -9
  3. package/lib/client.js +603 -134
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +3256 -55
  6. package/lib/types/client/common/ComposerQuotaBadge.d.ts +7 -0
  7. package/lib/types/client/common/ComposerQuotaBadge.d.ts.map +1 -1
  8. package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
  9. package/lib/types/client/kimi-code/KimiModelCapabilities.d.ts.map +1 -1
  10. package/lib/types/client/kimi-code/labels.d.ts +66 -0
  11. package/lib/types/client/kimi-code/labels.d.ts.map +1 -0
  12. package/lib/types/client/kimi-code/locales.d.ts +52 -11
  13. package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
  14. package/lib/types/client/locales-ru/kimi-code.d.ts.map +1 -1
  15. package/lib/types/client/locales-ru/opendesign.d.ts.map +1 -1
  16. package/lib/types/client/locales-ru/progress-updates.d.ts.map +1 -1
  17. package/lib/types/client/locales.d.ts +4 -4
  18. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts +6 -0
  19. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts.map +1 -1
  20. package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -1
  21. package/lib/types/client/opendesign/locales.d.ts +54 -0
  22. package/lib/types/client/opendesign/locales.d.ts.map +1 -1
  23. package/lib/types/client/opendesign/styles.d.ts +5 -0
  24. package/lib/types/client/opendesign/styles.d.ts.map +1 -1
  25. package/lib/types/client/progress-updates/locales.d.ts +17 -2
  26. package/lib/types/client/progress-updates/locales.d.ts.map +1 -1
  27. package/lib/types/client/progress-updates/settings-binding.d.ts +13 -3
  28. package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -1
  29. package/lib/types/client/progress-updates/settings-section.d.ts +5 -5
  30. package/lib/types/client/progress-updates/settings-section.d.ts.map +1 -1
  31. package/lib/types/client/progress-updates/styles.d.ts.map +1 -1
  32. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  33. package/lib/types/host/kimi-code/client.d.ts.map +1 -1
  34. package/lib/types/host/kimi-code/mapper.d.ts +89 -1
  35. package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
  36. package/lib/types/host/kimi-code/model-catalog.d.ts +20 -4
  37. package/lib/types/host/kimi-code/model-catalog.d.ts.map +1 -1
  38. package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
  39. package/lib/types/host/kimi-code/types.d.ts +50 -6
  40. package/lib/types/host/kimi-code/types.d.ts.map +1 -1
  41. package/lib/types/host/opendesign/client.d.ts +103 -0
  42. package/lib/types/host/opendesign/client.d.ts.map +1 -1
  43. package/lib/types/host/opendesign/routes.d.ts.map +1 -1
  44. package/lib/types/host/opendesign/types.d.ts +31 -0
  45. package/lib/types/host/opendesign/types.d.ts.map +1 -1
  46. package/lib/types/host/progress-updates/index.d.ts +5 -0
  47. package/lib/types/host/progress-updates/index.d.ts.map +1 -1
  48. package/lib/types/host/progress-updates/prompt.d.ts +37 -3
  49. package/lib/types/host/progress-updates/prompt.d.ts.map +1 -1
  50. package/lib/types/host/progress-updates/tool.d.ts.map +1 -1
  51. package/lib/types/host/proxy-manager.d.ts +63 -1
  52. package/lib/types/host/proxy-manager.d.ts.map +1 -1
  53. package/lib/types/host/widget-board/line-contracts.d.ts +192 -0
  54. package/lib/types/host/widget-board/line-contracts.d.ts.map +1 -0
  55. package/lib/types/host/widget-board/line-quota.d.ts +284 -0
  56. package/lib/types/host/widget-board/line-quota.d.ts.map +1 -0
  57. package/lib/types/host/widget-board/line-registry.d.ts +402 -0
  58. package/lib/types/host/widget-board/line-registry.d.ts.map +1 -0
  59. package/lib/types/host/widget-board/provider.d.ts +140 -0
  60. package/lib/types/host/widget-board/provider.d.ts.map +1 -0
  61. package/lib/types/index.d.ts +10 -0
  62. package/lib/types/index.d.ts.map +1 -1
  63. package/lib/types/shared/kimi-code-contracts.d.ts +30 -6
  64. package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
  65. package/lib/types/shared/opendesign-contracts.d.ts +47 -0
  66. package/lib/types/shared/opendesign-contracts.d.ts.map +1 -1
  67. package/package.json +2 -1
  68. package/widgets/line-flip/index.html +58 -0
  69. package/widgets/line-flip/main.js +1102 -0
  70. package/widgets/line-flip/style.css +729 -0
  71. package/widgets/line-flip/widget.json +555 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.38.0 - 2026-10-24
6
+ - **[kimi-code] 新增 K3.1 Pro 系列(与其它模型同一 OpenAI 兼容 chat completions)、只支持思考的档位、以及缓存写入这个计费项**
7
+ - **现象**:`k3.1-pro` / `k3.1-pro-highspeed` 不在模型目录、设置卡与能力表里;「默认思考档位」永远列着 `low` / `high` / `max` 与「关闭思考」,而 K3.1 Pro 根本关不掉(服务端 400);缓存区块只有命中率、命中 / 新处理 / 输出 tokens 与请求数,**写入**这个独立计费项一个数字都没有,看不出 5m / 1h 两档各写了多少。
8
+ - **模型目录**:两条新条目按官方型号表写入(`k3.1-pro` 默认 256K、可覆盖到 1M;`k3.1-pro-highspeed` 1M),含 `thinkingType: 'only'`、`defaultReasoningEffort: 'max'` 与 `quotaMultiplier: null`(官方未公布相对倍率,卡片显示「未公布」而不是猜成 1×)。**协议不新增分支**:本线路对全部模型只走 OpenAI 兼容 chat completions(与官方 agent 的 `type = "kimi"` 一致),因此 K3.1 Pro 的请求照常发往 `/v1/chat/completions`,视频输入按型号表声明可用。
9
+ - **thinking-only**:`types.ts` 增 `thinkingTypeFor` / `defaultReasoningEffortFor` / `coerceThinkingEffort`,`reasoningEffortsFor` 对 `only` 行剔除 `none`;`adapter.ts` 在构建 body 之前加一道闸门(THE THINKING GATE):被禁的 `none` 抬到模型默认档并通过 `recordThinkingCoercion` 记录(`KIMI_CODE_THINKING_COERCED` 警告),而不是让整轮失败。
10
+ - **缓存写入**:总量读 `usage.prompt_tokens_details.cache_write_tokens`(chat)与 `cache_creation_input_tokens`(Anthropic),5m / 1h 分档读 `Msh-Usage-Cache-Write-Tokens-5m/-1h` 响应头;`KimiCodeCacheStatsDto` 的 `cacheWriteTokens` / `cacheWrite5mTokens` / `cacheWrite1hTokens` 由 `routes.ts` 填真值(原 `cacheWriteTokensNote: 'always-zero-on-this-route'` 占位删除)。chat wire 的新处理量改为 `total − cached − written`(三者互斥),Anthropic 的 `input_tokens` 仍不减——它本身不含缓存。
11
+ - **改法(客户端)**:新增 `src/client/kimi-code/labels.ts`——`wireLabel`、`effortLadder`(读模型声明的档位,`thinkingType === 'only'` 时剔除 `none`)、`canDisableThinking`、`effortOptions`(取已勾选模型的并集;「关闭思考」是开关不是档位,任一勾选模型允许它就保留),两张卡片都从这里取标签。档位下拉改由 `effortOptions` 驱动;存着的档位若所有勾选模型都不接受,仍保留该选项并标注「当前勾选的模型不接受」。只支持思考的模型在档位旁给一句说明(含模型名与 400),能力表新增「只支持思考」标记与脚注。缓存区块新增一行 `缓存写入 = 总量 · 5 分钟档 · 1 小时档`,**0 也照实显示**(空白会被读成「没有测量」)。
12
+ - **改法(三语)**:`kimi-code/locales.ts`(zh + en)与 `locales-ru/kimi-code.ts` 同步新增 `capThinkingOnly` / `capEfforts` / `capThinkingOnlyFootnote` / `effortThinkingOnlyNote` / `effortNotOffered` / `quotaUnknown` / `cacheWrite` / `cacheWrite5m` / `cacheWrite1h` / `cacheWriteHint` / `unknownMetric`,并按官方口径重写 `cacheTtlHint`、`cacheTtlDefault`、`defaultReasoningEffortHint`;俄语包键集由 `Record<KimiCodeLocaleKey, string>` 在编译期强制,缺一个键 `tsc` 就红。
13
+ - **测试**:新增 `test/kimi-code-k31.test.ts`(17 例:两条条目的全部字段、thinking-only 语义、双值 wire 与视频按声明保留、卡片契约字段)、`test/kimi-code-k31-card-ui.test.tsx`(8 例)、`test/kimi-code-effort-ladder.test.ts`(6 例)与 `test/kimi-code-cache-write.test.ts`(9 例:chat wire 的 usage 三分解、Anthropic 不减、响应头分档、以及 thinking 闸门在 chat / Anthropic 两条 wire 上的行为);`test/kimi-code-capability-ui.test.tsx` 补「未公布倍率」与「只支持思考 + 400 脚注」两例。
14
+ - **验证**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 281 文件通过 / 2 skipped,4633 passed / 8 skipped / 0 failed(删掉的用例全部只属于已撤除的 Responses 分支)。
15
+ - **文档**:README 的线路总览把 Kimi 的协议列改为「OpenAI 兼容 Chat Completions(可选 Anthropic Messages)」,模型目录由四款改为六款,补缓存写入那一行、倍率表里的两个「未公布」,并明确「本线路对全部模型使用 OpenAI 兼容 chat completions(与官方 agent 的 `type = "kimi"` 一致)」、视频清单加入 `k3.1-pro`,以及设置步骤里「默认思考档位跟随模型声明」。
16
+
17
+ ## 0.37.0 - 2026-10-23
18
+ - **[progress-updates] 进展更新补上「开局」与「收尾」两条硬要求**
19
+ - **现象**:任务开始和结束都没有进展条目,整场只在被催到的时候冒出两三条;面板看着像「只有出结论才有动静」。
20
+ - **根因**:整条链路只折叠模型显式调用 `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 个事件里一条都没有。
21
+ - **改法**:`prompt.ts` 的引导词把「开局(第一批工具调用之前)」与「收尾(最终答复之前)」提成两条硬要求,原来的「任务早期」条目降级为「计划真的变了才补」;`tool.ts` 的工具描述在首句后同步一句书挡要求——描述是模型每次调用都会读到、离调用最近的一段文本。催促阈值不动默认值(仍是 8,`NUDGE_THRESHOLD` 是测试守着的冻结契约),本机在 profile 配置里设成 4。
22
+ - **验证**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件 / 4586 passed / 8 skipped / 0 failed(工具描述的子串断言一条没改);`npm run build` 通过,`lib/index.js` 里能搜到新文案。
23
+ - **留档**:结构层面的锚点(`agent/pre-step` 做开局、`agent/turn-stopping` + `steer` 做收尾)这次刻意没做,纯文本仍是软约束,模型可以不照做。
24
+ - **[progress-updates] 提示词整段转英文,并新增「输出语言」设置(auto / 中文 / English)**
25
+ - **现象**:进展更新的系统提示词是中文的,而工具描述本来就是英文——同一件事两套语言;用户也无法指定进展本身用哪种语言写。
26
+ - **改法(提示词)**:`prompt.ts` 的 `PROGRESS_GUIDANCE` 整段换成英文,与工具描述统一措辞。新增 `ProgressUpdateLanguage = 'auto' | 'zh' | 'en'` 与 `PROGRESS_LANGUAGE_DIRECTIVES`:把「标题与正文用哪种语言写」做成一句追加在引导词末尾的指令——`auto` 跟随对话语言(日、俄等其它语言自动跟随),`zh`/`en` 明确压过对话语言。**「指令用英文」与「输出用中文」是两件互不影响的事**,这正是把语言单独拆成一个开关的原因。
27
+ - **改法(设置)**:宿主 `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)。
28
+ - **测试**:`progress-updates-apply` 新增「语言指令追加在引导词末尾」(含活引用就地换值,单实例守卫下读一次卸一次)与「未知取值退回 auto」;`live-ref-and-route` 补 schema 默认值;`progress-updates-client` 新增「下拉写的是 progressUpdatesLanguage,选项就是三个取值」,行数断言 3→4,控件禁用态补一条;中文断言同步换成英文。9 个进展更新测试文件 150 例全绿。
29
+ - **验证**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件 / 4590 passed / 8 skipped / 0 failed;`npm run build` 通过。
30
+ - **[opendesign] 额度卡终于有进度条了:吃的是控制台同源的 Design Plan 窗口(5 小时 / 7 天),不是钱包余额**
31
+ - **现象**:OpenDesign 线路的卡与设置页只有金额(「可用余额 $1.50」),没有任何百分比进度条;而 OpenDesign 控制台的计费卡明明画着「Design Plan · 5 小时额度 剩余 90%」「7 天额度 剩余 81%」两条带重置倒计时的进度条。
32
+ - **根因(两层)**:一是**读错了面**。插件一直只读 `/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`。
33
+ - **改法(宿主)**:新增 `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` 继续只放钱包余额。
34
+ - **改法(界面)**:设置页每个窗口一行——名称 + 「已用 x% · 剩余 y%」+ `role="progressbar"` 进度条 + 「{时间} 重置」;读不到或该工作区未配置时只写一句弱化说明,绝不画 0% 的假条。输入框徽标在有窗口时显示最窄窗口的「剩余 90%」并带一条细进度条,tooltip 列出所有窗口;没有窗口则逐字退回原来的 `$余额`(其他线路的徽标 DOM 有专门用例守着,一个节点都没变)。看板卡复用既有窗口行,自动得到「5 小时 / 7 天」两行、两条 meter、百分比与倒计时。
35
+ - **一次被推翻的口径(留档)**:中途曾按「累计消耗占比 = 已消耗 ÷(已消耗 + 剩余)」做过一版,用户指出套餐本身有独立额度后废弃——那条式的分母会随充值漂移,且与「本期用了多少」不是同一件事。全部改动已回退,最终口径只有一套:窗口的 `limit − remaining`。
36
+ - **测试**:`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 值、失败/未配置不画条、徽标有窗口显示剩余%、无窗口退回余额且零新节点)。
37
+ - **验证(含实机结论)**:`npm run typecheck` 三工程 0 错误;全量 `npm test` 277 文件通过 / 2 skipped、4578 passed / 8 skipped / 0 failed;`npm run build` 通过。
38
+ **实机 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**。
39
+ **结论**:该端点只认控制台浏览器会话,插件持有的 key 一律不放行;官方 CLI 能读到同样窗口是用它自己的 `vela login` 会话。因此设置页把这种情况与「工作区未配置」分开,显示「额度窗口仅在 OpenDesign 控制台可见」;看板卡只写一句原因、不画 0% 假条。读取路径保留(上游哪天放开 key 或换到有会话能力的调用方即自动生效),失败时的 error 会带尝试记录,便于日后一眼判断。
40
+ - **[proxy] 代理不再劫持回环与本机网关,Linux 也能自动发现系统代理;代理卡文案改成“全部供应线路”**
41
+ - **现象**:把某条线路的 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`,只能靠环境变量。
42
+ - **改法(旁路)**:`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`,与“没有代理”是同一条路径,流式、超时与诊断包裹都不受影响。
43
+ - **改法(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`。
44
+ - **改法(文案)**:`proxyModeHint` 与 `proxyDirectHint` 三份语言包(中/英/俄)改成“本插件的全部供应线路”,并写明登录、令牌续期、模型目录与配额读取同样经过这条代理;README 的代理段落同步补上按平台的探测方式、旁路规则与 `NO_PROXY` 语义。旧文案只说“GPT 与 Antigravity(Gemini)共用”,在 12 条线路的时代早已不成立。
45
+ - **测试**:`test/proxy-manager.test.ts` 新增 22 例(42 例全绿)——回环无论列表怎么写都直连;`*`/后缀/精确主机/`host:port`/带 scheme 与路径的条目;无法解析的目标不旁路;`ProxyManager` 在代理生效时把回环与 `NO_PROXY` 主机交给 `baseFetch`(含 `Request` 入参);未列名主机仍走代理;TTL 缓存与抛错读取器;GNOME 解析(https 优先、socks 回落、`auto`/`none`/缺端口/IPv6 括号);`detectSystemProxy` 的 linux 分支与环境变量回落。
46
+ - **验证**:`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` 通过。
47
+ - **[board] 组件看板上一张卡看一条线路:`line-flip`,一条线路一张会翻面的卡**
48
+ - **形态**:看板插件在宿主上发布 cordis 服务 `widgetBoard`(apiVersion 3)。本插件在 `apply` 顶部无条件接线,经 `ctx.inject(['widgetBoard'])` 注册一个组件目录(`widgets/`,随包发布)、一个数据源(`line-card`)与三个能力(`line-refresh` / `line-account-switch` / `line-account-strategy`)。看板缺席时整段是 no-op;注册失败只 warn,绝不影响插件装载;卸载时一次 `handle.dispose()` 全撤。
49
+ - **一张卡一条线路**:`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` 里加一行。
50
+ - **单位**:各线路在 wire 上的时间表示并不统一(codex 是 Unix **秒**,antigravity / cline-pass 是 ISO 字符串,其余是**毫秒**),换算在 `src/host/widget-board/line-quota.ts` 的每线 normalizer 里各做一次,卡片数据一律毫秒,且不按数量级猜单位。
51
+ - **命名**:看板 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`。
52
+ - **数据源与能力都不声明 permission**:它们只读本机线路自己的 `GET /status`、只写本插件持有的号池文档,不跑命令、不访问组件指定的主机,没有需要人批准的东西。
53
+ - **测试**:`test/widget-board.test.ts`(11 例)只测仍然存在的边界——组件目录注册(provider 名、apiVersion 透传、id 语法)、看板缺席是 no-op、注册失败只 warn、卸载时 dispose(含迟到的注册被退回)、无 capabilities 的看板只注册数据源、没有线路注册表时不注册任何东西,以及 manifest 与注册 id 的逐字对齐。
54
+ - **验证**:`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。
55
+
5
56
  ## 0.36.2 - 2026-10-22
6
57
  - **[claude] 设置卡不再拿一枚已死的 access token 请求上游:status / 额度 / 测试连接 / 目录刷新统一走号池续期,托管账号闲置一夜后不再诱导用户重新登录(#66)**
7
58
  - **现象**:Claude 订阅的 access token 只有约 8 小时寿命。卡片上的「令牌到期」、额度读取与「测试连接」在托管(managed)账号闲置一夜后全部出错——到期时间显示为过去时间、额度区报错、连接测试失败,看起来像「登录每天失效」,用户于是每天重新登录一次;而重登只是把到期时间刷成新的 8 小时,第二天照旧。
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
 
@@ -35,7 +36,7 @@
35
36
  | Provider ID | 订阅 | 协议 | 登录方式 | 模型目录来源 |
36
37
  | --- | --- | --- | --- | --- |
37
38
  | `codex-chatgpt` | ChatGPT(Plus / Pro / Business…) | Responses | 浏览器 OAuth(localhost:1455 回调),或导入本机 Codex CLI 登录 | **实时** `/backend-api/codex/models` |
38
- | `kimi-code` | Kimi 会员 | Anthropic Messages | **设备码**(RFC 8628) | 实时 `/v1/models` + 本地兜底 |
39
+ | `kimi-code` | Kimi 会员 | OpenAI 兼容 Chat Completions(可选 Anthropic Messages) | **设备码**(RFC 8628) | 实时 `/v1/models` + 本地兜底 |
39
40
  | `command-code` | Command Code | Anthropic / OpenAI 双轨 | 浏览器 OAuth 或粘贴 API Key | 实时 `/provider/v1/models` |
40
41
  | `claude-subscription` | Claude Pro / Max | Anthropic Messages | 手动粘贴 / loopback 回调 | 实时 `/v1/models` + 本地兜底 |
41
42
  | `minimax-code` | MiniMax Code 编程订阅 | Anthropic Messages | **复用桌面端登录态** 或设备码 | **硬编码**(见下) |
@@ -118,13 +119,15 @@
118
119
  - 真正的 429 背压(`too many requests` / `engine is currently overloaded`)、连接失败与流停滞;
119
120
  - **不重试**,直接给出可操作提示(换模型 / 降上下文 / 等窗口重置 / 重新登录):配额耗尽型的 429、403 的账号额度上限、401 里的套餐权限不足、400 请求格式错误;
120
121
  - 服务把这些含义压进**同一个状态码**,因此分类读响应正文而不只看状态码;
121
- - 模型目录为订阅侧的四款模型:`k3`(1M 上下文,需 Allegretto+;Moderato 上限 256K,故默认按 256K 计算,可用上下文覆盖升到 1M)、`k3-256k`、`kimi-for-coding`(K2.8 Preview)、`kimi-for-coding-highspeed`(约 6× 速度、3× 额度),运行时以 `GET /v1/models` 为准;
122
+ - 模型目录为订阅侧的六款模型:`k3`(1M 上下文,需 Allegretto+;Moderato 上限 256K,故默认按 256K 计算,可用上下文覆盖升到 1M)、`k3-256k`、`kimi-for-coding`(K2.8 Preview)、`kimi-for-coding-highspeed`(约 6× 速度、3× 额度)、`k3.1-pro`(K3.1 Pro,默认 256K、可覆盖到 1M,需 Moderato 及以上,1M 需 Allegretto 及以上)与 `k3.1-pro-highspeed`(K3.1 Pro Highspeed,1M 上下文、约 2 倍配额,需 Pro / Allegretto 及以上),运行时以 `GET /v1/models` 为准;
122
123
  - **K3 行为按其官方文档实现**:
123
124
  - 思考档位只发 `low` / `high` / `max`(其余写法收敛映射,未知档位不发送);关闭思考发 `thinking:{type:"disabled"}`,开启时发 `thinking:{type,effort,keep:"all"}`;
124
125
  - **开启思考时每条 assistant 消息都回传 `reasoning_content`**(无推理则回传空串——服务要求的是空值而非省略,否则 400);
125
126
  - 不发送 `temperature`(采样参数按模型固定,显式值会报错);
126
127
  - 工具调用 id 截断到 64 字符;
127
128
  - `stop` 按上限裁剪为最多 5 条、每条 ≤32 字节,超长整条丢弃(截断的停止串会在错误位置终止生成);
129
+ - **K3.1 Pro 只支持思考模式**:关闭思考(`none`)会被服务端以 `400` 拒绝,所以它的档位只有 `low` / `high` / `max`、默认 `max`;「默认思考档位」下拉只列出勾选模型真正声明的档位,任一勾选模型允许关闭思考时它才出现,被拒时卡片上直接写明原因;
130
+ - **本线路对全部模型使用 OpenAI 兼容 chat completions**(与官方 agent 的 `type = "kimi"` 一致):K3.1 Pro 系列与其它模型同一协议、同一端点(`/v1/chat/completions`),Anthropic Messages 只在实时目录为某个 id 声明时启用;视频输入按官方型号表声明走,K3.1 Pro 系列可用;
128
131
  - **K3 的长思考不会被截断**:输出上限跟随上下文窗口(保留 4096 余量),因为 `reasoning_content` 计入输出,固定 32K 会把 `max` 档的长推理中途截断并返回 `length`;调用方已知 prompt 规模时上限会被下调到放得下,未知时不做猜测;
129
132
  - **请求体超 2 MB 本地即拒绝**:该端点最常见的 400 是 `total message size N exceeds limit 2097152`,官方文案不给建议,这里直接按真实序列化体积拦截,并按「循环实际做了什么」给出处方(有图可丢但丢了也补不上缺口 / 图已丢完仍超限 / 本来无图,三种情况文案不同,不再声称发生了没发生的省略);确有实测上限的部署(前置代理/网关)可设 `DSH_KIMI_CODE_MAX_BODY_BYTES` 指定该档上限,取值非正整数时**回落到默认值而不是关闭守卫**;带视频的请求走 64 MiB 档,不受该变量影响;**超限时报的是可恢复的溢出码**(`CONTEXT_WINDOW_EXCEEDED`):DSH 会对该码强制压缩本轮历史并重试同一步,所以长会话的表现是「压缩一次后继续」,而不是整轮失败——官方 `kimi-cli` 从不特殊处理 `2097152`,它靠 85% 提前压缩避开,详见下文「上下文窗口」那条;
130
133
  - **缓存是自动的,且无法手动干预**:
@@ -133,8 +136,9 @@
133
136
  - 真正决定命中率的是**内容稳定性**:同一会话内 `system` 或工具列表一旦变化会使整个前缀缓存失效(实测归零)。因此应保持工具集合稳定、把新增内容追加在末尾;
134
137
  - 卡片会显示滚动命中率,方便验证效果;
135
138
  - **写入时长可手动选择**(设置页):`prompt_cache_options`(OpenAI 兼容线路)或**顶层** `cache_control`(Anthropic 兼容线路)控制缓存**写入时长**,与上面的「无法干预」不矛盾——那一条说的是**缓存身份**(由内容前缀哈希决定),TTL 管的是另一回事;
136
- - 档位在**首次写入时锁定**,之后无法改写、命中时按原档免费续期;1 小时写入约为 5 分钟的两倍价,只有同一前缀会在一小时内被反复读取才划算。不选择时不发任何缓存字段;
137
- - **视频输入可用**(`k3`、`kimi-for-coding`):
139
+ - 档位在**首次写入时锁定**、之后无法改写,命中时按原 TTL 续期(官方口径:不传时按 **5 分钟档**写入,只有 5m / 1h 两档);1 小时写入约为 5 分钟的两倍价,只有同一前缀会在一小时内被反复读取才划算。不选择时不发任何缓存字段;
140
+ - 设置卡的缓存区块把**写入**单独列成一行(总量 + 5 分钟档 + 1 小时档):写入是独立计费项,折进「新处理 tokens」会让命中率说错话;某个分档是 0 时照实显示 0——响应头缺失只表示服务端没回报该档,不等于那里确实没写;
141
+ - **视频输入可用**(`k3`、`kimi-for-coding`、`k3.1-pro`):
138
142
  - DSH 的模态词表只有 `text`/`image`,但它是可合并扩展的接口,本插件用 TypeScript 模块增强把它扩到 `video`(**未改动 DSH 任何代码**),因此视频走 DSH 真实的能力通道,而不是只能显示在提示里;
139
143
  - 适配器把视频映射为服务文档的 `{type:'video_url',video_url:{url:'data:…'}}`。视频与图片**各有独立预算**(图片 1.5 MB、视频 48 MiB base64,最旧优先省略),请求体校验只在确实带视频时才放宽到 64 MiB;
140
144
  - 图片预算可用 `DSH_KIMI_CODE_MAX_IMAGE_BYTES` 覆盖(取值非正整数时回落到默认值)。视频预算**没有**环境变量出口,与 MiniMax 线路一致;
@@ -347,7 +351,11 @@ npx @deepseek-ai/dsh plugin --profile web add "link:C:\absolute\path\to\dsh-chat
347
351
 
348
352
  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
353
 
350
- **设置 → Codex 订阅 → 网络代理** 同时控制 GPT 与 Antigravity(Gemini)的 Host 请求,可选择系统代理(自动检测)、自定义代理或直连。Gemini 模型生成、网页登录后的令牌交换、令牌刷新、账号信息、项目发现、配额与模型目录查询均使用此设置;修改后对后续请求生效,无需重启 DSH。浏览器中的 Google 授权页面使用浏览器自己的网络设置。
354
+ **设置 → Codex 订阅 → 网络代理** 是本插件**全部供应线路共用**的一份代理设置(ChatGPT、Claude、Antigravity、Kimi Code、MiniMax Code、Command Code、Ollama、GLM Coding Plan、Step、Cline Pass、Qoder、OpenDesign),可选择系统代理(自动检测)、自定义代理或直连。各线路的模型生成、登录与令牌交换/续期、账号信息、项目发现、配额与模型目录查询,以及插件自带的工具与网页抓取,都使用此设置;修改后对后续请求生效,无需重启 DSH。
355
+
356
+ 系统代理自动检测按平台分流: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`。
357
+
358
+ 代理生效时,**回环地址**(整个 `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
359
 
352
360
  已经用官方 Codex CLI 登录过的用户可以跳过第 3 步的 OAuth:**设置 → 订阅服务 → ChatGPT**,在账号池卡片里点「登录」**旁边**的「导入本机 Codex CLI 登录」即可(见「本机登录」)。
353
361
 
@@ -540,9 +548,9 @@ DSH 设置页的「Subagent」卡片会把勾选的模型写成会话级的允
540
548
 
541
549
  `kimi-code` 会像其他 Provider 一样出现在 DSH 模型选择器中。**上下文窗口**默认取模型目录值,可逐模型覆盖(用于 DSH 的压缩与溢出判断,支持 `1M` / `256K` / `200000` 等写法)——注意 `k3` 的 1M 上下文需要 Allegretto 及以上套餐,因此默认按 256K 计算,升级后再在此覆盖为 1M。
542
550
 
543
- **申报的窗口默认就是目录值或你的覆盖值,不做折算**——`k3` 覆盖成 1M 就按 1M 申报。撞上 2 MB 请求体上限时,本地守卫抛的是 `CONTEXT_WINDOW_EXCEEDED`:DSH 会对该码**自动压缩本轮历史并重试同一步**,所以表现是「压缩一次后继续」,不是整轮失败。想要「撞墙之前就自动压缩」,可设 `DSH_KIMI_CODE_BYTES_PER_TOKEN` 启用窗口折算:申报值 = `min(声明值, floor(2MB / d))`。取值按内容密度选——DSH 的 token 计量是固定密度(4 字符/token,见 `@deepseek-ai/dsh-token-meter`),看不见中文占 3 字节,所以「一个计量 token 占多少字节」= 4 × 每字符字节数:纯 ASCII 约 4、中英混合约 8、密集中文约 12;对应的字节墙分别是 524288 / 262144 / 174763 计量 token。实测:`d=4` → 524288(代码为主的会话在 1.68 MB 处压缩)、`d=8` → 262144(混合)、`d=12` → 174762(中文,三种密度都在墙前)。压力阈值是 `min(floor(0.8 × 窗口), 窗口 − 65536)`(`compaction-basic`:`thresholdRatio` 默认 0.8、`headroomTokens` 默认 65536、本线路不申报 `defaultMaxTokens` 故无输出预留)。该变量是**可选的提前压缩开关**而不是安全守卫:不设或拼错等于不启用,真正兜底的是上面那个恢复码。**默认思考档位**只提供 `low` / `high` / `max` 三档与「关闭思考」(服务对这三档以外的取值直接报 400);切换模型或切换档位都会使上下文缓存失效,建议在同一会话内保持一致。
551
+ **申报的窗口默认就是目录值或你的覆盖值,不做折算**——`k3` 覆盖成 1M 就按 1M 申报。撞上 2 MB 请求体上限时,本地守卫抛的是 `CONTEXT_WINDOW_EXCEEDED`:DSH 会对该码**自动压缩本轮历史并重试同一步**,所以表现是「压缩一次后继续」,不是整轮失败。想要「撞墙之前就自动压缩」,可设 `DSH_KIMI_CODE_BYTES_PER_TOKEN` 启用窗口折算:申报值 = `min(声明值, floor(2MB / d))`。取值按内容密度选——DSH 的 token 计量是固定密度(4 字符/token,见 `@deepseek-ai/dsh-token-meter`),看不见中文占 3 字节,所以「一个计量 token 占多少字节」= 4 × 每字符字节数:纯 ASCII 约 4、中英混合约 8、密集中文约 12;对应的字节墙分别是 524288 / 262144 / 174763 计量 token。实测:`d=4` → 524288(代码为主的会话在 1.68 MB 处压缩)、`d=8` → 262144(混合)、`d=12` → 174762(中文,三种密度都在墙前)。压力阈值是 `min(floor(0.8 × 窗口), 窗口 − 65536)`(`compaction-basic`:`thresholdRatio` 默认 0.8、`headroomTokens` 默认 65536、本线路不申报 `defaultMaxTokens` 故无输出预留)。该变量是**可选的提前压缩开关**而不是安全守卫:不设或拼错等于不启用,真正兜底的是上面那个恢复码。**默认思考档位**的选项跟随勾选模型自己声明的档位——`low` / `high` / `max`,以及在允许关闭思考的模型上才出现的「关闭思考」(服务对这些以外的取值直接报 400);K3.1 Pro 系列只支持思考模式,硬关会被拒(400),所以勾选它时这一档不出现,卡片上会写明原因;切换模型或切换档位都会使上下文缓存失效,建议在同一会话内保持一致。
544
552
 
545
- **额度倍率**取自官方模型表并显示在设置页模型能力表的「说明」列(悬停可一并看到):`k3` = **2×**、`k3-256k` = **1×**、`kimi-for-coding` = **1×**、`kimi-for-coding-highspeed` = **3×**。倍率绑定**模型 id**,与上下文长度、缓存命中率都无关——选 `k3` 就是 2×,哪怕只用几千 token。注册表不认识的新模型 id 显示为**未知**而不是猜成 1×。
553
+ **额度倍率**取自官方模型表并显示在设置页模型能力表的「说明」列(悬停可一并看到):`k3` = **2×**、`k3-256k` = **1×**、`kimi-for-coding` = **1×**、`kimi-for-coding-highspeed` = **3×**;`k3.1-pro` 与 `k3.1-pro-highspeed` 官方未公布相对倍率(后者只说了「约为常规版 2 倍」),因此显示为**未知**而不是猜成 2×。倍率绑定**模型 id**,与上下文长度、缓存命中率都无关——选 `k3` 就是 2×,哪怕只用几千 token。注册表不认识的新模型 id 显示为**未知**而不是猜成 1×。
546
554
 
547
555
  **区域**:默认使用中国大陆主机(`auth.kimi.com` / `api.kimi.com`)。国际账号可设置 `DSH_KIMI_CODE_OAUTH_HOST=https://auth.kimi.ai` 与 `DSH_KIMI_CODE_BASE_URL=https://api.kimi.ai/coding` 后重新登录;环境变量同时会钉住区域,设置页会显示当前解析到的主机。
548
556
 
@@ -1064,9 +1072,9 @@ OAuth 是默认入口;「使用 API Key」按钮保留为兼容回退,部署
1064
1072
  | POST | `/models/visibility`、`/models/visibility-all` | 单个/批量隐藏 |
1065
1073
  | POST | `/models/context-window` | 单模型上下文窗口覆盖 |
1066
1074
  | POST | `/catalog/refresh` | 用号池里可用的 Key 同步实时目录;目录真的变了才通知模型选择器重建 |
1067
- | GET\|POST | `/usage` | 读取每个 OAuth 账号的钱包余额与账单摘要(套餐、credits、周期;每账号各一次请求);两项独立,失败作为数据显示,绝不标记账号 |
1075
+ | GET\|POST | `/usage` | 读取每个 OAuth 账号的钱包余额、账单摘要(套餐、credits、周期)与 **Design Plan 额度窗口**(5 小时 / 7 天,各自的 limit 与剩余;工作区 id 每个请求只解析一次);三路相互独立,失败作为数据显示,绝不标记账号 |
1068
1076
 
1069
- 协议事实与未验证项的完整证据记录见 `docs/opendesign-line-plan.md`:设备授权的创建与轮询响应是**实测**的,批准后的字段名来自上游 issue #8870;钱包与账单摘要在真实订阅账号上实测过,对话链路仍未与真实 Key 联调。
1077
+ 协议事实与未验证项的完整证据记录见 `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
1078
 
1071
1079
  ## 本机登录
1072
1080
 
@@ -1160,6 +1168,21 @@ Antigravity 的 Gemini 用量以流结束时的上游累计计数为准,缓存
1160
1168
 
1161
1169
  状态响应只包含脱敏 email、套餐、账号 ID 后四位、token 到期时间和额度 DTO。
1162
1170
 
1171
+ ## 组件看板卡片(dsh-widget-board)
1172
+
1173
+ 装了 `dsh-widget-board` 的 Host 上,本插件往组件库里放一张卡片 `line-flip`(**线路额度**):**一条线路一张卡**,同一份组件摆多张、每张在 `props.line` 里写自己那条线路,不需要额外配置。
1174
+
1175
+ | 卡片 | 数据源 | 能力 |
1176
+ | --- | --- | --- |
1177
+ | **线路额度** `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` |
1178
+
1179
+ - 卡片自己会翻面:正面是这条线路的额度窗口、进度条与重置倒计时;背面是它的号池、当前账号与三档轮换策略(顺序 / 轮询 / 粘住)。`props.line` 取 `codex`、`claude`、`kimi-code`、`minimax-code`、`antigravity`、`command-code`、`glm-coding-plan`、`step-code`、`qoder`、`cline-pass`、`opendesign` 之一,想看哪条线路就摆哪一张。
1180
+ - 注册走看板发布的 `widgetBoard` 服务(注册时带服务自己报的 `apiVersion` 协商),组件目录 `widgets/` 随包发布;看板没装时这段什么都不做,看板拒绝注册时只记一条 warn,不影响插件装载;卸载时一次 `handle.dispose()` 把组件目录、数据源与能力一起撤掉。
1181
+ - 数据源与三个能力都**不声明 `permission`**:它们只读本机这条线路自己的 `GET /status`、只写本插件持有的号池文档,不跑命令、不访问卡片指定的主机,所以不会弹授权按钮。
1182
+ - 数据源与能力名都以 `dsh-chatgpt-subscription:` 为前缀(**不带** `@eddyskywalker/` 的 scope):看板 manifest 的 id 正则不接受 `@` 与 `/`,带 scope 的名字在 manifest 里根本写不出来。
1183
+ - 卡片里的时间戳一律是**毫秒**:各条线路在 wire 上的单位并不统一(codex 是 Unix 秒,antigravity / cline-pass 是 ISO 字符串,其余是毫秒),换算在 `src/host/widget-board/line-quota.ts` 里每条线路各做一次,卡片不按数量级猜单位。
1184
+ - 插件更新后要**重启一次 Host**:看板没有插件热重载,新的组件目录只在装载时进组件库。
1185
+
1163
1186
  ## 开发与验证
1164
1187
 
1165
1188
  ```sh