dsh-workbuddy-bridge 0.1.0 → 0.2.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/README.md +58 -139
- package/README_en.md +90 -176
- package/icon.svg +42 -22
- package/lib/bin.js +1 -1
- package/lib/client.js +91 -63
- package/lib/index.js +1 -1
- package/lib/{variants-CFO_LIBm.js → variants-DP0Ho0Tc.js} +1 -1
- package/package.json +18 -11
package/README.md
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
<p><em>WorkBuddy desktop models in DeepSeek Harness</em></p>
|
|
8
8
|
|
|
9
9
|
<p>
|
|
10
|
-
<a href="https://
|
|
10
|
+
<a href="https://www.npmjs.com/package/dsh-workbuddy-bridge"><img src="https://img.shields.io/npm/v/dsh-workbuddy-bridge?style=flat" alt="npm"></a>
|
|
11
11
|
<a href="https://github.com/zlZayn/dsh-workbuddy-bridge/actions/workflows/ci.yml"><img src="https://github.com/zlZayn/dsh-workbuddy-bridge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
12
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DeepSeek%20Harness-Plugin-4176E6?style=flat" alt="DeepSeek Harness Plugin"></a>
|
|
12
13
|
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT 许可证"></a>
|
|
13
14
|
</p>
|
|
14
15
|
|
|
@@ -23,184 +24,109 @@
|
|
|
23
24
|
> **凭据不出本机**:登录状态取自 WorkBuddy 桌面 App 自己的凭据文件,插件只在本机留一份加密副本;
|
|
24
25
|
> 浏览器半边拿不到令牌,界面里也永远不出现凭据原文。
|
|
25
26
|
|
|
26
|
-
国内版 **WorkBuddy** 与国际版 **WorkBuddy AI**
|
|
27
|
+
国内版 **WorkBuddy** 与国际版 **WorkBuddy AI** 并存:装哪个 App 就出现哪个模型分组,两个都装就两组并排,
|
|
27
28
|
各自用自己的账号与积分。模型直接出现在 DSH 的模型选择器里,不必为它单独配一个 provider。
|
|
28
29
|
|
|
29
30
|
<p align="center">
|
|
30
|
-
<img src="assets/1.png" alt="WorkBuddy 模型出现在 DSH 模型选择器中" width="
|
|
31
|
+
<img src="assets/1.png" alt="WorkBuddy 模型出现在 DSH 模型选择器中" width="300">
|
|
31
32
|
<br>
|
|
32
|
-
<em
|
|
33
|
+
<em>国内版在模型选择器中自成一组,模型名后直接跟积分倍率与促销徽章;装国际版则出现「WorkBuddy AI」组。</em>
|
|
33
34
|
</p>
|
|
34
35
|
|
|
35
|
-
##
|
|
36
|
-
|
|
37
|
-
- **开箱即用**:装完启用,模型分组自己出现,没有必填项。
|
|
38
|
-
- **两版互不串号**:国内版是「WorkBuddy」分组、国际版是「WorkBuddy AI」分组,模型、账号与积分互不混用;
|
|
39
|
-
**各自只跟随自己那版 App 的登录状态** —— 退出其中一版,对应分组消失,另一版不受影响。
|
|
40
|
-
- **图片输入**:多数模型可直接粘贴或拖入图片(GLM-5.3-Flash、GLM-5.2、DeepSeek-V4 系列等);
|
|
41
|
-
少数纯文字模型(如 GLM-5.1)会明确说明不支持。
|
|
42
|
-
- **推理档位**:上游声明了档位的模型直接可选(如 GLM-5.3 / GLM-5.3-Flash 的 low / high / max);
|
|
43
|
-
没声明的模型可在 Web 与 Desktop 上**手动检测**(见[为什么是手动检测](#为什么是手动检测))。
|
|
44
|
-
未检测或没有可用档位的模型继续用 WorkBuddy 的默认档位。
|
|
45
|
-
- **模型显隐**:卡片的「模型」标签里勾选哪些模型出现在选择器里;**按登录账号分别保存**,
|
|
46
|
-
切换账号自动切换各自的配置。隐藏只影响可选择性,**已在用该模型的会话照常继续**。
|
|
47
|
-
- **账号与积分**:插件页里看账号、令牌有效期(自动续期)、剩余积分与模型优惠,可手动刷新模型列表,
|
|
48
|
-
并看到当前列表来自上游还是内置兜底。
|
|
49
|
-
- **费率与促销**:模型名后直接跟积分倍率(如 `GLM-5.2 · x0.79`)与促销徽章(限时免费 / 夜间折扣),
|
|
50
|
-
`/model` 弹窗与输入框下拉都能看到。倍率只是显示,不影响请求。
|
|
51
|
-
- **企业账号**:国内版企业账号走企业专用计费接口读周期额度,卡片显示「企业额度」与周期重置时间。
|
|
52
|
-
- **三种界面**:Web / Desktop / TUI 都能跑;只有 TUI 不提供手动检测。
|
|
53
|
-
- **插件页里以显示名出现**:`DSH WorkBuddy Bridge`(中英界面同名),标题下面另有一行代码体写着包名
|
|
54
|
-
`dsh-workbuddy-bridge` —— 两处都要能对上,才不会在插件列表里认错。
|
|
36
|
+
## 它能做什么
|
|
55
37
|
|
|
56
|
-
|
|
38
|
+
- **开箱即用** —— 装完启用,模型分组自己出现,没有必填项。
|
|
39
|
+
- **两版互不串号** —— 国内版是「WorkBuddy」分组、国际版是「WorkBuddy AI」分组;模型、账号与积分互不混用,
|
|
40
|
+
各自只跟随自己那版 App 的登录状态。退出其中一版,对应分组消失,另一版不受影响。
|
|
41
|
+
- **推理档位** —— 上游声明了档位的模型直接可选;没声明的模型可以在插件页里**手动检测**
|
|
42
|
+
(见[为什么是手动检测](#为什么是手动检测))。未检测或没有可用档位的模型继续用 WorkBuddy 的默认档位。
|
|
43
|
+
- **模型显隐** —— 卡片的「模型」标签里勾选哪些模型出现在选择器里,按登录账号分别保存;
|
|
44
|
+
隐藏只影响可选择性,已在用该模型的会话照常继续。
|
|
45
|
+
- **积分与账户** —— 插件页里看登录账号、剩余积分、各套餐余量,并可手动刷新模型列表。
|
|
46
|
+
- **图片输入** —— 多数模型可直接粘贴或拖入图片;少数纯文字模型会明确说明不支持。
|
|
47
|
+
- **三种界面** —— Web / Desktop / TUI 都能跑;只有 TUI 不提供手动检测。
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="assets/2.png" alt="插件详情页:配置表单与两张状态卡片" width="560">
|
|
51
|
+
<br>
|
|
52
|
+
<em>插件页里的样子:上面是配置表单,下面两张卡片各跟随自己 App 的登录状态。</em>
|
|
53
|
+
</p>
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
账号切换自动跟随;两版互不影响。
|
|
62
|
-
- DSH 的版本范围以 [package.json](package.json) 的 `engines` 与 `peerDependencies` 为准 —— 本仓只跟 **DSH `0.1.7` 线**。
|
|
63
|
-
- Node 22+(同上,真源是 `engines.node`)。
|
|
55
|
+
## 安装
|
|
64
56
|
|
|
65
|
-
|
|
57
|
+
前置只有一条:已安装并登录 **WorkBuddy 桌面 App**(国际版为 WorkBuddy AI App)—— 插件复用 App 的登录状态,
|
|
58
|
+
账号切换自动跟随。
|
|
66
59
|
|
|
67
60
|
```sh
|
|
68
61
|
dsh plugin --profile web add dsh-workbuddy-bridge
|
|
69
62
|
dsh web
|
|
70
63
|
```
|
|
71
64
|
|
|
72
|
-
|
|
65
|
+
Desktop 与 TUI 把 `--profile web` 换成 `desktop` / `dsh-tui` 即可(TUI 需终端插件
|
|
66
|
+
`@deepseek-harness-tui/dsh-tui` ≥ `0.10.0-beta.5`,且用 pnpm 11 安装,详见其文档)。
|
|
67
|
+
|
|
68
|
+
也可以从源码安装:
|
|
73
69
|
|
|
74
70
|
```sh
|
|
75
71
|
git clone https://github.com/zlZayn/dsh-workbuddy-bridge.git
|
|
76
72
|
cd dsh-workbuddy-bridge
|
|
77
73
|
pnpm install && pnpm build
|
|
78
|
-
|
|
79
74
|
dsh plugin --profile web add "$PWD"
|
|
80
|
-
dsh web
|
|
81
75
|
```
|
|
82
76
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```sh
|
|
86
|
-
# Desktop(DSH Desktop 桌面版)
|
|
87
|
-
dsh plugin --profile desktop add dsh-workbuddy-bridge
|
|
88
|
-
dsh --profile desktop
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
```sh
|
|
92
|
-
# TUI(终端界面)
|
|
93
|
-
dsh plugin --profile dsh-tui add dsh-workbuddy-bridge
|
|
94
|
-
dsh --profile dsh-tui
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
> **TUI 的版本搭配**:终端界面插件 `@deepseek-harness-tui/dsh-tui` 需 **`0.10.0-beta.5` 及以上** ——
|
|
98
|
-
> 更早的版本装了本插件会启动失败,报 `events is not iterable`。先用 TUI 自带的方式把壳升上去,再装本插件。
|
|
99
|
-
|
|
100
|
-
> **TUI 的 pnpm**:`dsh-tui` profile 需用 pnpm 11 安装(PATH 里是其他版本会报 `ERR_PNPM_UNEXPECTED_STORE`,
|
|
101
|
-
> 用 `npx pnpm@11` 即可)。
|
|
102
|
-
|
|
103
|
-
### 发现与安装
|
|
77
|
+
## 插件页
|
|
104
78
|
|
|
105
|
-
|
|
106
|
-
- 仓库带 GitHub topic `dsh-plugin`,插件市场据此自动发现。
|
|
79
|
+
侧边栏 **插件(Plugins)** → 已安装 → 点 **DSH WorkBuddy Bridge** 进详情页。配置区就在描述下面,直接可改,保存即生效:
|
|
107
80
|
|
|
108
|
-
|
|
81
|
+
- **登录文件路径**(国内版 / 国际版)—— 留空即用 App 自己的位置,一般不用填。
|
|
82
|
+
- **允许推理档位检测**、**使用上游声明的最大上下文窗口** —— 两个开关,默认够用。
|
|
109
83
|
|
|
110
|
-
|
|
111
|
-
- **不提供跨代兼容**:宿主换线时本仓跟着抬下限,不在一份代码里同时伺候两条线。
|
|
112
|
-
- 本仓**不查宿主版本号**:它按宿主声明的契约注册(槽、服务、配置接缝),没有防御性包装;
|
|
113
|
-
接缝缺席时对应功能静默不出现,不会拖垮界面。
|
|
114
|
-
|
|
115
|
-
## 配置
|
|
116
|
-
|
|
117
|
-
侧边栏 **插件(Plugins)** →「已安装(Installed)」→ 点插件名进详情页 ——
|
|
118
|
-
**配置区就在描述下面,直接可改**,那一行上没有第二个 Configure 步骤:
|
|
119
|
-
|
|
120
|
-
- **配置表单**:`authFile`(国内版登录文件路径)、`authFileAI`(国际版)、**允许推理档位检测**、
|
|
121
|
-
**使用上游声明的最大上下文窗口**。前两项留空即用 App 自己的位置。
|
|
122
|
-
- **两张卡片**:国内版与国际版各一张,各显示自己账号的信息。账号、令牌有效期与模型列表来源常驻展开区顶部,
|
|
123
|
-
下面三个标签按「读者要做什么」划分:
|
|
124
|
-
- **积分**:合计、周期重置与各套餐余量,一处读完。
|
|
125
|
-
- **模型**:完整目录一张表 —— **模型显隐**勾选、上下文窗口、积分倍率与促销徽章。
|
|
126
|
-
- **检测**:推理档位检测,一模型一行;没有可检测的模型时这一页为空。
|
|
84
|
+
配置改动立即生效,不需要重启;卡片上的实时状态(账号、积分、模型列表)则来自下面的两张卡。
|
|
127
85
|
|
|
128
86
|
<p align="center">
|
|
129
|
-
<img src="assets/
|
|
87
|
+
<img src="assets/6.png" alt="模型标签:显隐、窗口、倍率" width="300">
|
|
88
|
+
<img src="assets/7.png" alt="检测标签:推理档位检测" width="300">
|
|
130
89
|
<br>
|
|
131
|
-
<em
|
|
90
|
+
<em>展开「WorkBuddy(国内版)」卡片:左「模型」标签管理显隐、看窗口与倍率;右「检测」标签一模型一行,点「开始检测」确认它接受哪些推理档位,结果也回写到模型选择器里。</em>
|
|
132
91
|
</p>
|
|
133
92
|
|
|
134
93
|
<p align="center">
|
|
135
|
-
<img src="assets/3.png" alt="积分标签:合计与套餐余量" width="
|
|
136
|
-
<img src="assets/6.png" alt="模型标签:显隐、窗口、倍率" width="420">
|
|
137
|
-
<img src="assets/7.png" alt="检测标签:推理档位检测" width="420">
|
|
94
|
+
<img src="assets/3.png" alt="积分标签:合计与套餐余量" width="640">
|
|
138
95
|
<br>
|
|
139
|
-
<em
|
|
96
|
+
<em>「积分」标签:合计一行,下面是各套餐余量条。</em>
|
|
140
97
|
</p>
|
|
141
98
|
|
|
142
|
-
保存即生效。**配置改动不需要重启宿主**(配置是 volatile 引用);**改了插件代码才需要**。
|
|
143
|
-
|
|
144
|
-
> 设置弹窗里的「内置插件」页是**只读清单**(名称与运行状态),没有配置入口 —— 别在那里找配置。
|
|
145
|
-
|
|
146
99
|
## 为什么是手动检测
|
|
147
100
|
|
|
148
|
-
WorkBuddy 的推理档位信息分散在上游接口与客户端私有 UI
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
一次请求成功并不能证明某个档位真的可用。
|
|
153
|
-
|
|
154
|
-
<p align="center">
|
|
155
|
-
<img src="assets/4.png" alt="输入框模型选择器旁的「推理等级」检测控件" width="620">
|
|
156
|
-
<br>
|
|
157
|
-
<em>检测控件就在模型选择器旁;结果显示在模型下拉里,也回写到卡片上。</em>
|
|
158
|
-
</p>
|
|
159
|
-
|
|
160
|
-
所以对没有声明档位的模型,Web 与 Desktop 改为**先授权、再按需检测**:先确认上游会校验这个参数,
|
|
161
|
-
再逐项确认哪些规范档位被接受。检测会发送少量请求、可能消耗积分;结果只表示**上游当前接受该档位**,
|
|
162
|
-
不承诺它改变推理效果、速度或积分消耗。
|
|
101
|
+
WorkBuddy 的推理档位信息分散在上游接口与客户端私有 UI 逻辑里,且模型目录变化很快;而实测有些模型
|
|
102
|
+
**接受** `reasoning_effort` 却忽略未知值、回退到默认行为 —— 一次请求成功并不能证明某个档位真的可用。
|
|
103
|
+
所以插件不猜:先由你在配置里授权,再按需对单个模型发少量真实请求确认。检测可能消耗少量积分;
|
|
104
|
+
结果只表示**上游当前接受该档位**,不承诺它改变推理效果、速度或积分消耗。
|
|
163
105
|
|
|
164
106
|
## 命令行
|
|
165
107
|
|
|
166
|
-
|
|
167
|
-
dsh plugin --profile <web|desktop|dsh-tui> exec dsh-workbuddy-bridge status
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
登录状态与剩余积分;`--json` 输出机器可读格式,另有 `doctor`(诊断)与 `logout`(清理凭据)。
|
|
171
|
-
|
|
172
|
-
默认操作国内版,加 `--provider workbuddy-ai` 操作国际版:
|
|
108
|
+
不改界面也能查状态:
|
|
173
109
|
|
|
174
110
|
```sh
|
|
175
|
-
dsh plugin --profile web exec dsh-workbuddy-bridge status
|
|
176
|
-
dsh plugin --profile web exec dsh-workbuddy-bridge
|
|
111
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge status # 登录状态与剩余积分
|
|
112
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge status --json # 机器可读
|
|
113
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge doctor # 诊断 App 发现与凭据
|
|
114
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge logout # 清理插件自留的凭据副本
|
|
177
115
|
```
|
|
178
116
|
|
|
179
|
-
`logout`
|
|
180
|
-
(App 的凭据文件仍在时依然生效)。
|
|
117
|
+
默认操作国内版,加 `--provider workbuddy-ai` 操作国际版。`logout` 不动桌面 App 自己的登录。
|
|
181
118
|
|
|
182
|
-
##
|
|
119
|
+
## 兼容与已知限制
|
|
183
120
|
|
|
184
|
-
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
|
|
121
|
+
- 只支持 **DSH `0.1.7` 线**;下限以 [package.json](package.json) 的 `engines.dsh` 为准,不做跨代兼容。
|
|
122
|
+
- **凭据发现按平台**:macOS 直接支持;Windows 依次探测 Local 与 Roaming AppData(实测可用);
|
|
123
|
+
WSL 优先读挂载的 Windows 用户目录。找不到时用 `WORKBUDDY_AUTH_FILE`(国际版 `WORKBUDDY_AI_AUTH_FILE`)指定。
|
|
124
|
+
- **国际版目录来自 App 界面接口**(私有实现,上游改动可能失效);国内版走官方 CLI 同款接口。
|
|
125
|
+
- 无凭据时该版模型分组不再显示 —— 插件不会展示一份选了必然报错的兜底列表。
|
|
126
|
+
- 企业账号积分目前仅覆盖国内版。
|
|
190
127
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
- 在 macOS 的 DSH Web / Desktop / TUI 下验证通过。Windows 依次探测 Local 与 Roaming AppData;
|
|
194
|
-
WSL 优先从挂载的 Windows 用户目录读取登录凭据。Windows 与 Linux 用户名不同、且 Windows 环境变量
|
|
195
|
-
未传入 WSL 时,用 `WORKBUDDY_AUTH_FILE`(国际版 `WORKBUDDY_AI_AUTH_FILE`)指定实际位置。
|
|
196
|
-
- **国际版的模型目录来自 App 界面接口**:服务端按 User-Agent 分流,属私有实现,改动可能使其失效;
|
|
197
|
-
国内版走官方 CLI 同款接口,不受此影响。
|
|
198
|
-
- **国际版仍未覆盖的环境**:Windows / WSL / Linux 下国际版 App 的版本读取尚未找到可靠来源,
|
|
199
|
-
会退回最近保存的版本或内置值。
|
|
200
|
-
- **无凭据时的行为**:某版 App 从未登录、也没留下插件自留副本时,该版模型分组不再显示
|
|
201
|
-
(此前国内版会显示一份内置兜底列表,但那些模型选了必然报错)。
|
|
202
|
-
- **企业账号积分目前仅覆盖国内版**:国际版企业计费接口尚未验证,仍按个人版接口读取。
|
|
203
|
-
- 手动检测只在 Web 与 Desktop 提供,TUI 没有。
|
|
128
|
+
设计取舍 → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md);发版流程 → [docs/PUBLISHING.md](docs/PUBLISHING.md);
|
|
129
|
+
维护者文档地图 → [AGENTS.md](AGENTS.md)。
|
|
204
130
|
|
|
205
131
|
## 免责声明
|
|
206
132
|
|
|
@@ -216,11 +142,4 @@ dsh plugin --profile web exec dsh-workbuddy-bridge doctor --provider workbuddy-a
|
|
|
216
142
|
|
|
217
143
|
## 许可
|
|
218
144
|
|
|
219
|
-
[MIT](LICENSE)。
|
|
220
|
-
|
|
221
|
-
## 贡献
|
|
222
|
-
|
|
223
|
-
报缺陷请附 DSH 版本、插件版本与复现步骤;提功能前先翻 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) 看设计取舍。
|
|
224
|
-
|
|
225
|
-
设计取向 → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md);发布流程与版本号判定 → [docs/PUBLISHING.md](docs/PUBLISHING.md);
|
|
226
|
-
维护者文档地图 → [AGENTS.md](AGENTS.md)。
|
|
145
|
+
[MIT](LICENSE)。
|
package/README_en.md
CHANGED
|
@@ -3,247 +3,161 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
|
-
<p><strong>WorkBuddy desktop models in
|
|
7
|
-
<p><em>把 WorkBuddy 桌面 App 的模型接进 DSH 对话窗口</em></p>
|
|
6
|
+
<p><strong>WorkBuddy desktop models in DeepSeek Harness</strong></p>
|
|
8
7
|
|
|
9
8
|
<p>
|
|
10
|
-
<a href="https://
|
|
9
|
+
<a href="https://www.npmjs.com/package/dsh-workbuddy-bridge"><img src="https://img.shields.io/npm/v/dsh-workbuddy-bridge?style=flat" alt="npm"></a>
|
|
11
10
|
<a href="https://github.com/zlZayn/dsh-workbuddy-bridge/actions/workflows/ci.yml"><img src="https://github.com/zlZayn/dsh-workbuddy-bridge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
11
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DeepSeek%20Harness-Plugin-4176E6?style=flat" alt="DeepSeek Harness Plugin"></a>
|
|
12
12
|
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p>
|
|
16
|
-
<a href="README.md">简体中文</a> · <
|
|
16
|
+
<strong><a href="README.md">简体中文</a></strong> · <a href="README_en.md">English</a>
|
|
17
17
|
</p>
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
> [!NOTE]
|
|
23
|
-
> **Credentials never leave
|
|
24
|
-
>
|
|
25
|
-
>
|
|
23
|
+
> **Credentials never leave this machine**: sign-in state is read from the WorkBuddy desktop app's own
|
|
24
|
+
> credential file and kept as one encrypted local copy; the browser half never sees a token, and none
|
|
25
|
+
> ever appears in the UI.
|
|
26
26
|
|
|
27
|
-
The CN **WorkBuddy** and the international **WorkBuddy AI**
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
The CN **WorkBuddy** and the international **WorkBuddy AI** coexist: install one app and its model group
|
|
28
|
+
appears; install both and the two groups sit side by side, each with its own account and credit. The
|
|
29
|
+
models appear directly in the DSH model picker — no separate provider to configure.
|
|
30
30
|
|
|
31
31
|
<p align="center">
|
|
32
|
-
<img src="assets/1.png" alt="WorkBuddy models in the DSH model picker" width="
|
|
32
|
+
<img src="assets/1.png" alt="WorkBuddy models in the DSH model picker" width="300">
|
|
33
33
|
<br>
|
|
34
|
-
<em>The CN version forms its own group in the model picker
|
|
35
|
-
|
|
34
|
+
<em>The CN version forms its own group in the model picker, each model carrying its credit rate and promo
|
|
35
|
+
badge; installing the international version adds a "WorkBuddy AI" group the same way.</em>
|
|
36
36
|
</p>
|
|
37
37
|
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
- **
|
|
41
|
-
- **The two versions never
|
|
42
|
-
models, accounts
|
|
43
|
-
and
|
|
44
|
-
- **
|
|
45
|
-
the
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- **
|
|
53
|
-
offers; it can refresh the model list and shows whether the list came from the upstream or the built-in fallback.
|
|
54
|
-
- **Rates and promos**: each model name carries its credit multiplier (e.g. `GLM-5.2 · x0.79`) and promo badges
|
|
55
|
-
(limited-time free / night discount) in both the `/model` popup and the composer dropdown. The rate is display-only.
|
|
56
|
-
- **Enterprise accounts**: CN enterprise accounts read their cycle quota from the enterprise billing endpoint, and the
|
|
57
|
-
card shows an "enterprise quota" row with the reset time.
|
|
58
|
-
- **The plugin page shows a display name**: `DSH WorkBuddy Bridge` (the same in both UI languages), with the
|
|
59
|
-
package name `dsh-workbuddy-bridge` on the code-style line beneath it.
|
|
38
|
+
## What it does
|
|
39
|
+
|
|
40
|
+
- **Zero configuration** — install, enable, and the model group appears by itself.
|
|
41
|
+
- **The two versions never cross** — "WorkBuddy" for the CN app, "WorkBuddy AI" for the international one;
|
|
42
|
+
models, accounts and credit stay separate, and each group follows its own app's sign-in. Sign out of one
|
|
43
|
+
and its group disappears while the other is unaffected.
|
|
44
|
+
- **Reasoning levels** — models that declare levels expose them directly; the rest can be **checked manually**
|
|
45
|
+
on the plugin page (see [Why detection is manual](#why-detection-is-manual)). Unchecked models keep
|
|
46
|
+
WorkBuddy's default level.
|
|
47
|
+
- **Model visibility** — tick which models appear in the picker on the card's "Models" tab; saved per
|
|
48
|
+
signed-in account. Hiding only affects pickability — chats already using a hidden model keep working.
|
|
49
|
+
- **Credit and account** — the plugin page shows the signed-in account, remaining credit and per-package
|
|
50
|
+
allowances, with a manual model-list refresh.
|
|
51
|
+
- **Image input** — most models accept pasted or dropped images; the few text-only models say so explicitly.
|
|
52
|
+
- **Three surfaces** — Web, Desktop and TUI all work; only the TUI lacks manual detection.
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
<p align="center">
|
|
55
|
+
<img src="assets/2.png" alt="Plugin detail page: the configuration form and the two status cards" width="560">
|
|
56
|
+
<br>
|
|
57
|
+
<em>The plugin page: the configuration form on top, two cards below, each following its own app's sign-in.</em>
|
|
58
|
+
</p>
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
reuses the app's sign-in state and follows account switches; the two versions do not affect each other.
|
|
67
|
-
- The DSH version range is whatever [package.json](package.json) declares in `engines` and `peerDependencies` —
|
|
68
|
-
this repository tracks the **DSH `0.1.7` line** only.
|
|
69
|
-
- Node 22+ (same source: `engines.node`).
|
|
60
|
+
## Install
|
|
70
61
|
|
|
71
|
-
|
|
62
|
+
One prerequisite: the **WorkBuddy desktop app** is installed and signed in (WorkBuddy AI for the
|
|
63
|
+
international version) — the plugin reuses the app's sign-in state and follows account switches.
|
|
72
64
|
|
|
73
65
|
```sh
|
|
74
66
|
dsh plugin --profile web add dsh-workbuddy-bridge
|
|
75
67
|
dsh web
|
|
76
68
|
```
|
|
77
69
|
|
|
78
|
-
|
|
70
|
+
For Desktop and TUI swap `--profile web` for `desktop` / `dsh-tui` (the TUI needs the terminal plugin
|
|
71
|
+
`@deepseek-harness-tui/dsh-tui` ≥ `0.10.0-beta.5`, installed with pnpm 11 — see its docs).
|
|
72
|
+
|
|
73
|
+
Or from source:
|
|
79
74
|
|
|
80
75
|
```sh
|
|
81
76
|
git clone https://github.com/zlZayn/dsh-workbuddy-bridge.git
|
|
82
77
|
cd dsh-workbuddy-bridge
|
|
83
78
|
pnpm install && pnpm build
|
|
84
|
-
|
|
85
79
|
dsh plugin --profile web add "$PWD"
|
|
86
|
-
dsh web
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Other interfaces
|
|
90
|
-
|
|
91
|
-
```sh
|
|
92
|
-
# Desktop (the DSH Desktop app)
|
|
93
|
-
dsh plugin --profile desktop add dsh-workbuddy-bridge
|
|
94
|
-
dsh --profile desktop
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
```sh
|
|
98
|
-
# TUI (terminal UI)
|
|
99
|
-
dsh plugin --profile dsh-tui add dsh-workbuddy-bridge
|
|
100
|
-
dsh --profile dsh-tui
|
|
101
80
|
```
|
|
102
81
|
|
|
103
|
-
|
|
104
|
-
> older versions fail at startup with `events is not iterable` once this plugin is installed. Update the shell first.
|
|
82
|
+
## The plugin page
|
|
105
83
|
|
|
106
|
-
|
|
107
|
-
|
|
84
|
+
Sidebar **Plugins** → installed → click **DSH WorkBuddy Bridge**. The configuration area sits right under the
|
|
85
|
+
description, editable in place, saved immediately:
|
|
108
86
|
|
|
109
|
-
|
|
87
|
+
- **Sign-in file paths** (CN / international) — leave blank to use the app's own location; usually unnecessary.
|
|
88
|
+
- **Allow reasoning-level detection** and **use the largest declared context window** — two switches, defaults are fine.
|
|
110
89
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
## Version compatibility
|
|
115
|
-
|
|
116
|
-
- This repository supports the **DSH `0.1.7` line** only, verified on `0.1.7-rc.2`; the floor lives in
|
|
117
|
-
[package.json](package.json) (`engines.dsh`) and is not copied here.
|
|
118
|
-
- **No cross-generation compatibility**: when the host moves lines, this repository moves its floor with it rather
|
|
119
|
-
than serving two lines from one codebase.
|
|
120
|
-
- The plugin **never probes the host version**: it registers against the contracts the host declares (slots, services,
|
|
121
|
-
the configuration seam) with no defensive wrappers. Where a seam is absent the corresponding feature quietly does not
|
|
122
|
-
appear, and nothing else is dragged down with it.
|
|
123
|
-
|
|
124
|
-
## Configuration
|
|
125
|
-
|
|
126
|
-
Sidebar **Plugins** → "Installed" → click the plugin name to open its detail page — **the configuration area sits right
|
|
127
|
-
under the description and is editable in place**, with no second Configure step on that row:
|
|
128
|
-
|
|
129
|
-
- **Configuration form**: `authFile` (CN sign-in file), `authFileAI` (international), **allow reasoning-level detection**,
|
|
130
|
-
and **use the largest context window the upstream declares**. Leave the first two blank to use the app's own location.
|
|
131
|
-
- **Two cards**: one per version, each reporting its own account. The account, token validity and catalog source
|
|
132
|
-
sit above the tabs; the three tabs below split by what a reader came to do:
|
|
133
|
-
- **Credits**: total, cycle reset, and per-package allowances in one place.
|
|
134
|
-
- **Models**: the full catalog in one table — **visibility** checkboxes, context windows, credit rates and badges.
|
|
135
|
-
- **Detection**: reasoning-level detection, one row per model; empty when nothing needs detecting.
|
|
90
|
+
Configuration takes effect immediately — no restart needed. The live state on the cards (account, credit,
|
|
91
|
+
model list) comes from the two cards below.
|
|
136
92
|
|
|
137
93
|
<p align="center">
|
|
138
|
-
<img src="assets/
|
|
94
|
+
<img src="assets/6.png" alt="Models tab: visibility, windows, rates" width="300">
|
|
95
|
+
<img src="assets/7.png" alt="Detection tab: reasoning-level detection" width="300">
|
|
139
96
|
<br>
|
|
140
|
-
<em>
|
|
97
|
+
<em>Expanding the "WorkBuddy (CN)" card: the Models tab (left) manages visibility and shows windows and
|
|
98
|
+
rates; the Detection tab (right) is one row per model — press Detect to confirm which reasoning levels
|
|
99
|
+
it accepts, and the results also land in the model picker.</em>
|
|
141
100
|
</p>
|
|
142
101
|
|
|
143
102
|
<p align="center">
|
|
144
|
-
<img src="assets/3.png" alt="Credits tab: total and per-package allowances" width="
|
|
145
|
-
<img src="assets/6.png" alt="Models tab: visibility, windows, rates" width="420">
|
|
146
|
-
<img src="assets/7.png" alt="Detection tab: reasoning-level detection" width="420">
|
|
103
|
+
<img src="assets/3.png" alt="Credits tab: total and per-package allowances" width="640">
|
|
147
104
|
<br>
|
|
148
|
-
<em>
|
|
105
|
+
<em>The Credits tab: the total on one line, each package's allowance as a bar below.</em>
|
|
149
106
|
</p>
|
|
150
107
|
|
|
151
|
-
Saving takes effect immediately. **Configuration changes do not need a host restart** (configuration is a volatile
|
|
152
|
-
reference); **changing the plugin's code does**.
|
|
153
|
-
|
|
154
|
-
> The "Built-in Plugins" page in the settings dialog is a **read-only inventory** (name and runtime status) with no
|
|
155
|
-
> configuration entry — do not look for configuration there.
|
|
156
|
-
|
|
157
108
|
## Why detection is manual
|
|
158
109
|
|
|
159
|
-
WorkBuddy's reasoning-level information is
|
|
160
|
-
|
|
161
|
-
|
|
110
|
+
WorkBuddy's reasoning-level information is scattered across upstream endpoints and private client UI logic,
|
|
111
|
+
and the model catalog changes fast. Worse, testing showed some models **accept** `reasoning_effort` but
|
|
112
|
+
silently ignore unknown values — one successful request does not prove a level actually works. So the plugin
|
|
113
|
+
does not guess: you authorize detection in the configuration first, then each model is confirmed with a few
|
|
114
|
+
real requests on demand. Detection may consume a small amount of credit; a result only means **the upstream
|
|
115
|
+
currently accepts that level** — it does not promise any change in quality, speed, or cost.
|
|
162
116
|
|
|
163
|
-
|
|
164
|
-
their default — so one successful request does not prove that a level is actually usable.
|
|
117
|
+
## Command line
|
|
165
118
|
|
|
166
|
-
|
|
167
|
-
<img src="assets/4.png" alt="The reasoning-level control beside the composer's model picker" width="620">
|
|
168
|
-
<br>
|
|
169
|
-
<em>The control sits next to the model picker; results land in the model dropdown and are written back to the card.</em>
|
|
170
|
-
</p>
|
|
171
|
-
|
|
172
|
-
For models without declared levels, Web and Desktop therefore use **authorize first, then detect on demand**: confirm
|
|
173
|
-
that the upstream validates the parameter, then check which standard levels it accepts. Detection sends a few requests
|
|
174
|
-
and may consume credit; the result means only that **the upstream currently accepts that level** — it does not promise
|
|
175
|
-
a change in reasoning quality, speed, or credit use.
|
|
176
|
-
|
|
177
|
-
## CLI
|
|
119
|
+
Check status without the UI:
|
|
178
120
|
|
|
179
121
|
```sh
|
|
180
|
-
dsh plugin --profile
|
|
122
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge status # sign-in state and credit
|
|
123
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge status --json # machine-readable
|
|
124
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge doctor # diagnose app discovery and credentials
|
|
125
|
+
dsh plugin --profile web exec dsh-workbuddy-bridge logout # remove the plugin's local credential copy
|
|
181
126
|
```
|
|
182
127
|
|
|
183
|
-
|
|
184
|
-
|
|
128
|
+
Targets the CN version by default; add `--provider workbuddy-ai` for the international one. `logout` does not
|
|
129
|
+
touch the desktop app's own sign-in.
|
|
185
130
|
|
|
186
|
-
|
|
131
|
+
## Compatibility and known limits
|
|
187
132
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
133
|
+
- Supports the **DSH `0.1.7` line** only; the floor lives in [package.json](package.json) `engines.dsh` — no
|
|
134
|
+
cross-generation compatibility.
|
|
135
|
+
- **Credential discovery is per platform**: macOS supported directly; Windows probes Local then Roaming
|
|
136
|
+
AppData (tested working); WSL reads the mounted Windows user profile first. When nothing is found, point
|
|
137
|
+
`WORKBUDDY_AUTH_FILE` (international: `WORKBUDDY_AI_AUTH_FILE`) at the actual file.
|
|
138
|
+
- **The international catalog comes from the app's UI endpoint** (private, may break upstream); the CN version
|
|
139
|
+
uses the same official CLI endpoint.
|
|
140
|
+
- With no credentials the group does not appear — the plugin never shows a fallback list that would only error.
|
|
141
|
+
- Enterprise credit covers the CN version only.
|
|
192
142
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
## Security and boundaries
|
|
197
|
-
|
|
198
|
-
- **Credentials stay local**: read from the app's credential file, then kept as one **encrypted** plugin-owned copy.
|
|
199
|
-
The browser half never receives the token, file paths, or platform facts.
|
|
200
|
-
- **No credential text in the UI**: the cards report the account and status only.
|
|
201
|
-
- **Only WorkBuddy's own endpoints are contacted** — no proxying or forwarding of other traffic.
|
|
202
|
-
- The plugin depends on **WorkBuddy client interfaces (not a public API)**; upstream changes can break it. When that
|
|
203
|
-
happens it degrades to "this account's last successful catalog → built-in roster" and labels the source and failure
|
|
204
|
-
reason on the card.
|
|
205
|
-
|
|
206
|
-
## Known limitations
|
|
207
|
-
|
|
208
|
-
- Verified on macOS with the DSH Web / Desktop / TUI profiles. Windows probes Local and Roaming AppData in order; WSL
|
|
209
|
-
first reads credentials from the mounted Windows user profile. If the Windows and Linux user names differ and Windows
|
|
210
|
-
environment variables are not forwarded into WSL, point `WORKBUDDY_AUTH_FILE` (or `WORKBUDDY_AI_AUTH_FILE`) at the
|
|
211
|
-
actual file.
|
|
212
|
-
- **The international version's catalog comes from the app's own interface**: the service splits it by User-Agent, a
|
|
213
|
-
private implementation detail a server-side change can break. The CN version uses the same interface as the official
|
|
214
|
-
CLI and is unaffected.
|
|
215
|
-
- **International-version environments not yet covered**: on Windows / WSL / Linux no reliable source for the
|
|
216
|
-
international app's version has been located, so the saved value or the built-in default is used.
|
|
217
|
-
- **Behaviour with no credentials**: a version whose app was never signed in — and that left no plugin-owned copy —
|
|
218
|
-
no longer shows a model group. (The CN version used to display a built-in fallback list, but every model on it failed
|
|
219
|
-
when selected.)
|
|
220
|
-
- **The enterprise credit path currently covers the CN product only**: the international enterprise billing interface is
|
|
221
|
-
unverified, so those accounts still read through the personal endpoint.
|
|
222
|
-
- Manual detection is available on Web and Desktop only; TUI has none.
|
|
143
|
+
Design notes → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md); release process → [docs/PUBLISHING.md](docs/PUBLISHING.md);
|
|
144
|
+
maintainer map → [AGENTS.md](AGENTS.md).
|
|
223
145
|
|
|
224
146
|
## Disclaimer
|
|
225
147
|
|
|
226
|
-
- This project is for
|
|
227
|
-
Do not use it commercially or beyond reasonable personal use.
|
|
228
|
-
-
|
|
229
|
-
|
|
230
|
-
- The
|
|
231
|
-
-
|
|
232
|
-
|
|
148
|
+
- This project is **for personal study and research only**; it drives your own WorkBuddy account on your own
|
|
149
|
+
machine. Do not use it commercially or beyond reasonable personal use.
|
|
150
|
+
- You must comply with WorkBuddy's terms of service; any consequences (account restriction, credit forfeiture,
|
|
151
|
+
service interruption) are your own responsibility.
|
|
152
|
+
- The authors accept no liability for direct or indirect loss caused by use or misuse of this project.
|
|
153
|
+
- Not affiliated with, nor endorsed by, Tencent, WorkBuddy, or DeepSeek; names appear only to describe
|
|
154
|
+
compatibility, and trademarks belong to their owners.
|
|
233
155
|
|
|
234
156
|
## Acknowledgements
|
|
235
157
|
|
|
236
|
-
- [Sliverkiss/workbuddy2api](https://github.com/Sliverkiss/workbuddy2api) (MIT) — reference
|
|
237
|
-
- [franksong2702/dsh-codex-connect](https://github.com/franksong2702/dsh-codex-connect) (Apache-2.0) — reference for
|
|
158
|
+
- [Sliverkiss/workbuddy2api](https://github.com/Sliverkiss/workbuddy2api) (MIT) — reference for the WorkBuddy upstream protocol.
|
|
159
|
+
- [franksong2702/dsh-codex-connect](https://github.com/franksong2702/dsh-codex-connect) (Apache-2.0) — reference for DSH plugin structure and provider registration.
|
|
238
160
|
|
|
239
161
|
## License
|
|
240
162
|
|
|
241
|
-
[MIT](LICENSE).
|
|
242
|
-
|
|
243
|
-
## Contributing
|
|
244
|
-
|
|
245
|
-
Bug reports should include the DSH version, the plugin version, and reproduction steps. Before proposing a feature, read
|
|
246
|
-
[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the design trade-offs.
|
|
247
|
-
|
|
248
|
-
Design → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md); release process and version semantics → [docs/PUBLISHING.md](docs/PUBLISHING.md);
|
|
249
|
-
maintainer doc map → [AGENTS.md](AGENTS.md).
|
|
163
|
+
[MIT](LICENSE).
|
package/icon.svg
CHANGED
|
@@ -1,31 +1,51 @@
|
|
|
1
1
|
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
2
|
<!--
|
|
3
|
-
dsh-workbuddy-bridge
|
|
4
|
-
(src/client/probe-control.tsx 用宿主自己的 IconThinkOutlineRegular),放大到官方 36 格。
|
|
3
|
+
dsh-workbuddy-bridge 的插件页图标。
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
scale = 22 / (15.3767 − 0.6233) = 1.4912
|
|
10
|
-
translate = 7 − 0.6233 × 1.4912 = 6.0706
|
|
11
|
-
原先写的是 translate(2 2) scale(2)(内容 2–34,四周只留 2)—— 看起来就是「太大、太挤」。
|
|
5
|
+
源图是维护者给的一枚 280 格徽章(圆角方块 + 青绿渐变底 + 两团柔光 + 白色标记),
|
|
6
|
+
这里整组搬进官方 36 格:transform(7 7) scale(22/280) ——
|
|
7
|
+
墨迹外接框 7..29,四周各留 7,落在官方三个图标的 6–9 边距窗口里。
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
颜色是烘死的:宿主按图片渲染,currentColor 与主题变量都不起作用
|
|
10
|
+
(理由与取色判据同 dsh-ds-balance/icon.svg)。这里保留源图自带的品牌青绿渐变。
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
墨迹 #7F8287(亮暗两块主题下都落在宿主中性色附近);圆心那一点 #F59E0B
|
|
17
|
-
(宿主 warn 档语义色,亮暗同值)—— 语义是「正在检测的那一档」。
|
|
18
|
-
取色判据与 dsh-ds-balance 的 icon.svg 同一套。
|
|
19
|
-
|
|
20
|
-
形状真源是宿主:组件直接渲染 IconThinkOutlineRegular,本文件是它按官方边距放大后的副本。
|
|
21
|
-
宿主换字形时这里要同批跟(红线 test/redlines.spec.ts 对着三处路径逐字核)。
|
|
12
|
+
注意:XML 注释里不许出现连续两个连字符(浏览器会当图片解析失败,插件页静默回落成默认图形)。
|
|
22
13
|
-->
|
|
23
|
-
<g transform="translate(
|
|
24
|
-
<g
|
|
25
|
-
<
|
|
26
|
-
<
|
|
14
|
+
<g transform="translate(7 7) scale(0.07857142857142857)">
|
|
15
|
+
<g clip-path="url(#clip0)">
|
|
16
|
+
<rect width="280" height="280" rx="60.4211" fill="url(#paint0_linear)"/>
|
|
17
|
+
<g filter="url(#filter0_f)">
|
|
18
|
+
<circle cx="88.2504" cy="244.86" r="98.5668" fill="#32E6B9" fill-opacity="0.4"/>
|
|
19
|
+
</g>
|
|
20
|
+
<g filter="url(#filter1_f)">
|
|
21
|
+
<circle cx="223.384" cy="290.328" r="90.0931" fill="#FFE355" fill-opacity="0.49"/>
|
|
22
|
+
</g>
|
|
23
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M204.15 6.89352C206.896 4.43111 207.061 4.33611 209.074 4.21524C212.336 3.97692 215.324 5.54248 220.41 10.1729C232.291 20.9692 248.834 43.1654 259.119 62.1205L263.093 69.4768L268.707 72.2672C274.126 75.0055 283.015 80.6198 286.728 83.6308C288.407 85.0191 288.642 85.0483 290.388 84.3692C298.267 81.3008 309.553 85.3675 319.508 94.9178C328.47 103.507 337.052 118.181 340.34 130.429C340.82 132.4 341.458 136.638 341.69 139.794C342.44 150.876 338.886 159.726 332.042 163.733C330.644 164.54 330.551 164.759 330.59 168.245C330.905 184.841 326.432 201.406 317.445 217.561C307.301 235.7 289.238 254.464 264.791 272.142C251.663 281.695 220.604 299.792 206.561 306.145C172.92 321.29 145.952 327.1 122.527 324.23C108.554 322.537 92.7397 317.083 83.3819 310.752C80.9182 309.049 80.5286 308.944 78.6462 309.483C68.6285 312.36 55.5086 306.447 44.3628 294.075C39.9174 289.129 32.743 276.986 30.417 270.488C25.0365 255.281 26.1061 241.558 33.273 233.363C35.1245 231.252 35.1835 231.163 34.7791 227.614C34.1112 221.804 33.808 213.206 34.1131 207.656L34.3541 202.472L26.5713 188.706C14.5194 167.262 6.8648 149.255 3.91152 135.497C2.35249 127.954 2.44923 124.607 4.36401 122.131C5.52945 120.635 9.35191 119.087 13.9599 118.236C25.5602 116.199 50.8596 118.043 79.0059 123.012L81.9295 123.517L88.3537 117.834C99.0194 108.386 106.105 103.089 119.168 94.9439C132.783 86.4254 148.148 79.4181 165.452 73.8693L171.004 72.09L174.054 64.0775C184.981 35.233 196.172 13.9675 204.15 6.89352ZM112.625 154.702C100.275 161.832 94.0999 165.397 89.5627 169.393C71.1894 185.572 64.3228 211.198 72.145 234.396C74.0767 240.125 77.642 246.3 84.7719 258.65C91.9018 270.999 95.4667 277.173 99.4619 281.711C115.641 300.084 141.267 306.95 164.466 299.128C170.194 297.197 176.369 293.631 188.719 286.501L259.76 245.486C272.109 238.356 278.284 234.791 282.821 230.796C301.194 214.617 308.061 188.99 300.239 165.792C298.307 160.063 294.742 153.889 287.612 141.54C280.482 129.19 276.917 123.015 272.922 118.478C256.743 100.104 231.116 93.2378 207.918 101.06C202.19 102.992 196.015 106.557 183.666 113.687L112.625 154.702Z" fill="url(#paint1_linear)"/>
|
|
24
|
+
<rect x="119.473" y="204.341" width="28.0633" height="58.2852" rx="14.0316" transform="rotate(-30 119.473 204.341)" fill="white"/>
|
|
25
|
+
<rect x="195.186" y="160.627" width="28.0633" height="58.2852" rx="14.0316" transform="rotate(-30 195.186 160.627)" fill="white"/>
|
|
27
26
|
</g>
|
|
28
|
-
<!-- 圆心那一点:宿主原字形的第三条路径,填色而非描边,所以跟着同一组一起缩放。 -->
|
|
29
|
-
<path d="M8.9587 8.00025C8.9587 8.52835 8.5306 8.95655 8.0024 8.95655C7.47429 8.95655 7.04614 8.52835 7.04614 8.00025C7.04614 7.47209 7.47429 7.04395 8.0024 7.04395C8.5306 7.04395 8.9587 7.47209 8.9587 8.00025Z" fill="#F59E0B" />
|
|
30
27
|
</g>
|
|
28
|
+
<defs>
|
|
29
|
+
<filter id="filter0_f" x="-104.414" y="52.1958" width="385.327" height="385.328" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
30
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
31
|
+
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
32
|
+
<feGaussianBlur stdDeviation="47.0486" result="effect1_foregroundBlur"/>
|
|
33
|
+
</filter>
|
|
34
|
+
<filter id="filter1_f" x="56.2884" y="123.233" width="334.191" height="334.192" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
35
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
36
|
+
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
37
|
+
<feGaussianBlur stdDeviation="38.5013" result="effect1_foregroundBlur"/>
|
|
38
|
+
</filter>
|
|
39
|
+
<linearGradient id="paint0_linear" x1="140" y1="0" x2="140" y2="280" gradientUnits="userSpaceOnUse">
|
|
40
|
+
<stop stop-color="#0EC8A9"/>
|
|
41
|
+
<stop offset="1" stop-color="#01C886"/>
|
|
42
|
+
</linearGradient>
|
|
43
|
+
<linearGradient id="paint1_linear" x1="106.647" y1="62.5482" x2="237.632" y2="289.42" gradientUnits="userSpaceOnUse">
|
|
44
|
+
<stop stop-color="white" stop-opacity="0.8"/>
|
|
45
|
+
<stop offset="0.437689" stop-color="white"/>
|
|
46
|
+
</linearGradient>
|
|
47
|
+
<clipPath id="clip0">
|
|
48
|
+
<rect width="280" height="280" rx="60.4211" fill="white"/>
|
|
49
|
+
</clipPath>
|
|
50
|
+
</defs>
|
|
31
51
|
</svg>
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { D as cnAppDiscovery, E as WorkBuddyAtRestKeyProvider, O as WorkBuddyUpstreamClient, X as resolveAppVersion, b as WorkBuddyCredentialStore, f as WORKBUDDY_BRIDGE_VERSION, g as FALLBACK_WORKBUDDY_MODELS, h as FALLBACK_WORKBUDDY_AI_MODELS, i as variantFor, l as readHostHeartbeat, n as CN_VARIANT, r as WORKBUDDY_VARIANTS, s as isHeartbeatProcessAlive, u as workbuddyHostHeartbeatPath } from "./variants-
|
|
2
|
+
import { D as cnAppDiscovery, E as WorkBuddyAtRestKeyProvider, O as WorkBuddyUpstreamClient, X as resolveAppVersion, b as WorkBuddyCredentialStore, f as WORKBUDDY_BRIDGE_VERSION, g as FALLBACK_WORKBUDDY_MODELS, h as FALLBACK_WORKBUDDY_AI_MODELS, i as variantFor, l as readHostHeartbeat, n as CN_VARIANT, r as WORKBUDDY_VARIANTS, s as isHeartbeatProcessAlive, u as workbuddyHostHeartbeatPath } from "./variants-DP0Ho0Tc.js";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
//#region src/cli/bin.ts
|
package/lib/client.js
CHANGED
|
@@ -46,8 +46,8 @@ window.__ModuleLoader__.load({
|
|
|
46
46
|
return new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(percent);
|
|
47
47
|
}
|
|
48
48
|
//#endregion
|
|
49
|
-
//#region \0workbuddy-css
|
|
50
|
-
const css$1 = ".
|
|
49
|
+
//#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/workbuddy.module.css.js
|
|
50
|
+
const css$1 = "._8BbhmW_page,._8BbhmW_cards{flex-direction:column;gap:12px;display:flex}._8BbhmW_toggleRow{border-top:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);justify-content:space-between;align-items:flex-start;gap:16px;padding:12px 0;font-size:13px;line-height:1.5;display:flex}._8BbhmW_toggleLabel{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}._8BbhmW_toggleHint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}._8BbhmW_body{flex-direction:column;padding:4px 0 12px;display:flex}._8BbhmW_section{flex-direction:column;gap:6px;margin:12px 0;display:flex}._8BbhmW_title{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:500;line-height:1.5}._8BbhmW_row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;padding:12px 0;display:flex}._8BbhmW_summaryRow{flex-wrap:wrap;gap:4px;height:auto;min-height:28px}._8BbhmW_summaryTitle{flex:1;min-width:0}._8BbhmW_statusLine{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;font-size:12px;line-height:1.5;display:inline-flex}._8BbhmW_text{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}._8BbhmW_dim{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}._8BbhmW_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:1.5}._8BbhmW_package{flex-direction:column;gap:8px;display:flex}._8BbhmW_packageLabel{color:var(--dsw-alias-label-secondary);justify-content:space-between;gap:8px;font-size:13px;line-height:1.5;display:flex}._8BbhmW_track{corner-shape:round;background:var(--dsw-alias-border-l3);border-radius:999px;height:8px;overflow:hidden}._8BbhmW_fill{border-radius:inherit;background:var(--dsw-alias-brand-primary);height:100%}._8BbhmW_list{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;gap:6px;min-width:0;max-height:280px;margin:0;padding:14px;display:grid;overflow:auto}._8BbhmW_modelRow{justify-content:space-between;align-items:flex-start;gap:8px;display:flex}._8BbhmW_modelMain{align-items:center;gap:8px;min-width:0;display:flex}._8BbhmW_modelStack{flex-direction:column;gap:2px;min-width:0;display:flex}._8BbhmW_name{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5}._8BbhmW_modelEnd{text-align:right;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex-direction:column;gap:2px;font-size:12px;line-height:1.5;display:flex}._8BbhmW_meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}._8BbhmW_badges{flex-wrap:wrap;align-items:center;gap:6px;display:flex}._8BbhmW_sectionActions{justify-content:flex-end;display:flex}._8BbhmW_probeRow{justify-content:space-between;align-items:center;gap:8px;display:flex}._8BbhmW_probeEnd{flex:none;align-items:center;gap:8px;display:inline-flex}._8BbhmW_assist{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:8px;padding:12px;display:flex}._8BbhmW_prompt{min-width:0;color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;user-select:text;flex:220px;margin:0;font-size:12px;line-height:1.6}._8BbhmW_promptRow{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-3);flex-wrap:wrap;align-items:flex-start;gap:8px;padding:8px 9px 8px 11px;display:flex}";
|
|
51
51
|
const tagId$1 = "dsh-workbuddy-bridge/workbuddy.module.css";
|
|
52
52
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
53
53
|
const tag = document.createElement("style");
|
|
@@ -57,39 +57,39 @@ window.__ModuleLoader__.load({
|
|
|
57
57
|
document.head.appendChild(tag);
|
|
58
58
|
}
|
|
59
59
|
var workbuddy_module_css_default = {
|
|
60
|
-
"assist": "
|
|
61
|
-
"badges": "
|
|
62
|
-
"body": "
|
|
63
|
-
"cards": "
|
|
64
|
-
"dim": "
|
|
65
|
-
"error": "
|
|
66
|
-
"fill": "
|
|
67
|
-
"list": "
|
|
68
|
-
"meta": "
|
|
69
|
-
"modelEnd": "
|
|
70
|
-
"modelMain": "
|
|
71
|
-
"modelRow": "
|
|
72
|
-
"modelStack": "
|
|
73
|
-
"name": "
|
|
74
|
-
"package": "
|
|
75
|
-
"packageLabel": "
|
|
76
|
-
"page": "
|
|
77
|
-
"probeEnd": "
|
|
78
|
-
"probeRow": "
|
|
79
|
-
"prompt": "
|
|
80
|
-
"promptRow": "
|
|
81
|
-
"row": "
|
|
82
|
-
"section": "
|
|
83
|
-
"sectionActions": "
|
|
84
|
-
"statusLine": "
|
|
85
|
-
"summaryRow": "
|
|
86
|
-
"summaryTitle": "
|
|
87
|
-
"text": "
|
|
88
|
-
"title": "
|
|
89
|
-
"toggleHint": "
|
|
90
|
-
"toggleLabel": "
|
|
91
|
-
"toggleRow": "
|
|
92
|
-
"track": "
|
|
60
|
+
"assist": "_8BbhmW_assist",
|
|
61
|
+
"badges": "_8BbhmW_badges",
|
|
62
|
+
"body": "_8BbhmW_body",
|
|
63
|
+
"cards": "_8BbhmW_cards",
|
|
64
|
+
"dim": "_8BbhmW_dim",
|
|
65
|
+
"error": "_8BbhmW_error",
|
|
66
|
+
"fill": "_8BbhmW_fill",
|
|
67
|
+
"list": "_8BbhmW_list",
|
|
68
|
+
"meta": "_8BbhmW_meta",
|
|
69
|
+
"modelEnd": "_8BbhmW_modelEnd",
|
|
70
|
+
"modelMain": "_8BbhmW_modelMain",
|
|
71
|
+
"modelRow": "_8BbhmW_modelRow",
|
|
72
|
+
"modelStack": "_8BbhmW_modelStack",
|
|
73
|
+
"name": "_8BbhmW_name",
|
|
74
|
+
"package": "_8BbhmW_package",
|
|
75
|
+
"packageLabel": "_8BbhmW_packageLabel",
|
|
76
|
+
"page": "_8BbhmW_page",
|
|
77
|
+
"probeEnd": "_8BbhmW_probeEnd",
|
|
78
|
+
"probeRow": "_8BbhmW_probeRow",
|
|
79
|
+
"prompt": "_8BbhmW_prompt",
|
|
80
|
+
"promptRow": "_8BbhmW_promptRow",
|
|
81
|
+
"row": "_8BbhmW_row",
|
|
82
|
+
"section": "_8BbhmW_section",
|
|
83
|
+
"sectionActions": "_8BbhmW_sectionActions",
|
|
84
|
+
"statusLine": "_8BbhmW_statusLine",
|
|
85
|
+
"summaryRow": "_8BbhmW_summaryRow",
|
|
86
|
+
"summaryTitle": "_8BbhmW_summaryTitle",
|
|
87
|
+
"text": "_8BbhmW_text",
|
|
88
|
+
"title": "_8BbhmW_title",
|
|
89
|
+
"toggleHint": "_8BbhmW_toggleHint",
|
|
90
|
+
"toggleLabel": "_8BbhmW_toggleLabel",
|
|
91
|
+
"toggleRow": "_8BbhmW_toggleRow",
|
|
92
|
+
"track": "_8BbhmW_track"
|
|
93
93
|
};
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region src/client/panels.tsx
|
|
@@ -1278,8 +1278,8 @@ window.__ModuleLoader__.load({
|
|
|
1278
1278
|
});
|
|
1279
1279
|
}
|
|
1280
1280
|
//#endregion
|
|
1281
|
-
//#region \0workbuddy-css
|
|
1282
|
-
const css = ".
|
|
1281
|
+
//#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/probe-control.module.css.js
|
|
1282
|
+
const css = ".EVr7sG_wrapper{align-items:center;display:inline-flex;position:relative}.EVr7sG_trigger{corner-shape:round;cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:999px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.EVr7sG_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.EVr7sG_trigger:disabled{cursor:default;color:var(--dsw-alias-label-dimmed)}.EVr7sG_trigger:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:1px}.EVr7sG_panel{isolation:isolate;z-index:1100;box-sizing:border-box;border-radius:var(--dsw-radius-lg);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:max-content;min-width:min(280px,100vw - 24px);max-width:min(360px,100vw - 24px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-secondary);cursor:default;border:0;padding:12px;font-size:12px;line-height:1.5;position:fixed}.EVr7sG_panel:before{z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);content:\"\";pointer-events:none;position:absolute;inset:0}.EVr7sG_panelTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:13px;font-weight:500;line-height:1.5;display:flex}.EVr7sG_panelTitleIcon{color:var(--dsw-alias-label-secondary);flex:none;align-items:center;display:inline-flex}.EVr7sG_panelTitleText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.EVr7sG_titleRule{border-top:.5px solid var(--dsw-alias-border-l2);margin:8px 0 10px}.EVr7sG_levelsLabel{color:var(--dsw-alias-label-tertiary);margin:0 0 2px;font-size:12px;line-height:1.5}.EVr7sG_levels{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:13px;font-weight:500;line-height:1.5}.EVr7sG_note,.EVr7sG_dim{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.6}.EVr7sG_dim{margin-top:2px}.EVr7sG_panelActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}";
|
|
1283
1283
|
const tagId = "dsh-workbuddy-bridge/probe-control.module.css";
|
|
1284
1284
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1285
1285
|
const tag = document.createElement("style");
|
|
@@ -1289,19 +1289,18 @@ window.__ModuleLoader__.load({
|
|
|
1289
1289
|
document.head.appendChild(tag);
|
|
1290
1290
|
}
|
|
1291
1291
|
var probe_control_module_css_default = {
|
|
1292
|
-
"dim": "
|
|
1293
|
-
"levels": "
|
|
1294
|
-
"levelsLabel": "
|
|
1295
|
-
"note": "
|
|
1296
|
-
"panel": "
|
|
1297
|
-
"panelActions": "
|
|
1298
|
-
"panelTitle": "
|
|
1299
|
-
"panelTitleIcon": "
|
|
1300
|
-
"panelTitleText": "
|
|
1301
|
-
"titleRule": "
|
|
1302
|
-
"trigger": "
|
|
1303
|
-
"
|
|
1304
|
-
"wrapper": "Ivd5xG_wrapper"
|
|
1292
|
+
"dim": "EVr7sG_dim",
|
|
1293
|
+
"levels": "EVr7sG_levels",
|
|
1294
|
+
"levelsLabel": "EVr7sG_levelsLabel",
|
|
1295
|
+
"note": "EVr7sG_note",
|
|
1296
|
+
"panel": "EVr7sG_panel",
|
|
1297
|
+
"panelActions": "EVr7sG_panelActions",
|
|
1298
|
+
"panelTitle": "EVr7sG_panelTitle",
|
|
1299
|
+
"panelTitleIcon": "EVr7sG_panelTitleIcon",
|
|
1300
|
+
"panelTitleText": "EVr7sG_panelTitleText",
|
|
1301
|
+
"titleRule": "EVr7sG_titleRule",
|
|
1302
|
+
"trigger": "EVr7sG_trigger",
|
|
1303
|
+
"wrapper": "EVr7sG_wrapper"
|
|
1305
1304
|
};
|
|
1306
1305
|
//#endregion
|
|
1307
1306
|
//#region src/client/probe-control.tsx
|
|
@@ -1533,6 +1532,7 @@ window.__ModuleLoader__.load({
|
|
|
1533
1532
|
const shown = fresh ?? result;
|
|
1534
1533
|
const levels = levelsLine(shown);
|
|
1535
1534
|
const notValidating = shown?.validation === "non-validating";
|
|
1535
|
+
const lit = shown !== void 0;
|
|
1536
1536
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1537
1537
|
className: probe_control_module_css_default.wrapper,
|
|
1538
1538
|
ref: rootRef,
|
|
@@ -1551,7 +1551,7 @@ window.__ModuleLoader__.load({
|
|
|
1551
1551
|
onClick: () => {
|
|
1552
1552
|
setOpen(!open);
|
|
1553
1553
|
},
|
|
1554
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeIcon, {})
|
|
1554
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeIcon, { lit })
|
|
1555
1555
|
})
|
|
1556
1556
|
}), open ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1557
1557
|
ref: panelRef,
|
|
@@ -1564,7 +1564,7 @@ window.__ModuleLoader__.load({
|
|
|
1564
1564
|
className: probe_control_module_css_default.panelTitle,
|
|
1565
1565
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1566
1566
|
className: probe_control_module_css_default.panelTitleIcon,
|
|
1567
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeIcon, {})
|
|
1567
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeIcon, { lit })
|
|
1568
1568
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1569
1569
|
className: probe_control_module_css_default.panelTitleText,
|
|
1570
1570
|
children: model
|
|
@@ -1612,21 +1612,49 @@ window.__ModuleLoader__.load({
|
|
|
1612
1612
|
}), document.body) : null]
|
|
1613
1613
|
});
|
|
1614
1614
|
}
|
|
1615
|
+
/** The bulb's body — the maintainer's artwork, one filled path with the base cut out. */
|
|
1616
|
+
const BULB_BODY = "M496 64C681.6 64 832 208.896 832 387.648c0 124.544-73.152 232.704-180.352 286.784v24.256c0 6.912-0.64 13.76-1.856 20.288a56.32 56.32 0 0 1 20.672 20.416 54.848 54.848 0 0 1 7.552 27.712v37.312c0 29.312-23.04 53.312-52.288 55.808l-2.816 0.192h-23.04c0 54.976-46.336 99.584-103.424 99.584-57.024 0-103.296-44.544-103.296-99.584h-19.776l-2.24-0.128h-3.84a58.24 58.24 0 0 1-36.48-18.432 55.808 55.808 0 0 1-14.72-37.44v-37.312c0-20.16 11.008-37.888 27.328-47.744a104.064 104.064 0 0 1-1.984-20.672v-23.744C233.6 621.056 160 512.576 160 387.584 160.064 208.96 310.4 64 496 64z m-45.632 796.288c0 24.064 20.48 43.712 46.08 43.712 25.728 0 46.144-19.712 46.208-43.52v-0.192H450.368z m-76.992-56h247.296l0.064-37.056-0.512-0.32H373.632l-0.256 37.376zM496 120.064c-154.112 0-278.656 120-278.656 267.52 0 100.8 58.624 191.68 150.208 237.44l31.104 15.68 0.064 50.56c0 3.968 0.384 7.552 0.896 10.816l0.576 1.984H467.84V704h70.4v-0.128l55.488-0.32 0.512-1.472c0.64-3.776 0.96-7.552 0.96-11.328l-0.96-50.56 31.04-15.616c91.2-45.952 149.312-136.576 149.312-236.992 0-147.584-124.544-267.648-278.656-267.648v0.128z";
|
|
1617
|
+
/** The bolt drawn inside the bulb once a detection has landed. */
|
|
1618
|
+
const BULB_BOLT = "M465.536 443.264H396.8c-8.96 0-15.168-8.192-11.968-15.872l68.288-163.84a11.904 11.904 0 0 1 4.672-5.504A13.632 13.632 0 0 1 465.024 256h115.2c9.088 0 15.36 8.448 11.904 16.128L552.32 361.344H627.2c11.008 0 16.832 11.84 9.6 19.456L453.376 571.968c-8.96 9.28-25.472 1.28-22.016-10.752l34.176-117.952z";
|
|
1615
1619
|
/**
|
|
1616
|
-
* The control's icon
|
|
1620
|
+
* The control's icon: a light bulb, and the same bulb lit once a detection landed.
|
|
1617
1621
|
*
|
|
1618
|
-
*
|
|
1619
|
-
*
|
|
1620
|
-
*
|
|
1621
|
-
* land in the same visual language — anything original reads as foreign beside
|
|
1622
|
-
* the model picker it sits next to.
|
|
1622
|
+
* Two states carry the whole story without a word:
|
|
1623
|
+
* - **bulb** — nothing verified yet; this is the model whose levels are still unknown.
|
|
1624
|
+
* - **bulb with the bolt** — a recorded result says which levels this model accepts.
|
|
1623
1625
|
*
|
|
1624
|
-
*
|
|
1625
|
-
*
|
|
1626
|
-
*
|
|
1626
|
+
* That is why the bolt is a second path rather than decoration: the trigger has to answer
|
|
1627
|
+
* "is this model checked?" at a glance, in 28px, next to the host's model picker — and the
|
|
1628
|
+
* panel that opens from it repeats the same glyph, so trigger, panel and result read as one
|
|
1629
|
+
* object. The artwork is the maintainer's bulb, redrawn on the host's 16-unit grid: ink spans
|
|
1630
|
+
* 2..14 vertically and 3.5..12.5 horizontally (the host's own icons keep a 6–9 inset), filled
|
|
1631
|
+
* with `currentColor` so both themes come from the button's colour alone — no literal colour,
|
|
1632
|
+
* no `[data-ds-dark-theme]` selector.
|
|
1633
|
+
*
|
|
1634
|
+
* The bolt appears only for a **successful** detection (`lit`), never while a run is in
|
|
1635
|
+
* flight and never for a failure: a spinner-shaped claim would be answered by the tooltip,
|
|
1636
|
+
* which already says exactly what happened.
|
|
1627
1637
|
*/
|
|
1628
|
-
function ProbeIcon() {
|
|
1629
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1638
|
+
function ProbeIcon({ lit }) {
|
|
1639
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
1640
|
+
width: "16",
|
|
1641
|
+
height: "16",
|
|
1642
|
+
viewBox: "0 0 16 16",
|
|
1643
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1644
|
+
"aria-hidden": "true",
|
|
1645
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
1646
|
+
transform: "translate(1.35714 1.14286) scale(0.01339286)",
|
|
1647
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1648
|
+
d: BULB_BODY,
|
|
1649
|
+
fill: "currentColor",
|
|
1650
|
+
fillRule: "evenodd"
|
|
1651
|
+
}), lit ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1652
|
+
d: BULB_BOLT,
|
|
1653
|
+
fill: "currentColor",
|
|
1654
|
+
fillRule: "evenodd"
|
|
1655
|
+
}) : null]
|
|
1656
|
+
})
|
|
1657
|
+
});
|
|
1630
1658
|
}
|
|
1631
1659
|
//#endregion
|
|
1632
1660
|
//#region src/client/config-controller.ts
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as normalizeCredits, B as FALLBACK_CN_APP_VERSION, C as desktopAuthCandidatesFor, D as cnAppDiscovery, E as WorkBuddyAtRestKeyProvider, F as PROBE_EFFORT_CANDIDATES, G as validCliVersion, H as fallbackChatIdentity, I as probeModel, J as installedAppVersion, K as WORKBUDDY_APP_VERSION_FILENAME, L as randomSentinel, M as prepareChatBody, N as prepareInternationalChatBody, O as WorkBuddyUpstreamClient, P as regionOf, R as classifyUpstreamError, S as defaultDesktopAuthPath, T as workbuddyOwnAuthPath, U as readCliVersion, V as chatUserAgent, W as resolveChatIdentity, X as resolveAppVersion, Y as readBundleVersion, Z as validAppVersion, _ as WorkBuddyCatalog, a as WORKBUDDY_HOST_HEARTBEAT_FILENAME, b as WorkBuddyCredentialStore, c as processStartTimeMs, d as writeHostHeartbeat, f as WORKBUDDY_BRIDGE_VERSION, g as FALLBACK_WORKBUDDY_MODELS, h as FALLBACK_WORKBUDDY_AI_MODELS, i as variantFor, j as parseModelCatalog, k as modelWithCurrentPromotion, l as readHostHeartbeat, n as CN_VARIANT, o as clearHostHeartbeat, q as appUserAgent, r as WORKBUDDY_VARIANTS, s as isHeartbeatProcessAlive, t as AI_VARIANT, u as workbuddyHostHeartbeatPath, v as WORKBUDDY_AUTH_FILENAME, w as parseWorkBuddyAuth, x as defaultDesktopAuthCandidates, y as WORKBUDDY_AUTH_FILE_ENV, z as CN_APP_VERSION_FILENAME } from "./variants-
|
|
1
|
+
import { A as normalizeCredits, B as FALLBACK_CN_APP_VERSION, C as desktopAuthCandidatesFor, D as cnAppDiscovery, E as WorkBuddyAtRestKeyProvider, F as PROBE_EFFORT_CANDIDATES, G as validCliVersion, H as fallbackChatIdentity, I as probeModel, J as installedAppVersion, K as WORKBUDDY_APP_VERSION_FILENAME, L as randomSentinel, M as prepareChatBody, N as prepareInternationalChatBody, O as WorkBuddyUpstreamClient, P as regionOf, R as classifyUpstreamError, S as defaultDesktopAuthPath, T as workbuddyOwnAuthPath, U as readCliVersion, V as chatUserAgent, W as resolveChatIdentity, X as resolveAppVersion, Y as readBundleVersion, Z as validAppVersion, _ as WorkBuddyCatalog, a as WORKBUDDY_HOST_HEARTBEAT_FILENAME, b as WorkBuddyCredentialStore, c as processStartTimeMs, d as writeHostHeartbeat, f as WORKBUDDY_BRIDGE_VERSION, g as FALLBACK_WORKBUDDY_MODELS, h as FALLBACK_WORKBUDDY_AI_MODELS, i as variantFor, j as parseModelCatalog, k as modelWithCurrentPromotion, l as readHostHeartbeat, n as CN_VARIANT, o as clearHostHeartbeat, q as appUserAgent, r as WORKBUDDY_VARIANTS, s as isHeartbeatProcessAlive, t as AI_VARIANT, u as workbuddyHostHeartbeatPath, v as WORKBUDDY_AUTH_FILENAME, w as parseWorkBuddyAuth, x as defaultDesktopAuthCandidates, y as WORKBUDDY_AUTH_FILE_ENV, z as CN_APP_VERSION_FILENAME } from "./variants-DP0Ho0Tc.js";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
|
|
@@ -3579,7 +3579,7 @@ const WORKBUDDY_AI_STATUS_PATH = "/plugins/dsh-workbuddy-bridge/ai/status";
|
|
|
3579
3579
|
const WORKBUDDY_AI_PROBE_PATH = "/plugins/dsh-workbuddy-bridge/ai/probe";
|
|
3580
3580
|
//#endregion
|
|
3581
3581
|
//#region src/version.ts
|
|
3582
|
-
const WORKBUDDY_BRIDGE_VERSION = "0.
|
|
3582
|
+
const WORKBUDDY_BRIDGE_VERSION = "0.2.0";
|
|
3583
3583
|
//#endregion
|
|
3584
3584
|
//#region src/web/heartbeat.ts
|
|
3585
3585
|
/**
|
package/package.json
CHANGED
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
"name": "dsh-workbuddy-bridge",
|
|
3
3
|
"displayName": "DSH WorkBuddy Bridge",
|
|
4
4
|
"description": "将 WorkBuddy 桌面 App 包含的模型自动接入 DeepSeek Harness — bring WorkBuddy desktop app models into DeepSeek Harness with zero configuration.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.2.0",
|
|
6
6
|
"author": "zlZayn",
|
|
7
|
-
"keywords": [
|
|
7
|
+
"keywords": [
|
|
8
|
+
"dsh",
|
|
9
|
+
"deepseek-harness",
|
|
10
|
+
"dsh-plugin",
|
|
11
|
+
"workbuddy",
|
|
12
|
+
"models",
|
|
13
|
+
"llm",
|
|
14
|
+
"bridge"
|
|
15
|
+
],
|
|
8
16
|
"type": "module",
|
|
9
17
|
"engines": {
|
|
10
18
|
"node": "^22.19.0 || >=24.0.0",
|
|
@@ -16,14 +24,6 @@
|
|
|
16
24
|
"bin": {
|
|
17
25
|
"dsh-workbuddy-bridge": "lib/bin.js"
|
|
18
26
|
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"prepack": "node node_modules/tsdown/dist/run.mjs",
|
|
21
|
-
"build": "tsdown",
|
|
22
|
-
"test": "vitest run",
|
|
23
|
-
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
24
|
-
"check:release": "node scripts/check-release.mjs",
|
|
25
|
-
"check": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
26
|
-
},
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|
|
29
29
|
"types": "./lib/types/index.d.ts",
|
|
@@ -151,5 +151,12 @@
|
|
|
151
151
|
"unrun": "^0.3.1",
|
|
152
152
|
"vitest": "^4.1.8",
|
|
153
153
|
"zustand": "^5.0.15"
|
|
154
|
+
},
|
|
155
|
+
"scripts": {
|
|
156
|
+
"build": "tsdown",
|
|
157
|
+
"test": "vitest run",
|
|
158
|
+
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
159
|
+
"check:release": "node scripts/check-release.mjs",
|
|
160
|
+
"check": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
154
161
|
}
|
|
155
|
-
}
|
|
162
|
+
}
|