@eddyskywalker/dsh-chatgpt-subscription 0.8.5 → 0.9.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 +36 -0
- package/README.md +93 -38
- package/lib/client.js +2126 -1693
- package/lib/client.js.map +1 -1
- package/lib/index.js +7588 -2772
- package/lib/types/client/claude/ClaudeComposerQuota.d.ts +33 -0
- package/lib/types/client/claude/ClaudeComposerQuota.d.ts.map +1 -0
- package/lib/types/client/{zhipu/ZhipuSection.d.ts → claude/ClaudeSection.d.ts} +2 -2
- package/lib/types/client/claude/ClaudeSection.d.ts.map +1 -0
- package/lib/types/client/claude/locales.d.ts +444 -0
- package/lib/types/client/claude/locales.d.ts.map +1 -0
- package/lib/types/client/claude/styles.d.ts +15 -0
- package/lib/types/client/claude/styles.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/host/claude/__probe-assert.d.ts +2 -0
- package/lib/types/host/claude/__probe-assert.d.ts.map +1 -0
- package/lib/types/host/claude/account-pool.d.ts +580 -0
- package/lib/types/host/claude/account-pool.d.ts.map +1 -0
- package/lib/types/host/claude/adapter.d.ts +267 -0
- package/lib/types/host/claude/adapter.d.ts.map +1 -0
- package/lib/types/host/claude/adopt.d.ts +292 -0
- package/lib/types/host/claude/adopt.d.ts.map +1 -0
- package/lib/types/host/claude/client.d.ts +513 -0
- package/lib/types/host/claude/client.d.ts.map +1 -0
- package/lib/types/host/claude/mapper.d.ts +510 -0
- package/lib/types/host/claude/mapper.d.ts.map +1 -0
- package/lib/types/host/claude/model-catalog.d.ts +365 -0
- package/lib/types/host/claude/model-catalog.d.ts.map +1 -0
- package/lib/types/host/claude/oauth.d.ts +393 -0
- package/lib/types/host/claude/oauth.d.ts.map +1 -0
- package/lib/types/host/claude/routes.d.ts +128 -0
- package/lib/types/host/claude/routes.d.ts.map +1 -0
- package/lib/types/host/claude/token-store.d.ts +312 -0
- package/lib/types/host/claude/token-store.d.ts.map +1 -0
- package/lib/types/host/claude/types.d.ts +237 -0
- package/lib/types/host/claude/types.d.ts.map +1 -0
- package/lib/types/index.d.ts +10 -7
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/__probe-claude-import.d.ts +2 -0
- package/lib/types/shared/__probe-claude-import.d.ts.map +1 -0
- package/lib/types/shared/claude-contracts.d.ts +337 -0
- package/lib/types/shared/claude-contracts.d.ts.map +1 -0
- package/package.json +1 -1
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts +0 -26
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts.map +0 -1
- package/lib/types/client/zhipu/ZhipuSection.d.ts.map +0 -1
- package/lib/types/client/zhipu/locales.d.ts +0 -275
- package/lib/types/client/zhipu/locales.d.ts.map +0 -1
- package/lib/types/client/zhipu/styles.d.ts +0 -12
- package/lib/types/client/zhipu/styles.d.ts.map +0 -1
- package/lib/types/host/zhipu/account-pool.d.ts +0 -43
- package/lib/types/host/zhipu/account-pool.d.ts.map +0 -1
- package/lib/types/host/zhipu/adapter.d.ts +0 -93
- package/lib/types/host/zhipu/adapter.d.ts.map +0 -1
- package/lib/types/host/zhipu/client.d.ts +0 -153
- package/lib/types/host/zhipu/client.d.ts.map +0 -1
- package/lib/types/host/zhipu/mapper.d.ts +0 -111
- package/lib/types/host/zhipu/mapper.d.ts.map +0 -1
- package/lib/types/host/zhipu/model-catalog.d.ts +0 -73
- package/lib/types/host/zhipu/model-catalog.d.ts.map +0 -1
- package/lib/types/host/zhipu/routes.d.ts +0 -33
- package/lib/types/host/zhipu/routes.d.ts.map +0 -1
- package/lib/types/host/zhipu/token-store.d.ts +0 -112
- package/lib/types/host/zhipu/token-store.d.ts.map +0 -1
- package/lib/types/host/zhipu/types.d.ts +0 -125
- package/lib/types/host/zhipu/types.d.ts.map +0 -1
- package/lib/types/shared/zhipu-contracts.d.ts +0 -164
- package/lib/types/shared/zhipu-contracts.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- **移除 Claude 线路的「合规告知 + 确认门禁」**:设置卡片顶部那段必须显式接受的告知、`/claude/api/consent` 路由、以及**主机侧门禁**全部删除。
|
|
6
|
+
- **为什么必须整体删除而不是只删界面**:那条门禁不是纯 UI——它决定**适配器是否注册**,未接受时 `login`/`adopt`/`accounts`/`quota`/`connection/test`/`catalog/refresh`/`settings`(POST)/`login/input` 一律 403。**只删告知框会留下门禁、却再没有地方能确认它,等于把这条线路锁死。** 现在 `claimClaudeRoute` **无条件注册**(保留原有的路由争用处理:`try/catch` + `claudeConflict` 上报 + `llm/adapters-updated` 重新认领)。
|
|
7
|
+
- **风险事实不变,只是不再要求点击**:Anthropic 现行条款仍明确不允许第三方应用提供 Claude.ai 登录、也不允许代用户经 Free/Pro/Max 凭据转发请求,本插件**仍未获任何授权或认可**。README 保留了如实说明,并写明「此前版本有确认步骤,现已移除;移除的只是那一步交互,不改变上述事实」。
|
|
8
|
+
- **用户已有数据必须继续可读**——这是本次最需要小心的点,因为**已确认过的用户磁盘上确实写有 `consent` 键**(实测本机 `~/.dsh/storages/claude-models.json` 含 `{accepted:true, acceptedAt:..., version:"1"}`)。已加测试锁定:含旧 `consent` 键的设置文档**仍能正常解析、其余字段完好**,两条读取路径(手写文件回退解析器、命名空间 schema)都覆盖。手写解析器本就逐字段显式读取、不拒绝未知键,因此无需修改,但现在有测试固定这一行为。
|
|
9
|
+
- **一处纠正**:实现中途曾误以为「zod 默认剥离未知键」。实测本仓库使用的 `@deepseek-ai/schemastery` **会保留**未知键于 scope 值内,只是 `registerClaudePreferenceStore.status()` 按已知字段重建对象,因此陈旧键不会逃逸到状态响应、卡片或路由;文件回退路径则在下一次保存时丢弃它。**结果与预期一致,机制与当初描述不同**,已按实测记录。
|
|
10
|
+
- **验证**:`tsc` 三个项目**均 0 错误**;`npm test` **110 文件 / 1573 项通过、0 失败**(删除 1 个只测该特性的测试文件 367 行,新增 5 条把「不再有门禁」钉死的用例);其中一条端到端用例证明一个从前被拦下的 settings POST 在**完全没有确认状态**时成功,并校验落盘键集合不含 `consent`。源码中仅剩 2 处 `consent` 字样,属于 **antigravity 线路自己的 OAuth `prompt:'consent'` 参数**,与本次无关、按边界未动。
|
|
11
|
+
- **新增模型 Claude Opus 5.5(`claude-opus-5-5`)**,规格取自 Anthropic 官方文档(2026-09-22 发布):1M 上下文 / 128K 输出 / 支持图片输入 / 档位 `low`–`max`。
|
|
12
|
+
- **它不能关闭思考**:官方文档明确 `thinking:{type:"disabled"}` 与 `{type:"enabled",budget_tokens:N}` **都返回 400**,只能省略 `thinking` 或发 `{type:"adaptive"}`。因此能力表标记为**不可关闭思考**,并有测试固定。
|
|
13
|
+
- **它的默认档位是 `medium`**(其它带 effort 的模型默认 `high`),因此**没有被归入 `mid-convo` 分支**——该分支会强制发送 `output_config.effort='high'`,对 Opus 5.5 等于**静默抬高一档、增加开销**。代码注释记录了这条推理,测试另有断言把 `mid-convo` 集合钉死为原有的两个 id,使「再加一个强制档位模型」必须是一次经过审视的改动。
|
|
14
|
+
- **不受影响的破坏性变更**:官方同时列出「不支持强制工具调用(`tool_choice` 为 `any`/`tool` 返回 400)」。已核实**本仓库 mapper 从不发送 `tool_choice`**,因此不受影响(此为查证结果,非假定)。
|
|
15
|
+
- **保真锁没有被削弱**:原测试硬断言「恰好 14 行且 id 与参照快照完全相等」,而本机快照(`@earendil-works/pi-ai@0.85.1`)**早于 Opus 5.5**。改法是:快照内每条仍逐字段比对(强度不变);id 相等改为**同相对顺序的子序列匹配**;超出快照的 id 必须出现在测试内显式的 `LOCALLY_CURATED_MODEL_IDS` 清单上,并有**反向断言**(表里任何超出快照的 id 若不在清单上即失败),从而**臆造或拼错的 id 无法蒙混**。`DEFAULT_VISIBLE_MODEL_IDS` 现以 `claude-opus-5-5` 开头。
|
|
16
|
+
- **变异验证**:臆造 id、转录字段漂移、转录行乱序、把第三个模型标成 `mid-convo`、以及新增一条未登记的 id —— 五种篡改**均会导致测试失败**。
|
|
17
|
+
- **未联网核实的项**:模型行本身的字段值来自官方文档(非实测);服务端的 actual effort 默认与 400 行为**未在真实账号上验证**。
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
- **GLM(智谱 Coding Plan)线路被 Claude(订阅)线路取代**:移除 provider `zhipu-coding-plan` 的全部实现(`src/host/zhipu/`、`src/client/zhipu/`、`src/shared/zhipu-contracts.ts` 与三个 zhipu 测试文件),新增 provider `claude-subscription`,以 **Claude Pro / Max 订阅的 OAuth 登录态**访问 Anthropic Messages 接口(不使用 API Key、不按量计费)。设置页第六个标签由 **GLM** 换成 **Claude**。
|
|
21
|
+
- ⚠️ **合规前提,且已在 UI 上如实告知**:Anthropic 现行条款写明 *"Anthropic does not permit third-party developers to offer Claude.ai login into their own applications, or to route requests through Free, Pro, or Max plan credentials on behalf of their users"*,并声明保留不经预告的执法权;已有开源项目被下架、有账号因此被限制。本插件**未获 Anthropic 任何授权或认可**,且**告知不改变条款效力**——风险由使用者承担。卡片文案据实措辞,并明确写出「未经授权」而非暗示合规。
|
|
22
|
+
- **门禁在 Host 侧强制,不是界面上的一个勾**:未接受时 `login` / `adopt` / `accounts` / `quota` / `connection/test` / `catalog/refresh` / settings POST / `login/input` **一律 403**,且**不读取本机 Claude Code 凭据、不注册适配器**(模型不出现在选择器里);只有 `GET /status` 与 consent 接口开放,否则用户看不到也无法接受那段告知。撤销接受会**注销适配器**、中止在飞登录、停止额度轮询,但**保留已存凭据而使其不可用**(不静默删除用户数据)。以上每一条都有测试。
|
|
23
|
+
- **协议事实的出处是"本机可复核的引用",不是自评**:OAuth 端点、client_id、鉴权头、Claude Code 身份块、工具名归一化表、模型能力表,全部取自本机随 harness 安装的 `@earendil-works/pi-ai@0.85.1`(lockfile integrity `b9bcce47…`,harness checkout `477b4f4205` = `dsh-v0.1.7-rc.2`)的 `dist/` 产物,均在代码注释与测试中带行号引用。**没有发出过任何真实 OAuth 或 Messages 请求**:本机无 Claude 凭据、无 Claude Code 安装,因此真实可用性**未经验证**(见下)。
|
|
24
|
+
- **本实现不照抄参照实现的一处安全缺陷**:参照实现把 PKCE verifier 直接当作 OAuth `state`(`dist/auth/oauth/anthropic.js:209` 的 `state: verifier`),会把本应保密的 verifier 写进授权 URL、地址栏、浏览器历史与剪贴板。本线路是两次**独立**随机抽样,并有测试断言授权 URL 中不出现原始 verifier(该测试先从真实的兑换请求里取出 verifier,因此否定断言不是空转)。
|
|
25
|
+
- **思考形态有四类,顺序决定成败**:`mid-convo`(`compat.supportsMidConvoEffort === true`,**排在最前且无条件**)→ `{type:'adaptive', block_binding:{prefix_mismatch_behavior:'drop_block'}}` **外加** `output_config.effort`;`adaptive` → `{type:'adaptive'}`;`budget` → `{type:'enabled', budget_tokens}`;`none` → 不发。**`claude-fable-5-1` 与 `claude-opus-5` 同时带 `forceAdaptiveThinking`**,因此把它们当成普通 `adaptive` 会**静默丢掉 `block_binding` 与 `output_config`**——看起来完全正确,而参照实现自己的注释写明该缺失会导致**持续 400**。这条缺陷是在实现过程中被独立核对发现并修正的,并补了反向对照(改回旧值即失败),因为它原本连"保真锁"一起锁错了。
|
|
26
|
+
- **预算算术按参照实现转录**(`MIN_ANSWER_TOKENS = 1024`、`DEFAULT_THINKING_BUDGETS`、`clampReasoning` 把 `xhigh`/`max` 夹到 `high`、以及 caller 侧与 wire 侧两道钳制),并测试了两个陷阱:`undefined` 的输出上限**不得**被当成 0(否则思考预算吞掉整个响应上限、回答没有余量),以及传入的必须是**已解析**的上限。
|
|
27
|
+
- **思考块带签名则原样回放**(`redacted_thinking` 同样回放),**无签名则丢弃**——这是思考模式下多轮工具调用的前提;有真正的多轮集成测试(`thinking → tool_use → tool_result → 续轮`),不是手搭 fixture。工具名出站按 Claude Code 规范大小写归一化、入站按大小写无关匹配回原名;**归一化后碰撞则放弃归一化**,避免把结果投给错误的工具。
|
|
28
|
+
- **两条登录路径是两个流程**:授权码与签发它的 `redirect_uri` 绑定,因此模式在流程开始时确定、中途切换即作废重发。默认**手动粘贴**(授权页把码显示在屏幕上),loopback 为可选并绑定 `127.0.0.1`。**一次授权只兑换一次**(compare-and-set:浏览器回调与粘贴同时到达时只有一方兑换,另一方得 409;已结算得 410 且不兑换);**错误的 state 只拒绝那一个请求**,不终止合法登录。刷新是**单飞**的,否则到期瞬间一批请求会各自轮换刷新令牌全部作废。
|
|
29
|
+
- **账号身份是两层,令牌绝不作键**:不可变的 `internalId` 是唯一路由键;`identityKeys`(uuid / email / 派生 seed)只增不换,同一账号再次登录**合并**而非产生幽灵账号。**唯一例外的限制被如实写明并有测试**:服务端既无 uuid 也无 email 时无法自动识别同一账号,卡片会标注并提供**手动合并**——不伪造稳定 id。
|
|
30
|
+
- **收编本机 Claude Code 登录是可选且默认关闭的只读操作**:开启前只探测文件是否存在(不读内容),开启后才读取;得到的是**快照,永不由本插件刷新**——Claude Code 刷新同一枚轮换令牌,两个进程各自刷新会互相作废,而进程内单飞**解决不了跨进程竞态**,因此"永不刷新"是唯一正确答案而非优化。**绝不写入或删除 Claude Code 的任何文件**;managed 与 adopted 冲突时合并为一条且 managed 胜出,**adopted 标记不得残留**(残留会让该账号永远不再刷新)。
|
|
31
|
+
- **额度两套单位,分别换算且有交叉锁**:`/api/oauth/usage` 的 `utilization` 是**已用百分比 0–100**,而 `anthropic-ratelimit-unified-*-utilization` 响应头是**分数 0–1**、重置时间是 **epoch 秒**(与 body 的 ISO 字符串不同)。**`utilization: 0` 是「尚未使用」的正常态,不是额度耗尽**;两套单位不会被混淆(有测试证明同一状态的两种表达得到相同结果)。键集随账号类型变化且含会漂移的开关代号,因此只读已知键、**缺失不当作 0**。
|
|
32
|
+
- **换号两条硬约束**:只在**凭据失败**或**账号级限流**时换号——全局限流 / 过载 / 5xx **绝不换号**(其它账号共享同一全局限制);**一旦已有输出产出就绝不换号**(否则重复文本或重复工具调用),改为直接报错。最多 3 次。
|
|
33
|
+
- **`xhigh` 原样透传,不做收敛**:`ReasoningEffortId` 在 dsh-llm 中是无约束 brand(`brandString(id)`,注释明写 no validation),本仓库已有四条线路使用 `xhigh`。写一张多余的收敛表会把用户选的档位静默降级——这条曾一度被误判为"harness 词表不支持",经读定义后纠正。
|
|
34
|
+
- **移除是纯代码移除,不动用户数据**:`storages/zhipu-*.json` 与 `dsh-zhipu` 设置命名空间**原样留在磁盘、不再被读取**(不删除、不迁移、不加提示)。**兄弟线路不受影响**:`command-code` 与 `workbuddy` 目录中的 `zai-org/GLM-5.3`、`glm-5.3` 等是它们各自上游的**真实模型名**,全部保留(约 42 处,有命令核对数量未变)。
|
|
35
|
+
- **旧会话的恢复行为**:选择仍指向已删除 provider 的旧会话,发送时会被 harness 以 `session/model-unavailable`("Select an available model before sending a message.")拒绝——这是 harness 内建行为,**不新增桥接**。恢复方式就是在模型选择器里另选一个模型。本机已核实无默认模型指向该 provider。
|
|
36
|
+
- **验证**:`tsc -p tsconfig.host.json` / `tsconfig.client.json` / `test/tsconfig.json` 三个项目**均 0 错误**;`npm test` **全绿**,无回归;`npm run build` 成功;`pnpm-lock.yaml` / `pnpm-workspace.yaml` **无 diff**(未改依赖)。新增约 11 个源文件与 12 个测试文件、约 260 项测试。
|
|
37
|
+
- **未经核实的项(必须如实记录)**:(1) **真实订阅端到端从未执行**——登录、令牌刷新、多轮工具调用、图片、额度读取、取消登录均未在真实账号上跑过,因此该线路应被视为**未经端到端验证**;(2) `/api/oauth/usage` 的确切键集与限流行为来自二手来源,整个 pnpm 树中不存在;(3) Claude Code 凭据文件的确切布局来自二手来源,且本机不存在该文件,收编路径只能靠 fixture 构造性验证;(4) macOS 钥匙串服务名未核实且明确列为非目标。以上各项均在代码注释中标注为来源等级,不冒充为本机事实。
|
|
38
|
+
- **回滚**:本条替代 `0.8.5`。如需退回带 GLM 线路的版本,安装 `@eddyskywalker/dsh-chatgpt-subscription@0.8.5` 即可;该版本的 GLM 凭据与设置仍在本机磁盘上,可直接复用。
|
|
39
|
+
|
|
40
|
+
|
|
5
41
|
- **修复 issue #18:在 DSH Desktop 0.1.7-rc.2 启用本插件时报 `fiber state 5`、导致三条 web 行「未激活」**。报错原文是 `dsh: warning: 3 entries did not activate`,点名 `web`、`web-search-deepseek`、`web-fetch-http`,且**只有装了本插件才会出现**。根因是**启用路径上的启动时序**,不是本插件把 `web` 弄坏了。
|
|
6
42
|
- **`fiber state 5` 是 `UNLOADING`**(`FiberState`:0 PENDING / 1 LOADING / 2 ACTIVE / 3 FAILED / 4 DISPOSED / 5 UNLOADING)。harness 的 `inactiveEntries()`(`packages/boot/app-boot/src/index.ts:857`)把任何非 ACTIVE / PENDING / FAILED 的行渲染成 `fiber state N`;「未激活」是它对**卸载中**这一瞬态的措辞,不是加载失败。
|
|
7
43
|
- **为什么是这三行**:`web-search-deepseek` 与 `web-fetch-http` 都 `inject: ['web']`,所以 `web` 一旦重启,它们必然跟着卸载。它们是**被牵连**的,不是各自出错的。
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
- [Kimi Code 线路](#kimi-code-线路)
|
|
15
15
|
- [Command Code 线路](#command-code-线路)
|
|
16
16
|
- [WorkBuddy 线路](#workbuddy-线路)
|
|
17
|
-
- [
|
|
17
|
+
- [Claude(订阅)线路](#claude订阅线路)
|
|
18
18
|
- [子代理模型授权](#子代理模型授权0215-起)
|
|
19
19
|
- [随包分发的 Agent Preset](#随包分发的-agent-preset)
|
|
20
20
|
- [升级、降级与卸载](#升级降级与卸载)
|
|
@@ -84,17 +84,23 @@
|
|
|
84
84
|
- **流中断即失败**:上游必然以 `finish_reason` 或 `data: [DONE]` 结束,两者都缺失说明连接中途断开,此时抛出错误而不是把半截文本当成完整回答;
|
|
85
85
|
- 额度来自 `/billing/meter/get-user-resource`,卡片展示套餐名、本周期已用/上限、剩余额度与重置时间;设置页为「设置 → 订阅服务 → WorkBuddy」标签页,对话输入框右侧有该线路的额度胶囊。
|
|
86
86
|
|
|
87
|
-
**
|
|
88
|
-
|
|
89
|
-
- 注册 `
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
87
|
+
**Claude(订阅)线路**
|
|
88
|
+
|
|
89
|
+
- 注册 `claude-subscription` Provider,以 **Claude Pro / Max 订阅的 OAuth 登录态**访问 Claude 模型(Anthropic Messages 接口),**不使用 API Key、也不按量计费**;
|
|
90
|
+
- ⚠️ **风险须知(插件不设确认步骤,但事实不变)**:Anthropic 现行条款明确写明**不允许第三方应用提供 Claude.ai 登录、也不允许代用户经 Free / Pro / Max 凭据转发请求**,并保留不经预告的执法权;已有开源项目被下架、有账号因此被限制。**本插件未获 Anthropic 任何授权或认可**,使用风险由使用者自行承担。此前版本在卡片上设有确认步骤与配套主机门禁,两者均已移除;移除的只是那一步交互,**不改变上述事实**;
|
|
91
|
+
- **这不是抄一个 token 就能用**:订阅令牌要求请求**完整模仿 Claude Code 的身份**,否则会被服务端拒绝或分类判别——`Authorization: Bearer` 且 **`x-api-key` 必须缺省**、`user-agent: claude-cli/<版本>`、`x-app: cli`、`anthropic-beta` 至少含 `oauth-2025-04-20` 与 `claude-code-20250219`、`system` 的**首个块必须是 Claude Code 身份声明**。这些都在代码里显式实现并有测试锁定;
|
|
92
|
+
- **OAuth 用 PKCE,且 state 与 verifier 独立生成**。这一点特意**不照抄参照实现**:本机参照实现把 PKCE verifier 直接当作 OAuth `state`(`state: verifier`),那会把本应保密的 verifier 写进授权 URL、地址栏、浏览器历史乃至剪贴板。本线路是两次独立随机抽样,并有测试断言授权 URL 中**不出现原始 verifier**;
|
|
93
|
+
- **两条登录路径,模式在流程开始时确定且不可中途切换**:默认是**手动粘贴**(授权页把码显示在屏幕上,粘贴 `<code>#<state>`;也容错接受整条重定向 URL)。可选 loopback 回调,绑定 `127.0.0.1` 并顺序探测可用端口(Windows 的保留端口段会让固定端口绑定失败)。端口探测失败**降级为手动**而不是报错。切换模式等于作废当前流程并重新发起——授权码与签发它的那次请求的 `redirect_uri` 绑定,这是该流程最常见的失败;
|
|
94
|
+
- **一次授权只兑换一次**:浏览器回调与手动粘贴可能同时到达,用 compare-and-set 保证只有一方发起兑换(另一方得到「正在处理中」,已结算的流程得到 410 且**不做任何兑换**)。错误的 `state` **只拒绝那一个请求**,不会终止正在进行的合法登录。回调服务器只绑 loopback、只应答 `/callback`、只接受本机来源;
|
|
95
|
+
- **刷新是单飞的**:并发请求共享同一次刷新。否则到期瞬间的一批请求会各自轮换刷新令牌,除第一个之外全部作废(上游会给出终局判定)。刷新令牌轮换后**先读回校验再落盘**;
|
|
96
|
+
- **模型能力逐模型查表**(`src/host/claude/model-catalog.ts`),**不从模型名推断**。该表转录自本机随 harness 安装的参照目录,**只证明抄录忠实,不证明服务端提供这些模型**——服务端自己的 `GET /v1/models` 才是权威,且它**只覆盖上下文窗口**,能力字段不被改写;
|
|
97
|
+
- **思考形态有四类,顺序决定成败**(`thinkingMode`):`mid-convo` → `{type:'adaptive', block_binding:{prefix_mismatch_behavior:'drop_block'}}` 外加 `output_config.effort`;`adaptive` → `{type:'adaptive'}`;`budget` → `{type:'enabled', budget_tokens}`(预算算术按参照实现转录,思考预算计入 `max_tokens`,**必须为回答留出至少 1024 token**);`none` → 不发思考字段。**`mid-convo` 排在最前且无条件**——`claude-fable-5-1` 与 `claude-opus-5` 同时带 `forceAdaptiveThinking`,把它们当成普通 `adaptive` 会**静默丢掉 `block_binding` 与 `output_config`**,而参照实现自己的注释写明该缺失会导致**持续 400**;
|
|
98
|
+
- **思考块带签名则原样回放**(这是思考模式下多轮工具调用的前提;`redacted_thinking` 同样回放),**无签名则丢弃**。工具名在出站时按 Claude Code 规范大小写归一化、入站时按大小写无关匹配回用户工具名;若两个工具归一化后碰撞,则**放弃归一化**原样发送,避免把结果投给错误的工具;
|
|
99
|
+
- **多账号号池,与其它线路同源**:走共享内核 `AccountPoolCore` 并复用同一张设置卡片,具备顺序耗尽 / 轮询调度 / 粘性会话、429 冷却换号、账号级失效保留、设为主账号与备注。**账号身份是两层**:不可变的 `internalId` 是唯一路由键,`identityKeys`(uuid / email / 派生 seed)是**只增不换**的别名集,同一账号再次登录会**合并**而不是产生幽灵账号。**唯一例外的诚实说明**:当服务端既没返回 uuid 也没返回 email 时无法自动识别同一账号,卡片会把该账号标注出来并提供**手动合并**;
|
|
100
|
+
- **可选择性收编本机已有的 Claude Code 登录(默认关闭)**:开启前只做一次「文件是否存在」的探测,**不读取内容**;只有你显式开启后才读取。收编得到的是一份**快照**,**永不由本插件刷新**——Claude Code 刷新的是同一枚轮换令牌,两个进程各自刷新会互相作废,而进程内的单飞解决不了跨进程竞态。快照过期后卡片会提示你**回 Claude Code 重新登录后再收编**,并且**绝不会写入或删除 Claude Code 的任何文件**;
|
|
101
|
+
- **额度面有两个来源、两套单位**:主来源 `GET /api/oauth/usage` 的 `utilization` 是**已用百分比 0–100**;而 `/v1/messages` 响应头 `anthropic-ratelimit-unified-5h-utilization` 是**分数 0–1**、重置时间是 **epoch 秒**。两套单位分别换算并有交叉测试证明它们描述同一状态。**`utilization: 0` 表示「尚未使用」,是正常状态,不是额度耗尽**;两者都不会混淆。有真实流量时以响应头为准以降低查询频率,但卡片仍会按 `QUOTA_FULL_REFRESH_MS` 做一次完整读取;
|
|
102
|
+
- **换号的两条硬约束**:只在**凭据失败**或**账号级限流**时换号——全局限流、过载与 5xx **绝不换号**(其它账号共享同一全局限制)。**一旦已有输出产出就绝不换号**(否则会重复文本或重复工具调用),改为直接报错。换号最多 3 次;
|
|
103
|
+
- 模型勾选、思考深度、上下文窗口覆盖与额度在「设置 → 订阅服务 → Claude」标签页中配置,输入框右侧另有额度胶囊(取**剩余最紧的那个窗口**)。
|
|
98
104
|
|
|
99
105
|
**设置页**
|
|
100
106
|
- 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;
|
|
@@ -383,43 +389,85 @@ DSH 设置页的「Subagent」卡片会把勾选的模型写成会话级的允
|
|
|
383
389
|
|
|
384
390
|
与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host`。
|
|
385
391
|
|
|
386
|
-
##
|
|
392
|
+
## Claude(订阅)线路
|
|
393
|
+
|
|
394
|
+
### 风险须知(请先读)
|
|
395
|
+
|
|
396
|
+
本线路以 **Claude Pro / Max 订阅登录**访问模型。Anthropic 现行条款写明**不允许第三方应用提供 Claude.ai
|
|
397
|
+
登录、也不允许代用户经 Free / Pro / Max 凭据转发请求**,并保留不经预告的执法权;**本插件未获 Anthropic
|
|
398
|
+
任何授权或认可**,你的账号**可能因此被限制、暂停或终止**。
|
|
387
399
|
|
|
388
|
-
|
|
400
|
+
此前版本在设置卡片上设有一个必须显式接受的确认步骤,并配套一条主机侧门禁;**该步骤与门禁均已移除**,
|
|
401
|
+
现在打开卡片即可直接使用。移除的只是那一步交互——上面这段事实、以及由此产生的风险,都不因移除而改变。
|
|
402
|
+
是否使用请自行判断并承担后果。
|
|
403
|
+
|
|
404
|
+
### 登录
|
|
405
|
+
|
|
406
|
+
1. 订阅 **Claude Pro 或 Max**,并确保你能在浏览器里登录 claude.ai;
|
|
389
407
|
2. 重启 DSH,让 Host 加载本插件;
|
|
390
|
-
3. 打开 **设置 → 订阅服务 →
|
|
391
|
-
4.
|
|
408
|
+
3. 打开 **设置 → 订阅服务 → Claude**;
|
|
409
|
+
4. 点「登录 Claude 订阅」。默认走**手动粘贴**:浏览器打开授权页后会把授权码显示在屏幕上,把
|
|
410
|
+
`<授权码>#<state>` 整段复制粘贴回来即可(也接受直接粘贴整条重定向 URL)。若使用 loopback 回调模式,
|
|
411
|
+
本机一个可用端口会被自动探测并绑定 `127.0.0.1`;
|
|
392
412
|
5. 按需勾选模型、设置默认思考深度与上下文窗口。
|
|
393
413
|
|
|
394
|
-
`
|
|
414
|
+
`claude-subscription` 会像其他 Provider 一样出现在 DSH 模型选择器中。**上下文窗口**默认取内置能力表声明的窗口,
|
|
415
|
+
可逐模型覆盖(用于 DSH 的压缩与溢出判断,支持 `1M` / `512K` / `200000` 等写法);**默认思考深度**只对声明了
|
|
416
|
+
档位的模型生效。**档位原样透传**(`ReasoningEffortId` 在 harness 里是无约束 brand,本仓库多条线路都直接使用
|
|
417
|
+
`xhigh`),不做任何收敛,以免把用户选的档位静默降级。
|
|
418
|
+
|
|
419
|
+
**模型表**共 15 条:14 条转录自本机随 harness 安装的参照目录,另加 1 条**本地新增**的 **Claude Opus 5.5**
|
|
420
|
+
(`claude-opus-5-5`,官方 2026-09-22 发布,1M 上下文 / 128K 输出 / 支持图片,档位 `low`–`max`)。
|
|
421
|
+
它有一条**与其它模型不同的硬约束**:**思考永远开启、不能关闭**——官方文档明确 `thinking:{type:"disabled"}`
|
|
422
|
+
与 `{type:"enabled",budget_tokens:N}` **都会返回 400**,因此能力表把它标为不可关闭思考,档位表是控制思考深度的
|
|
423
|
+
唯一手段。它的**默认档位是 `medium`**(其余带 effort 的模型默认 `high`),这一点被刻意保留:本仓库有两类模型走
|
|
424
|
+
「强制 effort」分支,若把 Opus 5.5 一并归入,就会**静默把每次请求抬高一档、花更多钱**,因此它走的是普通 adaptive
|
|
425
|
+
分支。
|
|
395
426
|
|
|
396
|
-
|
|
427
|
+
### 收编本机已有的 Claude Code 登录(可选,默认关闭)
|
|
428
|
+
|
|
429
|
+
如果你本机已经登录过 Claude Code,可以点「收编本机登录」把它作为一条账号导入,省去再次登录。
|
|
430
|
+
两点必须清楚:
|
|
431
|
+
|
|
432
|
+
- 开启前插件只探测**文件是否存在**,不读取内容;只有你显式开启后才读取;
|
|
433
|
+
- 导入的是**快照**,**本插件永不再刷新它**。Claude Code 刷新的是同一枚轮换令牌,两个进程各自刷新会互相
|
|
434
|
+
作废,进程内的单飞机制解决不了跨进程竞态。快照过期后请**回 Claude Code 重新登录,再收编一次**;
|
|
435
|
+
- 本插件**绝不写入或删除** Claude Code 的任何文件;「停止收编」只移除插件这边的记录。
|
|
436
|
+
|
|
437
|
+
### 上游接口
|
|
397
438
|
|
|
398
439
|
| 用途 | 路径 | 鉴权 |
|
|
399
440
|
| --- | --- | --- |
|
|
400
|
-
| 模型生成 | `POST
|
|
401
|
-
|
|
|
402
|
-
|
|
|
403
|
-
|
|
|
441
|
+
| 模型生成 | `POST https://api.anthropic.com/v1/messages?beta=true` | `Authorization: Bearer <access token>`,**且 `x-api-key` 必须缺省** |
|
|
442
|
+
| 模型目录 | `GET https://api.anthropic.com/v1/models` | 同上 |
|
|
443
|
+
| 订阅额度 | `GET https://api.anthropic.com/api/oauth/usage` | 同上,另带 `user-agent: claude-code/<版本>` |
|
|
444
|
+
| 授权 / 令牌 | `https://claude.ai/oauth/authorize`、`https://platform.claude.com/v1/oauth/token` | PKCE S256(端点可用环境变量覆盖) |
|
|
404
445
|
|
|
405
|
-
|
|
446
|
+
请求带有 Claude Code 身份头(`user-agent`、`x-app`、`anthropic-beta`),并在 `system` 首块声明 Claude Code 身份。
|
|
447
|
+
这是订阅令牌被服务端接受的前提,已在代码与测试中显式锁定。
|
|
406
448
|
|
|
407
|
-
### 插件路由(
|
|
449
|
+
### 插件路由(Claude 订阅)
|
|
408
450
|
|
|
409
|
-
所有路由都以 `/
|
|
451
|
+
所有路由都以 `/claude/api` 为前缀:
|
|
410
452
|
|
|
411
453
|
| 方法 | 路径 | 说明 |
|
|
412
454
|
| --- | --- | --- |
|
|
413
|
-
| GET | `/status` |
|
|
414
|
-
| POST | `/
|
|
415
|
-
|
|
|
416
|
-
| POST | `/
|
|
417
|
-
|
|
|
455
|
+
| GET | `/status` | 账号、额度、模型目录、登录流程与路由归属 |
|
|
456
|
+
| POST | `/login` | 开始 OAuth 登录,立即返回流程状态(不阻塞) |
|
|
457
|
+
| GET | `/login/status` | 轮询登录流程状态(客户端每 2 秒一次,无 SSE) |
|
|
458
|
+
| POST | `/login/cancel` | 取消登录并释放回调端口 |
|
|
459
|
+
| POST | `/login/input` | 提交手动粘贴的授权码 / 重定向 URL |
|
|
460
|
+
| POST | `/adopt` | 收编本机 Claude Code 登录(只读,作快照入池) |
|
|
461
|
+
| POST | `/adopt/disable` | 停止收编(不触碰 Claude Code 的文件) |
|
|
462
|
+
| GET / POST | `/quota` | 读取或强制刷新额度;失败以 `quotaError` 呈现而非请求失败 |
|
|
418
463
|
| GET / POST | `/models`、`/settings` | 读取或更新勾选模型、上下文窗口、默认思考深度与选中账号 |
|
|
419
464
|
| POST | `/catalog/refresh` | 强制刷新模型目录 |
|
|
420
|
-
| POST | `/connection/test` |
|
|
465
|
+
| POST | `/connection/test` | 向上游发一次最小请求测试连接 |
|
|
466
|
+
| POST | `/accounts` | 号池动作:`set-primary` / `set-alias` / `delete` / `clear-cooldown` / `clear-auth-failed` / `strategy` |
|
|
467
|
+
| POST | `/logout` | 注销(号池感知) |
|
|
421
468
|
|
|
422
|
-
与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host
|
|
469
|
+
与其它线路一样,所有修改状态的路由只接受同源 JSON POST,并校验 `Origin` 与 `Host`。**响应里永远不含
|
|
470
|
+
access token / refresh token / 授权码 / PKCE verifier**(有测试锁定)。
|
|
423
471
|
|
|
424
472
|
## 安全边界
|
|
425
473
|
|
|
@@ -427,7 +475,11 @@ Antigravity 的 access token / refresh token 使用独立的系统凭据存储
|
|
|
427
475
|
|
|
428
476
|
**WorkBuddy token 仅在 Host 内处理,从不进入浏览器**(`/workbuddy/api` 响应不含 `accessToken` / `refreshToken`,有测试锁定)。桌面扫描账号仍使用 CodeBuddy 自己的登录态文件:续期只原子写回其 `auth` 块;从本插件删除时只隐藏/恢复,绝不删除原文件。通过浏览器授权添加的账号归本插件所有,保存在独立系统凭据存储中:Windows CurrentUser DPAPI(`$DSH_HOME/storages/workbuddy-accounts.json.dpapi`)、macOS 登录钥匙串、Linux Secret Service;这类账号可在设置页真正删除。
|
|
429
477
|
|
|
430
|
-
**
|
|
478
|
+
**Claude 订阅的 access token / refresh token 同样只在 Host 内处理,从不进入浏览器**(`/claude/api` 的响应只含非机密事实,有测试锁定)。它保存在独立系统凭据存储中:Windows CurrentUser DPAPI(`$DSH_HOME/storages/claude-credentials.json.dpapi`)、macOS 登录钥匙串、Linux Secret Service;号池另用一份同样加密的文件 `$DSH_HOME/storages/claude-pool.json`。凭据文档是**多账号**结构,账号身份由不可变的 `internalId` 与只增不换的别名集共同表达,**任何路由键都不是令牌或其摘要**(令牌会轮换,用它做键会产生幽灵账号)。每次写入都**先读回校验再落盘**,校验失败会抛错且不破坏既有数据。
|
|
479
|
+
|
|
480
|
+
**收编(adopt)是只读的**:本插件从不创建、修改、移动或删除 Claude Code 的任何文件;它只读取。收编得到的快照**永不由本插件刷新**(原因见上文)。
|
|
481
|
+
|
|
482
|
+
macOS 钥匙串服务名为 `Claude Code-credentials`(**未核实**,本仓库不读取它:一份第三方指南与真实客户端对该名称说法不一致,因此它被明确列为非目标)。
|
|
431
483
|
|
|
432
484
|
升级后首次访问 Antigravity 凭据时,会读取旧 `storages/antigravity-oauth.json`,加密保存并读回校验;成功后删除旧 JSON,通常无需重新登录。失败会保留旧文件并报告错误,不会回退到明文存储。注销同时清理旧文件和新凭据。Linux 需要 `secret-tool`(libsecret 工具包)及可用、已解锁的 Secret Service 钥匙环;无桌面服务的主机也需要配置该服务。系统凭据存储保护落盘数据,不防御当前用户下已获权限的进程。
|
|
433
485
|
|
|
@@ -503,9 +555,12 @@ npm pack --dry-run
|
|
|
503
555
|
| Kimi Code 报 429 `engine is currently overloaded` | 服务容量问题(工作日 14:00–17:00 高峰更常见),会自动退避重试;若响应里带 `error.type = exceeded_current_quota_error` 则属于配额耗尽,插件不会重试而是提示补充额度 |
|
|
504
556
|
| Kimi Code 额度显示为空 | 卡片会同时给出失败原因(`/v1/usages` 的 401/403/5xx 文案),按提示处理后点「刷新用量」重试;确认用的是订阅账号——开放平台的 key 在这里不会被接受 |
|
|
505
557
|
| Kimi Code 账号一栏为空 | 账号身份取自 OAuth token 自身的 JWT 声明,套餐名取自 `/me`(`/usages` 自 2026-09 起不再返回 `user_level_name`)。重新登录或点「刷新用量」即可写入;若仍为空但显示「已登录」,点「测试连接」可确认凭据是否仍被接受 |
|
|
506
|
-
|
|
|
507
|
-
|
|
|
508
|
-
|
|
|
509
|
-
|
|
|
510
|
-
|
|
|
558
|
+
| Claude 相关接口返回 403 | 403 现在是**同源校验**的结果(修改状态的路由只接受同源 JSON POST)。若出现在浏览器里,检查是否从其它来源发起了请求;插件已不再有任何"确认后才能用"的门禁 |
|
|
559
|
+
| 授权后粘贴授权码报「请把 # 后面的部分一起复制」 | 手动流程需要 `<授权码>#<state>` **整段**。只粘贴授权码是不被接受的:用流程自己的 state 顶上会架空 state 参数、把粘贴框变成登录 CSRF 的入口,因此插件宁可报错也不猜 |
|
|
560
|
+
| loopback 回调收不到 / 端口绑定失败 | 端口探测失败会自动**降级为手动粘贴**(卡片会说明原因),照提示粘贴授权码即可。另:若浏览器把 `localhost` 解析到 `::1`,依赖浏览器的跨地址族回退可达本机 v4 监听,这是**假定**而非实测 |
|
|
561
|
+
| 模型请求报持续 400 / 「You're out of extra usage」 | 可能是身份或版本门槛:订阅令牌要求 Claude Code 身份头与 `system` 首块,且服务端会校验你申报的客户端版本(过旧会答 `claude_code_version_too_old`)。可用 `DSH_CLAUDE_CLI_VERSION` 抬高申报版本;该错误被归类为**请求问题而非凭据问题**,不会把你登出 |
|
|
562
|
+
| 额度显示为空 / 某项显示「—」 | 额度接口的键集随账号类型变化,未提供的窗口会显示为未知而**不会伪造 0**。注意 **`utilization` 是已用百分比,0% 表示尚未使用(正常态)**,不是额度耗尽;真正的耗尽会以 429 与响应头状态呈现。接口被限流时卡片保留上次成功快照并标注时间 |
|
|
563
|
+
| 收编后提示「本机 Claude Code 登录已过期」 | 这是设计如此:收编的是**快照**,插件永不刷新它(Claude Code 刷新同一枚轮换令牌,两个进程各自刷新会互相作废)。回 Claude Code 重新登录后**再收编一次**即可 |
|
|
564
|
+
| 账号被标为「无法识别账号身份」 | 服务端这个账号既没返回 uuid 也没返回 email,插件无法在再次登录时自动认出它。用卡片上的**手动合并**把它并入既有账号;这是已知限制,插件不会用假 id 掩盖它 |
|
|
565
|
+
| 模型不出现在选择器里 | 依次检查:卡片是否显示「模型路由已被其他 Provider 占用」(另一适配器持有该 id 时本插件会如实报告冲突而非抛错);以及模型是否已勾选 |
|
|
511
566
|
| Kimi Code 发送视频却没有画面 | `k3-256k` 不支持视频,切到 `k3` 或 `kimi-for-coding`;容器须在白名单内(mp4/mpeg/mov/avi/x-flv/mpg/webm/wmv/3gpp);若该模型走的是 Anthropic 线路,视频会降级为文字(该协议没有文档化的视频块)。以上情况模型都会收到明确的文字说明,据此向你说明而不是凭空回答 |
|