dsh-workbuddy-bridge 0.4.0 → 0.5.1

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/NOTICE CHANGED
@@ -12,4 +12,4 @@
12
12
  ## 本仓维护者
13
13
 
14
14
  - Copyright (c) 2026 zlZayn
15
- - 仓库:<https://github.com/zlZayn/dsh-workbuddy-bridge>
15
+ - 仓库:<https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge>
package/README.md CHANGED
@@ -9,14 +9,18 @@
9
9
  <p><em>WorkBuddy desktop models in DeepSeek Harness</em></p>
10
10
 
11
11
  <p>
12
+ <a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat&logo=deepseek&logoColor=white" alt="由 dsh 驱动"></a>
13
+ </p>
14
+
15
+ <p>
16
+ <a href="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/actions/workflows/ci.yml"><img src="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
12
17
  <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>
13
- <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>
14
- <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>
15
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT 许可证"></a>
18
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat" alt="MIT 许可证"></a>
19
+ <a href="https://www.npmjs.com/package/dsh-workbuddy-bridge"><img src="https://img.shields.io/badge/SLSA-Build%20L2-green?logo=slsa&style=flat" alt="SLSA Build L2"></a>
16
20
  </p>
17
21
 
18
22
  <p>
19
- 各版本改动 → <a href="https://github.com/zlZayn/dsh-workbuddy-bridge/releases">Releases</a>(与 npm 版本一一对应)
23
+ 各版本改动 → <a href="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/releases">Releases</a>(与 npm 版本一一对应)
20
24
  </p>
21
25
 
22
26
  <p>
@@ -36,17 +40,18 @@
36
40
  <p align="center">
37
41
  <img src="assets/model-picker.png" alt="WorkBuddy 模型出现在 DSH 模型选择器中" width="300">
38
42
  <br>
39
- <em>国内版在模型选择器中自成一组,模型名后直接跟积分倍率与促销徽章;装国际版则出现「WorkBuddy AI」组。</em>
43
+ <em>中文界面截图:国内版在模型选择器中自成一组,模型名后直接跟积分倍率与促销徽章;装国际版则出现「WorkBuddy AI」组。</em>
40
44
  </p>
41
45
 
42
46
  ## 能力
43
47
 
44
48
  - **开箱即用** —— 装完启用,模型分组自己出现。
45
49
  - **两版隔离** —— 国内版与国际版各自分组,模型、账号、积分互不混用,只跟随各自 App 的登录状态。
46
- - **推理档位** —— 上游声明了档位的模型直接可选;没声明的可在插件页**手动检测**。
47
50
  - **推理档位** —— 上游声明了档位的模型直接可选;没声明的可在插件页**手动检测**。
48
51
  灯泡表示能切档位;上游已声明的模型也亮着,只是不需要检测。
49
52
  能切档位的模型会带一个**默认档位**(上游声明了就按声明,否则取 `high`),因此选择器里不再出现「Default」这一项。
53
+ 档位里的 **Off 表示「不发送档位参数」**:两个接口都不接受这个字面量,所以插件不会把它发出去;
54
+ 实际是否关闭思考由上游决定,插件不做保证。
50
55
  - **积分可见** —— 每条回复下方显示本次消耗,模型选择器旁常驻剩余积分。拿不到数字时不显示。
51
56
  - **模型显隐** —— 卡片「模型」标签里勾选哪些模型出现在选择器里,按登录账号分别保存。
52
57
  - **图片输入** —— 多数模型可直接粘贴或拖入图片;纯文字模型会明确说明。
@@ -55,13 +60,13 @@
55
60
  <p align="center">
56
61
  <img src="assets/composer-row.png" alt="输入区那一行:币图标与余额、推理档位灯泡、模型名,从左到右一行" width="560">
57
62
  <br>
58
- <em>对话窗口里每天看到的样子:币图标与余额、推理档位灯泡,再往右是模型名——都排在同一行。</em>
63
+ <em>中文界面截图:对话窗口里每天看到的样子:币图标与余额、推理档位灯泡,再往右是模型名——都排在同一行。</em>
59
64
  </p>
60
65
 
61
66
  <p align="center">
62
67
  <img src="assets/plugin-page.png" alt="插件详情页:配置表单与两张状态卡片" width="480">
63
68
  <br>
64
- <em>插件页:上面是配置表单,下面两张卡片各跟随自己 App 的登录状态。</em>
69
+ <em>中文界面截图:插件页:上面是配置表单,下面两张卡片各跟随自己 App 的登录状态。</em>
65
70
  </p>
66
71
 
67
72
  ## 安装
@@ -79,7 +84,7 @@ Desktop 与 TUI 把 `--profile web` 换成 `desktop` / `dsh-tui`(TUI 需较新
79
84
  也可以从源码安装:
80
85
 
81
86
  ```sh
82
- git clone https://github.com/zlZayn/dsh-workbuddy-bridge.git
87
+ git clone https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge.git
83
88
  cd dsh-workbuddy-bridge
84
89
  pnpm install && pnpm build
85
90
  dsh plugin --profile web add "$PWD"
@@ -98,14 +103,14 @@ dsh plugin --profile web add "$PWD"
98
103
  <p align="center">
99
104
  <img src="assets/models-tab.png" alt="模型标签:显隐、窗口、倍率" width="480">
100
105
  <br>
101
- <em>「模型」标签:勾选哪些模型出现在选择器里,同时看窗口与倍率。</em>
106
+ <em>中文界面截图:「模型」标签:勾选哪些模型出现在选择器里,同时看窗口与倍率。</em>
102
107
  </p>
103
108
 
104
109
  <p align="center">
105
110
  <img src="assets/detection-tab.png" alt="检测标签:每个推理模型一行" width="300">
106
111
  <img src="assets/credits-tab.png" alt="积分标签:总余额与各套餐余量条" width="300">
107
112
  <br>
108
- <em>左「检测」:每个推理模型一行,点按钮确认它接受哪些推理档位;右「积分」:总余额,下面是各套餐的余量条。</em>
113
+ <em>中文界面截图:左「检测」:每个推理模型一行,点按钮确认它接受哪些推理档位;右「积分」:总余额,下面是各套餐的余量条。</em>
109
114
  </p>
110
115
 
111
116
  ## 为什么是手动检测
@@ -118,7 +123,7 @@ WorkBuddy 接口不保证档位信息可靠——有的模型**接受** `reasoni
118
123
  <p align="center">
119
124
  <img src="assets/reasoning-levels-declared.png" alt="推理档位控件:上游已声明档位、检测按钮禁用" width="300">
120
125
  <br>
121
- <em>已声明档位的模型:灯泡点亮、档位直接可选,检测按钮禁用。</em>
126
+ <em>中文界面截图:已声明档位的模型:灯泡点亮、档位直接可选,检测按钮禁用。</em>
122
127
  </p>
123
128
 
124
129
  ## 兼容与限制
@@ -146,4 +151,4 @@ WorkBuddy 接口不保证档位信息可靠——有的模型**接受** `reasoni
146
151
 
147
152
  ## 贡献
148
153
 
149
- 流程与本地钩子 → [CONTRIBUTING.md](CONTRIBUTING.md)。缺陷与需求走仓库 Issues。
154
+ 缺陷与需求走仓库 Issues。
package/README_en.md CHANGED
@@ -9,14 +9,18 @@
9
9
  <p><em>把 WorkBuddy 桌面 App 的模型接进 DSH 对话窗口</em></p>
10
10
 
11
11
  <p>
12
+ <a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat&logo=deepseek&logoColor=white" alt="powered by dsh"></a>
13
+ </p>
14
+
15
+ <p>
16
+ <a href="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/actions/workflows/ci.yml"><img src="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
12
17
  <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>
13
- <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>
14
- <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>
15
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
18
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat" alt="MIT License"></a>
19
+ <a href="https://www.npmjs.com/package/dsh-workbuddy-bridge"><img src="https://img.shields.io/badge/SLSA-Build%20L2-green?logo=slsa&style=flat" alt="SLSA Build L2"></a>
16
20
  </p>
17
21
 
18
22
  <p>
19
- Per-version changes → <a href="https://github.com/zlZayn/dsh-workbuddy-bridge/releases">Releases</a> (one-to-one with npm versions)
23
+ Per-version changes → <a href="https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/releases">Releases</a> (one-to-one with npm versions)
20
24
  </p>
21
25
 
22
26
  <p>
@@ -37,7 +41,7 @@ models appear directly in the DSH model picker — no separate provider to confi
37
41
  <p align="center">
38
42
  <img src="assets/model-picker.png" alt="WorkBuddy models in the DSH model picker" width="300">
39
43
  <br>
40
- <em>The CN version forms its own group in the model picker, each model carrying its credit rate and promo
44
+ <em>Chinese UI screenshot: The CN version forms its own group in the model picker, each model carrying its credit rate and promo
41
45
  badge; installing the international version adds a "WorkBuddy AI" group the same way.</em>
42
46
  </p>
43
47
 
@@ -50,6 +54,8 @@ models appear directly in the DSH model picker — no separate provider to confi
50
54
  on the plugin page. The bulb means "this model can switch levels"; a declared model shows it too, it just
51
55
  has nothing to detect. A switchable model also carries a **default level** (the upstream's own declaration
52
56
  when it has one, otherwise `high`), so the picker no longer offers "Default".
57
+ **Off means "send no level parameter"**: neither endpoint accepts that literal, so the plugin never puts it
58
+ on the wire — whether thinking is then actually disabled is up to the upstream, and the plugin makes no claim.
53
59
  - **Credit in view** — each reply shows what it consumed, and remaining credit sits beside the model picker.
54
60
  Nothing renders when a figure is unavailable.
55
61
  - **Model visibility** — tick which models appear in the picker on the card's "Models" tab, saved per
@@ -60,14 +66,14 @@ models appear directly in the DSH model picker — no separate provider to confi
60
66
  <p align="center">
61
67
  <img src="assets/composer-row.png" alt="The composer row: the coin and balance, the reasoning-level bulb and the model name in one line" width="560">
62
68
  <br>
63
- <em>The everyday view in the conversation window: the coin and its balance, the reasoning-level bulb, then the
69
+ <em>Chinese UI screenshot: The everyday view in the conversation window: the coin and its balance, the reasoning-level bulb, then the
64
70
  model name — one row, left to right.</em>
65
71
  </p>
66
72
 
67
73
  <p align="center">
68
74
  <img src="assets/plugin-page.png" alt="Plugin detail page: the configuration form and the two status cards" width="480">
69
75
  <br>
70
- <em>The plugin page: the configuration form on top, two cards below, each following its own app's sign-in.</em>
76
+ <em>Chinese UI screenshot: The plugin page: the configuration form on top, two cards below, each following its own app's sign-in.</em>
71
77
  </p>
72
78
 
73
79
  ## Install
@@ -86,7 +92,7 @@ the terminal plugin `@deepseek-harness-tui/dsh-tui` — see its docs).
86
92
  Or from source:
87
93
 
88
94
  ```sh
89
- git clone https://github.com/zlZayn/dsh-workbuddy-bridge.git
95
+ git clone https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge.git
90
96
  cd dsh-workbuddy-bridge
91
97
  pnpm install && pnpm build
92
98
  dsh plugin --profile web add "$PWD"
@@ -107,14 +113,14 @@ the description and takes effect on save:
107
113
  <p align="center">
108
114
  <img src="assets/models-tab.png" alt="Models tab: visibility, windows, rates" width="480">
109
115
  <br>
110
- <em>The Models tab: tick which models appear in the picker, and read each one's window and rate.</em>
116
+ <em>Chinese UI screenshot: The Models tab: tick which models appear in the picker, and read each one's window and rate.</em>
111
117
  </p>
112
118
 
113
119
  <p align="center">
114
120
  <img src="assets/detection-tab.png" alt="Detection tab: one row per reasoning model" width="300">
115
121
  <img src="assets/credits-tab.png" alt="Credits tab: the total balance and per-package allowances" width="300">
116
122
  <br>
117
- <em>Left, "Detection": one row per reasoning model — press the button to confirm which reasoning levels it
123
+ <em>Chinese UI screenshots: Left, "Detection": one row per reasoning model — press the button to confirm which reasoning levels it
118
124
  accepts. Right, "Credits": the total balance, each package's allowance as a row below.</em>
119
125
  </p>
120
126
 
@@ -130,7 +136,7 @@ Mechanism and trade-offs in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
130
136
  <p align="center">
131
137
  <img src="assets/reasoning-levels-declared.png" alt="The reasoning-level control: levels declared upstream, detect disabled" width="300">
132
138
  <br>
133
- <em>A model with declared levels: the bulb is lit, the levels are directly selectable, and detection is disabled.</em>
139
+ <em>Chinese UI screenshot: A model with declared levels: the bulb is lit, the levels are directly selectable, and detection is disabled.</em>
134
140
  </p>
135
141
 
136
142
  ## Compatibility and limits
@@ -161,4 +167,4 @@ maintainer map → [AGENTS.md](AGENTS.md).
161
167
 
162
168
  ## Contributing
163
169
 
164
- Process and local hooks → [CONTRIBUTING.md](CONTRIBUTING.md). Bugs and requests go to the repo Issues.
170
+ Bugs and requests go to the repo Issues.
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as variantFor, D as WorkBuddyUpstreamClient, S as WORKBUDDY_VARIANTS, Y as resolveAppVersion, a as readHostHeartbeat, c as WORKBUDDY_BRIDGE_VERSION, l as FALLBACK_WORKBUDDY_AI_MODELS, m as WorkBuddyCredentialStore, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, x as CN_VARIANT } from "./heartbeat-CP6YM98x.js";
2
+ import { C as variantFor, D as WorkBuddyUpstreamClient, S as WORKBUDDY_VARIANTS, Y as resolveAppVersion, a as readHostHeartbeat, c as WORKBUDDY_BRIDGE_VERSION, l as FALLBACK_WORKBUDDY_AI_MODELS, m as WorkBuddyCredentialStore, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, x as CN_VARIANT } from "./heartbeat-DR6QsZ9h.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
@@ -55,8 +55,8 @@ window.__ModuleLoader__.load({
55
55
  return credit.toFixed(2).replace(/\.?0+$/u, "");
56
56
  }
57
57
  //#endregion
58
- //#region \0workbuddy-css:D:\ProjectSomething\dsh-plugins\dsh-workbuddy-bridge\src\client\workbuddy.module.css.js
59
- const css$4 = "._1kHyqG_page,._1kHyqG_cards{flex-direction:column;gap:12px;display:flex}._1kHyqG_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}._1kHyqG_toggleLabel{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}._1kHyqG_toggleHint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}._1kHyqG_body{flex-direction:column;gap:12px;padding:4px 0 12px;display:flex}._1kHyqG_section{flex-direction:column;display:flex}._1kHyqG_section>*+*{margin-top:12px}._1kHyqG_cardActions{align-items:center;gap:8px;display:flex}._1kHyqG_field{flex-direction:column;gap:6px;display:flex}._1kHyqG_head{align-items:center;gap:8px;display:flex}._1kHyqG_main{flex-wrap:wrap;flex:1;align-items:baseline;gap:8px;min-width:0;display:flex}._1kHyqG_action{flex:none;align-items:center;gap:8px;display:inline-flex}._1kHyqG_note{flex-wrap:wrap;align-items:baseline;gap:8px;min-width:0;display:flex}._1kHyqG_part{flex-wrap:wrap;align-items:baseline;gap:8px;min-width:0;font-size:13px;line-height:1.5;display:inline-flex}._1kHyqG_caption{color:var(--dsw-alias-label-tertiary)}._1kHyqG_figure{min-width:0;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;align-items:baseline;gap:6px;font-weight:500;display:inline-flex}._1kHyqG_sectionActions{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;gap:8px;padding-top:10px;display:flex}._1kHyqG_title{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:500;line-height:1.5}._1kHyqG_summaryRow{flex-wrap:wrap;gap:4px;height:auto;min-height:28px}._1kHyqG_summaryTitle{flex:1;min-width:0}._1kHyqG_statusLine{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;font-size:12px;line-height:1.5;display:inline-flex}._1kHyqG_text{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}._1kHyqG_dim{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}._1kHyqG_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:1.5}._1kHyqG_package{flex-direction:column;gap:8px;padding:8px 0;display:flex}._1kHyqG_package+._1kHyqG_package{border-top:.5px solid var(--dsw-alias-border-l2)}._1kHyqG_packageLabel{justify-content:space-between;align-items:baseline;gap:8px;font-size:13px;line-height:1.5;display:flex}._1kHyqG_track{corner-shape:round;background:var(--dsw-alias-border-l3);border-radius:999px;height:8px;overflow:hidden}._1kHyqG_fill{border-radius:inherit;background:var(--dsw-alias-brand-primary);height:100%}._1kHyqG_panel{flex-direction:column;gap:12px;height:380px;display:flex}._1kHyqG_panel>*{flex:none}._1kHyqG_list{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;gap:0;min-width:0;margin:0;padding:6px 14px;display:grid;overflow:auto}._1kHyqG_panel>._1kHyqG_list{flex:auto;min-height:0}._1kHyqG_listHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin:0;padding:6px 0 8px;font-size:12px;line-height:1.5}._1kHyqG_modelRow{justify-content:space-between;align-items:center;gap:8px;padding:8px 0;display:flex}._1kHyqG_modelRow+._1kHyqG_modelRow{border-top:.5px solid var(--dsw-alias-border-l2)}._1kHyqG_modelMain{align-items:center;gap:8px;min-width:0;display:flex}._1kHyqG_modelCheck{font-size:13px;line-height:1.5}._1kHyqG_modelStack{flex-direction:column;gap:2px;min-width:0;display:flex}._1kHyqG_name{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5}._1kHyqG_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}._1kHyqG_meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}._1kHyqG_badges{flex-wrap:wrap;align-items:center;gap:6px;display:flex}._1kHyqG_probeRow{justify-content:space-between;align-items:center;gap:8px;padding:8px 0;display:flex}._1kHyqG_modelStack+._1kHyqG_modelStack{border-top:.5px solid var(--dsw-alias-border-l2)}._1kHyqG_probeEnd{flex:none;align-items:center;gap:8px;display:inline-flex}._1kHyqG_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}._1kHyqG_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}._1kHyqG_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}";
58
+ //#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/workbuddy.module.css.js
59
+ const css$4 = "._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;gap:12px;padding:4px 0 12px;display:flex}._8BbhmW_section{flex-direction:column;display:flex}._8BbhmW_section>*+*{margin-top:12px}._8BbhmW_cardActions{align-items:center;gap:8px;display:flex}._8BbhmW_field{flex-direction:column;gap:6px;display:flex}._8BbhmW_head{align-items:center;gap:8px;display:flex}._8BbhmW_main{flex-wrap:wrap;flex:1;align-items:baseline;gap:8px;min-width:0;display:flex}._8BbhmW_action{flex:none;align-items:center;gap:8px;display:inline-flex}._8BbhmW_note{flex-wrap:wrap;align-items:baseline;gap:8px;min-width:0;display:flex}._8BbhmW_part{flex-wrap:wrap;align-items:baseline;gap:8px;min-width:0;font-size:13px;line-height:1.5;display:inline-flex}._8BbhmW_caption{color:var(--dsw-alias-label-tertiary)}._8BbhmW_figure{min-width:0;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;align-items:baseline;gap:6px;font-weight:500;display:inline-flex}._8BbhmW_sectionActions{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;gap:8px;padding-top:10px;display:flex}._8BbhmW_title{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:500;line-height:1.5}._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;padding:8px 0;display:flex}._8BbhmW_package+._8BbhmW_package{border-top:.5px solid var(--dsw-alias-border-l2)}._8BbhmW_packageLabel{justify-content:space-between;align-items:baseline;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_panel{flex-direction:column;gap:12px;height:380px;display:flex}._8BbhmW_panel>*{flex:none}._8BbhmW_list{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;gap:0;min-width:0;margin:0;padding:6px 14px;display:grid;overflow:auto}._8BbhmW_panel>._8BbhmW_list{flex:auto;min-height:0}._8BbhmW_listHeader{border-bottom:.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin:0;padding:6px 0 8px;font-size:12px;line-height:1.5}._8BbhmW_modelRow{justify-content:space-between;align-items:center;gap:8px;padding:8px 0;display:flex}._8BbhmW_modelRow+._8BbhmW_modelRow{border-top:.5px solid var(--dsw-alias-border-l2)}._8BbhmW_modelMain{align-items:center;gap:8px;min-width:0;display:flex}._8BbhmW_modelCheck{font-size:13px;line-height:1.5}._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_probeRow{justify-content:space-between;align-items:center;gap:8px;padding:8px 0;display:flex}._8BbhmW_modelStack+._8BbhmW_modelStack{border-top:.5px solid var(--dsw-alias-border-l2)}._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}";
60
60
  const tagId$4 = "dsh-workbuddy-bridge/workbuddy.module.css";
61
61
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
62
62
  const tag = document.createElement("style");
@@ -66,50 +66,50 @@ window.__ModuleLoader__.load({
66
66
  document.head.appendChild(tag);
67
67
  }
68
68
  var workbuddy_module_css_default = {
69
- "action": "_1kHyqG_action",
70
- "assist": "_1kHyqG_assist",
71
- "badges": "_1kHyqG_badges",
72
- "body": "_1kHyqG_body",
73
- "caption": "_1kHyqG_caption",
74
- "cardActions": "_1kHyqG_cardActions",
75
- "cards": "_1kHyqG_cards",
76
- "dim": "_1kHyqG_dim",
77
- "error": "_1kHyqG_error",
78
- "field": "_1kHyqG_field",
79
- "figure": "_1kHyqG_figure",
80
- "fill": "_1kHyqG_fill",
81
- "head": "_1kHyqG_head",
82
- "list": "_1kHyqG_list",
83
- "listHeader": "_1kHyqG_listHeader",
84
- "main": "_1kHyqG_main",
85
- "meta": "_1kHyqG_meta",
86
- "modelCheck": "_1kHyqG_modelCheck",
87
- "modelEnd": "_1kHyqG_modelEnd",
88
- "modelMain": "_1kHyqG_modelMain",
89
- "modelRow": "_1kHyqG_modelRow",
90
- "modelStack": "_1kHyqG_modelStack",
91
- "name": "_1kHyqG_name",
92
- "note": "_1kHyqG_note",
93
- "package": "_1kHyqG_package",
94
- "packageLabel": "_1kHyqG_packageLabel",
95
- "page": "_1kHyqG_page",
96
- "panel": "_1kHyqG_panel",
97
- "part": "_1kHyqG_part",
98
- "probeEnd": "_1kHyqG_probeEnd",
99
- "probeRow": "_1kHyqG_probeRow",
100
- "prompt": "_1kHyqG_prompt",
101
- "promptRow": "_1kHyqG_promptRow",
102
- "section": "_1kHyqG_section",
103
- "sectionActions": "_1kHyqG_sectionActions",
104
- "statusLine": "_1kHyqG_statusLine",
105
- "summaryRow": "_1kHyqG_summaryRow",
106
- "summaryTitle": "_1kHyqG_summaryTitle",
107
- "text": "_1kHyqG_text",
108
- "title": "_1kHyqG_title",
109
- "toggleHint": "_1kHyqG_toggleHint",
110
- "toggleLabel": "_1kHyqG_toggleLabel",
111
- "toggleRow": "_1kHyqG_toggleRow",
112
- "track": "_1kHyqG_track"
69
+ "action": "_8BbhmW_action",
70
+ "assist": "_8BbhmW_assist",
71
+ "badges": "_8BbhmW_badges",
72
+ "body": "_8BbhmW_body",
73
+ "caption": "_8BbhmW_caption",
74
+ "cardActions": "_8BbhmW_cardActions",
75
+ "cards": "_8BbhmW_cards",
76
+ "dim": "_8BbhmW_dim",
77
+ "error": "_8BbhmW_error",
78
+ "field": "_8BbhmW_field",
79
+ "figure": "_8BbhmW_figure",
80
+ "fill": "_8BbhmW_fill",
81
+ "head": "_8BbhmW_head",
82
+ "list": "_8BbhmW_list",
83
+ "listHeader": "_8BbhmW_listHeader",
84
+ "main": "_8BbhmW_main",
85
+ "meta": "_8BbhmW_meta",
86
+ "modelCheck": "_8BbhmW_modelCheck",
87
+ "modelEnd": "_8BbhmW_modelEnd",
88
+ "modelMain": "_8BbhmW_modelMain",
89
+ "modelRow": "_8BbhmW_modelRow",
90
+ "modelStack": "_8BbhmW_modelStack",
91
+ "name": "_8BbhmW_name",
92
+ "note": "_8BbhmW_note",
93
+ "package": "_8BbhmW_package",
94
+ "packageLabel": "_8BbhmW_packageLabel",
95
+ "page": "_8BbhmW_page",
96
+ "panel": "_8BbhmW_panel",
97
+ "part": "_8BbhmW_part",
98
+ "probeEnd": "_8BbhmW_probeEnd",
99
+ "probeRow": "_8BbhmW_probeRow",
100
+ "prompt": "_8BbhmW_prompt",
101
+ "promptRow": "_8BbhmW_promptRow",
102
+ "section": "_8BbhmW_section",
103
+ "sectionActions": "_8BbhmW_sectionActions",
104
+ "statusLine": "_8BbhmW_statusLine",
105
+ "summaryRow": "_8BbhmW_summaryRow",
106
+ "summaryTitle": "_8BbhmW_summaryTitle",
107
+ "text": "_8BbhmW_text",
108
+ "title": "_8BbhmW_title",
109
+ "toggleHint": "_8BbhmW_toggleHint",
110
+ "toggleLabel": "_8BbhmW_toggleLabel",
111
+ "toggleRow": "_8BbhmW_toggleRow",
112
+ "track": "_8BbhmW_track"
113
113
  };
114
114
  //#endregion
115
115
  //#region src/client/field.tsx
@@ -663,8 +663,8 @@ window.__ModuleLoader__.load({
663
663
  }
664
664
  };
665
665
  //#endregion
666
- //#region \0workbuddy-css:D:\ProjectSomething\dsh-plugins\dsh-workbuddy-bridge\src\client\coin-glyph.module.css.js
667
- const css$3 = ".sapSKa_glyph{flex:none;align-self:center}";
666
+ //#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/coin-glyph.module.css.js
667
+ const css$3 = ".W7jfGW_glyph{flex:none;align-self:center}";
668
668
  const tagId$3 = "dsh-workbuddy-bridge/coin-glyph.module.css";
669
669
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
670
670
  const tag = document.createElement("style");
@@ -673,7 +673,7 @@ window.__ModuleLoader__.load({
673
673
  tag.textContent = css$3;
674
674
  document.head.appendChild(tag);
675
675
  }
676
- var coin_glyph_module_css_default = { "glyph": "sapSKa_glyph" };
676
+ var coin_glyph_module_css_default = { "glyph": "W7jfGW_glyph" };
677
677
  //#endregion
678
678
  //#region src/client/coin-glyph.tsx
679
679
  /** Render the coin-stack glyph. Decorative: the caller supplies the accessible name. */
@@ -1663,8 +1663,8 @@ window.__ModuleLoader__.load({
1663
1663
  });
1664
1664
  }
1665
1665
  //#endregion
1666
- //#region \0workbuddy-css:D:\ProjectSomething\dsh-plugins\dsh-workbuddy-bridge\src\client\probe-control.module.css.js
1667
- const css$2 = ".Ivd5xG_wrapper{align-items:center;display:inline-flex;position:relative}.Ivd5xG_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}.Ivd5xG_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.Ivd5xG_trigger:disabled{cursor:default;color:var(--dsw-alias-label-dimmed)}.Ivd5xG_trigger:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:1px}.Ivd5xG_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}.Ivd5xG_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}.Ivd5xG_panelTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:13px;font-weight:500;line-height:1.5;display:flex}.Ivd5xG_panelTitleIcon{color:var(--dsw-alias-label-secondary);flex:none;align-items:center;display:inline-flex}.Ivd5xG_panelTitleText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.Ivd5xG_titleRule{border-top:.5px solid var(--dsw-alias-border-l2);margin:8px 0 10px}.Ivd5xG_levelsLabel{color:var(--dsw-alias-label-tertiary);margin:0 0 2px;font-size:12px;line-height:1.5}.Ivd5xG_levels{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:13px;font-weight:500;line-height:1.5}.Ivd5xG_note,.Ivd5xG_dim{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.6}.Ivd5xG_dim{margin-top:2px}.Ivd5xG_panelActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}";
1666
+ //#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/probe-control.module.css.js
1667
+ const css$2 = ".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}";
1668
1668
  const tagId$2 = "dsh-workbuddy-bridge/probe-control.module.css";
1669
1669
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
1670
1670
  const tag = document.createElement("style");
@@ -1674,18 +1674,18 @@ window.__ModuleLoader__.load({
1674
1674
  document.head.appendChild(tag);
1675
1675
  }
1676
1676
  var probe_control_module_css_default = {
1677
- "dim": "Ivd5xG_dim",
1678
- "levels": "Ivd5xG_levels",
1679
- "levelsLabel": "Ivd5xG_levelsLabel",
1680
- "note": "Ivd5xG_note",
1681
- "panel": "Ivd5xG_panel",
1682
- "panelActions": "Ivd5xG_panelActions",
1683
- "panelTitle": "Ivd5xG_panelTitle",
1684
- "panelTitleIcon": "Ivd5xG_panelTitleIcon",
1685
- "panelTitleText": "Ivd5xG_panelTitleText",
1686
- "titleRule": "Ivd5xG_titleRule",
1687
- "trigger": "Ivd5xG_trigger",
1688
- "wrapper": "Ivd5xG_wrapper"
1677
+ "dim": "EVr7sG_dim",
1678
+ "levels": "EVr7sG_levels",
1679
+ "levelsLabel": "EVr7sG_levelsLabel",
1680
+ "note": "EVr7sG_note",
1681
+ "panel": "EVr7sG_panel",
1682
+ "panelActions": "EVr7sG_panelActions",
1683
+ "panelTitle": "EVr7sG_panelTitle",
1684
+ "panelTitleIcon": "EVr7sG_panelTitleIcon",
1685
+ "panelTitleText": "EVr7sG_panelTitleText",
1686
+ "titleRule": "EVr7sG_titleRule",
1687
+ "trigger": "EVr7sG_trigger",
1688
+ "wrapper": "EVr7sG_wrapper"
1689
1689
  };
1690
1690
  //#endregion
1691
1691
  //#region src/client/probe-control.tsx
@@ -2217,8 +2217,8 @@ window.__ModuleLoader__.load({
2217
2217
  return { credits };
2218
2218
  }
2219
2219
  //#endregion
2220
- //#region \0workbuddy-css:D:\ProjectSomething\dsh-plugins\dsh-workbuddy-bridge\src\client\credit-label.module.css.js
2221
- const css$1 = ".VopAXG_label{white-space:nowrap;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);color:var(--dsw-alias-label-tertiary);padding-left:4px;line-height:1}";
2220
+ //#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/credit-label.module.css.js
2221
+ const css$1 = "._9Bx4Wa_label{white-space:nowrap;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);color:var(--dsw-alias-label-tertiary);padding-left:4px;line-height:1}";
2222
2222
  const tagId$1 = "dsh-workbuddy-bridge/credit-label.module.css";
2223
2223
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
2224
2224
  const tag = document.createElement("style");
@@ -2227,7 +2227,7 @@ window.__ModuleLoader__.load({
2227
2227
  tag.textContent = css$1;
2228
2228
  document.head.appendChild(tag);
2229
2229
  }
2230
- var credit_label_module_css_default = { "label": "VopAXG_label" };
2230
+ var credit_label_module_css_default = { "label": "_9Bx4Wa_label" };
2231
2231
  //#endregion
2232
2232
  //#region src/client/credit-label.tsx
2233
2233
  /**
@@ -2275,8 +2275,8 @@ window.__ModuleLoader__.load({
2275
2275
  });
2276
2276
  }
2277
2277
  //#endregion
2278
- //#region \0workbuddy-css:D:\ProjectSomething\dsh-plugins\dsh-workbuddy-bridge\src\client\credit-balance.module.css.js
2279
- const css = ".zUqKXG_readout{white-space:nowrap;height:28px;color:var(--dsw-alias-label-tertiary);align-items:center;gap:4px;display:inline-flex}.zUqKXG_amount{font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);font-variant-numeric:tabular-nums;line-height:1}";
2278
+ //#region \0workbuddy-css:/home/runner/work/dsh-workbuddy-bridge/dsh-workbuddy-bridge/src/client/credit-balance.module.css.js
2279
+ const css = ".Rbiksq_readout{white-space:nowrap;height:28px;color:var(--dsw-alias-label-tertiary);align-items:center;gap:4px;display:inline-flex}.Rbiksq_amount{font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);font-variant-numeric:tabular-nums;line-height:1}";
2280
2280
  const tagId = "dsh-workbuddy-bridge/credit-balance.module.css";
2281
2281
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
2282
2282
  const tag = document.createElement("style");
@@ -2286,8 +2286,8 @@ window.__ModuleLoader__.load({
2286
2286
  document.head.appendChild(tag);
2287
2287
  }
2288
2288
  var credit_balance_module_css_default = {
2289
- "amount": "zUqKXG_amount",
2290
- "readout": "zUqKXG_readout"
2289
+ "amount": "Rbiksq_amount",
2290
+ "readout": "Rbiksq_readout"
2291
2291
  };
2292
2292
  //#endregion
2293
2293
  //#region src/client/credit-balance.tsx
@@ -828,13 +828,21 @@ function billingHeaders(credential) {
828
828
  * Normalize an OpenAI chat-completions body for the WorkBuddy upstream:
829
829
  * force `stream: true` (the upstream rejects non-streaming), flatten
830
830
  * `tool_choice` (the upstream's field is a string; object forms return 400),
831
- * and rewrite `developer` messages as `system`.
831
+ * rewrite `developer` messages as `system`, and drop the adapter's own `off`
832
+ * effort spelling (see {@link dropUnsupportedEffort}).
832
833
  *
833
834
  * The `developer` rewrite is load-bearing: pi-ai emits the system prompt as
834
835
  * `role: "developer"` (the OpenAI convention it adopted), but the WorkBuddy
835
836
  * upstream rejects that role with HTTP 400 code 11128 ("Illegal API
836
837
  * invocation from an unapproved channel"). Rewriting to `system` is the
837
838
  * compatible spelling the upstream accepts.
839
+ *
840
+ * Every transformation here is region-agnostic on purpose. The two endpoints
841
+ * differ in what they *add* (the international one also needs a leading system
842
+ * prompt — see {@link prepareInternationalChatBody}), not in what they reject:
843
+ * both refuse the picker's `off` spelling, which is why that strip lives here
844
+ * rather than in the international layer (issue #13 reversed the earlier
845
+ * international-only scope decision, which rested on CN accepting it).
838
846
  */
839
847
  function prepareChatBody(source) {
840
848
  let body;
@@ -848,6 +856,7 @@ function prepareChatBody(source) {
848
856
  obj["stream"] = true;
849
857
  normalizeDeveloperRole(obj);
850
858
  normalizeToolChoice(obj);
859
+ dropUnsupportedEffort(obj);
851
860
  return JSON.stringify(obj);
852
861
  }
853
862
  /** Rewrite `role: "developer"` messages to `role: "system"` (upstream rejects developer). */
@@ -937,7 +946,20 @@ var WorkBuddyUpstreamClient = class {
937
946
  this.resolveAppVersion = options.resolveAppVersion ?? (() => resolveAppVersion());
938
947
  this.resolveChatIdentity = options.resolveChatIdentity ?? ((region) => resolveChatIdentity(region));
939
948
  }
940
- /** POST the chat endpoint; a successful answer is the raw SSE response. */
949
+ /**
950
+ * POST the chat endpoint; a successful answer is the raw SSE response.
951
+ *
952
+ * This is the one place every chat request converges on (the loopback shim,
953
+ * the host LLM route, and any direct caller all end up here), so it is also
954
+ * where the body is normalized for the upstream — in *both* regions. The
955
+ * region only decides which extra requirement applies on top: the
956
+ * international gateway additionally demands a leading system message. It
957
+ * used to decide whether the body was normalized at all, which left the CN
958
+ * path sending the picker's `off` spelling verbatim (issue #13).
959
+ *
960
+ * Normalization is idempotent, so a caller that already prepared the body
961
+ * (the shim does) sees no second change.
962
+ */
941
963
  async chatStream(credential, bodyJson, signal) {
942
964
  const region = regionOf(credential.domain);
943
965
  let userAgent;
@@ -946,6 +968,7 @@ var WorkBuddyUpstreamClient = class {
946
968
  } catch {
947
969
  userAgent = chatUserAgent(fallbackChatIdentity(region), region);
948
970
  }
971
+ const body = region === "global" ? prepareInternationalChatBody(bodyJson) : prepareChatBody(bodyJson);
949
972
  let response;
950
973
  try {
951
974
  response = await fetch(`${chatBase(credential)}/v2/chat/completions`, {
@@ -954,7 +977,7 @@ var WorkBuddyUpstreamClient = class {
954
977
  ...chatHeaders(credential, userAgent),
955
978
  Authorization: `Bearer ${credential.accessToken}`
956
979
  },
957
- body: region === "global" ? prepareInternationalChatBody(bodyJson) : bodyJson,
980
+ body,
958
981
  ...signal === void 0 ? {} : { signal }
959
982
  });
960
983
  } catch (error) {
@@ -1498,6 +1521,11 @@ function modelWithCurrentPromotion(model, now = Date.now()) {
1498
1521
  * merged: existing messages keep their order and wording. A body that is not a
1499
1522
  * JSON object is returned unchanged, exactly as {@link prepareChatBody} does,
1500
1523
  * so this is safe to run over an already-prepared-or-not body.
1524
+ *
1525
+ * This layer now carries *only* that requirement. The `reasoning_effort` strip
1526
+ * used to live here, scoped to this region; issue #13 showed CN rejects the
1527
+ * same spelling, so it moved into the shared {@link prepareChatBody} and this
1528
+ * function no longer touches the effort field at all.
1501
1529
  */
1502
1530
  function prepareInternationalChatBody(source) {
1503
1531
  const prepared = prepareChatBody(source);
@@ -1508,7 +1536,6 @@ function prepareInternationalChatBody(source) {
1508
1536
  return prepared;
1509
1537
  }
1510
1538
  if (!isObject(body)) return prepared;
1511
- dropUnsupportedEffort(body);
1512
1539
  const messages = body["messages"];
1513
1540
  if (!Array.isArray(messages)) return JSON.stringify(body);
1514
1541
  const first = messages[0];
@@ -1520,25 +1547,35 @@ function prepareInternationalChatBody(source) {
1520
1547
  return JSON.stringify(body);
1521
1548
  }
1522
1549
  /**
1523
- * Remove the adapter's own `off` effort spelling from the **international** wire.
1524
- *
1525
- * `thinkingLevelMap.off` is pinned to the literal `'off'` for models that
1526
- * declare `canDisableThinking`, so that the level stays selectable. pi-ai
1527
- * sends that value for any request carrying no explicit level, and the
1528
- * international endpoint rejects it on the GPT family with HTTP 400 `11133` /
1529
- * `extError.param === 'reasoning.effort'` (issue #49). Omission is the only
1530
- * form measured good on every such model; a literal `'none'` is *not* a safe
1531
- * substitute — accepted by the GPT-5.6 family and GLM, rejected by
1532
- * `gpt-6-astra`.
1533
- *
1534
- * Consequences, stated honestly: the international picker still offers Off,
1535
- * but selecting it now means "the field is omitted" — the model's actual
1536
- * behaviour is decided upstream and is *not* guaranteed to disable thinking
1537
- * or to match the catalog's `defaultEffort`. Declared spellings
1538
- * (`low`/`medium`/`high`/`xhigh`/`max`) and an explicit `none` pass through
1539
- * untouched. The CN variant is deliberately unaffected: its endpoint has
1540
- * accepted this spelling in every measurement so far, and keeping its wire
1541
- * unchanged is a scope decision, not a claim about that endpoint's future.
1550
+ * Remove the adapter's own `off` effort spelling from the wire, in both regions.
1551
+ *
1552
+ * `thinkingLevelMap.off` is pinned to the literal `'off'` so the level stays
1553
+ * selectable in the picker — pi-ai exposes a level only when its entry is a
1554
+ * string — but that same entry is also the value pi-ai puts on the wire, both
1555
+ * for an explicit Off selection and for *every* request that carries no level
1556
+ * at all. `'off'` is a picker name, not an upstream spelling, and both
1557
+ * endpoints reject it:
1558
+ *
1559
+ * - international GPT family: HTTP 400 `11133` / `extError.param ===
1560
+ * 'reasoning.effort'` (issue #49);
1561
+ * - CN: the same 400 `11133` on every `canDisableThinking` model — measured
1562
+ * on `deepseek-v4.1-flash`, where the author also confirmed `'disabled'`
1563
+ * is rejected and `'none'` answers 200 (issue #13). This is what made the
1564
+ * earlier international-only scope decision obsolete.
1565
+ *
1566
+ * Omission is the only form measured good on every affected model, so it is
1567
+ * the only form this function can produce; a literal `'none'` is *not* a safe
1568
+ * substitute (accepted by the GPT-5.6 family and GLM, rejected by
1569
+ * `gpt-6-astra`, and silently ignored by `kimi-k2.8-preview`). Declared
1570
+ * spellings (`low`/`medium`/`high`/`xhigh`/`max`) and an explicit `none` pass
1571
+ * through untouched — the adapter does not decide a user's `none` for them.
1572
+ *
1573
+ * Consequences, stated honestly: the picker still offers Off in both regions,
1574
+ * but selecting it means "the field is omitted". The model's actual behaviour
1575
+ * is then decided upstream — *not* guaranteed to disable thinking and not
1576
+ * guaranteed to match the catalog's `defaultEffort`. The plugin used to claim
1577
+ * more than that on CN, where `'off'` was merely accepted (accepted never
1578
+ * meant effective); #13 is why the claim is withdrawn rather than reworded.
1542
1579
  */
1543
1580
  function dropUnsupportedEffort(obj) {
1544
1581
  if (obj["reasoning_effort"] === "off") delete obj["reasoning_effort"];
@@ -3688,7 +3725,7 @@ var WorkBuddyCatalog = class {
3688
3725
  };
3689
3726
  //#endregion
3690
3727
  //#region src/version.ts
3691
- const WORKBUDDY_BRIDGE_VERSION = "0.4.0";
3728
+ const WORKBUDDY_BRIDGE_VERSION = "0.5.1";
3692
3729
  //#endregion
3693
3730
  //#region src/web/heartbeat.ts
3694
3731
  /**
package/lib/index.d.ts CHANGED
@@ -613,13 +613,21 @@ declare function regionOf(domain: string): WorkBuddyRegion;
613
613
  * Normalize an OpenAI chat-completions body for the WorkBuddy upstream:
614
614
  * force `stream: true` (the upstream rejects non-streaming), flatten
615
615
  * `tool_choice` (the upstream's field is a string; object forms return 400),
616
- * and rewrite `developer` messages as `system`.
616
+ * rewrite `developer` messages as `system`, and drop the adapter's own `off`
617
+ * effort spelling (see {@link dropUnsupportedEffort}).
617
618
  *
618
619
  * The `developer` rewrite is load-bearing: pi-ai emits the system prompt as
619
620
  * `role: "developer"` (the OpenAI convention it adopted), but the WorkBuddy
620
621
  * upstream rejects that role with HTTP 400 code 11128 ("Illegal API
621
622
  * invocation from an unapproved channel"). Rewriting to `system` is the
622
623
  * compatible spelling the upstream accepts.
624
+ *
625
+ * Every transformation here is region-agnostic on purpose. The two endpoints
626
+ * differ in what they *add* (the international one also needs a leading system
627
+ * prompt — see {@link prepareInternationalChatBody}), not in what they reject:
628
+ * both refuse the picker's `off` spelling, which is why that strip lives here
629
+ * rather than in the international layer (issue #13 reversed the earlier
630
+ * international-only scope decision, which rested on CN accepting it).
623
631
  */
624
632
  declare function prepareChatBody(source: string): string;
625
633
  /** Provenance of one successful catalog fetch, surfaced by the status card. */
@@ -660,7 +668,20 @@ declare class WorkBuddyUpstreamClient {
660
668
  /** Provenance of the most recent successful catalog fetch, for the card. */
661
669
  lastCatalog: WorkBuddyCatalogFetch | undefined;
662
670
  constructor(options?: WorkBuddyUpstreamClientOptions);
663
- /** POST the chat endpoint; a successful answer is the raw SSE response. */
671
+ /**
672
+ * POST the chat endpoint; a successful answer is the raw SSE response.
673
+ *
674
+ * This is the one place every chat request converges on (the loopback shim,
675
+ * the host LLM route, and any direct caller all end up here), so it is also
676
+ * where the body is normalized for the upstream — in *both* regions. The
677
+ * region only decides which extra requirement applies on top: the
678
+ * international gateway additionally demands a leading system message. It
679
+ * used to decide whether the body was normalized at all, which left the CN
680
+ * path sending the picker's `off` spelling verbatim (issue #13).
681
+ *
682
+ * Normalization is idempotent, so a caller that already prepared the body
683
+ * (the shim does) sees no second change.
684
+ */
664
685
  chatStream(credential: WorkBuddyCredential, bodyJson: string, signal?: AbortSignal): Promise<WorkBuddyChatResult>;
665
686
  /** POST the token-refresh endpoint; the caller merges the outcome. */
666
687
  refreshToken(credential: WorkBuddyCredential): Promise<WorkBuddyRefreshOutcome>;
@@ -833,6 +854,11 @@ declare function modelWithCurrentPromotion(model: WorkBuddyUpstreamModel, now?:
833
854
  * merged: existing messages keep their order and wording. A body that is not a
834
855
  * JSON object is returned unchanged, exactly as {@link prepareChatBody} does,
835
856
  * so this is safe to run over an already-prepared-or-not body.
857
+ *
858
+ * This layer now carries *only* that requirement. The `reasoning_effort` strip
859
+ * used to live here, scoped to this region; issue #13 showed CN rejects the
860
+ * same spelling, so it moved into the shared {@link prepareChatBody} and this
861
+ * function no longer touches the effort field at all.
836
862
  */
837
863
  declare function prepareInternationalChatBody(source: string): string;
838
864
  //#endregion
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as parseModelCatalog, B as chatUserAgent, C as variantFor, D as WorkBuddyUpstreamClient, F as probeModel, G as WORKBUDDY_APP_VERSION_FILENAME, H as readCliVersion, I as randomSentinel, J as readBundleVersion, K as appUserAgent, L as classifyUpstreamError, M as prepareInternationalChatBody, N as regionOf, O as modelWithCurrentPromotion, P as PROBE_EFFORT_CANDIDATES, R as CN_APP_VERSION_FILENAME, S as WORKBUDDY_VARIANTS, U as resolveChatIdentity, V as fallbackChatIdentity, W as validCliVersion, X as validAppVersion, Y as resolveAppVersion, _ as desktopAuthCandidatesFor, a as readHostHeartbeat, b as AI_VARIANT, c as WORKBUDDY_BRIDGE_VERSION, d as WorkBuddyCatalog, f as WORKBUDDY_AUTH_FILENAME, g as defaultDesktopAuthPath, h as defaultDesktopAuthCandidates, i as processStartTimeMs, j as prepareChatBody, k as normalizeCredits, l as FALLBACK_WORKBUDDY_AI_MODELS, m as WorkBuddyCredentialStore, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as WORKBUDDY_AUTH_FILE_ENV, q as installedAppVersion, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as FALLBACK_WORKBUDDY_MODELS, v as parseWorkBuddyAuth, w as WORKBUDDY_CREDIT_PATH, x as CN_VARIANT, y as workbuddyOwnAuthPath, z as FALLBACK_CN_APP_VERSION } from "./heartbeat-CP6YM98x.js";
1
+ import { A as parseModelCatalog, B as chatUserAgent, C as variantFor, D as WorkBuddyUpstreamClient, F as probeModel, G as WORKBUDDY_APP_VERSION_FILENAME, H as readCliVersion, I as randomSentinel, J as readBundleVersion, K as appUserAgent, L as classifyUpstreamError, M as prepareInternationalChatBody, N as regionOf, O as modelWithCurrentPromotion, P as PROBE_EFFORT_CANDIDATES, R as CN_APP_VERSION_FILENAME, S as WORKBUDDY_VARIANTS, U as resolveChatIdentity, V as fallbackChatIdentity, W as validCliVersion, X as validAppVersion, Y as resolveAppVersion, _ as desktopAuthCandidatesFor, a as readHostHeartbeat, b as AI_VARIANT, c as WORKBUDDY_BRIDGE_VERSION, d as WorkBuddyCatalog, f as WORKBUDDY_AUTH_FILENAME, g as defaultDesktopAuthPath, h as defaultDesktopAuthCandidates, i as processStartTimeMs, j as prepareChatBody, k as normalizeCredits, l as FALLBACK_WORKBUDDY_AI_MODELS, m as WorkBuddyCredentialStore, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as WORKBUDDY_AUTH_FILE_ENV, q as installedAppVersion, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as FALLBACK_WORKBUDDY_MODELS, v as parseWorkBuddyAuth, w as WORKBUDDY_CREDIT_PATH, x as CN_VARIANT, y as workbuddyOwnAuthPath, z as FALLBACK_CN_APP_VERSION } from "./heartbeat-DR6QsZ9h.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";
@@ -446,6 +446,13 @@ function withCatalogDisplay(name, info) {
446
446
  * The offered set is described internally as "verified accepted", never as
447
447
  * "verified effective": acceptance proves the upstream did not reject the
448
448
  * spelling, not that it changes what the model does.
449
+ *
450
+ * `off` is a picker name, not a wire spelling. It stays pinned to the literal
451
+ * `'off'` (a `null` here would remove the level from the picker entirely), and
452
+ * the shared preparation in `src/protocol/client.ts` strips that exact value
453
+ * before the request leaves the plugin — in both regions, because both
454
+ * endpoints reject it (issues #49 and #13). Selecting Off therefore means "send
455
+ * no `reasoning_effort`", and what the model then does is upstream's call.
449
456
  */
450
457
  function reasoningFields(info, observed) {
451
458
  const resolved = resolveEfforts(info, observed);
@@ -0,0 +1,10 @@
1
+ # locale/ — 包展示元数据
2
+
3
+ - 职责:宿主直读的**包展示元数据**(插件页上的标题与一句话说明)。
4
+ 不是插件界面文案 —— 那在 [../src/client/locales.ts](../src/client/locales.ts),运行时经 `ctx.locale` 注册。
5
+ - `en.json`:`meta.title` + `meta.description` 的英文。宿主先解析这一份,它不在就不会读其他语言文件。
6
+ - `zh.json`:同一键集的中文。
7
+ - 生效条件:随包发布(`package.json` 的 `files` 收了 `locale/*.json`),宿主从 `<包名>/locale/<语言>.json` 读;
8
+ 不进 `lib/`,本仓代码一个字节都不读它。
9
+ - 被谁依赖:宿主插件页;发布面断言在 [../scripts/check-release.mjs](../scripts/check-release.mjs)。
10
+ - 回落链、字段形状、改动波及面(规则层)→ 见 [AGENTS.md](AGENTS.md)
package/package.json CHANGED
@@ -2,7 +2,7 @@
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.4.0",
5
+ "version": "0.5.1",
6
6
  "author": "zlZayn",
7
7
  "keywords": [
8
8
  "dsh",
@@ -16,7 +16,7 @@
16
16
  "type": "module",
17
17
  "engines": {
18
18
  "node": "^22.19.0 || >=24.0.0",
19
- "dsh": ">=0.1.7-rc.2"
19
+ "dsh": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1"
20
20
  },
21
21
  "icon": "./icon.svg",
22
22
  "main": "lib/index.js",
@@ -24,17 +24,6 @@
24
24
  "bin": {
25
25
  "dsh-workbuddy-bridge": "lib/bin.js"
26
26
  },
27
- "scripts": {
28
- "prepack": "node node_modules/tsdown/dist/run.mjs",
29
- "build": "tsdown",
30
- "test": "vitest run",
31
- "lint": "eslint .",
32
- "format": "prettier --write .",
33
- "format:check": "prettier --check .",
34
- "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
35
- "check:release": "node scripts/check-release.mjs",
36
- "check": "pnpm run typecheck && pnpm run build && pnpm run test"
37
- },
38
27
  "exports": {
39
28
  ".": {
40
29
  "types": "./lib/index.d.ts",
@@ -61,10 +50,10 @@
61
50
  "license": "MIT",
62
51
  "repository": {
63
52
  "type": "git",
64
- "url": "git+https://github.com/zlZayn/dsh-workbuddy-bridge.git"
53
+ "url": "git+https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge.git"
65
54
  },
66
- "homepage": "https://github.com/zlZayn/dsh-workbuddy-bridge#readme",
67
- "bugs": "https://github.com/zlZayn/dsh-workbuddy-bridge/issues",
55
+ "homepage": "https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge#readme",
56
+ "bugs": "https://github.com/dsh-plugin-lab/dsh-workbuddy-bridge/issues",
68
57
  "dsh": {
69
58
  "bundle": {
70
59
  "patch": "./cordis.patch.yml"
@@ -86,52 +75,52 @@
86
75
  },
87
76
  "peerDependencies": {
88
77
  "@deepseek-ai/cordis": "^4.0.4",
89
- "@deepseek-ai/dsh-api-remotes": ">=0.1.7-rc.2",
90
- "@deepseek-ai/dsh-atomic-write": ">=0.1.7-rc.2",
91
- "@deepseek-ai/dsh-attachment": ">=0.1.7-rc.2",
92
- "@deepseek-ai/dsh-client-locale": ">=0.1.7-rc.2",
93
- "@deepseek-ai/dsh-client-store": ">=0.1.7-rc.2",
94
- "@deepseek-ai/dsh-client-ui-chat": ">=0.1.7-rc.2",
95
- "@deepseek-ai/dsh-client-ui-plugin-manager": ">=0.1.7-rc.2",
96
- "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.7-rc.2",
97
- "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.7-rc.2",
98
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.7-rc.2",
99
- "@deepseek-ai/dsh-client-ui-slots": ">=0.1.7-rc.2",
100
- "@deepseek-ai/dsh-home-paths": ">=0.1.7-rc.2",
101
- "@deepseek-ai/dsh-host-webserver": ">=0.1.7-rc.2",
102
- "@deepseek-ai/dsh-llm": ">=0.1.7-rc.2",
103
- "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.7-rc.2",
104
- "@deepseek-ai/dsh-settings": ">=0.1.7-rc.2",
78
+ "@deepseek-ai/dsh-api-remotes": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
79
+ "@deepseek-ai/dsh-atomic-write": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
80
+ "@deepseek-ai/dsh-attachment": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
81
+ "@deepseek-ai/dsh-client-locale": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
82
+ "@deepseek-ai/dsh-client-store": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
83
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
84
+ "@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
85
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
86
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
87
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
88
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
89
+ "@deepseek-ai/dsh-home-paths": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
90
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
91
+ "@deepseek-ai/dsh-llm": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
92
+ "@deepseek-ai/dsh-llm-pi-ai": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
93
+ "@deepseek-ai/dsh-settings": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
105
94
  "@deepseek-ai/schemastery": "^3.18.4",
106
- "@earendil-works/pi-ai": "^0.85.1",
95
+ "@earendil-works/pi-ai": "^1.1.0",
107
96
  "react": "^18.2.0",
108
97
  "react-dom": "^18.2.0"
109
98
  },
110
99
  "devDependencies": {
111
- "@deepseek-ai/cordis": "4.0.4",
112
- "@deepseek-ai/dsh-api-remotes": "0.2.0-rc.2",
113
- "@deepseek-ai/dsh-atomic-write": "0.2.0-rc.2",
114
- "@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
115
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
116
- "@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
117
- "@deepseek-ai/dsh-client-ui-chat": "0.2.0-rc.2",
118
- "@deepseek-ai/dsh-client-ui-conversation": "0.2.0-rc.2",
119
- "@deepseek-ai/dsh-client-ui-model-selection": "0.2.0-rc.2",
120
- "@deepseek-ai/dsh-client-ui-plugin-manager": "0.2.0-rc.2",
121
- "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
122
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
123
- "@deepseek-ai/dsh-client-ui-session": "0.2.0-rc.2",
124
- "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
125
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
126
- "@deepseek-ai/dsh-home-paths": "0.2.0-rc.2",
127
- "@deepseek-ai/dsh-host-webserver": "0.2.0-rc.2",
128
- "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
129
- "@deepseek-ai/dsh-llm-pi-ai": "0.2.0-rc.2",
130
- "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
131
- "@deepseek-ai/dsh-util-code-language": "0.2.0-rc.2",
132
- "@deepseek-ai/dsh-util-workspace-path": "0.2.0-rc.2",
133
- "@deepseek-ai/schemastery": "3.18.4",
134
- "@earendil-works/pi-ai": "^0.87.1",
100
+ "@deepseek-ai/cordis": "^4.0.4",
101
+ "@deepseek-ai/dsh-api-remotes": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
102
+ "@deepseek-ai/dsh-atomic-write": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
103
+ "@deepseek-ai/dsh-attachment": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
104
+ "@deepseek-ai/dsh-client-locale": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
105
+ "@deepseek-ai/dsh-client-store": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
106
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
107
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
108
+ "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
109
+ "@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
110
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
111
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
112
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
113
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
114
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
115
+ "@deepseek-ai/dsh-home-paths": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
116
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
117
+ "@deepseek-ai/dsh-llm": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
118
+ "@deepseek-ai/dsh-llm-pi-ai": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
119
+ "@deepseek-ai/dsh-settings": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
120
+ "@deepseek-ai/dsh-util-code-language": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
121
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.7-rc.1 || ^0.2.0-rc.1 || ^0.2.1-rc.1",
122
+ "@deepseek-ai/schemastery": "^3.18.4",
123
+ "@earendil-works/pi-ai": "^1.1.0",
135
124
  "@eslint/js": "^10.0.1",
136
125
  "@shikijs/langs": "^4.4.3",
137
126
  "@types/node": "^22.20.0",
@@ -161,7 +150,7 @@
161
150
  "micromark-util-symbol": "^2.0.1",
162
151
  "prettier": "^3.9.9",
163
152
  "react": "^18.2.0",
164
- "react-dom": "^18.3.1",
153
+ "react-dom": "^18.2.0",
165
154
  "react-test-renderer": "18.3.1",
166
155
  "shiki": "^4.4.3",
167
156
  "simple-icons": "^16.32.0",
@@ -171,5 +160,15 @@
171
160
  "unrun": "^0.3.1",
172
161
  "vitest": "^4.1.11",
173
162
  "zustand": "^5.0.15"
163
+ },
164
+ "scripts": {
165
+ "build": "tsdown",
166
+ "test": "vitest run",
167
+ "lint": "eslint .",
168
+ "format": "prettier --write .",
169
+ "format:check": "prettier --check .",
170
+ "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
171
+ "check:release": "node scripts/check-release.mjs",
172
+ "check": "pnpm run typecheck && pnpm run build && pnpm run test"
174
173
  }
175
- }
174
+ }