DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-workbuddy-meter

d

dsh-workbuddy-meter

Identified★ 2

Fix WorkBuddy/CodeBuddy 400 'Illegal API invocation from an unapproved channel' (code 11128) —— prompt-preserving bypass + credits usage metering panel | Fix WorkBuddy unapproved channel 400

WorkBuddy 400 错误修复 · unapproved channel (code 11128) · 积分用量计量

License: MIT Node DSH fix

两件事,一个仓库:

① 修复一个让人抓狂的 400 错误 —— WorkBuddy / CodeBuddy 返回 Illegal API invocation from an unapproved channel(code 11128)。 这个报错的文案是骗人的:它跟渠道、域名、身份、请求头全都无关, 真正原因是上游在按关键词拦 system prompt(命中的是 DeepSeek Harness)。 本仓库给出提示词无损绕过方案 —— 插一个零宽空格,语义不变、请求通过。 → 直接看修复方法

② 顺带把积分账算清楚 —— 逐请求记录本地 OFM 通道 (buddy/ = CodeBuddy 国内版、workbuddy/ = WorkBuddy 国际版)的 token 明细与 credit(积分)消耗,在 DSH Web UI 给出实测单价、缓存命中率、 冷热对比、账号余额。

关键词:unapproved channel · Illegal API invocation · code 11128 · 11140 · WorkBuddy 400 · CodeBuddy 400 · 请求被拦截 · 提示词风控 · 关键词过滤绕过 · 零宽空格 · DeepSeek Harness


⚠️ 搜索到这里? 如果你正在找下面这个报错的解决方法,直接跳到 🔧 修复 WorkBuddy「请求被拦截 / unapproved channel」400 错误 —— 那是本仓库最常被搜索到的部分。

常见报错速查

搜到这些错误?点进去看原因和修法:

你看到的报错真实原因章节
buddy: 请求被拦截,请重新发送 Illegal API invocation from an unapproved channel上游按关键词风控 system prompt修复 400 错误
workbuddy: 请求被安全策略拦截... first message is not system prompt首条消息不是 system 角色同章节
code 11128 / code 11140 / HTTP 400上游内容/结构校验失败(同一个错误族)同章节
code 11133 integer_below_min_valuemax_tokens 给太小同章节·附注
code 6004 usage exceeds frequency limit上游限流切账号或等冷却
EMPTY_RESPONSE / 有思考无正文推理模型把 max_tokens 吃光了max_tokens ≥ 4096

🔧 修复 WorkBuddy「请求被拦截 / unapproved channel」400 错误

这是本仓库存在的主要理由。 如果你因为下面这个报错搜到这里,你要的东西就在这一节。

你会看到的报错

buddy: 请求被拦截,请重新发送 Illegal API invocation from an unapproved channel

或者英文原文:

Illegal API invocation from an unapproved channel

HTTP 状态码 400,上游业务码 11128(有时 11140)。

真实原因(不是你想的那个)

报错文案说 "unapproved channel"(未获批准的渠道),这个措辞是误导的。 实测逐项排除后可以确定:它跟渠道、域名、客户端身份、请求头、账号、API Key 全都无关。

真因是:上游对 system prompt 做关键词内容风控。

只要 system prompt 里出现 DeepSeek​ Harness 这个词组,就会被拒。

说白了就是「逆天操作」—— 上游在按品牌词拦请求,然后用一个完全不相关的错误信息掩盖它。

怎么验证是这个原因(60 秒)

用同一个 token 打两次,只改 system prompt 里的一个词:

system prompt 内容结果
You are an AI agent powered by DeepSeek​ Harness.❌ 400 / 11128
You are an AI agent.✅ 200

如果符合这个规律,就是这个原因。其他已排除的可能见下表。

修复方法(本仓库的做法,无损绕过)

把散文语境里的 DeepSeek​ Harness 中间插入一个零宽空格 \u200B:

// 改前
"You are an AI agent powered by DeepSeek Harness."
// 改后(两个词之间多了一个不可见字符 U+200B)
"You are an AI agent powered by DeepSeek\u200B Harness."
  • 模型看到的语义完全不变(零宽空格在渲染、分词上几乎无影响)
  • 上游的字符串匹配不再命中
  • 这是无损的:没有裁剪、没有改写、没有丢上下文

实测对比(真实 DSH 请求形状:316 tools + effort=max + max_tokens=128000):

原文   → ❌ 0/5 全部失败
中和后 → ✅ 5/5 全部成功

关键约束:文件路径不能被改写 ⚠️

运行时上下文里有真实路径:

D:\10_COD\DeepSeek Harness\resources\app.asar\dsh\

如果在路径里也插入零宽字符,模型会把坏路径传给工具调用,直接失败。

所以匹配器必须跳过路径语境(前后不能是 / 或 \):

/(?<![\\/])(DeepSeek)[ \u00A0]+(Harness)(?![\\/])/gi

实测:中和后路径里残留的那一处不会触发拦截(上游匹配的是身份陈述位置,不是全文子串)。

一键用(本仓库已实现)

装好插件后,面板底部有「关键词风控中和」卡片,4 个开关:

开关默认作用
总开关开关掉即完全恢复原始请求(一个字节都不改)
中和身份关键词开上面说的零宽空格替换
补首条 system开首条非 system 时注入保底 system
隐藏品牌词关更激进:连 DeepSeek 也打散

改完即时生效,不需要重启。 上游以后不拦了,把总开关关掉就行。

不想装插件?手动改也行

最小实现就是一段字符串替换。如果你自己在写反代:

const ZW = '\u200B'
const PATTERN = /(?<![\\/])(DeepSeek)[ \u00A0]+(Harness)(?![\\/])/gi

function neutralize(messages) {
  for (const msg of messages) {
    const walk = (obj) => {
      for (const key of Object.keys(obj)) {
        const v = obj[key]
        if (typeof v === 'string') obj[key] = v.replace(PATTERN, '$1' + ZW + ' $2')
        else if (Array.isArray(v)) v.forEach((x) => typeof x === 'string'
          ? null : (x && typeof x === 'object' && walk(x)))
        else if (v && typeof v === 'object') walk(v)
      }
    }
    walk(msg)
  }
}

把它挂在出站请求前(组装好 messages、JSON.stringify 之前)。

已排除的其他可能(省得你重复排查)

这些我都实测排除了,都不是原因:

假设实测结果
账号被风控 / 坏了❌ 换账号同样报;改昵称前后无差异
域名错(copilot vs workbuddy.cn)❌ copilot.tencent.com 是正确端点
客户端身份错(CodeBuddy vs WorkBuddy)❌ 两种身份 × 两种域名交叉测试全 200
请求头缺失(X-User-Id 等 13 个头)❌ 全部补齐后仍失败
reasoning_effort 值非法❌ max 单独测也 200
max_tokens=128000 超限❌ 上限是 131072
工具数量太多(316 个)❌ 单独带 316 tools 多次成功
网络代理改写请求❌ 无代理时同样报
并发太高❌ 12 并发全成功

唯一能稳定复现的条件:system prompt 含 DeepSeek​ Harness 且 请求体够大(约 >1KB)。 短 prompt 即使含关键词也会放过 —— 这是它表现得「时好时坏」的原因。

附注:其他错误码

  • 11133 integer_below_min_value —— max_tokens 太小(< 某个下限),不是风控
  • 11128 first message is not system prompt —— 首条必须是 system 角色
  • 11140 —— 安全策略拦截,同一错误族的另一种

为什么需要它

OFM(dsh-our-free-model)的 channel-pack 已经有一份 token 账本 (~/.dsh/channel-pack/token-ledger.json),但只记 token,不记积分 —— 而积分才是这两个渠道真正在消耗的额度。

上游其实报了积分。实测 WorkBuddy / CodeBuddy 的 SSE 最后一帧:

"usage": {
  "prompt_tokens": 4018, "completion_tokens": 8, "total_tokens": 4026,
  "prompt_cache_hit_tokens": 0, "prompt_cache_miss_tokens": 4018,
  "credit": 0.17
}

OFM 解析 usage 时只取了 token 字段,credit 被丢弃。本插件用一行补丁把它接出来。


三个组件

组件位置作用
补丁引擎src/patch-engine.mjs打/还原/检查 OFM 补丁的唯一实现(脚本与 Host 自愈共用)
词库模块src/lexicon.mjs关键词风控中和的实际逻辑 + 永不抛错的钩子
补丁脚本scripts/patch-ofm.mjs命令行包装:dry-run / --apply / --revert / --check
Host 半身index.js采集回调 → 写 JSONL → 聚合 → 5 个 HTTP 路由;启动时自愈两个补丁
Client 半身client.js侧边栏「用量」图标 + 独立主面板

关键词风控中和(2026-10-21 新增,可运行时开关)

它解决什么

上游腾讯 WorkBuddy/CodeBuddy 网关会对 system prompt 做关键词风控:命中 「DeepSeek Harness」就返回 HTTP 400 / code 11128,报文写着 Illegal API invocation from an unapproved channel —— 这个措辞极具误导性, 实测与渠道、域名、客户端身份、请求头全都无关。

实测证据(真实 DSH 请求形状:316 tools + effort=max + max_tokens=128000):

system prompt 内容结果
含 DeepSeek Harness 原样❌ 0/5 全部失败
含 DeepSeek\u200B Harness(零宽空格)✅ 5/5 通过
改写成 DSH / 去掉身份词✅ 通过
小写 deepseek harness✅ 通过(大小写敏感)
只写 DeepSeek 或只写 Harness✅ 通过(需完整词对)

⚠️ 体积是关键变量:短 system prompt(<1KB)即使含关键词也会放行, 只有真实 DSH 那种大请求体才稳定触发。

面板上的开关

面板底部「关键词风控中和」卡片有 4 个开关,改完即时生效,不需要重启:

开关默认作用
总开关开关掉后完全恢复原始请求,一个字节都不改
中和身份关键词开把散文里的关键词换成零宽分隔
补首条 system开首条非 system 时注入保底 system(11128 的另一个成因)
隐藏品牌词关更激进:连 DeepSeek 也打散

卡片同时显示运行时统计(已中和多少处 / 注入多少次)和补丁健康状态。

关键约束:文件路径不能被改写

运行时上下文里有真实路径:

D:\10_COD\DeepSeek Harness\resources\app.asar\dsh\

若在路径里插入零宽字符,模型会把坏路径传给工具调用导致失败。所以匹配器用 前后负向断言 (?<![\\/])…(?![\\/]) 跳过路径语境。实测:中和后路径里残留的 那一处不会触发拦截(上游匹配的是身份陈述位置,不是全文子串)。

为什么是可开关的

上游策略随时可能变化。关掉 = 钩子直接返回,行为与未打补丁完全一致, 不需要重新打补丁或重启 —— 这就是「万一到时候要切回来」的用途。

实现方式:一行钩子 + Host 提供逻辑

pack.js 里只插一行:

;globalThis.__wbLexicon?.rewrite?.(messages);

真正的替换逻辑在 src/lexicon.mjs,由 Host 半身通过 globalThis.__wbLexicon 提供。这样除了能即时开关,还有个好处:OFM 升级后重打成本极低(就一行)。

补丁自愈(重要)

每次用 pluginManager 装卸任何插件都会跑 pnpm,而 pnpm 会把 dsh-our-free-model 从它钉住的 tarball 重新解包 —— 补丁必被冲掉。 所以 Host 半身启动 1.5 秒后会自检一次:发现 pack.js 里没有 __wbMeter 标记且锚点唯一,就自动重打并写 patch-state.json(selfHealed: true)。 关键词钩子同理(1.8 秒后自检 __wbLexicon)。自助修复不会改变你的开关选择 —— 开关状态存在 ~/.dsh/workbuddy-meter/lexicon.json。

实测验证:手动 --revert 后重装插件 → 补丁自动恢复,--check 退出码 0。

数据落在 ~/.dsh/workbuddy-meter/:

usage-<YYYY-MM-DD>.jsonl   # 逐请求记录(UTC+8 分天,append-only)
balance.json               # 账号积分余额快照
patch-state.json           # 补丁状态(版本/时间/备份路径/前后 sha256)

前置条件

本插件是 DSH(DeepSeek Harness)的插件,不是独立程序。装之前请确认:

必需

项要求怎么确认
DSH 桌面版已在用,且能打开 Web UI应用里能看到侧边栏「用量」区域
dsh-our-free-model(OFM)已安装并至少登录一个 WorkBuddy / CodeBuddy 账号DSH 设置 → 渠道包 / Channel Pack 里能看到账号
Node.js^22.19.0 或 >=24.0.0node --version

本插件的数据全部来自 OFM 的 channel-pack。没装 OFM 或没登录账号, 面板会是空的 —— 那不是 bug。

平台

  • Windows / macOS / Linux 均可(纯 Node + 浏览器 CSS,无原生依赖)
  • 已在 Windows 11 + DSH 0.2.1-rc.2 实测

可选(按需)

项用途
Git从仓库克隆安装
任意支持 OpenAI 协议的客户端只是想测通道是否通,不需要装本插件

不需要

  • ❌ 不需要 WorkBuddy 官方客户端在后台运行
  • ❌ 不需要额外的 API Key(插件读的是 OFM 已存好的凭据)
  • ❌ 不需要管理员权限

快速开始

方式 A:让 DSH 的 agent 帮你装(推荐)

在 DSH 里直接说:

把这个目录装成插件:<本仓库的绝对路径>

agent 会调用 plugin_manager 的 install_bundle,几秒钟装好,不用重启。

方式 B:手动走 pluginManager RPC

先取到当前 Web 端口(每次启动 DSH 都会变):

# 从 DSH 窗口标题或运行时上下文里读到 http://127.0.0.1:<端口>

然后:

POST http://127.0.0.1:<端口>/api/pluginManager/installBundle
Content-Type: application/json
Cookie: dsh-auth-<...>=v1.<...>.<...>

{"type":"client-request","rpcId":"install-1","method":"pluginManager/installBundle",
 "payload":{"args":{"spec":"<本仓库绝对路径>","options":{"saveExact":true,"enabled":true}}}}

⚠️ 认证 cookie 的签名算法见 CONTRACT.md。如果嫌麻烦,用方式 A。

装完要做的两件事

1. 打补丁

插件需要往 OFM 的 channel-pack/pack.js 里插两处极小的钩子。 默认 dry-run,先看会改什么:

cd <本仓库>

# 补丁 1:meter 采集(记录每次请求的 usage.credit)
node scripts/patch-ofm.mjs              # 预览
node scripts/patch-ofm.mjs --apply      # 落盘
node scripts/patch-ofm.mjs --check      # 退出码 0 = 在位

# 补丁 2:关键词风控中和(可选,见下文)
node scripts/patch-keyword-bypass.mjs
node scripts/patch-keyword-bypass.mjs --apply
node scripts/patch-keyword-bypass.mjs --check

💡 其实不打也行 —— 插件启动后 1.5 秒会自动自检并补上。 手动跑是为了当场看到「改了什么」。

2. 重启 DSH 一次

补丁改的是 pack.js,而 Node 会缓存已加载的模块。 新装的补丁必须重启一次 DSH 才生效(之后不用再重启)。

验证装好了

打开侧边栏「用量」,应该看到:

  • 顶部有「今日 / 7 天 / 30 天」切换
  • 大数字区显示积分消耗
  • 底部有「已打补丁 OFM x.y.z」绿字
  • 最底部有「关键词风控中和」卡片

如果底部显示「未打补丁」:点「打补丁」按钮,或按上面手动跑一次。


特色功能

1. 逐请求记账,不是估算

别的工具多半是按余额差算消耗。本插件在 OFM 的 SSE 流里挂一个钩子, 把上游返回的 usage(含 credit 积分字段)逐请求抄下来:

provider / model / accountId / prompt / cache_read / cache_write
/ completion / reasoning / credit / ttft / duration

所以能算出实测单价,而不是「大概」。

2. 缓存命中率 → 直接换算成钱

上游对冷/热请求的计价差极大。本插件把命中率变成可操作的数字:

场景实测单价
冷请求(cache_miss)17.92 积分/1M token
热请求(cache_hit)0.68 积分/1M token

差 26 倍。面板会直接告诉你「你的命中率是多少、离目标差多少」。

3. 模型性价比排行

同一个问题,不同模型的实付价可能差 3 倍。面板按你实际用出来的单价排序, 并标出「换这个模型能省多少」。

官方倍率只能做粗筛 —— 真实差价要看实测,因为缓存命中率会放大差距。

4. 还能用多久 / 还能用多少 token

两个视角同时给:

  • 整个号池:所有账号余额加起来能撑多久
  • 当前账号:这个账号自己还能撑多久

并且换算成还能用多少 token(结合你的实测单价和缓存命中率)。

5. 一键测速 + 限速倒计时

点一下就用一个真实请求测当前账号的 deepseek-v4.1-flash 通不通。 如果不通,直接显示距离解除限速还有多久(用上游返回的权威解封时间,不是猜的)。

6. 账号池可视化 + 昵称编辑

  • 每个账号的余额、占比、消耗
  • 点 ✎ 内联改名(只改本地显示,不动上游账号)
  • 一键切换当前使用的账号

7. 关键词风控中和(应急开关)

上游可能会按关键词拦截请求。面板提供 4 个开关,改完即时生效、关掉即恢复原样。 详见下面「关键词风控中和」章节。

8. 省钱诊断

面板会读你的实际数据,给具体建议而不是泛泛而谈:

  • 「你的缓存命中率 87%,低于 90% —— 每次多花 X 积分」
  • 「47.6% 的请求上下文超过 500k,吃掉 63.2% 的积分」
  • 「v4-flash 比 v4.1-flash 贵 2.9 倍,本区间多花 Y 积分」

9. 全部本地,零遥测

没有上报、没有外发。关键词中和是纯字符串处理。 数据结构见 CONTRACT.md。


补丁详解

打在哪

BuddyAdapter.consumeSse(同时服务 buddy 与 workbuddy 两个 provider)内, if (data.usage) { ... } 块、yield { type: "usage", ... } 之前:

;globalThis.__wbMeter?.capture?.({
  provider: this.product.id,
  model: options.model,
  accountId: policyBlockedAccountId ?? "",
  usage: data.usage,
  startedAt: Date.now()
})

为什么只打一处就够

markGatewayChannel() 只给 options 打标记(用于 OFM 自己的 ledger 归属), 不改变解析路径 —— 所以 DSH 内直接调用(direct)和经 8326/18326 网关(gateway) 都走同一个 consumeSse。一处补丁覆盖两条路。

安全性

  • 打前自动备份 pack.js.backup-<ISO时间戳>(同目录)
  • 幂等:已含 __wbMeter 即跳过
  • 锚点校验:命中数 ≠ 1 就中止,不改文件
  • 可还原:--revert 从备份还原,sha256 逐字节一致
  • 补丁后 node --check 语法校验通过(脚本内置)

⚠️ OFM 升级会覆盖补丁

OFM 的升级(应用内「立即升级」或 pnpm)会重写 pack.js → 补丁消失。 面板的「补丁状态」条会显示 未打补丁 / 版本漂移,点「打补丁」重打即可。 升级后请先跑一次 node scripts/patch-ofm.mjs --check。


数据语义(重要)

情况记录面板显示
上游报 credit: 0.17credit: 0.17, creditReported: true0.17
上游报 credit: 0credit: 0, creditReported: true0
上游没报 creditcredit: null, creditReported: false—(未上报)

0 与 null 语义不同,不要混:小请求低于计费门槛会返回 0(真实免费), 而上游没给这个字段时我们不知道消耗了多少,如实留空。

实测基线(2026-10-18,deepseek-v4.1-flash 国内站)

场景积分 / 1M token
冷(无缓存命中)≈ 14.4
热(大量缓存命中)≈ 0.40
日均混合≈ 3.2

缓存命中与否差 36 倍。面板的「冷/热单价」就是给你看这个的。

本机 2026-10-18 实测(deepseek-v4-flash,96 条真实请求): 冷 65.57 / 热 1.64 积分 per 1M token,差 41 倍,缓存命中率 99.8%。


面板设计

设计立意取自计价器 / 电表,不是通用数据看板 —— 因为这套数据唯一值得一眼看懂的事 就是「同样 1M token,冷请求比热请求贵几十倍」。

区块设计决策
Hero一个大号(44px)的「本区间消耗积分」,右侧一条紧凑指标轨(请求/token/单价/命中率/每积分 token)。刻意不做 6 个等大卡片 —— 那会埋没主数字。
冷热单价尺本面板唯一"值得记住"的元素:对数刻度的横向尺,冷价与热价钉在上面,中间用渐变段连起来并标出差值倍数。线性刻度看不出 41 倍,对数刻度能。
趋势图手写 SVG(零依赖),token 柱 + 积分折线双轴。高度随数据量自适应(≤2 天 168px / ≤5 天 209px / 更多 250px)—— 固定 250px 在只有一天数据时会留下半屏空白。
模型明细紧凑表格,积分与单价分列。
账号余额每个账号一张小卡,剩余积分用 *Precise 字段(8 位小数)。
补丁状态底部一条,含版本/锚点/自愈标记与三个操作按钮。

工程约束(自检脚本强制):

  • 只用 var(--dsw-alias-*) 主题 token,零硬编码颜色(亮/暗自动适配)
  • 类名全部 wbm- 前缀,不污染全局
  • 数字全部 font-variant-numeric: tabular-nums
  • backdrop-filter 有 @supports 回退
  • 响应式:820 / 1024 / 1440 三档实测无横向溢出、无标注重叠

动画(全部 CSS/rAF,零依赖)

一次编排好的开场 + 交互反馈,没有滚动触发的重复播放: 设计原则是"把大胆花在一次开场,其余保持安静"。

动画实现实测证据(CDP 帧采样)
阶梯入场hero → 尺 → 趋势 → 明细 → 余额,60ms 阶梯延迟 + 500ms 上升淡入t=124ms 时首区块 opacity 0.40、其余仍 0
数字滚动rAF 计数,1100ms ease-out(1−(1−p)³)28.4 → 56.8 → 83.0 → … → 134.8
冷热尺生长span 条 scaleX 0→1(900ms)宽度 231 → 616px
柱子生长scaleY 0→1(800ms)高度 51 → 122px
折线绘制pathLength=1 + dashoffset 动画(1.2s)—
标记浮现冷 0.95s / 热 0.5s 依次上浮—
hover 反馈卡片边框亮起 + 轻投影(180ms)—

prefers-reduced-motion: reduce 时全部禁用(CDP 模拟实测: 数字直接显示终值、区块全部立即可见、柱子无生长)。


已知边界

  1. 只统计本机 OFM 进程内的请求。你在服务器上反代给朋友用的流量不在这里 (那台机要单独装本插件才能记)。
  2. 不是余额扣减量。逐请求的 credit 是上游对该请求的计价, 而账号余额是另一套(get-user-resource)——两者会有小差异(上游计价与结算口径)。
  3. 小请求 credit=0 不代表免费模型。要判断模型是否免费,看 OFM 模型目录的 creditsRate(x0 = 免费)。
  4. 数据只增不删。本插件不做轮转,长期使用请自行归档旧 usage-*.jsonl。

文件清单

workbuddy-meter/
├── CONTRACT.md              # 冻结的接口契约(数据/聚合/路由/面板)
├── package.json             # 插件清单
├── cordis.patch.yml         # bundle 插入行
├── icon.svg                 # 侧边栏图标
├── index.js                 # Host 半身(采集/聚合/余额/路由/两个补丁自愈)
├── client.js                # Client 半身(面板 UI,含内嵌 zh/en 字典)
├── src/
│   ├── patch-engine.mjs     # 补丁引擎(脚本与自愈共用;两个补丁)
│   └── lexicon.mjs          # 关键词风控中和逻辑 + 永不抛错的钩子
├── locale/{zh,en}.json      # 文案(与 client.js 内嵌字典保持同键集)
├── scripts/
│   ├── patch-ofm.mjs        # meter 采集补丁命令行
│   └── patch-keyword-bypass.mjs # 关键词中和补丁独立命令行(备选路径)
└── _out/                    # 自检与验证脚本(不发布)
    ├── host-selftest.mjs    # Host 半身 162 项自检
    ├── selftest.mjs         # Client 半身 116 项自检(含静态审计)
    ├── test-lexicon.mjs     # 词库逻辑 18 项断言(含路径安全)
    ├── test-click.mjs       # CDP 真浏览器点开关验证
    ├── lead-adversarial4.mjs# 独立复算聚合数学
    ├── cdp-verify-ui.mjs    # CDP 真浏览器渲染验证(多视口)
    └── verify-patch.mjs     # 补丁静态+功能验证

回滚

# 1. 还原 OFM 补丁
node scripts/patch-ofm.mjs --revert

# 2. 卸载插件
POST .../pluginManager/removeBundle  {"payload":{"args":{"name":"dsh-workbuddy-meter"}}}

# 3. 数据(可选,默认保留)
#    ~/.dsh/workbuddy-meter/  整目录删除即清空全部历史

隐私说明

这个插件不会把你的数据发到任何地方:

  • 用量记录、余额快照、补丁状态、开关配置全部写在本地 ~/.dsh/workbuddy-meter/
  • 没有任何遥测、上报或外部请求(除了你本来就在用的 WorkBuddy 上游)
  • 关键词中和是纯本地的字符串处理,不发任何东西出去

贡献

欢迎 issue 与 PR。提交前请确保:

node _out/host-selftest.mjs   # Host 半身 164 项
node _out/selftest.mjs        # Client 半身 116 项(含静态审计)

三条代码约定(自测会强制检查):

  1. 样式只能用 var(--dsw-alias-*) token —— 不允许十六进制色值或 rgb()/hsl()
  2. 所有 CSS 类名以 wbm- 开头 —— 避免污染宿主样式
  3. 中英文案键集必须完全一致 —— locale/zh.json 与 client.js 内嵌字典同步

许可

MIT © 2026 balong


2026-10-18 建立,2026-10-21 开源。补丁点与数据契约见 CONTRACT.md。

Comments

Loading…