@moonquake2004/dsh-doctor 0.4.0 → 0.4.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.
Files changed (2) hide show
  1. package/dsh-doctor.mjs +21 -7
  2. package/package.json +2 -2
package/dsh-doctor.mjs CHANGED
@@ -335,6 +335,10 @@ function checkProfile(name) {
335
335
  for (const b of bundles) {
336
336
  const dir2 = findPkg(b);
337
337
  if (!dir2) {
338
+ // installAnchor 为 null(web GUI/无 dsh 锚点)时,宿主侧 bundle 无法验证——
339
+ // 跳过而非误报(#917 core bundles dsh-base/dsh-web-app 由宿主直接提供,
340
+ // 不在 profile node_modules 里,installAnchor 缺失时 findPkg 找不到是正常的)
341
+ if (!installAnchor) continue;
338
342
  report('profile', 'P1', false, `bundle 条目 ${b} 无法在安装目录或 profile node_modules 解析(#917/#1377/#880)`, `dsh plugin --profile ${name} add ${b} 或从 dsh.profile.bundles 移除`);
339
343
  } else {
340
344
  const pkg = JSON.parse(readFileSync(join(dir2, 'package.json'), 'utf8'));
@@ -343,19 +347,28 @@ function checkProfile(name) {
343
347
  }
344
348
  }
345
349
  }
346
- // P2 id 冲突
347
- const bundleIds = new Set();
350
+ // P2 id 冲突(#1404 bundle↔user + #2315 bundle↔bundle)
351
+ const bundleIdSources = new Map(); // id → Set<bundle name>
348
352
  for (const b of bundles) {
349
353
  const dir2 = findPkg(b);
350
354
  if (!dir2) continue;
351
355
  const pkg = JSON.parse(readFileSync(join(dir2, 'package.json'), 'utf8'));
352
356
  const rel = pkg.dsh?.bundle?.patch;
353
357
  if (!rel) continue;
354
- for (const id of readInsertIds(join(dir2, rel))) bundleIds.add(id);
358
+ for (const id of readInsertIds(join(dir2, rel))) {
359
+ if (!bundleIdSources.has(id)) bundleIdSources.set(id, new Set());
360
+ bundleIdSources.get(id).add(b);
361
+ }
355
362
  }
356
- const dup = [...bundleIds].filter((id) => userIds.has(id));
357
- if (dup.length) {
358
- report('profile', 'P2', false, `bundle 与用户 patch 的 id 冲突(启动必崩 duplicate loader entry id,#1404): ${dup.join(', ')}`, `备份后从 ${patchPath} 删除这些 insert(或运行 check-dsh-profile.mjs 查看详情)`);
363
+ // bundle 冲突:多个 bundle 注册同一 entry id(#2315 dsh-tui↔dsh-web-app agent-presets)
364
+ const crossBundleDup = [...bundleIdSources].filter(([, s]) => s.size > 1).map(([id, s]) => `${id}(${[...s].join(' + ')})`);
365
+ // bundle vs 用户 patch 冲突(#1404
366
+ const userBundleDup = [...bundleIdSources.keys()].filter((id) => userIds.has(id));
367
+ const p2Issues = [];
368
+ if (crossBundleDup.length) p2Issues.push(`多个 bundle 注册相同 entry id(启动必崩 duplicate loader entry id,#2315): ${crossBundleDup.join('; ')}`);
369
+ if (userBundleDup.length) p2Issues.push(`bundle 与用户 patch 的 id 冲突(启动必崩 duplicate loader entry id,#1404): ${userBundleDup.join(', ')}`);
370
+ if (p2Issues.length) {
371
+ report('profile', 'P2', false, p2Issues.join(' | '), crossBundleDup.length ? '移除冲突 bundle 中的一个(如不兼容的 TUI/standalone 插件误装入 profile),或让上游协商唯一 entry id' : `备份后从 ${patchPath} 删除这些 insert(或运行 check-dsh-profile.mjs 查看详情)`);
359
372
  } else {
360
373
  report('profile', 'P2', true, '无 bundle/用户 patch id 冲突', undefined);
361
374
  }
@@ -395,7 +408,8 @@ function checkProfile(name) {
395
408
  const fp = join(topDir, p);
396
409
  let st;
397
410
  try { st = lstatSync(fp); } catch { continue; }
398
- if (st.isSymbolicLink() && hostScope) {
411
+ if (st.isSymbolicLink()) {
412
+ if (!hostScope) continue; // installAnchor 缺失时无法验证 symlink 指向宿主——跳过(#1697 workaround 已知安全形态)
399
413
  try {
400
414
  const real = realpathSync(fp);
401
415
  const hostPkg = join(hostScope, p);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonquake2004/dsh-doctor",
3
- "version": "0.4.0",
3
+ "version": "0.4.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": [
@@ -48,4 +48,4 @@
48
48
  "bin": {
49
49
  "dsh-doctor": "./dsh-doctor.mjs"
50
50
  }
51
- }
51
+ }