@moonquake2004/dsh-doctor 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -16,6 +16,24 @@
16
16
 
17
17
  ---
18
18
 
19
+ ## [0.6.1] — 2026-09-15
20
+
21
+ ### Fixed — `--boot-check` 在"bundle 缺 `dsh.bundle`"这一类上给假绿灯(社区 #6788)
22
+
23
+ #6788 报告:0.1.6-alpha.1 起 loader **严格要求** `dsh.profile.bundles` 里每个包声明 `dsh.bundle.patch`,
24
+ 而 `@deepseek-ai/dsh-computer-use` 等包发布时**漏了这个字段** → 照文档 `dsh plugin add` 之后 profile **立刻起不来**。
25
+
26
+ 这一类的特点是:**没有任何 entry 可探**(包没有 patch,自然没有 insert 条目),于是只做 import 的
27
+ `--boot-check` 会输出"✓ 所有可探测 entry 均可导入"——而用户恰恰是按我们的建议先跑它的。**假绿灯出现在
28
+ 最该给出结论的时刻**,比不报更糟。
29
+
30
+ 现在 `--boot-check`(及其同步版,供 `--safe-add` 使用)在探测 entry 之前先判 **bundle 级前置条件**:
31
+ 列出的包若解析得到、却没有 `dsh.bundle.patch` → 直接判失败,给出 `missing-bundle-manifest`、
32
+ 修复方向与隔离命令。宿主核心包(`dsh-base`/`dsh-web-app`,由 CLI 提供)照旧跳过。
33
+
34
+ (`P1` 早已覆盖同一类:`bundle 条目 X 存在但未声明 dsh.bundle`——本次修的是**我们最推荐的那条自救路径**
35
+ 没有覆盖它。)
36
+
19
37
  ## [0.6.0] — 2026-09-15
20
38
 
21
39
  ### Added
package/dsh-doctor.mjs CHANGED
@@ -2492,6 +2492,30 @@ function listProfilePackages(profileDir) {
2492
2492
  return out;
2493
2493
  }
2494
2494
 
2495
+
2496
+ /**
2497
+ * 列出 `dsh.profile.bundles` 里**能解析到、但没有 `dsh.bundle`** 的包。
2498
+ * 这类会让 loader 拒绝整个 profile(#6788/#1378),且**没有任何 entry 可探**——
2499
+ * 所以必须由 bundle 级前置条件来判,否则装载模拟会给出假绿灯。
2500
+ * 宿主核心包(如 @deepseek-ai/dsh-base / dsh-web-app)由 CLI 提供、不在 profile node_modules 里,跳过。
2501
+ */
2502
+ function bundlesMissingManifest(profileDir) {
2503
+ const out = [];
2504
+ try {
2505
+ const read = readJsonReportingBom(join(profileDir, 'package.json'));
2506
+ const bundles = read.data?.dsh?.profile?.bundles ?? [];
2507
+ for (const b of bundles) {
2508
+ if (String(b).startsWith('@deepseek-ai/dsh-base') || String(b).startsWith('@deepseek-ai/dsh-web-app')) continue;
2509
+ const mf = join(profileDir, 'node_modules', String(b), 'package.json');
2510
+ if (!existsSync(mf)) continue; // 解析不到 → 由 P1 报(且可能是宿主提供的核心包)
2511
+ const pkg = readJsonReportingBom(mf).data;
2512
+ if (!pkg) continue;
2513
+ if (!pkg.dsh?.bundle?.patch) out.push({ id: String(b), bundle: String(b) });
2514
+ }
2515
+ } catch { /* 读不了就不判 */ }
2516
+ return out;
2517
+ }
2518
+
2495
2519
  /** 解析 profile 的启动列表与各 bundle 的 entry(含用户 patch 的 insert),跳过 disabled 与已隔离项。 */
2496
2520
  function collectBootEntries(profileDir) {
2497
2521
  const manifest = JSON.parse(readFileSync(join(profileDir, 'package.json'), 'utf8'));
@@ -2678,6 +2702,10 @@ function safeAdd(profileArg, pkg) {
2678
2702
  /** 同步版装载模拟(--safe-add 内部用;与 --boot-check 同一逻辑) */
2679
2703
  function runBootCheckSync(profileDir) {
2680
2704
  const out = [];
2705
+ // **bundle 级前置条件**(社区 #6788):loader 要求 `dsh.profile.bundles` 里每个包都声明
2706
+ // `dsh.bundle.patch`,否则**整场启动硬失败**。这类失败**没有任何 entry 可探**,于是只做 import 的
2707
+ // 探针会给出"全部可导入 ✓"的**假绿灯**——而用户是按我们的建议先跑 `--boot-check` 的,被误导的代价最大。
2708
+ for (const miss of bundlesMissingManifest(profileDir)) out.push({ id: miss.id, bundle: miss.bundle, spec: '(bundle 清单)', status: 'failed', kind: 'missing-bundle-manifest', hint: '该包未声明 dsh.bundle(loader 会拒绝整个 profile);升级/更换该包,或从 dsh.profile.bundles 移除', error: `bundle 条目 ${miss.bundle} 存在但未声明 dsh.bundle.patch(#1378/#6788)` });
2681
2709
  for (const e of collectBootEntries(profileDir)) {
2682
2710
  if (!e.name) continue;
2683
2711
  const spec = e.name;
@@ -2741,6 +2769,10 @@ async function runBootCheck(profileDir) {
2741
2769
  const entries = collectBootEntries(profileDir);
2742
2770
  const targets = entries.filter((e) => e.name);
2743
2771
  const results = [];
2772
+ // 同 runBootCheckSync:bundle 级前置条件必须一并判,否则这一类会得到假绿灯(#6788)
2773
+ for (const miss of bundlesMissingManifest(profileDir)) {
2774
+ results.push({ id: miss.id, bundle: miss.bundle, spec: '(bundle 清单)', status: 'failed', kind: 'missing-bundle-manifest', hint: '该包未声明 dsh.bundle(loader 会拒绝整个 profile);升级/更换该包,或从 dsh.profile.bundles 移除', error: `bundle 条目 ${miss.bundle} 存在但未声明 dsh.bundle.patch(#1378/#6788)` });
2775
+ }
2744
2776
  for (const e of targets) {
2745
2777
  const spec = e.name;
2746
2778
  // 宿主内置与相对路径不做 import 探测(前者由宿主提供,后者依赖运行上下文)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonquake2004/dsh-doctor",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Offline diagnostic for DeepSeek Harness — 28 built-in + 5 catalog checks across env/profile/session (Layer A checks-as-data), self-update (Layer B), and a semi-automatic LLM observer (Layer C, --observe); Doctor panel in web UI settings.",
5
5
  "main": "lib/index.js",
6
6
  "files": [