dsh-connect-workbuddy 1.1.2 → 1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 (2026-09-09)
4
+
5
+ ### Features
6
+
7
+ - **模型选择器显示积分倍率**:DSH 模型选择器中的 WorkBuddy 模型现在按 WorkBuddy 自身选择器的拼写显示积分倍率(如 `GLM-5.3 · x0.79`;未解析到倍率则保持原名称,免费模型显示 `x0.00`)。仅改 DSH 侧显示名(`toPiModel` 与模型 discovery 的 `name`):模型 `id`、`lastCatalog` 存档与插件卡片显示不变——DSH 的选择状态、会话事件(`model/selection` / `request/header`)、agent 默认模型设置与请求路由全部以 `provider + model id` 为连接键,倍率后缀不参与任何映射。
8
+
9
+ ### Fixes
10
+
11
+ - **修复模型保存始终失败(`client api: settings/mutate rejected "ops"`)**:卡片保存 `lastCatalog` 时曾用 `nativeContextWindow: undefined, multimodal: undefined` 显式清字段——显式 `undefined` 值会穿过 `structuredClone` 并被设置写入路径的严格 JSON codec 拒绝,导致**整次保存静默失败**(错误是 unhandled rejection,UI 无任何提示;用户侧表现为「保存按钮按不下去」)。姊妹项目 dsh-connect-trae 的 payload 不含 undefined 字段,故不受影响。现在改用 `toPersistedWorkBuddyModel` 按 KEY 剥离卡片专用字段(附回归测试:持久化形状不得含 undefined 值属性、JSON 往返无损)。
12
+ - **保存失败可见化**:保存抛错此前是静默的 unhandled rejection(UI 零提示,正是它掩盖了上一条 bug)。现在保存失败时在按钮旁显示具体原因,草稿保持 dirty 可直接重试;成功路径与 dsh-connect-trae 卡片完全一致(保存中… → 自然结束 → 恢复「保存」并禁用),无额外装饰。
13
+
14
+ ## 1.1.3 (2026-09-04)
15
+
16
+ ### Breaking Changes
17
+
18
+ - **跟进上游 DSH 0.1.2-rc.1 / Cordis 4.0.2**:本插件依赖链全部更新至 `0.1.2-rc.1`(`@deepseek-ai/dsh-*`)与 `4.0.2`(`@deepseek-ai/cordis`)。以下 API 变更需要同步适配:
19
+
20
+ - `installSettingsSection(ctx, ns, schema, entry, hooks)` 移除:改为 `ctx.settings.installSection(ctx, ns, schema, entry, hooks)`(实为 `SettingsProvider.installSection` 实例方法)。
21
+ - `settingsNamespace('workbuddy')` 移除:改为 `'workbuddy' as SettingsNamespace`(dsh-settings 导出的 branded type)。
22
+ - `registerModelDiscovery` 回调签名的 `signal` 字段从 `request.signal` 移至回调第二参数 `async (request, signal) =>`。
23
+ - `SettingsNamespace` branded type 语义收紧:`WORKBUDDY_SETTINGS_NS` 需显式 `as SettingsNamespace` 断言。
24
+ - Cordis 4.0.2 要求所有服务访问显式 inject:`inject` 声明从 `['llm']` 扩为 `['llm', 'settings']`。
25
+ - `onChange` 回调在 `installSection` 注册时同步触发:涉及的前置变量(如 `invalidateCatalog`)需提前声明。
26
+
27
+ ### Dependencies
28
+
29
+ - `@deepseek-ai/cordis`:`4.0.1` → `4.0.2`
30
+ - 所有 `@deepseek-ai/dsh-*` 包:`0.1.1-rc.1` → `0.1.2-rc.1`
31
+ - `@deepseek-ai/dsh-client-runtime`:`0.1.1-rc.2`(不变,0.1.2-rc.1 未发布)
32
+ - `@deepseek-ai/schemastery`:`3.18.1-rc.1` → `3.18.2`
33
+ - `@earendil-works/pi-ai`:`0.82.1` → `0.85.0`
34
+ - `@deepseek-ai/dsh-client-ui-settings`:补充显式 devDependency(已作为 0.1.2-rc.1 依赖)
35
+
36
+ ### Infrastructure
37
+
38
+ - `pnpm.overrides` 从 `package.json` 迁移至 `pnpm-workspace.yaml`(pnpm 11 要求)。
39
+
3
40
  ## 1.1.2 (2026-08-31)
4
41
 
5
42
  ### Fixes
package/README.en.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/v/dsh-connect-workbuddy?style=flat-square&label=npm&color=cb3837" alt="npm version"></a>
11
- <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/dm/dsh-connect-workbuddy?style=flat-square&label=downloads" alt="npm downloads"></a>
11
+ <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/d18m/dsh-connect-workbuddy?style=flat-square&label=downloads&color=cb3837" alt="npm downloads"></a>
12
12
  <a href="https://github.com/dingminhua/dsh-connect-workbuddy/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/dingminhua/dsh-connect-workbuddy/ci.yml?branch=main&style=flat-square&label=tests" alt="test status"></a>
13
13
  <a href="LICENSE"><img src="https://img.shields.io/github/license/dingminhua/dsh-connect-workbuddy?style=flat-square" alt="MIT license"></a>
14
14
  <a href="https://github.com/dingminhua/dsh-connect-workbuddy/stargazers"><img src="https://img.shields.io/github/stars/dingminhua/dsh-connect-workbuddy?style=flat-square" alt="GitHub stars"></a>
@@ -21,7 +21,7 @@ A [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) bund
21
21
 
22
22
  ## Features
23
23
 
24
- - **WorkBuddy model provider** — registers locally signed-in WorkBuddy models as the `workbuddy` provider (e.g. `GLM-5.3`, `DeepSeek-V4-Pro`, `Kimi-K3`, `MiniMax-M3`, `Hy3`).
24
+ - **WorkBuddy model provider** — registers locally signed-in WorkBuddy models as the `workbuddy` provider (e.g. `GLM-5.3`, `DeepSeek-V4-Pro`, `Kimi-K3`, `MiniMax-M3`, `Hy3`); model names carry the upstream credit multiplier (e.g. `GLM-5.3 · x0.79`), matching WorkBuddy's own model menu.
25
25
  - **Model management** — refresh the full catalog from upstream and enable or disable each model individually; refresh is a draft operation that only takes effect on save. Upstream also reports credit multiplier, context/output limits, and reasoning efforts; image input is opted in per model manually (off by default).
26
26
  - **Local account switching** — discovers the multiple sign-in credentials WorkBuddy's desktop app leaves behind and lets you switch between them. Tokens are never written to DSH settings.
27
27
  - **Read-only credits overview** — remaining credit aggregated per package, plus each model's credit multiplier. Queries consume no credits.
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  <p align="center">
18
18
  <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/v/dsh-connect-workbuddy?style=flat-square&label=npm&color=cb3837" alt="npm version"></a>
19
- <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/dm/dsh-connect-workbuddy?style=flat-square&label=downloads" alt="npm downloads"></a>
19
+ <a href="https://www.npmjs.com/package/dsh-connect-workbuddy"><img src="https://img.shields.io/npm/d18m/dsh-connect-workbuddy?style=flat-square&label=downloads&color=cb3837" alt="npm downloads"></a>
20
20
  <a href="https://github.com/dingminhua/dsh-connect-workbuddy/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/dingminhua/dsh-connect-workbuddy/ci.yml?branch=main&style=flat-square&label=tests" alt="test status"></a>
21
21
  <a href="LICENSE"><img src="https://img.shields.io/github/license/dingminhua/dsh-connect-workbuddy?style=flat-square" alt="MIT license"></a>
22
22
  <a href="https://github.com/dingminhua/dsh-connect-workbuddy/stargazers"><img src="https://img.shields.io/github/stars/dingminhua/dsh-connect-workbuddy?style=flat-square" alt="GitHub stars"></a>
@@ -27,7 +27,7 @@
27
27
 
28
28
  ## 功能特性
29
29
 
30
- - **WorkBuddy 模型接入** —— 把本机登录的 WorkBuddy 模型注册为 DSH 的 `workbuddy` provider,模型选择器出现 `GLM-5.3`、`DeepSeek-V4-Pro`、`Kimi-K3`、`MiniMax-M3`、`Hy3` 等。
30
+ - **WorkBuddy 模型接入** —— 把本机登录的 WorkBuddy 模型注册为 DSH 的 `workbuddy` provider,模型选择器出现 `GLM-5.3`、`DeepSeek-V4-Pro`、`Kimi-K3`、`MiniMax-M3`、`Hy3` 等;模型名内嵌上游积分倍率(如 `GLM-5.3 · x0.79`),与 WorkBuddy 自身模型菜单一致。
31
31
  - **模型管理** —— 从上游刷新完整模型目录,逐项勾选启用或禁用;刷新是草稿操作,点保存才生效。上游同时给出积分倍率、上下文/输出上限与推理档位;图片输入按模型手动勾选(默认不勾选)。
32
32
  - **本机账号切换** —— 自动发现 WorkBuddy 桌面端留下的多个登录凭据,可切换账号;Token 不写入 DSH 设置。
33
33
  - **只读积分概览** —— 按套餐聚合展示剩余积分,并列出每个模型的积分倍率。查询不消耗积分。
@@ -137,6 +137,12 @@ dsh plugin --profile desktop add /Users/dmh2002/DshProject/dsh-connect-workbuddy
137
137
  - [corrinehu/dsh-workbuddy-connect](https://github.com/corrinehu/dsh-workbuddy-connect)(MIT,Copyright (c) 2026 Corrine Hu)— **本项目的主要参照**。WorkBuddy 接入 DeepSeek Harness 的完整可行方案由该项目首先验证:桌面端凭据的发现与刷新机制、上游协议与请求头约定、loopback shim 的入站加固、pi-ai provider 的装配方式、以及状态诊断 CLI,均以其为参照。本项目在保留这些已验证能力的基础上重写,着重改善使用体验。
138
138
  - [Sliverkiss/workbuddy2api](https://github.com/Sliverkiss/workbuddy2api)(MIT)— WorkBuddy 上游协议(`copilot.tencent.com` 的 wire behavior)的参照实现,经 `dsh-workbuddy-connect` 转引。
139
139
 
140
+ ### 插件呈现与结构的基线
141
+
142
+ - [dingminhua/dsh-connect-trae](https://github.com/dingminhua/dsh-connect-trae)(MIT,Copyright (c) 2026 LaoDing)— 插件的呈现方式与其保持一致:设置卡片的结构与交互、模型管理(刷新 → 勾选 → 保存)与账号选择模型、只读的 host↔client 路由形态,以及 npm 发布工程。
143
+ - [dingminhua/dsh-subagent-default-model](https://github.com/dingminhua/dsh-subagent-default-model)(MIT,Copyright (c) 2026 LaoDing)— `dsm-*` 卡片风格体系、`row.*` 双语文案键约定与品牌图标的来源,经 `dsh-connect-trae` 转引。
144
+ - [franksong2702/dsh-codex-connect](https://github.com/franksong2702/dsh-codex-connect)(Apache-2.0)— DSH 插件结构与 provider 注册的参照,经 `dsh-workbuddy-connect` 转引;其 Apache-2.0 义务在 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) 中单独履行。
145
+
140
146
  ### 说明
141
147
 
142
148
  以上项目的版权归各自作者所有。本项目采用**借鉴设计思路 + 独立实现**的方式,未整体复制任何参考项目的源码;关键模块均为独立编写,并在源文件头部注释中标注了所参考的具体项目与模式。若你发现本项目的标注有遗漏或不当之处,请提交 issue,我们会立即更正。
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as defaultDesktopAuthCandidates, O as workbuddyOwnAuthPath, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, g as FALLBACK_WORKBUDDY_MODELS, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore } from "./host-heartbeat-DzAs1jZ6.js";
2
+ import { C as defaultDesktopAuthCandidates, O as workbuddyOwnAuthPath, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, g as FALLBACK_WORKBUDDY_MODELS, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore } from "./host-heartbeat-BKokeDPN.js";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/bin.ts
package/lib/client.js CHANGED
@@ -29,6 +29,22 @@ window.__ModuleLoader__.load({
29
29
  const WORKBUDDY_ACCOUNTS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/accounts/refresh";
30
30
  /** Plugin-owned daily check-in action endpoint. */
31
31
  const WORKBUDDY_CHECKIN_PATH = "/plugins/dsh-connect-workbuddy/checkin";
32
+ /**
33
+ * Project one card row into its persisted `lastCatalog` shape: the native
34
+ * context window becomes the stored `contextWindow`, and the card-only
35
+ * presentation fields (`nativeContextWindow`, `multimodal`) are removed BY
36
+ * KEY. They must never be set to `undefined`: explicit `undefined` values
37
+ * survive `structuredClone` and are rejected by the settings write path's
38
+ * strict JSON codec (`client api: settings/mutate rejected "ops"`), which
39
+ * fails the whole save.
40
+ */
41
+ function toPersistedWorkBuddyModel(model) {
42
+ const { nativeContextWindow, multimodal: _cardOnly, ...rest } = model;
43
+ return {
44
+ ...rest,
45
+ contextWindow: nativeContextWindow
46
+ };
47
+ }
32
48
  //#endregion
33
49
  //#region src/client/icon.ts
34
50
  /**
@@ -142,6 +158,7 @@ window.__ModuleLoader__.load({
142
158
  .dsm-workbuddy-context-budget input{margin:0;accent-color:var(--dsw-alias-brand-primary,#5686fe)}
143
159
  .dsm-workbuddy-model-capability-note{margin:0;color:var(--dsw-alias-label-tertiary,#999);font-size:12px;line-height:18px}
144
160
  .dsm-workbuddy-model-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--dsw-alias-border-l2,#36373b);padding-top:12px}
161
+ .dsm-workbuddy-model-save-error{flex:1;min-width:0;color:var(--dsw-alias-state-error-primary,#ef4444);font-size:12px;line-height:16px;text-align:right}
145
162
  .dsm-workbuddy-model-actions-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px}
146
163
  .dsm-workbuddy-usage-cheer{display:inline-flex;align-items:center;gap:4px;flex:none;text-decoration:underline;text-underline-offset:2px;color:var(--dsw-alias-label-tertiary,#999);font-size:13px;line-height:1.5;transition:color .16s}
147
164
  .dsm-workbuddy-usage-cheer-star{font-size:12px;line-height:1;display:inline-flex}
@@ -232,6 +249,8 @@ window.__ModuleLoader__.load({
232
249
  const [draftImageIds, setDraftImageIds] = (0, react.useState)(void 0);
233
250
  const [draftContextBudgets, setDraftContextBudgets] = (0, react.useState)(void 0);
234
251
  const [saving, setSaving] = (0, react.useState)(false);
252
+ /** Save failure surfaced next to the buttons; cleared by the next attempt. */
253
+ const [saveError, setSaveError] = (0, react.useState)(void 0);
235
254
  const [switchingAccount, setSwitchingAccount] = (0, react.useState)(false);
236
255
  const [checkingIn, setCheckingIn] = (0, react.useState)(false);
237
256
  const [checkinActionError, setCheckinActionError] = (0, react.useState)(void 0);
@@ -403,18 +422,16 @@ window.__ModuleLoader__.load({
403
422
  const saveModels = async () => {
404
423
  if (settingsScope === void 0) return;
405
424
  setSaving(true);
425
+ setSaveError(void 0);
406
426
  try {
407
- await settingsScope.set("lastCatalog", visibleModels.map((model) => ({
408
- ...model,
409
- contextWindow: model.nativeContextWindow,
410
- nativeContextWindow: void 0,
411
- multimodal: void 0
412
- })));
427
+ await settingsScope.set("lastCatalog", visibleModels.map(toPersistedWorkBuddyModel));
413
428
  await settingsScope.set("enabledModelIds", [...activeEnabledIds]);
414
429
  await settingsScope.set("imageModelIds", [...activeImageIds]);
415
430
  await settingsScope.set("contextBudgets", activeContextBudgets);
416
431
  discardModels();
417
432
  await refreshUsage();
433
+ } catch (error) {
434
+ if (mounted.current) setSaveError(error instanceof Error ? error.message : t("row.requestFailed"));
418
435
  } finally {
419
436
  if (mounted.current) setSaving(false);
420
437
  }
@@ -694,34 +711,41 @@ window.__ModuleLoader__.load({
694
711
  }),
695
712
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
696
713
  className: "dsm-workbuddy-model-actions",
697
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
698
- className: "dsm-workbuddy-usage-cheer",
699
- href: WORKBUDDY_GITHUB_URL,
700
- target: "_blank",
701
- rel: "noopener noreferrer",
702
- children: [t("row.cheer"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
703
- className: "dsm-workbuddy-usage-cheer-star",
704
- "aria-hidden": "true",
705
- children: "★"
706
- })]
707
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
708
- className: "dsm-workbuddy-model-actions-buttons",
709
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
710
- type: "button",
711
- className: "dsm-btn dsm-btn-outline",
712
- disabled: !dirty || saving,
713
- onClick: discardModels,
714
- children: t("row.discard")
715
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
716
- type: "button",
717
- className: "dsm-btn dsm-btn-primary",
718
- disabled: !dirty || saving || activeEnabledIds.size === 0,
719
- onClick: () => {
720
- saveModels();
721
- },
722
- children: saving ? t("row.saving") : t("row.save")
723
- })]
724
- })]
714
+ children: [
715
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
716
+ className: "dsm-workbuddy-usage-cheer",
717
+ href: WORKBUDDY_GITHUB_URL,
718
+ target: "_blank",
719
+ rel: "noopener noreferrer",
720
+ children: [t("row.cheer"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
721
+ className: "dsm-workbuddy-usage-cheer-star",
722
+ "aria-hidden": "true",
723
+ children: "★"
724
+ })]
725
+ }),
726
+ saveError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
727
+ className: "dsm-workbuddy-model-save-error",
728
+ children: t("row.saveError", { message: saveError })
729
+ }),
730
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
731
+ className: "dsm-workbuddy-model-actions-buttons",
732
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
733
+ type: "button",
734
+ className: "dsm-btn dsm-btn-outline",
735
+ disabled: !dirty || saving,
736
+ onClick: discardModels,
737
+ children: t("row.discard")
738
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
739
+ type: "button",
740
+ className: "dsm-btn dsm-btn-primary",
741
+ disabled: !dirty || saving || activeEnabledIds.size === 0,
742
+ onClick: () => {
743
+ saveModels();
744
+ },
745
+ children: saving ? t("row.saving") : t("row.save")
746
+ })]
747
+ })
748
+ ]
725
749
  })
726
750
  ]
727
751
  })
@@ -785,6 +809,7 @@ window.__ModuleLoader__.load({
785
809
  "row.discard": "Discard changes",
786
810
  "row.save": "Save",
787
811
  "row.saving": "Saving…",
812
+ "row.saveError": "Save failed: {message}",
788
813
  "row.modelContext": "Maximum context {context}",
789
814
  "row.contextBudget": "DSH context budget",
790
815
  "row.modelOutput": "Output {output}",
@@ -829,6 +854,7 @@ window.__ModuleLoader__.load({
829
854
  "row.discard": "放弃修改",
830
855
  "row.save": "保存",
831
856
  "row.saving": "保存中…",
857
+ "row.saveError": "保存失败:{message}",
832
858
  "row.modelContext": "最大上下文 {context}",
833
859
  "row.contextBudget": "DSH 上下文预算",
834
860
  "row.modelOutput": "最大输出 {output}",
@@ -996,7 +996,7 @@ var WorkBuddyUpstreamClient = class {
996
996
  //#endregion
997
997
  //#region src/version.ts
998
998
  /** The npm package version this build was produced from. */
999
- const WORKBUDDY_CONNECT_VERSION = "1.1.2";
999
+ const WORKBUDDY_CONNECT_VERSION = "1.2.0";
1000
1000
  //#endregion
1001
1001
  //#region src/host-heartbeat.ts
1002
1002
  /**
package/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
3
3
  import { Context } from "@deepseek-ai/cordis";
4
+ import { SettingsNamespace } from "@deepseek-ai/dsh-settings";
4
5
  import { AttachmentStore } from "@deepseek-ai/dsh-attachment";
5
6
  //#region src/auth.d.ts
6
7
  /** Normalized WorkBuddy credential, timestamps in epoch milliseconds. */
@@ -397,6 +398,18 @@ type WorkBuddyThinkingLevel = typeof THINKING_LEVELS[number];
397
398
  type WorkBuddyThinkingLevelMap = Partial<Record<'off' | WorkBuddyThinkingLevel, string | null>>;
398
399
  /** pi-ai input modalities: images only when WorkBuddy advertises them. */
399
400
  declare function workBuddyModelInput(info: WorkBuddyModelInfo): ('text' | 'image')[];
401
+ /**
402
+ * DSH-facing display name: the model name plus the upstream credit multiplier,
403
+ * spelled the way WorkBuddy's own selector does (`GLM-5.3 · x0.79`).
404
+ *
405
+ * Display-only by construction: every DSH-side join keys on the model id —
406
+ * the selector's current choice (`provider` + `model`), the durable
407
+ * `model/selection` / `request/header` session events, the agent default-model
408
+ * settings, and the request wire (`model: <id>` reaching the shim). A model
409
+ * without a parsed multiplier keeps its bare name; a zero multiplier shows
410
+ * `x0.00`, matching WorkBuddy's rendering of free models.
411
+ */
412
+ declare function workBuddyDisplayName(info: WorkBuddyModelInfo): string;
400
413
  /** Map only levels advertised by WorkBuddy; undeclared DSH levels stay unavailable. */
401
414
  declare function workBuddyThinkingLevelMap(info: WorkBuddyModelInfo): WorkBuddyThinkingLevelMap | undefined;
402
415
  /**
@@ -545,6 +558,16 @@ interface WorkBuddyWebModel {
545
558
  };
546
559
  description?: string;
547
560
  }
561
+ /**
562
+ * Project one card row into its persisted `lastCatalog` shape: the native
563
+ * context window becomes the stored `contextWindow`, and the card-only
564
+ * presentation fields (`nativeContextWindow`, `multimodal`) are removed BY
565
+ * KEY. They must never be set to `undefined`: explicit `undefined` values
566
+ * survive `structuredClone` and are rejected by the settings write path's
567
+ * strict JSON codec (`client api: settings/mutate rejected "ops"`), which
568
+ * fails the whole save.
569
+ */
570
+ declare function toPersistedWorkBuddyModel(model: WorkBuddyWebModel): Omit<WorkBuddyWebModel, 'nativeContextWindow' | 'multimodal'>;
548
571
  /** One selectable local account, token-free. */
549
572
  interface WorkBuddyWebAccount {
550
573
  id: string;
@@ -617,7 +640,7 @@ declare const name = "dsh-connect-workbuddy";
617
640
  /** The model registry required before the provider can register. */
618
641
  declare const inject: string[];
619
642
  /** Settings namespace for the plugin configuration card. */
620
- declare const WORKBUDDY_SETTINGS_NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
643
+ declare const WORKBUDDY_SETTINGS_NS: SettingsNamespace;
621
644
  /** Plugin configuration. */
622
645
  interface Config {
623
646
  /** Explicit WorkBuddy desktop auth-file path, overriding env and platform defaults. */
@@ -642,4 +665,4 @@ declare const Config: z<Config>;
642
665
  */
643
666
  declare function apply(ctx: Context, config: Config): void;
644
667
  //#endregion
645
- export { Config, FALLBACK_WORKBUDDY_MODELS, type UpstreamErrorKind, WORKBUDDY_ACCOUNTS_REFRESH_PATH, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_CHECKIN_PATH, WORKBUDDY_CONNECT_VERSION, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_MODELS_REFRESH_PATH, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WORKBUDDY_USAGE_PATH, type WorkBuddyAccountChoice, type WorkBuddyAdapter, type WorkBuddyAuthStatus, WorkBuddyCatalog, type WorkBuddyChatResult, type WorkBuddyCredential, WorkBuddyCredentialStore, type WorkBuddyCreditPackage, type WorkBuddyCredits, type WorkBuddyHostHeartbeat, type WorkBuddyModelInfo, type WorkBuddyReasoning, type WorkBuddyRefreshOutcome, type WorkBuddyShim, type WorkBuddyStatusRouteOptions, type WorkBuddyStoreOptions, WorkBuddyUpstreamClient, type WorkBuddyUpstreamModel, type WorkBuddyWebAccount, type WorkBuddyWebCheckin, type WorkBuddyWebCredits, type WorkBuddyWebModel, type WorkBuddyWebPackage, type WorkBuddyWebUsage, apply, authFileName, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthDirs, defaultDesktopAuthPath, deriveCatalog, inject, isHeartbeatProcessAlive, name, parseCreditMultiplier, parseReasoning, parseUpstreamModel, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, registerWorkBuddyStatusRoute, workBuddyModelInput, workBuddyThinkingLevelMap, workBuddyWebStatus, workbuddyAccountId, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath, writeHostHeartbeat };
668
+ export { Config, FALLBACK_WORKBUDDY_MODELS, type UpstreamErrorKind, WORKBUDDY_ACCOUNTS_REFRESH_PATH, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_CHECKIN_PATH, WORKBUDDY_CONNECT_VERSION, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_MODELS_REFRESH_PATH, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WORKBUDDY_USAGE_PATH, type WorkBuddyAccountChoice, type WorkBuddyAdapter, type WorkBuddyAuthStatus, WorkBuddyCatalog, type WorkBuddyChatResult, type WorkBuddyCredential, WorkBuddyCredentialStore, type WorkBuddyCreditPackage, type WorkBuddyCredits, type WorkBuddyHostHeartbeat, type WorkBuddyModelInfo, type WorkBuddyReasoning, type WorkBuddyRefreshOutcome, type WorkBuddyShim, type WorkBuddyStatusRouteOptions, type WorkBuddyStoreOptions, WorkBuddyUpstreamClient, type WorkBuddyUpstreamModel, type WorkBuddyWebAccount, type WorkBuddyWebCheckin, type WorkBuddyWebCredits, type WorkBuddyWebModel, type WorkBuddyWebPackage, type WorkBuddyWebUsage, apply, authFileName, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthDirs, defaultDesktopAuthPath, deriveCatalog, inject, isHeartbeatProcessAlive, name, parseCreditMultiplier, parseReasoning, parseUpstreamModel, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, registerWorkBuddyStatusRoute, toPersistedWorkBuddyModel, workBuddyDisplayName, workBuddyModelInput, workBuddyThinkingLevelMap, workBuddyWebStatus, workbuddyAccountId, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath, writeHostHeartbeat };
package/lib/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import { C as defaultDesktopAuthCandidates, D as workbuddyAccountId, E as parseWorkBuddyAuth, O as workbuddyOwnAuthPath, S as authFileName, T as defaultDesktopAuthPath, _ as WorkBuddyCatalog, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, d as parseCreditMultiplier, f as parseReasoning, g as FALLBACK_WORKBUDDY_MODELS, h as regionOf, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as prepareChatBody, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as parseUpstreamModel, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as deriveCatalog, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore, y as WORKBUDDY_AUTH_FILENAME } from "./host-heartbeat-DzAs1jZ6.js";
1
+ import { C as defaultDesktopAuthCandidates, D as workbuddyAccountId, E as parseWorkBuddyAuth, O as workbuddyOwnAuthPath, S as authFileName, T as defaultDesktopAuthPath, _ as WorkBuddyCatalog, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, d as parseCreditMultiplier, f as parseReasoning, g as FALLBACK_WORKBUDDY_MODELS, h as regionOf, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as prepareChatBody, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as parseUpstreamModel, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as deriveCatalog, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore, y as WORKBUDDY_AUTH_FILENAME } from "./host-heartbeat-BKokeDPN.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
- import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
4
3
  import { randomBytes, timingSafeEqual } from "node:crypto";
5
4
  import { createProvider } from "@earendil-works/pi-ai";
6
5
  import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
@@ -81,6 +80,20 @@ const THINKING_LEVELS = [
81
80
  function workBuddyModelInput(info) {
82
81
  return info.multimodal === true ? ["text", "image"] : ["text"];
83
82
  }
83
+ /**
84
+ * DSH-facing display name: the model name plus the upstream credit multiplier,
85
+ * spelled the way WorkBuddy's own selector does (`GLM-5.3 · x0.79`).
86
+ *
87
+ * Display-only by construction: every DSH-side join keys on the model id —
88
+ * the selector's current choice (`provider` + `model`), the durable
89
+ * `model/selection` / `request/header` session events, the agent default-model
90
+ * settings, and the request wire (`model: <id>` reaching the shim). A model
91
+ * without a parsed multiplier keeps its bare name; a zero multiplier shows
92
+ * `x0.00`, matching WorkBuddy's rendering of free models.
93
+ */
94
+ function workBuddyDisplayName(info) {
95
+ return info.creditMultiplier === void 0 ? info.name : `${info.name} · x${info.creditMultiplier.toFixed(2)}`;
96
+ }
84
97
  /** Map only levels advertised by WorkBuddy; undeclared DSH levels stay unavailable. */
85
98
  function workBuddyThinkingLevelMap(info) {
86
99
  const supported = info.reasoning?.supportedEfforts?.filter((effort) => THINKING_LEVELS.includes(effort));
@@ -94,7 +107,7 @@ function toPiModel(info, baseUrl) {
94
107
  const thinkingLevelMap = workBuddyThinkingLevelMap(info);
95
108
  return {
96
109
  id: info.id,
97
- name: info.name,
110
+ name: workBuddyDisplayName(info),
98
111
  api: "openai-completions",
99
112
  provider: WORKBUDDY_PROVIDER,
100
113
  baseUrl,
@@ -410,6 +423,22 @@ const WORKBUDDY_MODELS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/models/ref
410
423
  const WORKBUDDY_ACCOUNTS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/accounts/refresh";
411
424
  /** Plugin-owned daily check-in action endpoint. */
412
425
  const WORKBUDDY_CHECKIN_PATH = "/plugins/dsh-connect-workbuddy/checkin";
426
+ /**
427
+ * Project one card row into its persisted `lastCatalog` shape: the native
428
+ * context window becomes the stored `contextWindow`, and the card-only
429
+ * presentation fields (`nativeContextWindow`, `multimodal`) are removed BY
430
+ * KEY. They must never be set to `undefined`: explicit `undefined` values
431
+ * survive `structuredClone` and are rejected by the settings write path's
432
+ * strict JSON codec (`client api: settings/mutate rejected "ops"`), which
433
+ * fails the whole save.
434
+ */
435
+ function toPersistedWorkBuddyModel(model) {
436
+ const { nativeContextWindow, multimodal: _cardOnly, ...rest } = model;
437
+ return {
438
+ ...rest,
439
+ contextWindow: nativeContextWindow
440
+ };
441
+ }
413
442
  //#endregion
414
443
  //#region src/web-status.ts
415
444
  /** Redact token-like content before it crosses to the browser. */
@@ -610,9 +639,9 @@ function registerWorkBuddyStatusRoute(ctx, deps) {
610
639
  /** Stable Cordis plugin name. */
611
640
  const name = "dsh-connect-workbuddy";
612
641
  /** The model registry required before the provider can register. */
613
- const inject = ["llm"];
642
+ const inject = ["llm", "settings"];
614
643
  /** Settings namespace for the plugin configuration card. */
615
- const WORKBUDDY_SETTINGS_NS = settingsNamespace("workbuddy");
644
+ const WORKBUDDY_SETTINGS_NS = "workbuddy";
616
645
  const modelConfig = z.object({
617
646
  id: z.string().required(),
618
647
  name: z.string().required(),
@@ -656,6 +685,7 @@ function apply(ctx, config) {
656
685
  const configuredModels = (value) => withImageSelection(deriveCatalog(value.lastCatalog?.length ? value.lastCatalog : FALLBACK_WORKBUDDY_MODELS, enabledSet(value), value.contextBudgets ?? {}), imageSet(value));
657
686
  const displayModels = (value) => value.lastCatalog?.length ? value.lastCatalog : FALLBACK_WORKBUDDY_MODELS;
658
687
  let current = () => config;
688
+ let invalidateCatalog = () => {};
659
689
  const discoverModels = async (signal) => {
660
690
  const credential = await store.resolve();
661
691
  return client.fetchModels(credential, signal);
@@ -669,7 +699,7 @@ function apply(ctx, config) {
669
699
  contextBudgets: () => current().contextBudgets ?? {},
670
700
  discoverModels
671
701
  }));
672
- installSettingsSection(ctx, WORKBUDDY_SETTINGS_NS, Config, config, {
702
+ ctx.settings.installSection(ctx, WORKBUDDY_SETTINGS_NS, Config, config, {
673
703
  setSource(source) {
674
704
  current = source;
675
705
  },
@@ -682,7 +712,6 @@ function apply(ctx, config) {
682
712
  }
683
713
  });
684
714
  let stopped = false;
685
- let invalidateCatalog = () => {};
686
715
  ctx.effect(() => () => {
687
716
  stopped = true;
688
717
  shim.close();
@@ -728,11 +757,11 @@ function apply(ctx, config) {
728
757
  releaseAdapter?.();
729
758
  releaseDirectory?.();
730
759
  }
731
- ctx.llm.registerModelDiscovery(WORKBUDDY_SETTINGS_NS, async (request) => {
760
+ ctx.llm.registerModelDiscovery(WORKBUDDY_SETTINGS_NS, async (request, signal) => {
732
761
  if (request.provider !== "workbuddy") return [];
733
- return withImageSelection(deriveCatalog(await discoverModels(request.signal), enabledSet(current()), current().contextBudgets ?? {}), imageSet(current())).map((model) => ({
762
+ return withImageSelection(deriveCatalog(await discoverModels(signal), enabledSet(current()), current().contextBudgets ?? {}), imageSet(current())).map((model) => ({
734
763
  id: model.id,
735
- name: model.name,
764
+ name: workBuddyDisplayName(model),
736
765
  contextWindow: model.contextWindow,
737
766
  maxTokens: model.maxTokens,
738
767
  inputModalities: workBuddyModelInput(model)
@@ -761,4 +790,4 @@ function apply(ctx, config) {
761
790
  });
762
791
  }
763
792
  //#endregion
764
- export { Config, FALLBACK_WORKBUDDY_MODELS, WORKBUDDY_ACCOUNTS_REFRESH_PATH, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_CHECKIN_PATH, WORKBUDDY_CONNECT_VERSION, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_MODELS_REFRESH_PATH, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WORKBUDDY_USAGE_PATH, WorkBuddyCatalog, WorkBuddyCredentialStore, WorkBuddyUpstreamClient, apply, authFileName, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthDirs, defaultDesktopAuthPath, deriveCatalog, inject, isHeartbeatProcessAlive, name, parseCreditMultiplier, parseReasoning, parseUpstreamModel, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, registerWorkBuddyStatusRoute, workBuddyModelInput, workBuddyThinkingLevelMap, workBuddyWebStatus, workbuddyAccountId, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath, writeHostHeartbeat };
793
+ export { Config, FALLBACK_WORKBUDDY_MODELS, WORKBUDDY_ACCOUNTS_REFRESH_PATH, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_CHECKIN_PATH, WORKBUDDY_CONNECT_VERSION, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_MODELS_REFRESH_PATH, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WORKBUDDY_USAGE_PATH, WorkBuddyCatalog, WorkBuddyCredentialStore, WorkBuddyUpstreamClient, apply, authFileName, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthDirs, defaultDesktopAuthPath, deriveCatalog, inject, isHeartbeatProcessAlive, name, parseCreditMultiplier, parseReasoning, parseUpstreamModel, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, registerWorkBuddyStatusRoute, toPersistedWorkBuddyModel, workBuddyDisplayName, workBuddyModelInput, workBuddyThinkingLevelMap, workBuddyWebStatus, workbuddyAccountId, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath, writeHostHeartbeat };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-workbuddy",
3
3
  "displayName": "DSH Connect WorkBuddy",
4
4
  "description": "Connect locally signed-in WorkBuddy models to DeepSeek Harness with a read-only credits overview and model management.",
5
- "version": "1.1.2",
5
+ "version": "1.2.0",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",
@@ -75,35 +75,37 @@
75
75
  "url": "https://github.com/dingminhua/dsh-connect-workbuddy/issues"
76
76
  },
77
77
  "peerDependencies": {
78
- "@deepseek-ai/cordis": "^4.0.1-rc.1",
79
- "@deepseek-ai/dsh-atomic-write": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
80
- "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
81
- "@deepseek-ai/dsh-home-paths": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
82
- "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
83
- "@deepseek-ai/dsh-llm": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
84
- "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
85
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
86
- "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-alpha.0 <0.1.3",
87
- "@deepseek-ai/schemastery": "^3.18.1-rc.1",
88
- "@earendil-works/pi-ai": ">=0.82.1 <0.85.0",
78
+ "@deepseek-ai/cordis": ">=4.0.1-rc.1 <5.0.0 || >=4.0.2 <5.0.0",
79
+ "@deepseek-ai/dsh-atomic-write": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
80
+ "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
81
+ "@deepseek-ai/dsh-home-paths": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
82
+ "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
83
+ "@deepseek-ai/dsh-llm": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
84
+ "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
85
+ "@deepseek-ai/dsh-settings": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
86
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.1 <0.2.0 || >=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
87
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
88
+ "@deepseek-ai/schemastery": ">=3.18.1-rc.1 <4.0.0 || >=3.18.2 <4.0.0",
89
+ "@earendil-works/pi-ai": ">=0.82.1 <0.85.0 || >=0.85.0 <0.86.0",
89
90
  "react": "^18.2.0"
90
91
  },
91
92
  "devDependencies": {
92
- "@deepseek-ai/cordis": "^4.0.1",
93
- "@deepseek-ai/dsh-atomic-write": "^0.1.1-rc.2",
94
- "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2",
95
- "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
96
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
97
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
98
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.1-rc.2",
99
- "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
100
- "@deepseek-ai/dsh-home-paths": "^0.1.1-rc.2",
101
- "@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
102
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
103
- "@deepseek-ai/dsh-llm-pi-ai": "^0.1.1-rc.2",
104
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
105
- "@deepseek-ai/schemastery": "3.18.1",
106
- "@earendil-works/pi-ai": "0.82.1",
93
+ "@deepseek-ai/cordis": ">=4.0.1 <5.0.0 || >=4.0.2 <5.0.0",
94
+ "@deepseek-ai/dsh-atomic-write": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
95
+ "@deepseek-ai/dsh-attachment": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
96
+ "@deepseek-ai/dsh-client-locale": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
97
+ "@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
98
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
99
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
100
+ "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
101
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
102
+ "@deepseek-ai/dsh-home-paths": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
103
+ "@deepseek-ai/dsh-host-webserver": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
104
+ "@deepseek-ai/dsh-llm": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
105
+ "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
106
+ "@deepseek-ai/dsh-settings": ">=0.1.1-rc.1 <0.2.0 || >=0.1.2-rc.1 <0.2.0",
107
+ "@deepseek-ai/schemastery": ">=3.18.1 <4.0.0 || >=3.18.2 <4.0.0",
108
+ "@earendil-works/pi-ai": ">=0.82.1 <0.85.0 || >=0.85.0 <0.86.0",
107
109
  "@types/node": "^22.20.0",
108
110
  "@types/react": "~18.3.31",
109
111
  "react": "^18.3.1",