DeepSeek Harness Hub
← 返回列表

渠道钉选插件BreakFree003/dsh-clinepass-deepseekv4.1

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
⚠ 装前注意

把 Cline Pass 接进 DeepSeek Harnessdsh,并把每条请求钉死在 DeepSeek…

基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/16 · 已提供中文文档

Cline Pass for DeepSeek Harness (dsh): one pi-ai provider route pinned to the DeepSeek upstream channel, key entered on Settings → Models. Share-only snapshot — 分享性质,非长期维护。

综合分
31.3
GitHub 分
31.3
用户评分
★ Stars
2
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add BreakFree003/dsh-clinepass-deepseekv4.1
未发布到 npm registry,仅可从源码安装,改用 GitHub 源安装
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

npm 包dsh-clinepass(未发布到 npm,仅可源码安装)
Node 引擎要求 >=20 · 基线 Node 22.19 满足
dsh CLI 依赖未声明 dsh 版本约束
入口文件main/exports/bin 已声明

未发布到 npm registry,仅可从源码安装

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/19 04:05:18

用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-clinepass

把 Cline Pass 接进 DeepSeek Harness(dsh),并把每条请求钉死在 DeepSeek 官方渠道上(不回退)。
API key 在 设置 → 模型 里直接填,卡片上还带一条 5 小时 / 每周 / 每月 的用量条(显示剩余量)。默认不开任何本地端口。

Cline Pass for DeepSeek Harness. One provider route, pinned to the DeepSeek upstream channel, with the API key entered on Settings → Models — plus a usage card for the 5-hour, weekly and monthly windows.

分享性质,非长期维护项目。 这是作者自用插件的公开快照:按 MIT 原样提供,
不承诺持续维护,也不承诺跟进上游 dsh 的接口漂移。插件依赖 dsh 的内部行为
(pi-ai 每次请求新建 client、不传自己的 options.fetch,因此真正发请求的是全局
fetch);上游哪天改掉这一点,插件会静默失效——下面的状态文件
(hook: installed)就是为这件事准备的报警器。装之前建议先读「验证」一节。
能跑测试不代表上游永远不变。

它做了什么(架构)

四件事各由最合适的部分负责:

1. 路由本身是一个普通的 pi-ai provider profile(llm-pi-ai.providers.cline-pass):OpenAI 兼容协议 + 一个存在凭据库里的 key。
正因为如此,它才会原生出现在「设置 → 模型」里 —— key 输入框、模型目录、地址都是 dsh 自带的界面,不需要自写 UI,也不需要一个可能随 dsh 升级而漂移的手写流式 adapter。

2. 本插件只做一件事:给请求体加上渠道钉选字段。
Cline Pass 的钉选是请求体里的 providerOptions.gateway.only,而 dsh 刻意屏蔽了 pi-ai 的 openRouterRouting / vercelGatewayRouting 兼容开关 —— settings 里写不了。插件把这个字段加在出去的请求上,字节层面其它什么都不動,SSE / 工具调用 / 推理 / 用量 / 图片全部走 pi-ai 已验证的通路。

3. 提示词里的模型名去前缀(0.6.2 起)。网关要求请求体的 model 是 type/model 形状(裸 id 会被拒:
invalid model format. Expected format: modelType/model),而 dsh 把 catalog 的 models[].id 原样发给线上 ——
所以这条路由的 id 必须写成 cline-pass/deepseek-v4.1-flash。前缀是传输层的要求,但 {{model}}
会把它当模型名渲染进 persona,而官方部署的提示词里是没有前缀的(官方 deepseek 路由的 id 本身就是裸 id)。
插件因此在提示词装配时把 persona 两段模板里的 {{model}} 换成 deepseek-v4.1-flash:线上 id、
会话记录、选择器都不动,只改提示词显示。详见下面的 plainModelId 选项。

4. Cline Pass 卡片上的用量条(0.7.0 起):5 小时 / 每周 / 每月三条,显示剩余百分比、重置倒计时和读取
时间,带一个刷新按钮。数据由宿主半边用凭据库里的 key 去问网关
(GET https://api.cline.bot/api/v1/users/me/plan/usage-limits,与开源的
CodexBar 同一个端点),挂在一条同源路径上给浏览器读 ——
浏览器永远拿不到 key。详见下面的「用量条」一节。

dsh ──pi-ai──> https://api.cline.bot/api/v1   (进程内改写请求体,无监听、无端口)

注入方式是进程内的:包一层 globalThis.fetch,只改写发往本网关的 chat/completions 请求体。
依赖的是 pi-ai 的既有行为(它每次请求新建 client、不传自己的 options.fetch,所以真正承载请求的就是全局 fetch);万一将来 dsh 改成自带 fetch,就会静默失效 —— 下面的状态文件就是为此存在的。

0.5.0 起,本插件不再开任何监听。 之前的 loopback 反代 transport(transport: proxy / listen / captureDir)已经删除;旧配置里还留着这些字段不会报错,但会在启动日志里被指出一次并忽略。

0.7.0 起多了一条「路径」,仍然没有监听。 用量条需要浏览器读一份宿主取来的数据,插件把它注册成
dsh 自己那台 HTTP 服务上的一条 exact 路由(/api/clinepass.usage,走
ctx.connection.fetch.register)—— 加的是路径,不是端口、不是 socket、不是第二次监听;
插件进程里依然没有任何 listen。这条路径在 dsh 自己的 Host/Origin 信任栅栏和浏览器 cookie
认证之后才被派发,和设置页读凭据走的是同一层。

只有落到 upstream 这一个 origin 的 chat/completions 会被改写;其它 provider 的请求连对象都不会被复制(同一个 init 原样传给原函数)。

插件启动时还会自动登记那条 provider profile:不存在就创建;如果它认得出是自己建的那张卡、只是地址过期了(例如从旧版反代换过来后地址还指着 127.0.0.1:8791),就只把地址改回来;认不出(是别人/手工建的)就原样不动并在日志里报警。

环境要求

- dsh 0.1.6-alpha.1(唯一实测过的版本)。注意 npm 上没有 0.1.5 这个版本,只有
0.1.5-alpha. / 0.1.5-rc.;dsh plugin 与 dsh.bundle 相关的模块从 0.1.2-alpha.3
的包里就已存在,但更早的版本没有实测过,不保证。
- Node.js ≥ 20
- 一个 Cline Pass API key(sk_...)

没有任何第三方依赖:插件只用 Node 内置模块,index.js 一个文件就能读完、审完。test-fetch.mjs / test-settings.mjs / test-install.mjs / test-usage.mjs 在任何目录都能跑(不需要 dsh 的 node_modules);test-package.mjs 会读 CHANGELOG.md 和 install.mjs,所以要在源码检出里跑(它本来也不随安装复制过去);smoke-test.mjs 要读 settings.yaml,所以需要 dsh 自带的 js-yaml。

安装

方式 A:一条命令(推荐)

dsh plugin --profile web add github:BreakFree003/dsh-clinepass-deepseekv4.1

dsh plugin 把命令转发给 profile 目录里的 pnpm;装完它再看这个包有没有声明
dsh.bundle.patch(package.json 里有),有就自动把 dsh-clinepass 追加进
dsh.profile.bundles —— 不用 clone,也不用自己动 cordis.patch.yml。插件行来自
包自带的 cordis.patch.yml;卸载同样交给 pnpm:

dsh plugin --profile web remove dsh-clinepass

要锁版本就带上 tag(不带则取默认分支的最新提交):

dsh plugin --profile web add github:BreakFree003/dsh-clinepass-deepseekv4.1#v0.6.2

这条路径要求 PATH 上有 pnpm —— dsh plugin 本身就是 pnpm 转发器。

方式 B:用安装器(不需要 pnpm,离线可用)

git clone https://github.com/BreakFree003/dsh-clinepass-deepseekv4.1
cd dsh-clinepass-deepseekv4.1
node install.mjs                    # 默认装进 ~/.dsh,profile web

常用参数:

node install.mjs --dsh-home /tmp/mydsh         # 装进别的 DSH_HOME
node install.mjs --profile headless            # 装进别的 profile
node install.mjs --dry-run                     # 只看会改什么

--transport / --port 在 0.5.0 已移除。安装器会明确拒绝它们,而不是默默忽略 —— 一个被忽略的 --port 看起来会像“生效了”。

--dry-run 只是不写文件,仍然要求那个 profile 已经存在:没有的话它会报 no profile at … 并以 1 退出(信息里告诉你了先启动一次 dsh)。这不是 bug,是不想对着一个你还没创建的目标做“预览”。

安装器会:把插件复制到 /profiles//plugins/dsh-clinepass/,并把一条 loader 行追加到该 profile 的 cordis.patch.yml(幂等,改动前自动备份;重跑会把旧行升级成当前规范形态)。

A 和 B 二选一。 两条路径挂载的都是 id 为 clinepass 的那一行,只是来源不同:
A 取包自带的 cordis.patch.yml,B 往你 profile 的 cordis.patch.yml 里写。同时用
会挂两份。换路径前先按「卸载」清掉上一种。

方式 C:手动

1. 复制 index.js、package.json、test-fetch.mjs、test-settings.mjs 到 /profiles//plugins/dsh-clinepass/(这是最小可运行集;下面「验证」一节里的 test-package.mjs 与 test-install.mjs 检查的是仓库/安装器布局,这样装没有它们,也跑不了);
2. 在 /profiles//cordis.patch.yml 里加一段(见 patch.example.yml):

- insert:
- id: clinepass
name: './plugins/dsh-clinepass/index.js'
config:
upstream: https://api.cline.bot
pin:
- deepseek

然后

1. 重启 dsh(profile 只在启动时读取):终端里 Ctrl-C,再 dsh web。
2. 打开 设置 → 模型,会出现一张 Cline Pass 卡片(插件启动时自动登记)。把 API key 粘进去、保存。
3. 在模型选择器里选 Cline Pass / DeepSeek V4.1 Flash。

想让它成为默认模型,在 ~/.dsh/settings.yaml 里加:

agent-default-model:
provider: cline-pass
model: cline-pass/deepseek-v4.1-flash
reasoningEffort: high

档位只有两个:high(线上 reasoning_effort: "high")和 max(线上 "max")。max 就是 pi-ai 升级顺序里的最高档,profile 里可以直接声明它,不需要别名。
从旧版本升上来不用手改:插件会把卡片地址改回网关,把卡片里那两个档位声明补齐,并清掉已废弃的 xhigh;如果你 settings 里存的正是 xhigh,启动时会把它改成 max(同一个意思,不会悄悄降档)。

设置 key(重点)

「设置 → 模型 → Cline Pass → 编辑」里的 API 密钥 就是它:

- key 存在 dsh 凭据库里,引用名 CLINE_PASS_API_KEY;
- 卡片会显示「API 密钥已配置 / 缺失」;
- 换 key 直接覆盖,不需重启。

key 也可以在启动环境里给(凭据库优先):CLINE_PASS_API_KEY=sk_... dsh web。

用量条(设置 → 模型 → Cline Pass)

卡片下半部分会多出三条。显示的是剩余(还够用多少),不是已用:

ClinePass 剩余用量                 更新于 15:25  刷新
5 小时  ██████████████████████████  98%
2 小时 59 分 后重置 · 2026/9/16 18:42:08
每周    █████░░░░░░░░░░░░░░░░░░░░░  18%
3 天 23 小时 后重置 · 2026/9/20 15:42:08
每月    ██░░░░░░░░░░░░░░░░░░░░░░░░   9%
11 天 23 小时 后重置 · 2026/9/28 15:42:08

- 百分比是剩余,进度条跟它是同一个量(油表:越满 = 剩得越多),颜色按剩余分档:
30% 绿、≤30% 黄、≤10% 红。标题里写了「剩余」,因为右边那个百分比是裸数字 ——
不写清楚就只能靠猜它到底是已用还是剩余。
- 网关只返回 percentUsed:响应里没有任何绝对额度字段(limit / used / remaining
都没有),所以「剩余」只能是 100 - percentUsed。差值按一位小数收口后再取 —— 直接算
100 - 82.4 会得到 17.599999999999994,那不是「剩余 17.6%」。结果夹在 0–100,用完就是 0%。
- 宿主半边不做这个翻转:它照网关的原样带 percentUsed,怎么显示是浏览器半边的事。
- 三条来自网关的 five_hour / weekly / monthly 三个窗口;网关返回的其它窗口类型(它有过
experimental_pool 这类实验值)不显示,而不是猜一个名字画上去。
- 「刷新」绕过缓存真问一次;不点它的话一次成功读取会缓存 usageCacheMs(默认 60 秒),
所以来回切设置页不会刷屏打网关。失败也记 5 秒(不是 60 秒):网关挂着时反复进出设置页
不会再打一遍网关,但重新填好 key 后下一次看仍然是新的 —— 而且卡片在 key 变化时会强制
重读,直接绕开这段短缓存。
- 浏览器这一侧也有自己的超时(20 秒):宿主只保证它到网关那一段。没有它,一个卡住的 dsh
会让卡片永远停在「读取中…」,而那时刷新按钮是禁用的 —— 用户没有任何可点的东西。
- 语言跟随 dsh 的「设置 → 通用 → 语言」(中/英两套文案写死在 client.js 里)。

数据是怎么到浏览器里的:dsh 的凭据设计是密钥只能写、不能读(credentials/set 单向,
没有任何 read 路径把它交回来),所以浏览器里没有 key,也就不能自己请求 Cline。于是:

1. 宿主半边从凭据库取出 CLINE_PASS_API_KEY(环境变量也算,凭据库那一层已经覆盖),
用 Authorization: Bearer  请求 GET https://api.cline.bot/api/v1/users/me/plan/usage-limits;
2. 把响应用 normalizeUsage 收窄成三个窗口的 {type, percentUsed, resetsAt},只有这些数字
挂到 /api/clinepass.usage 上;
3. 浏览器半边(client.js)读这条同源路径,渲染成上面那三条。

几个刻意的取舍:

- key 从不进浏览器:不写进 DOM、不写进返回体、不进日志。返回体里只有三个数字。
- resetsAt 在宿主侧归一化:网关发的是纳秒精度(...T11:38:00.490486029Z),
Date 的规范只承诺毫秒。宿主(永远是 Node)转一次,浏览器就不用去当宽容解析器。
- 不认识的响应一律不画:success 必须恰好是 true、percentUsed 必须是有限数(夹到 0–100)、
读不懂就整条不显示并说明原因,而不是画一个错的条。
- 卡片按槽位挂载,不改 dsh 的文件:用的是 dsh 给外部插件留的
settings.models.provider-card slot(注册在 llm-pi-ai 这个 key 上,非本路由的卡片直接
返回 null)。所以不是补丁,dsh 升级不会把它打散(对比改 node_modules 里客户端 bundle 的做法)。
- client.js 是手写的、没有构建步骤(与 dsh-notify-ping 同款):它只 require('react'),
而 React 是 web shell 静态模块表里的基线模块,所以既不需要 tsdown,也不需要写 dsh.client.external。

排障

| 现象 | 原因 / 处理 |
| --- | --- |
| 卡片上没有用量条 | 刚装完没重启:浏览器半边的 bundle 是宿主启动时组进 boot 图的,重启 dsh 后才有(宿主半边的路由是保存即生效的,所以别拿路由能通当已经好了);或 usage: false |
| 卡片整块不显示,DOM 里只有空的  | 客户端半边抛异常,被 slot 的 error boundary 吞了。最常见的原因是访问了没写进 inject 的 cordis 服务 —— cordis 对未声明的服务属性是抛错(cannot get property "x" without inject),不是返回 undefined。浏览器控制台里有原始异常;test-usage.mjs 有一条静态断言守着这一类 |
| 用量条显示「还没填 API 密钥」 | 密钥没配,或配到了别的引用名。在卡片下面的「API 密钥」里填 sk_... 保存 |
| 显示「网关拒绝了这把 API 密钥」 | key 失效或不对(网关返回 401/403);重新填一次 |
| 显示「连不上网关」/「超时」 | 本机到 api.cline.bot 的网络问题;插件不会重试,点「刷新」 |
| 想确认宿主这半边活着 | 带 token 打开页面后访问 /api/clinepass.usage,应返回 {"ok":true,"limits":[…]};或把 usage: false 再看卡片上的条是否消失 |

配置项

全部有默认值,只挂载就够用。

| 字段 | 默认 | 说明 |
| --- | --- | --- |
| upstream | https://api.cline.bot | 真网关 origin |
| pin | ['deepseek'] | 所有请求限制到的上游渠道 |
| pins | {} | 按模型覆盖,如 { 'cline-pass/deepseek-v4.1-flash': ['deepseek'] } |
| provider | cline-pass | provider 路由 id(= profile 的 key) |
| model | cline-pass/deepseek-v4.1-flash | 模型 id,原样作为线上 model 字段(网关要求 type/model) |
| displayName | Cline Pass | 选择器里的名字 |
| contextWindow / maxTokens | 921600 / 131072 | 模型容量,登记 profile 时使用 |
| apiKeyEnv | CLINE_PASS_API_KEY | profile 里记录的凭据引用 |
| provision | true | 启动时自动登记 provider profile(缺失则创建;自家卡片地址过期则只修地址) |
| alignReasoningEffort | true | 若 agent-default-model.reasoningEffort 不是本模型声明的档位(只剩 high / max 两个),启动时对齐:废弃的 xhigh → max,其它不认识的值 → high |
| plainModelId | true | 提示词(persona 两段)里显示去掉本路由前缀的 id:cline-pass/deepseek-v4.1-flash → deepseek-v4.1-flash。线上 id、会话记录、选择器都不受影响;false 则原样显示完整 id |
| usage | true | 在「设置 → 模型 → Cline Pass」卡片上显示用量条(5 小时 / 每周 / 每月,剩余量)。false 时宿主不注册路由、不读凭据,并显式广播 enabled: false 让浏览器半边不渲染这张卡片(浏览器半边是从 package.json 发现的,配置管不到它加载与否,所以必须显式告知) |
| usageRoute | /api/clinepass.usage | 用量数据这条 exact 路由的路径。宿主会把它一并告诉浏览器半边,两边不会走散 |
| usageTimeoutMs | 15000 | 问网关的超时;超时按「网关没应答」显示,不会挂住设置页 |
| usageCacheMs | 60000 | 一次成功读取的缓存时长。设置页每次重渲染都会读它,缓存是为了不把重渲染变成一串网关请求;0 = 每次都真问 |
| statusFile | true | 把钉选状态写到 /dsh-clinepass-status.json(见下);也可给自定义路径,或 false 关掉 |

pin: [] = 不注入任何字段(纯透传)。pins 优先于 pin;把某个模型配成 pins: { '': [] } 等于单独关掉那条路由的钉选,启动时会警告。

plainModelId 只改提示词模板(deployment:persona-prefix / -suffix 两段里的 {{model}}),
且仅当会话确实跑在本路由、且 id 以本路由自己的 / 开头时才改;官方路由的裸 id、
别的 provider、本路由上的裸 id、以及 interpolate: false 的字面量段落一律不动。
刻意不去改 catalog id(已存会话的 model/selection / request/header 里记的还是带前缀的 id,
改名会让它们一直报 UNKNOWN_MODEL),也不去改 prompt variable(会话层的
installModelSelection 会在内层 listener 返回后覆盖 variables.model,而且
session-reference 会快照那些变量算引用预算)。

已删除(0.5.0):transport、listen、captureDir,以及旧版的 address / baseURL。旧配置里留着不会报错,启动日志会各指出一次。

验证

cat ~/.dsh/dsh-clinepass-status.json     # 正在跑的 dsh 自己写的状态(见下)
实际是 2 空格缩进的 JSON,字段就是这些:
{
"service": "dsh-clinepass", "transport": "fetch", "hook": "installed",
"upstream": "https://api.cline.bot", "pin": ["deepseek"],
"profileBaseURL": "https://api.cline.bot/api/v1",
"counters": { "seen": 4, "pinned": 4, "skipped": 0 },
"lastPin": { "model": "cline-pass/deepseek-v4.1-flash", "only": ["deepseek"] },
"ignoredOptions": [], "pid": 1234, "at": "2026-09-15T11:13:13.910Z"
}
node test-package.mjs       # 打包不变量:bundle 声明可用、无生命周期脚本、bundle 行与安装器行不漂移、client 半边声明可用
node test-fetch.mjs         # 单元测试:URL 域限定/透传保真/安装卸载/请求体形态/robustness/状态文件 + 经真 fetch(undici) 打本地 server 的集成
node test-settings.mjs      # 配置面(含已删除选项)、profile 登记与修复、档位迁移
node test-usage.mjs         # 用量:响应收窄、网关读取、路由处理器(缓存/去重/失败分类/key 不外泄)、apply 接线、client bundle 契约
node test-install.mjs       # 安装器/卸载器往返测试(幂等、注释不丢、逐字节还原)
node smoke-test.mjs         # 冒烟:读状态文件确认活着的 dsh 挂着钩子 + 经真网关跑一轮,断言 finalProvider=deepseek
node smoke-test.mjs --negative   # 追加反向对照:不可能渠道必须被拒绝

没有测试框架,全是自带断言的 Node 脚本(零依赖)。npm test 跑前五个,五个都不需要网络;
不过 test-package.mjs 和 test-install.mjs 只在源码检出里成立,所以安装副本里应该跑
npm run test:installed(就是不依赖检出布局的那三个:fetch / settings / usage)。
test-fetch.mjs 用一个本地 HTTP server 冒充网关(它自己的文件头也是这么写的),走真
undici、但只连 127.0.0.1;test-usage.mjs 连那个都不需要 —— 它把网关换成一个返回固定
Response 的桩函数,连 127.0.0.1 都不连。唯一会真的打网关的是 smoke-test.mjs,它另外还
要求正在运行的 dsh。

hook 字段就是「静默失效」的报警器:installed = 钩子在全局 fetch 上;uninstalled = 被卸载了;unavailable = 装不进去(有东西先替换了 fetch,日志里会报,这种情况现在没有备用 transport 可切,要先找出是哪个插件抢了全局 fetch);foreign = 装好之后有别的代码把全局 fetch 换掉了(插件每 30 秒自查一次,所以最迟半分钟内可见;换掉之后请求就不再被钉)。counters.seen 是落到本网关的 chat 请求数,pinned 是真正注入了钉选的请求数 —— seen 涨而 pinned 不涨就说明有请求被跳过了(日志里有 [clinepass] not pinning ... 的原因)。状态文件里不含任何凭据,并且只有当前持有全局 fetch 的那个插件实例会写它。

smoke-test.mjs 会先读状态文件确认正在运行的 dsh 里钩子是 installed、且计数器在动(pid 已退出/hook: uninstalled 时会明确说明它只能验到哪一步;记录里的 pid 存活才作数),确认本插件没有监听任何本地端口,再用同一份插件代码在测试进程里注入一次、打真网关断言 finalProvider: "deepseek"。

provision 字段说明 provider 卡片的登记结果:created(新建)/ present(已存在)/ repaired(地址过期已修正)/ mismatch(那张卡片不是本插件建的,未改动;请求会绕过钉选,需要你手动改地址)/ failed(settings 写入失败,日志里会有原因)。

常见问题

| 现象 | 原因 / 处理 |
| --- | --- |
| 设置 → 模型里没有 Cline Pass 卡片 | dsh 还没重启;或 provision 被关掉、settings 只读。看日志与状态文件的 hook;也可手动按 patch.example.yml 里的 profile 结构添加 |
| 卡片里 API 地址不是 https://api.cline.bot/api/v1 | 那张卡片不是本插件建的(provision: mismatch),插件不去改它。改成网关地址,否则请求绕过钉选 |
| 状态文件里 hook: unavailable | 有别的插件先替换了 globalThis.fetch。找出是哪个插件;现在没有备用 transport,钩子装不进去时请求会不带钉选 |
| 状态文件里 hook: foreign | 装好之后全局 fetch 被别的代码换掉了(插件每 30 秒自查)。换掉之后的请求不再被钉,排查是哪个插件 |
| 状态文件里 seen 在涨、pinned 不涨 | 有请求被跳过:日志里的 [clinepass] not pinning request #N: ... 会给出原因(非 JSON 体、流式体、无 body),或按模型的 pins 被配成了 [] |
| reasoningEffort: max 能用吗 | 能,而且是两个档位里的最高档。卡片里声明 high / max:线上分别发 reasoning_effort: "high" / "max"。旧卡片里多出来的 xhigh 会被清掉;settings 里存的 xhigh 会被改成 max |
| 状态文件里 seen: 0 但你刚聊过 | 那条路由没走本网关(地址被改过 / 选了别的 provider),或 dsh 里跑的不是这份插件 |
| UNKNOWN_MODEL | profile 里的 models[].id 与 dsh 选择的模型不一致。id 必须是 cline-pass/deepseek-v4.1-flash 这种带前缀形式 |
| UNSUPPORTED_REASONING_EFFORT | 存的档位不在卡片声明的档位里(只有 high / max)。插件启动时会把默认模型的那个值对齐(xhigh → max,其它 → high);若某个已存会话仍报错,在输入框的档位选择里重选一次即可 |
| MISSING_CREDENTIAL | 还没在设置页填 key,或填到了别的引用名 |
| 启动日志说 "listen" is no longer used | 旧配置里还留着已删除的反代选项;删掉那个字段即可(不影响运行) |
| 严格钉选的代价 | fallbacksAvailable: [] 意味着 deepseek 渠道不可用时请求直接失败、不会回退 —— 这是「钉死」的语义 |

安全说明

- 不监听任何端口:插件只包一层 globalThis.fetch,且只改写发往 upstream 的 chat/completions。用量功能加的是 dsh 自己那台 HTTP 服务上的一条路径(/api/clinepass.usage,见上),插件进程里没有 listen,也没有第二个 socket。
- 插件不持有 API key —— key 由 dsh 从凭据库取出、写进请求头,插件只加一个路由字段。状态文件里只有服务与钩子状态、上游与 profile 地址、计数与时间、模型名、钉选渠道和 pid:没有任何密钥,test-fetch.mjs 里有一条断言专门守着这一点。
- 用量读取里的 key 也不外泄:宿主用 Authorization: Bearer  问网关,然后把响应收窄成三个数字再返回。浏览器拿到的 JSON 里没有 key,DOM 里也没有;test-usage.mjs 有两条断言守着(key 不出现在任何返回值里、只出现在那一个请求头里)。这条路在 dsh 自己的 Host/Origin 信任栅栏与浏览器 cookie 认证之后才派发。
- 日志只打印请求方法/URL/模型/钉选渠道(形如 [clinepass] → #004 POST https://api.cline.bot/api/v1/chat/completions pinned to deepseek (model …, in-process)),以及配置/登记结果与「没钉上的原因」。请求头从不进日志 —— authorization 没有被打印的机会,也就不存在"脱敏"这一步。用量那一路同理:只记「注册了哪条路径」和「读取意外失败」,不记 key、不记响应体。
- 旧版的 captureDir 会把请求/响应原文(含对话内容)落盘,该功能已随反代一起删除。

与 npm 上 dsh-cline-pass 的区别

npm 上另有一个名字很像的包 dsh-cline-pass(作者 yhshzh),解决的问题有重叠,路线不同:
它自带 provider 适配器、渠道枚举与账户池,走 npm 发布;本插件(dsh-clinepass,没有连字符)
刻意反过来 —— 不自带适配器,复用 dsh 内置的 pi-ai 路由,只往出站请求体里注入渠道钉选字段,
所以不存在第二套会随上游漂移的流式适配器。

两者都会注册 provider 路由,不要同时挂载。装之前看清楚名字。

卸载

方式 A(bundle)装的:

1. 先摘掉自动登记的那张 provider 卡片 —— 这一步要在移除包之前跑
DSH_HOME=~/.dsh node ~/.dsh/profiles/web/node_modules/dsh-clinepass/uninstall.mjs --profile web
2. 再让 pnpm 移除包,并自动把它从 dsh.profile.bundles 摘掉
dsh plugin --profile web remove dsh-clinepass

第 1 步会顺带报「没找到 clinepass 行」「插件目录已不存在」——bundle 布局下这两件事本来
就无事可做,它真正干活的是删掉 settings.yaml 里的 llm-pi-ai.providers.cline-pass。
想留着那张卡片就加 --keep-provider。

方式 B(安装器)装的:

node uninstall.mjs                  # 移除 loader 行 + 插件目录 + 自动登记的 profile
node uninstall.mjs --keep-provider  # 保留设置页那张卡片

两种方式卸载后都要重启 dsh,「Cline Pass」卡片才会从设置页消失。

English

dsh-clinepass connects Cline Pass to DeepSeek Harness with every request pinned to the DeepSeek upstream channel (strict, no fallback), and its API key entered on Settings → Models.
架构。 该路由是一个普通的 pi-ai 提供商配置(llm-pi-ai.providers.cline-pass,兼容 OpenAI,密钥来自凭据存储)——这正是 dsh 为其渲染出带密钥字段的原生提供商卡片的原因。该插件只向发出的请求添加 providerOptions.gateway.only,将流式传输、工具调用、推理、用量和图像保留在 pi-ai 经过验证的路径上。该固定值是在进程内注入的:插件在进程的整个生命周期内包装 globalThis.fetch,并且仅重写此网关的聊天补全请求体——没有监听器、没有端口、无需为传输配置任何东西。(0.5.0 移除了可选的环回反向代理;仍指定 transport / listen / captureDir 的配置会被报告一次并忽略。)只有发往所配置 upstream 源的请求才会被触及,无关调用会以完全相同的参数原样传递。启动时,插件还会配置该配置文件(仅修复可识别为自身所有的过期地址,绝不覆盖外来的地址),并对齐不受支持的已存储推理级别。自 0.6.2 起,它还会将网关的 type/ 前缀排除在提示词之外:一个前置的 system-prompt/assemble 监听器会重写两个角色设定部分中的 {{model}} 引用,因此角色设定读取到的是 deepseek-v4.1-flash,而传输线路、会话记录和模型选择器仍保留 cline-pass/deepseek-v4.1-flash(plainModelId: false 可将其关闭)。自 0.7.0 起,设置 → 模型中的 Cline Pass 卡片还会显示用量:5 小时、每周和每月窗口以剩余量的进度条呈现,并带有剩余百分比、重置倒计时和读取时间(网关只报告 percentUsed,因此剩余量为 100 − percentUsed,在浏览器端计算并四舍五入到一位小数,这样 100 − 82.4 就不会打印出 17.599999999999994)。client.js 是浏览器端部分——一个手写打包文件(无构建步骤,类似 dsh-notify-ping),它注册到 dsh 文档化的 settings.models.provider-card 插槽中;宿主端部分使用存储的密钥读取 GET https://api.cline.bot/api/v1/users/me/plan/usage-limits,并仅在 /api/clinepass.usage 发布所得数字,这是 dsh 已经运行的 HTTP 服务器上的一个精确 Fetch 路由——一条新路径,仍然没有我们自己的监听器。浏览器按设计无法读取密钥(dsh 的凭据接缝是只写的),这正是该卡片需要宿主端部分的原因。
安装。 dsh plugin --profile web add github:BreakFree003/dsh-clinepass-deepseekv4.1 —— 该包声明了 dsh.bundle.patch,因此 dsh plugin(一个 pnpm 转发器)会安装它,并自行将其追加到 dsh.profile.bundles:无需克隆,无需手动编辑补丁。追加 #v0.7.0 可固定到某个标签。如果没有 pnpm,node install.mjs 会将插件复制到 profile 中,并改为追加加载器行(幂等 + 已备份)—— 两种方式二选一,切勿同时使用。无论哪种方式,都要重启 dsh,然后在 Settings → Models 上设置密钥。配置默认值已完整 —— upstream、pin、pins、provider、model、apiKeyEnv、provision、alignReasoningEffort、plainModelId、usage、usageRoute、usageTimeoutMs、usageCacheMs、statusFile。无第三方依赖:宿主端只导入 Node 内置模块,浏览器端只从 shell 的静态模块表中请求 React。

验证。 cat ~/.dsh/dsh-clinepass-status.json —— 运行中的 dsh 会在那里写入其钩子状态和计数器(hook: installed、seen/pinned/skipped、最后一次 pin),这正是让被静默绕过的钩子变得可见的方式;node test-package.mjs(打包不变量:bundle 声明可安装、无生命周期脚本、bundle 与安装器行不会漂移、客户端半部分声明可加载)、node test-fetch.mjs(URL 作用域、透传保真度、安装/卸载与重载语义、body 形状、健壮性、状态文件、通过真实 fetch 的集成)、node test-settings.mjs(选项表面、provisioning 与 effort 迁移)、node test-usage.mjs(响应收窄、网关读取、路由处理器的缓存/去重/失败分类与密钥隔离、apply 接线)、node test-install.mjs(安装/卸载往返)、node smoke-test.mjs [--negative](检查运行中进程的状态文件,然后运行一次真实的网关往返,断言 finalProvider: "deepseek" 且无回退)。要针对运行中进程检查 usage 半部分,请用其 token 打开页面并 GET /api/clinepass.usage —— 它应返回 {"ok":true,"limits":[…]}。

卸载。 Bundle 安装:从已安装的包中运行 uninstall.mjs(node /node_modules/dsh-clinepass/uninstall.mjs —— 它会删除已 provision 的 provider profile),然后 dsh plugin --profile web remove dsh-clinepass。安装器安装:node uninstall.mjs [--keep-provider]。之后重启 dsh。

状态。 按原样共享供他人使用,并非受维护的项目:无支持承诺,无跟踪上游 dsh 变更的承诺。该插件依赖 dsh/pi-ai 的一个内部细节(pi-ai 为每个请求构建一个新的客户端,并且不传递 options.fetch,因此真正的传输层是全局 fetch);如果这一点发生变化,pin 会静默失败,而这正是状态文件的 hook 字段存在的意义 —— 将其暴露出来。
另请参阅。 一个名为 dsh-cline-pass 的相关包(npm,由 yhshzh 开发)通过自包含的 provider 适配器和账户池解决了重叠的问题;而本包(dsh-clinepass,无连字符)则有意复用 dsh 内置的 pi-ai 路由,仅注入 pin 字段。两者都会注册 provider 路由——请勿同时挂载两者。

安全性。 该插件完全不打开任何套接字——用量功能仅在 dsh 已运行的 HTTP 服务器上添加一个路径,位于 dsh 自身的 Host/Origin 信任防护和浏览器 cookie 身份验证之后——而钩子仅重写发往所配置网关源的请求。它自身不持有任何凭据(密钥随 dsh 设置的请求头传输;用量读取会将其发送一次,发往同一网关,且永不返回),其状态文件不包含任何机密(有测试对此进行断言),并且任何请求头都不会被记录——日志仅包含方法、URL、模型和 pin 通道,因此没有任何需要脱敏的内容。

许可证

MIT——参见 LICENSE。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群