dsh-workbuddy-xdpool 1.7.7 → 1.7.8

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
@@ -4,6 +4,63 @@
4
4
 
5
5
  版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
6
6
 
7
+ ## 1.7.8 — 说清楚卡片在哪儿、以及我们支持到哪个版本
8
+
9
+ > 这次没有功能问题,全在「声明」上:一处把你引到不存在的路径,一处让你以为装错了版本。
10
+
11
+ ### README 的入口路径是 0.1.x 时代的,0.2.0 上按它找不到
12
+
13
+ README 一直写着「设置 → 插件 → DSH WorkBuddy XD Pool」。**0.2.0 起没有这条二层路径了。**
14
+
15
+ 实际位置是:**打开设置面板 → 顶部平级标签里的「XD Pool」**(排在 `通用设置 / 模型 / 内置插件 / Agent 预设` 后面)。开设置面板的方式是**侧边栏左下角的齿轮**,或快捷键 `Ctrl+Alt+,`。
16
+
17
+ 已把 README 三处改掉,并且**补上了开面板的方法**——只写「切到 XD Pool」而不说怎么开设置,等于没写。老路径保留一句「0.1.x 时代叫这个」,方便升级上来的人理解自己的习惯为什么突然不灵了。
18
+
19
+ ### `engines.dsh` 写着 `<0.2.0`,可它在 0.2.0 上跑得好好的
20
+
21
+ 这个声明的问题不在于"保守",而在于**它会把人带偏**:任何人按 `engines` 做兼容判断,第一反应都是"这插件不支持 0.2.0",然后往错误的方向排查。反馈里就有一位因此走了一大圈。
22
+
23
+ 现在放宽到 `<0.3.0`,并且**把三个 host peer 依赖(`dsh-llm` / `dsh-llm-pi-ai` / `dsh-settings`)一起对齐**——它们约束的是同一批宿主包,只改一个反而制造新的不一致。
24
+
25
+ 放宽不等于"什么都接受":上界仍然卡在 `<0.3.0`,**没测过的大版本不该被默认声称支持**。
26
+
27
+ ### 导航图标匹配不上时,现在会说话
28
+
29
+ `installNavIcon()` 靠选择器找设置面板里那一行。**找不到时它完全静默** —— 表现就是"图标没出来",没有任何线索。这次排查里它不是故障点,但它是最贵的一环:**看起来什么都没发生**。
30
+
31
+ 现在连续匹配失败会 `console.warn` 一次,带上选择器、期望的标签、以及**当前导航里实际有什么**:
32
+
33
+ ```
34
+ [dsh-workbuddy-xdpool] the settings nav row could not be found, so the icon was not applied.
35
+ selector="[role=\"dialog\"] nav button" expectedLabel="XD Pool" rowsPresent=["通用设置","模型",...]
36
+ This is cosmetic only — the card itself still works. Please report this line…
37
+ ```
38
+
39
+ **不是每次都喊**:设置面板没打开时找不到是**正常的**(那一行压根不在 DOM 里),每次都喊只会让人学会忽略它。所以只在"面板开着、却连续 N 次找不到"时才报一次,且每轮只报一次。
40
+
41
+ ### 关于那份"0.2.0 删了 slots 服务"的报告
42
+
43
+ 反馈者**自己撤回了**那个结论,我更正一下:**不成立**。
44
+
45
+ 他后来实测到:`__DSH_BOOT__.entries` 含本插件、`importErrors` 为空、客户端 fiber 状态是 ACTIVE、卡片 DOM 完整渲染、`installNavIcon` 正常生效。而且**把 `dsh.client.inject` 改掉再测,行为完全一致** —— 所以那两个包的声明**不会阻断加载,不需要改**。
46
+
47
+ 他复盘出的两个方法论坑,我认为值得原样记下来,因为它们非常容易重犯:
48
+ - 只用正则扫「谁 `provide("name")` 了服务」,漏掉别的声明写法,就宣布服务被删了 —— **典型的假阴性**;
49
+ - 在**会话页**(设置面板没开)dump DOM 搜插件节点,0 命中当成故障证据 —— 而 `settings.section` **只在面板打开时才进 DOM**,0 命中是必然的。
50
+
51
+ `slots` 和 `settings.section` 在 0.2.0 里都健在,渲染方是 `dsh-client-ui-settings-general` 的 `renderSlot("settings.section", …)`。
52
+
53
+ ### 验证
54
+
55
+ - 类型检查全绿,测试 **332 项全绿**(+7)。
56
+ - 新增 `tests/compatibility-declaration.test.ts`:`engines.dsh` 必须容纳 0.2.x、**上界仍要卡住没测过的大版本**、三个 host peer 与 `engines.dsh` 保持一致、README **不得再把老路径当指引**(但允许作为历史说明出现)、必须写出开设置面板的方法。
57
+ - **反向验证**:把 `engines` 退回 `<0.2.0` → 2 项变红;把 README 退回老路径 → 1 项变红。
58
+ - 本机核对宿主代码:`renderSlot("settings.section", { close }, { only: active })` 确为**平级渲染**,插件注册 `order: 440`(排最后),与反馈的实测描述一致。
59
+
60
+ ### 一点说明
61
+
62
+ 我本机是 DSH Desktop 2.0.15(内核 0.1.7-rc.2),**不是 0.2.0-rc.2**,所以我**没法在本地复现 0.2.0 的渲染行为**。本次改动依据的是反馈者提供的实测数据,外加我对本机宿主代码里 `renderSlot` 调用的核对。放宽 `engines` 这个结论我是采信的,但没有在 0.2.0 上亲手验过。
63
+
7
64
  ## 1.7.7 — 别再让你为了一个「等一会儿」去重新登录
8
65
 
9
66
  > 报错说「API 密钥无效」,于是你跑去重新登录 —— 但密钥根本没问题,只是那个模型暂时限流了。
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## 先看几张图
21
21
 
22
- **插件配置卡片(设置 → 插件 → DSH WorkBuddy XD Pool)**
22
+ **插件配置卡片(设置 → 「XD Pool」一节)**
23
23
 
24
24
  ![WorkBuddy 池设置卡片:国内版 / 国际版切换栏、池健康状态、账号面板、积分包与合计、每账号每日签到、积分自动化面板、模型管理](assets/settings-card.png)
25
25
 
@@ -83,9 +83,13 @@
83
83
 
84
84
  ## 安装
85
85
 
86
- 前置条件:装好 WorkBuddy 桌面 App 并登录(插件复用它存在本机的登录状态)。多账号 = 在桌面 App 里换着登几次,每次登录都会被自动吸进池里。已针对 DSH Desktop host `0.1.2` 适配。
86
+ 前置条件:装好 WorkBuddy 桌面 App 并登录(插件复用它存在本机的登录状态)。多账号 = 在桌面 App 里换着登几次,每次登录都会被自动吸进池里。
87
87
 
88
- > 兼容 host `0.1.1-rc.2` / `0.1.2` 系列:安装设置节时会按 host 能力自动选择 `settings.installSection`(0.1.2-rc.1+)或更早的自由函数写法。
88
+ > 兼容 host `0.1.1-rc.2` 起的整个 0.1.x 系列,以及 `0.2.0-rc.2`。安装设置节时会按 host 能力自动选择 `settings.installSection`(0.1.2-rc.1+)或更早的自由函数写法;卡片在 0.2.0 上作为设置面板里一个**平级标签页**渲染。
89
+
90
+ > **卡片在哪儿打开**:DSH 设置面板本身。开法是**侧边栏左下角的齿轮**,或者快捷键 `Ctrl+Alt+,`。
91
+ > 面板顶部是平级标签:`通用设置 / 模型 / 内置插件 / Agent 预设 / XD Pool` —— 本插件就是最后那个 **XD Pool**。
92
+ > (0.1.x 时代它叫「设置 → 插件 → DSH WorkBuddy XD Pool」,0.2.0 起改成了平级标签,按老路径找不到。)
89
93
 
90
94
  **方式一:从 npm 安装(推荐)**
91
95
 
@@ -129,7 +133,7 @@ pnpm typecheck:client # 客户端类型检查
129
133
 
130
134
  > 注意:`pnpm install` 要用 pnpm 11(`npx pnpm@11`),必要时加 `--config.confirmModulesPurge=false --config.minimumReleaseAge=0`——pnpm 11 默认的 `minimumReleaseAge` 供应链年龄策略会拦下刚发布的 rc 包。
131
135
 
132
- 装完以后:模型选择器里会出现 **WorkBuddy XD Pool** 分组;设置 → 插件 → **DSH WorkBuddy XD Pool** 能看池健康、各账号的令牌 / 积分 / 签到 / 冷却状态,还有「重新检测账号」「清除所有冷却」按钮和每个账号的签到按钮。
136
+ 装完以后:模型选择器里会出现 **WorkBuddy XD Pool** 分组;打开设置面板(左下角齿轮或 `Ctrl+Alt+,`)切到 **XD Pool** 一栏,能看池健康、各账号的令牌 / 积分 / 签到 / 冷却状态,还有「重新检测账号」「清除所有冷却」按钮和每个账号的签到按钮。
133
137
 
134
138
  Web / TUI profile 也能用(`--profile web` / `--profile dsh-tui`)。
135
139
 
package/lib/client.js CHANGED
@@ -2536,6 +2536,15 @@ window.__ModuleLoader__.load({
2536
2536
  */
2537
2537
  const NAV_ROW_SELECTOR = "[role=\"dialog\"] nav button";
2538
2538
  /**
2539
+ * How many consecutive in-dialog passes may miss the nav row before the
2540
+ * diagnostic fires.
2541
+ *
2542
+ * Above 1 because a single miss is routine — the shell can re-render between
2543
+ * our mutation callback and the query. Small enough that a genuinely broken
2544
+ * selector is reported within a frame or two of opening the settings panel.
2545
+ */
2546
+ const NAV_ICON_MISS_THRESHOLD = 3;
2547
+ /**
2539
2548
  * Draw this page's own glyph in its Settings nav row.
2540
2549
  *
2541
2550
  * The `settings.section` contract carries no icon: the shell decides the glyph
@@ -2576,13 +2585,46 @@ window.__ModuleLoader__.load({
2576
2585
  document.head.appendChild(tag);
2577
2586
  let disposed = false;
2578
2587
  let scheduled = false;
2588
+ /**
2589
+ * Consecutive passes that found no matching row.
2590
+ *
2591
+ * A miss is NORMAL most of the time: the settings dialog is closed, so its
2592
+ * nav is not in the DOM at all, and the icon stays unapplied by design.
2593
+ * Warning on the first miss would fire constantly and train everyone to
2594
+ * ignore it.
2595
+ *
2596
+ * What is worth reporting is a PERSISTENT miss while the dialog IS open —
2597
+ * that means the shell's nav markup changed and the selector no longer
2598
+ * matches, which is exactly the failure that looks like "nothing happened"
2599
+ * and cost hours to find. So the threshold is a burst of misses, and the
2600
+ * warning is emitted once per burst rather than once per mutation.
2601
+ */
2602
+ let missStreak = 0;
2603
+ let warned = false;
2579
2604
  const sync = () => {
2580
2605
  scheduled = false;
2581
2606
  if (disposed) return;
2582
2607
  const wanted = String(resolveLabel() ?? "").trim();
2583
2608
  if (wanted === "") return;
2584
- for (const row of document.querySelectorAll(NAV_ROW_SELECTOR)) if (String(row.textContent ?? "").trim() === wanted) row.setAttribute(NAV_ICON_MARKER, "");
2585
- else row.removeAttribute(NAV_ICON_MARKER);
2609
+ let matched = 0;
2610
+ for (const row of document.querySelectorAll(NAV_ROW_SELECTOR)) if (String(row.textContent ?? "").trim() === wanted) {
2611
+ row.setAttribute(NAV_ICON_MARKER, "");
2612
+ matched += 1;
2613
+ } else row.removeAttribute(NAV_ICON_MARKER);
2614
+ if (matched > 0) {
2615
+ missStreak = 0;
2616
+ warned = false;
2617
+ return;
2618
+ }
2619
+ if (document.querySelector(NAV_ROW_SELECTOR) === null) {
2620
+ missStreak = 0;
2621
+ return;
2622
+ }
2623
+ missStreak += 1;
2624
+ if (missStreak < NAV_ICON_MISS_THRESHOLD || warned) return;
2625
+ warned = true;
2626
+ const present = [...document.querySelectorAll(NAV_ROW_SELECTOR)].map((row) => String(row.textContent ?? "").trim()).filter((text) => text !== "");
2627
+ console.warn(`[dsh-workbuddy-xdpool] the settings nav row could not be found, so the icon was not applied. selector=${JSON.stringify(NAV_ROW_SELECTOR)} expectedLabel=${JSON.stringify(wanted)} rowsPresent=${JSON.stringify(present)}. This is cosmetic only — the card itself still works. Please report this line so the selector can be updated.`);
2586
2628
  };
2587
2629
  const schedule = () => {
2588
2630
  if (scheduled || disposed) return;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-workbuddy-xdpool",
3
3
  "displayName": "DSH WorkBuddy XD Pool",
4
4
  "description": "Merge every locally signed-in WorkBuddy account into DeepSeek Harness as one auto-failing-over model pool (multi-account rotation, live credits, daily check-in and model catalog).",
5
- "version": "1.7.7",
5
+ "version": "1.7.8",
6
6
  "license": "MIT",
7
7
  "author": "XDTrees",
8
8
  "homepage": "https://github.com/XDTrees/dsh-workbuddy-xdpool#readme",
@@ -25,7 +25,7 @@
25
25
  "type": "module",
26
26
  "engines": {
27
27
  "node": "^22.19.0 || >=24.0.0",
28
- "dsh": ">=0.1.5-rc.1 <0.2.0"
28
+ "dsh": ">=0.1.5-rc.1 <0.3.0"
29
29
  },
30
30
  "main": "lib/index.js",
31
31
  "types": "lib/index.d.ts",
@@ -99,9 +99,9 @@
99
99
  },
100
100
  "peerDependencies": {
101
101
  "@deepseek-ai/cordis": "^4.0.1-rc.1",
102
- "@deepseek-ai/dsh-llm": ">=0.1.1-rc.1 <0.2.0",
103
- "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.1-rc.1 <0.2.0",
104
- "@deepseek-ai/dsh-settings": ">=0.1.1-rc.1 <0.2.0",
102
+ "@deepseek-ai/dsh-llm": ">=0.1.1-rc.1 <0.3.0",
103
+ "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.1-rc.1 <0.3.0",
104
+ "@deepseek-ai/dsh-settings": ">=0.1.1-rc.1 <0.3.0",
105
105
  "@deepseek-ai/schemastery": "^3.18.1",
106
106
  "@earendil-works/pi-ai": ">=0.82.1"
107
107
  },