@customize-agent/server 4.58.0 → 4.59.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 (226) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +132 -143
  3. package/.next/prerender-manifest.json +3 -3
  4. package/.next/routes-manifest.json +117 -9
  5. package/.next/server/chunks/1001.js +56 -0
  6. package/.next/server/chunks/1928.js +1 -1
  7. package/.next/server/chunks/1936.js +2 -2
  8. package/.next/server/chunks/2434.js +4 -0
  9. package/.next/server/chunks/299.js +50 -0
  10. package/.next/server/chunks/5547.js +350 -0
  11. package/.next/server/chunks/6087.js +3 -0
  12. package/.next/server/chunks/6321.js +3 -0
  13. package/.next/server/chunks/8204.js +1 -1
  14. package/.next/server/middleware-build-manifest.js +1 -1
  15. package/.next/server/pages/404.html +1 -1
  16. package/.next/server/pages/500.html +1 -1
  17. package/.next/server/pages/api/assets/generated/preview.js +1 -1
  18. package/.next/server/pages/api/assets/generated/preview.js.nft.json +1 -1
  19. package/.next/server/pages/api/assets/generated.js +1 -1
  20. package/.next/server/pages/api/assets/generated.js.nft.json +1 -1
  21. package/.next/server/pages/api/config/embedding/healthCheck.js.nft.json +1 -1
  22. package/.next/server/pages/api/config/healthCheck.js +2 -2
  23. package/.next/server/pages/api/config/providers.js +2 -2
  24. package/.next/server/pages/api/documents/canvas/[id].js +2 -0
  25. package/.next/server/pages/api/documents/canvas/[id].js.nft.json +1 -0
  26. package/.next/server/pages/api/documents/export.js +3 -3
  27. package/.next/server/pages/api/documents/export.js.nft.json +1 -1
  28. package/.next/server/pages/api/documents/generate/preview.js +2 -0
  29. package/.next/server/pages/api/documents/generate/preview.js.nft.json +1 -0
  30. package/.next/server/pages/api/documents/generate.js +2 -2
  31. package/.next/server/pages/api/documents/generate.js.nft.json +1 -1
  32. package/.next/server/pages/api/documents/generated/[id]/events.js +10 -0
  33. package/.next/server/pages/api/documents/generated/[id]/events.js.nft.json +1 -0
  34. package/.next/server/pages/api/documents/generated/[id]/figure/[name].js +1 -0
  35. package/.next/server/pages/api/documents/generated/[id]/figure/[name].js.nft.json +1 -0
  36. package/.next/server/pages/api/documents/generated/[id]/nodes/[nodeId].js +2 -0
  37. package/.next/server/pages/api/documents/generated/[id]/nodes/[nodeId].js.nft.json +1 -0
  38. package/.next/server/pages/api/documents/generated/[id]/nodes.js +2 -0
  39. package/.next/server/pages/api/documents/generated/[id]/nodes.js.nft.json +1 -0
  40. package/.next/server/pages/api/documents/generated/[id]/pause.js +2 -0
  41. package/.next/server/pages/api/documents/generated/[id]/pause.js.nft.json +1 -0
  42. package/.next/server/pages/api/documents/generated/[id]/preview.js +2 -0
  43. package/.next/server/pages/api/documents/generated/[id]/preview.js.nft.json +1 -0
  44. package/.next/server/pages/api/documents/generated/[id]/repair/[rid]/confirm.js +1 -0
  45. package/.next/server/pages/api/documents/generated/[id]/repair/[rid]/confirm.js.nft.json +1 -0
  46. package/.next/server/pages/api/documents/generated/[id]/repair/[rid]/rollback.js +1 -0
  47. package/.next/server/pages/api/documents/generated/[id]/repair/[rid]/rollback.js.nft.json +1 -0
  48. package/.next/server/pages/api/documents/generated/[id]/repair.js +1 -0
  49. package/.next/server/pages/api/documents/generated/[id]/repair.js.nft.json +1 -0
  50. package/.next/server/pages/api/documents/generated/[id]/resume-generate.js +2 -0
  51. package/.next/server/pages/api/documents/generated/[id]/resume-generate.js.nft.json +1 -0
  52. package/.next/server/pages/api/documents/generated/[id].js +2 -2
  53. package/.next/server/pages/api/documents/generated/[id].js.nft.json +1 -1
  54. package/.next/server/pages/api/documents/generated.js +1 -1
  55. package/.next/server/pages/api/documents/generated.js.nft.json +1 -1
  56. package/.next/server/pages/api/jobs/[id].js +1 -1
  57. package/.next/server/pages/api/jobs/[id].js.nft.json +1 -1
  58. package/.next/server/pages/api/jobs.js +1 -1
  59. package/.next/server/pages/api/jobs.js.nft.json +1 -1
  60. package/.next/server/pages/api/kb/categories.js +2 -2
  61. package/.next/server/pages/api/kb/categories.js.nft.json +1 -1
  62. package/.next/server/pages/api/kb/duplicates.js +2 -2
  63. package/.next/server/pages/api/kb/duplicates.js.nft.json +1 -1
  64. package/.next/server/pages/api/kb/evaluate.js +3 -3
  65. package/.next/server/pages/api/kb/evaluate.js.nft.json +1 -1
  66. package/.next/server/pages/api/kb/files/detail.js +4 -4
  67. package/.next/server/pages/api/kb/files/detail.js.nft.json +1 -1
  68. package/.next/server/pages/api/kb/files/export.js +3 -3
  69. package/.next/server/pages/api/kb/files/export.js.nft.json +1 -1
  70. package/.next/server/pages/api/kb/files/open.js +2 -2
  71. package/.next/server/pages/api/kb/files/open.js.nft.json +1 -1
  72. package/.next/server/pages/api/kb/files/preview-pdf-page.js +1 -1
  73. package/.next/server/pages/api/kb/files/preview-pdf-page.js.nft.json +1 -1
  74. package/.next/server/pages/api/kb/files/reindex.js +1 -1
  75. package/.next/server/pages/api/kb/files/reindex.js.nft.json +1 -1
  76. package/.next/server/pages/api/kb/files/search.js +3 -3
  77. package/.next/server/pages/api/kb/files/search.js.nft.json +1 -1
  78. package/.next/server/pages/api/kb/files/tree.js +3 -3
  79. package/.next/server/pages/api/kb/files/tree.js.nft.json +1 -1
  80. package/.next/server/pages/api/kb/files.js +4 -4
  81. package/.next/server/pages/api/kb/files.js.nft.json +1 -1
  82. package/.next/server/pages/api/kb/ignore.js +2 -2
  83. package/.next/server/pages/api/kb/ignore.js.nft.json +1 -1
  84. package/.next/server/pages/api/kb/intelligence.js +1 -1
  85. package/.next/server/pages/api/kb/intelligence.js.nft.json +1 -1
  86. package/.next/server/pages/api/kb/material-groups.js +2 -0
  87. package/.next/server/pages/api/kb/material-groups.js.nft.json +1 -0
  88. package/.next/server/pages/api/kb/operations.js +1 -1
  89. package/.next/server/pages/api/kb/operations.js.nft.json +1 -1
  90. package/.next/server/pages/api/kb/reindex.js +1 -1
  91. package/.next/server/pages/api/kb/reindex.js.nft.json +1 -1
  92. package/.next/server/pages/api/kb/search.js +2 -2
  93. package/.next/server/pages/api/kb/search.js.nft.json +1 -1
  94. package/.next/server/pages/api/kb/stats.js +2 -2
  95. package/.next/server/pages/api/kb/stats.js.nft.json +1 -1
  96. package/.next/server/pages/api/kb/tags.js +1 -1
  97. package/.next/server/pages/api/kb/tags.js.nft.json +1 -1
  98. package/.next/server/pages/api/kb/upload/complete.js +1 -1
  99. package/.next/server/pages/api/kb/upload/complete.js.nft.json +1 -1
  100. package/.next/server/pages/api/kb/upload/progress.js +2 -2
  101. package/.next/server/pages/api/kb/upload/progress.js.nft.json +1 -1
  102. package/.next/server/pages/api/kb/upload.js +1 -1
  103. package/.next/server/pages/api/kb/upload.js.nft.json +1 -1
  104. package/.next/server/pages/api/prompt.js +1 -1
  105. package/.next/server/pages/api/prompt.js.nft.json +1 -1
  106. package/.next/server/pages/api/skills/[id].js +1 -0
  107. package/.next/server/pages/api/skills/[id].js.nft.json +1 -0
  108. package/.next/server/pages/api/skills/validate.js +1 -0
  109. package/.next/server/pages/api/skills/validate.js.nft.json +1 -0
  110. package/.next/server/pages/api/skills.js +1 -0
  111. package/.next/server/pages/api/skills.js.nft.json +1 -0
  112. package/.next/server/pages/api/system/logs.js +2 -2
  113. package/.next/server/pages/api/system/stats.js +1 -1
  114. package/.next/server/pages/canvas/[id].html +1 -0
  115. package/.next/server/pages/canvas/[id].js.nft.json +1 -0
  116. package/.next/server/pages/canvas.html +1 -0
  117. package/.next/server/pages/canvas.js.nft.json +1 -0
  118. package/.next/server/pages/documents.html +1 -1
  119. package/.next/server/pages/documents.js.nft.json +1 -1
  120. package/.next/server/pages/guide.html +1 -1
  121. package/.next/server/pages/index.html +1 -1
  122. package/.next/server/pages/knowledge/file-detail.html +1 -1
  123. package/.next/server/pages/knowledge/files.html +1 -1
  124. package/.next/server/pages/knowledge/files.js.nft.json +1 -1
  125. package/.next/server/pages/knowledge/manage.html +1 -1
  126. package/.next/server/pages/knowledge/manage.js.nft.json +1 -1
  127. package/.next/server/pages/knowledge.html +1 -1
  128. package/.next/server/pages/knowledge.js.nft.json +1 -1
  129. package/.next/server/pages/models.html +1 -1
  130. package/.next/server/pages/overview.html +1 -1
  131. package/.next/server/pages/prompt.html +1 -1
  132. package/.next/server/pages/settings.html +1 -1
  133. package/.next/server/pages/skills.html +1 -0
  134. package/.next/server/pages/system/logs.html +1 -1
  135. package/.next/server/pages-manifest.json +41 -28
  136. package/.next/static/4xQDkixSretJDM503EzIq/_buildManifest.js +1 -0
  137. package/.next/static/chunks/127-20f09f6ebe1e6c1f.js +1 -0
  138. package/.next/static/chunks/174-1bc48f295d7dd075.js +10 -0
  139. package/.next/static/chunks/189-3f4f4e237056adaf.js +4 -0
  140. package/.next/static/chunks/243-03eba51d5d737e98.js +1 -0
  141. package/.next/static/chunks/269-7a3502478bf67fff.js +11 -0
  142. package/.next/static/chunks/289-0cccd8131332e041.js +78 -0
  143. package/.next/static/chunks/310-6c678cb70e4ba2d6.js +19 -0
  144. package/.next/static/chunks/422-46f07037c58d2309.js +1 -0
  145. package/.next/static/chunks/426-22c4cedb04b0d45d.js +21 -0
  146. package/.next/static/chunks/445-d12731f107978b10.js +6 -0
  147. package/.next/static/chunks/530-6f3f5848c6f702ae.js +1 -0
  148. package/.next/static/chunks/569-2bfdde9e402af5b2.js +16 -0
  149. package/.next/static/chunks/700-5d29b0475311f590.js +1 -0
  150. package/.next/static/chunks/709-a7c652953ccd3b4b.js +1 -0
  151. package/.next/static/chunks/787-207289f4bb577708.js +10 -0
  152. package/.next/static/chunks/795-9e0cb0bb11e8c89f.js +1 -0
  153. package/.next/static/chunks/914-292edce0ba2a212d.js +1 -0
  154. package/.next/static/chunks/{framework-161be364fd69a7ce.js → framework-4b565b3ddc94cdac.js} +1 -1
  155. package/.next/static/chunks/main-0c91f573696223ca.js +1 -0
  156. package/.next/static/chunks/pages/_app-ebb535779b63fd5d.js +185 -0
  157. package/.next/static/chunks/pages/canvas/[id]-515edd3e72acaf82.js +1 -0
  158. package/.next/static/chunks/pages/canvas-323d44fe56d685a7.js +1 -0
  159. package/.next/static/chunks/pages/documents-e6a80f2de39c6fd2.js +1 -0
  160. package/.next/static/chunks/pages/guide-7367305082617e3c.js +1 -0
  161. package/.next/static/chunks/pages/knowledge/file-detail-aee7c15541d1d130.js +1 -0
  162. package/.next/static/chunks/pages/knowledge/files-b3ef5324e4b74c4a.js +1 -0
  163. package/.next/static/chunks/pages/knowledge/manage-d9eaebf3a8307953.js +1 -0
  164. package/.next/static/chunks/pages/knowledge-09dde24cdce1b195.js +1 -0
  165. package/.next/static/chunks/pages/models-8b96ba85131d5408.js +1 -0
  166. package/.next/static/chunks/pages/prompt-6a224562d194cb45.js +1 -0
  167. package/.next/static/chunks/pages/settings-0a7709bf039a2a4d.js +1 -0
  168. package/.next/static/chunks/pages/skills-3d77213c3e9ef0b5.js +1 -0
  169. package/.next/static/chunks/pages/system/logs-70790bee46e5a08d.js +1 -0
  170. package/.next/static/chunks/webpack-6224d37324e372cb.js +1 -0
  171. package/.next/static/css/85c434f8fd3a17ae.css +1 -0
  172. package/messages/en-US.json +108 -344
  173. package/messages/zh-CN.json +109 -345
  174. package/package.json +6 -5
  175. package/scripts/capture-baseline.mjs +541 -0
  176. package/scripts/half-built-scan.mjs +150 -0
  177. package/.next/server/chunks/208.js +0 -136
  178. package/.next/server/chunks/4435.js +0 -250
  179. package/.next/server/chunks/5840.js +0 -1
  180. package/.next/server/pages/api/documents/drafts.js +0 -1
  181. package/.next/server/pages/api/documents/drafts.js.nft.json +0 -1
  182. package/.next/server/pages/api/documents/refine.js +0 -13
  183. package/.next/server/pages/api/documents/refine.js.nft.json +0 -1
  184. package/.next/server/pages/api/documents/roles.js +0 -1
  185. package/.next/server/pages/api/documents/roles.js.nft.json +0 -1
  186. package/.next/server/pages/api/documents/templates.js +0 -1
  187. package/.next/server/pages/api/documents/templates.js.nft.json +0 -1
  188. package/.next/server/pages/asset-library.html +0 -1
  189. package/.next/server/pages/document-roles.html +0 -1
  190. package/.next/server/pages/document-roles.js.nft.json +0 -1
  191. package/.next/static/2vWd2mBe-maL25SFytCur/_buildManifest.js +0 -1
  192. package/.next/static/chunks/195-2c0168eacab722d2.js +0 -1
  193. package/.next/static/chunks/289-35ac595388bbd018.js +0 -78
  194. package/.next/static/chunks/44-d3545eedd5c75ef1.js +0 -4
  195. package/.next/static/chunks/455-e1b41ac4946d2b6f.js +0 -6
  196. package/.next/static/chunks/563-b12f299d34bb9e44.js +0 -1
  197. package/.next/static/chunks/665-88e20299084b9e73.js +0 -1
  198. package/.next/static/chunks/7-20bcc985742a9ae1.js +0 -10
  199. package/.next/static/chunks/717-743b697a417dd5ee.js +0 -4
  200. package/.next/static/chunks/760-f8bb8e969c5e0d57.js +0 -1
  201. package/.next/static/chunks/787-c18af810af3433f6.js +0 -25
  202. package/.next/static/chunks/788-3afeb069ed706ac0.js +0 -1
  203. package/.next/static/chunks/795-cd94e8d4e9768eb9.js +0 -1
  204. package/.next/static/chunks/81-c3a7f04d96ea3f7d.js +0 -1
  205. package/.next/static/chunks/827-a6dc09e42833e6a3.js +0 -1
  206. package/.next/static/chunks/883-506cbca959974997.js +0 -16
  207. package/.next/static/chunks/986-49b865de7906320a.js +0 -8
  208. package/.next/static/chunks/994-241f87efc61005b8.js +0 -4
  209. package/.next/static/chunks/main-91fb767ebd74c9c1.js +0 -1
  210. package/.next/static/chunks/pages/_app-66149ba52ad1dc26.js +0 -185
  211. package/.next/static/chunks/pages/asset-library-a1047694e888e655.js +0 -1
  212. package/.next/static/chunks/pages/document-roles-5620a98d6312f81c.js +0 -1
  213. package/.next/static/chunks/pages/documents-d60a47643f5bd6b4.js +0 -1
  214. package/.next/static/chunks/pages/guide-a411c554520b7109.js +0 -1
  215. package/.next/static/chunks/pages/knowledge/file-detail-fe69eb38d70adea0.js +0 -1
  216. package/.next/static/chunks/pages/knowledge/files-8e25066889a85834.js +0 -1
  217. package/.next/static/chunks/pages/knowledge/manage-d0d0e0716e9d705b.js +0 -1
  218. package/.next/static/chunks/pages/knowledge-905248d8dcb15453.js +0 -1
  219. package/.next/static/chunks/pages/models-6ef838f3e00ba21e.js +0 -1
  220. package/.next/static/chunks/pages/prompt-5e1fb81efc656866.js +0 -1
  221. package/.next/static/chunks/pages/settings-810eb1a6cf1a6b02.js +0 -1
  222. package/.next/static/chunks/pages/system/logs-6f45ef8d862759a2.js +0 -1
  223. package/.next/static/chunks/webpack-4224e970a97a4a86.js +0 -1
  224. package/.next/static/css/18018ee565a1deba.css +0 -1
  225. /package/.next/server/pages/{asset-library.js.nft.json → skills.js.nft.json} +0 -0
  226. /package/.next/static/{2vWd2mBe-maL25SFytCur → 4xQDkixSretJDM503EzIq}/_ssgManifest.js +0 -0
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 半成品扫描器(2026-09-28)。
4
+ *
5
+ * ## 为什么要有它
6
+ * 用户口径:「每次问你都会遗漏很多东西,都会有很多都是半成品」。
7
+ * 结构性原因不是"不够仔细",而是:**仓库里已有九份缺口账本,散在九个文件里,没有一处汇总**——
8
+ * 所以任何一次凭记忆回答都必然只覆盖一两份(见 `docs/half-built-inventory-2026-09-28.md` 第零节)。
9
+ *
10
+ * 本脚本负责的是**账本记不住的那一类**:**声明了、实现了,但生产代码里零调用点**。
11
+ *
12
+ * ## 判定口径(刻意保守)
13
+ * 对每个导出符号分别统计:
14
+ * - `inFile`:**本文件内**引用次数(扣掉声明行本身)——>0 说明它是模块内部实现的一部分(正常);
15
+ * - `otherProd`:**其它生产文件**引用次数——**这是唯一判定"接线与否"的量**;
16
+ * - `tests`:测试目录引用次数——>0 且 otherProd=0 = **典型的"只在测试里活着"**。
17
+ *
18
+ * 三种分类:
19
+ * | 分类 | 判据 | 含义 |
20
+ * |---|---|---|
21
+ * | 半成品嫌疑 | otherProd=0 且 tests>0 | 写好了、测过了,生产里没人用 |
22
+ * | 谁都不用 | inFile=0 且 otherProd=0 且 tests=0 | 真死代码,或被取代的旧 API |
23
+ * | 封装暴露 | otherProd=0 但 inFile>0 | 只是导出给测试用,**不是**半成品 |
24
+ *
25
+ * ## 已知局限(写在这里,免得被当成结论用)
26
+ * - **动态引用识别不了**:`await import('...')`、字符串派发、计算属性访问都会漏判 ⇒ 会误报;
27
+ * - 因此本脚本的输出是**候选清单**,逐条必须 grep 复核后才能写进账本;
28
+ * 实测教训:本轮用它测"画布标签表",头两版都测错(表其实是完整的),最后以读文件逐键核对为准。
29
+ *
30
+ * ## 用法
31
+ * node apps/server/scripts/half-built-scan.mjs # 全仓
32
+ * node apps/server/scripts/half-built-scan.mjs apps/server/src/services # 指定目录
33
+ */
34
+ import fs from 'node:fs';
35
+ import path from 'node:path';
36
+ import { fileURLToPath } from 'node:url';
37
+
38
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
39
+ const ROOT = path.resolve(HERE, '../../..'); // 仓库根
40
+ const DEFAULT_DIRS = ['apps/server/src', 'packages'];
41
+ const DIRS = process.argv.slice(2).length > 0 ? process.argv.slice(2) : DEFAULT_DIRS;
42
+
43
+ const TEST_HINT = /(^|\/)(test|tests|__tests__|__mocks__)\//;
44
+ const isSource = file => /\.(ts|tsx)$/.test(file) && !/\.d\.ts$/.test(file);
45
+ const SKIP_DIRS = new Set(['node_modules', 'dist', '.next', 'coverage']);
46
+
47
+ function walk(dir, out = []) {
48
+ if (!fs.existsSync(dir)) return out;
49
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
50
+ const full = path.join(dir, entry.name);
51
+ if (entry.isDirectory()) {
52
+ if (SKIP_DIRS.has(entry.name)) continue;
53
+ walk(full, out);
54
+ } else if (isSource(full)) out.push(full);
55
+ }
56
+ return out;
57
+ }
58
+
59
+ /**
60
+ * ★ **引用池永远是全仓,报告范围才是参数**(2026-09-28 实测修正)。
61
+ *
62
+ * 第一版把"其它生产文件"也限定在扫描目录内 ⇒ 扫 `services/agent` 时,调用点落在
63
+ * `document-workflow` 的 `closePhaseNode` / `closeDanglingConnections` 被误报成"谁都不用"。
64
+ * **工具撒谎比没有工具更糟**:这会让人去删正在用的代码。
65
+ */
66
+ const ALL_DIRS = DEFAULT_DIRS;
67
+ const allFiles = ALL_DIRS.flatMap(dir => walk(path.resolve(ROOT, dir)));
68
+ const texts = new Map(allFiles.map(f => [f, fs.readFileSync(f, 'utf8')]));
69
+ const prod = allFiles.filter(f => !TEST_HINT.test(f));
70
+ const tests = allFiles.filter(f => TEST_HINT.test(f));
71
+ const scopeRoots = DIRS.map(dir => path.resolve(ROOT, dir));
72
+ const inScope = file => scopeRoots.some(root => file.startsWith(root + path.sep) || file === root);
73
+
74
+ const EXPORT_PATTERNS = [
75
+ [/^export\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/gm, 'fn'],
76
+ [/^export\s+class\s+([A-Za-z_$][\w$]*)/gm, 'class'],
77
+ [/^export\s+(?:const|let|var)\s+([A-Za-z_$][\w$]*)/gm, 'const'],
78
+ ];
79
+
80
+ function countRefs(name, pool, selfFile, subtractDeclaration) {
81
+ const re = new RegExp(`\\b${name.replace(/\$/g, '\\$')}\\b`, 'g');
82
+ let total = 0;
83
+ for (const file of pool) {
84
+ let hits = (texts.get(file).match(re) || []).length;
85
+ if (subtractDeclaration && file === selfFile) {
86
+ const decl = new RegExp(`^export\\s+(async\\s+)?(function|class|const|let|var)\\s+${name.replace(/\$/g, '\\$')}\\b`, 'gm');
87
+ hits -= (texts.get(file).match(decl) || []).length;
88
+ }
89
+ total += Math.max(0, hits);
90
+ }
91
+ return total;
92
+ }
93
+
94
+ const rows = [];
95
+ for (const file of prod) {
96
+ if (!inScope(file)) continue; // 报告范围 = 参数;引用池 = 全仓
97
+ const rel = path.relative(ROOT, file);
98
+ const text = texts.get(file);
99
+ for (const [pattern, kind] of EXPORT_PATTERNS) {
100
+ for (const match of text.matchAll(pattern)) {
101
+ const name = match[1];
102
+ if (name.length < 4) continue;
103
+ const inFile = countRefs(name, [file], file, true);
104
+ const otherProd = countRefs(name, prod.filter(f => f !== file), file, false);
105
+ const testRefs = countRefs(name, tests, file, false);
106
+ if (otherProd > 0) continue;
107
+ rows.push({
108
+ rel, name, kind, inFile, testRefs,
109
+ verdict: inFile === 0 && testRefs === 0 ? '谁都不用'
110
+ : inFile === 0 && testRefs > 0 ? '半成品嫌疑'
111
+ : '封装暴露(只导出给测试)',
112
+ });
113
+ }
114
+ }
115
+ }
116
+
117
+ const byVerdict = verdict => rows.filter(r => r.verdict === verdict);
118
+ const suspect = byVerdict('半成品嫌疑');
119
+ const unused = byVerdict('谁都不用');
120
+
121
+ console.log('════════ 半成品扫描 ════════');
122
+ console.log(`扫描范围:${DIRS.join(', ')}(引用池 = 全仓 ${prod.length} 个生产文件 / ${tests.length} 个测试文件)`);
123
+ console.log(`导出符号在他处生产零引用:${rows.length}`);
124
+ console.log(` · 半成品嫌疑(仅测试引用) ${suspect.length}`);
125
+ console.log(` · 谁都不用(含自身文件) ${unused.length}`);
126
+ console.log(` · 封装暴露(本文件内自用) ${byVerdict('封装暴露(只导出给测试)').length}`);
127
+
128
+ const print = (title, list, limit = 40) => {
129
+ if (list.length === 0) return;
130
+ console.log(`\n── ${title}(${list.length} 条,列前 ${Math.min(limit, list.length)})`);
131
+ for (const row of list.slice(0, limit)) {
132
+ console.log(` ${row.rel} :: ${row.name}${row.testRefs ? ` (测试引用 ${row.testRefs})` : ''}`);
133
+ }
134
+ };
135
+ print('半成品嫌疑', suspect);
136
+ print('谁都不用', unused, 30);
137
+
138
+ console.log('\n════════ 另外九份账本(本脚本扫不到,必须一起看)════════');
139
+ for (const line of [
140
+ 'L1 A/B 接线缺口 test/services/agent/detailLayerWiring.test.ts 的 WIRING_GAPS',
141
+ 'L2 N 类判据处置表 document-workflow/nClassJudges.ts 的 N_CLASS_JUDGE_DISPOSITIONS',
142
+ 'L3 写作期处置欠账 detectorFixerRegistry.ts 的 PENDING_WRITING_TIME_DISPOSITION',
143
+ 'L4 未锚定修复轮 agent/tools/repairRounds.ts 的 unanchoredRepairRounds()',
144
+ 'L5 manual 检测器 detectorFixerRegistry 的 fixerDisposition==="manual"(54 条)',
145
+ 'L6 工具面空壳(已删) services/agent/toolRegistry.ts 的删除记录',
146
+ 'L7 91 条对照表缺口 docs/closure-checklist-mapping-2026-09-28.md',
147
+ 'L8 机制级缺口 docs/judgment-completeness-2026-09-28.md',
148
+ 'L9 零生产者节点类型 docs/half-built-inventory-2026-09-28.md 第一节',
149
+ ]) console.log(` ${line}`);
150
+ console.log('\n完整口径与不确定性见 docs/half-built-inventory-2026-09-28.md。');