@dommaker/harness 0.19.0 → 1.1.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.
Files changed (398) hide show
  1. package/CHANGELOG.md +22 -9
  2. package/bin/harness.js +136 -557
  3. package/dist/cli/commands/check.d.ts.map +1 -1
  4. package/dist/cli/commands/check.js +2 -13
  5. package/dist/cli/commands/check.js.map +1 -1
  6. package/dist/cli/commands/definitions.d.ts +90 -0
  7. package/dist/cli/commands/definitions.d.ts.map +1 -0
  8. package/dist/cli/commands/definitions.js +519 -0
  9. package/dist/cli/commands/definitions.js.map +1 -0
  10. package/dist/cli/commands/knowledge.js.map +1 -1
  11. package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
  12. package/dist/cli/commands/sync-docs/agents-syncer.js +25 -4
  13. package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
  14. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +3 -25
  15. package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
  16. package/dist/cli/commands/sync-docs/capabilities-syncer.js +3 -93
  17. package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
  18. package/dist/cli/commands/sync-docs/index.d.ts +1 -1
  19. package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
  20. package/dist/cli/commands/sync-docs/index.js +4 -4
  21. package/dist/cli/commands/sync-docs/index.js.map +1 -1
  22. package/dist/completion-checkers/classify.d.ts +23 -0
  23. package/dist/completion-checkers/classify.d.ts.map +1 -0
  24. package/dist/completion-checkers/classify.js +37 -0
  25. package/dist/completion-checkers/classify.js.map +1 -0
  26. package/dist/completion-checkers/contract-presence.d.ts +12 -0
  27. package/dist/completion-checkers/contract-presence.d.ts.map +1 -0
  28. package/dist/completion-checkers/contract-presence.js +36 -0
  29. package/dist/completion-checkers/contract-presence.js.map +1 -0
  30. package/dist/completion-checkers/glob-match.d.ts +13 -0
  31. package/dist/completion-checkers/glob-match.d.ts.map +1 -0
  32. package/dist/completion-checkers/glob-match.js +58 -0
  33. package/dist/completion-checkers/glob-match.js.map +1 -0
  34. package/dist/completion-checkers/index.d.ts +19 -0
  35. package/dist/completion-checkers/index.d.ts.map +1 -0
  36. package/dist/completion-checkers/index.js +47 -0
  37. package/dist/completion-checkers/index.js.map +1 -0
  38. package/dist/completion-checkers/phase-format.d.ts +15 -0
  39. package/dist/completion-checkers/phase-format.d.ts.map +1 -0
  40. package/dist/completion-checkers/phase-format.js +42 -0
  41. package/dist/completion-checkers/phase-format.js.map +1 -0
  42. package/dist/completion-checkers/tdd-chain.d.ts +16 -0
  43. package/dist/completion-checkers/tdd-chain.d.ts.map +1 -0
  44. package/dist/completion-checkers/tdd-chain.js +57 -0
  45. package/dist/completion-checkers/tdd-chain.js.map +1 -0
  46. package/dist/completion-checkers/types.d.ts +77 -0
  47. package/dist/completion-checkers/types.d.ts.map +1 -0
  48. package/dist/completion-checkers/types.js +10 -0
  49. package/dist/completion-checkers/types.js.map +1 -0
  50. package/dist/context/index.d.ts +1 -5
  51. package/dist/context/index.d.ts.map +1 -1
  52. package/dist/context/index.js +1 -5
  53. package/dist/context/index.js.map +1 -1
  54. package/dist/context/knowledge-injector.d.ts +3 -3
  55. package/dist/context/knowledge-injector.d.ts.map +1 -1
  56. package/dist/context/knowledge-injector.js +1 -1
  57. package/dist/context/session-manager.d.ts +1 -12
  58. package/dist/context/session-manager.d.ts.map +1 -1
  59. package/dist/context/session-manager.js +0 -63
  60. package/dist/context/session-manager.js.map +1 -1
  61. package/dist/context/types.d.ts +1 -39
  62. package/dist/context/types.d.ts.map +1 -1
  63. package/dist/context/types.js +2 -15
  64. package/dist/context/types.js.map +1 -1
  65. package/dist/core/constraints/agent-prompt-renderer.d.ts +1 -1
  66. package/dist/core/constraints/agent-prompt-renderer.js +1 -1
  67. package/dist/core/constraints/capabilities-parser.d.ts +17 -2
  68. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  69. package/dist/core/constraints/capabilities-parser.js +84 -2
  70. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  71. package/dist/core/constraints/checker.d.ts +3 -17
  72. package/dist/core/constraints/checker.d.ts.map +1 -1
  73. package/dist/core/constraints/checker.js +7 -47
  74. package/dist/core/constraints/checker.js.map +1 -1
  75. package/dist/core/constraints/definitions.d.ts +0 -7
  76. package/dist/core/constraints/definitions.d.ts.map +1 -1
  77. package/dist/core/constraints/definitions.js +1 -8
  78. package/dist/core/constraints/definitions.js.map +1 -1
  79. package/dist/core/constraints/doc-freshness/runner.d.ts +0 -2
  80. package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
  81. package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
  82. package/dist/core/constraints/index.d.ts +1 -1
  83. package/dist/core/constraints/index.d.ts.map +1 -1
  84. package/dist/core/constraints/index.js +2 -3
  85. package/dist/core/constraints/index.js.map +1 -1
  86. package/dist/core/constraints/interceptor.d.ts.map +1 -1
  87. package/dist/core/constraints/interceptor.js +1 -5
  88. package/dist/core/constraints/interceptor.js.map +1 -1
  89. package/dist/core/effective-constraints.d.ts.map +1 -1
  90. package/dist/core/effective-constraints.js +0 -1
  91. package/dist/core/effective-constraints.js.map +1 -1
  92. package/dist/core/project-config-loader.d.ts.map +1 -1
  93. package/dist/core/project-config-loader.js +1 -8
  94. package/dist/core/project-config-loader.js.map +1 -1
  95. package/dist/dashboard/stats.d.ts.map +1 -1
  96. package/dist/dashboard/stats.js.map +1 -1
  97. package/dist/dashboard/types.d.ts +2 -2
  98. package/dist/dashboard/types.d.ts.map +1 -1
  99. package/dist/failure/constraint-handler.d.ts.map +1 -1
  100. package/dist/failure/constraint-handler.js +0 -2
  101. package/dist/failure/constraint-handler.js.map +1 -1
  102. package/dist/gates/acceptance.d.ts +9 -1
  103. package/dist/gates/acceptance.d.ts.map +1 -1
  104. package/dist/gates/acceptance.js +21 -0
  105. package/dist/gates/acceptance.js.map +1 -1
  106. package/dist/gates/checker-gate.d.ts +23 -0
  107. package/dist/gates/checker-gate.d.ts.map +1 -0
  108. package/dist/gates/checker-gate.js +53 -0
  109. package/dist/gates/checker-gate.js.map +1 -0
  110. package/dist/gates/command.d.ts +9 -2
  111. package/dist/gates/command.d.ts.map +1 -1
  112. package/dist/gates/command.js +10 -0
  113. package/dist/gates/command.js.map +1 -1
  114. package/dist/gates/contract.d.ts +8 -2
  115. package/dist/gates/contract.d.ts.map +1 -1
  116. package/dist/gates/contract.js +9 -0
  117. package/dist/gates/contract.js.map +1 -1
  118. package/dist/gates/decision.d.ts +17 -0
  119. package/dist/gates/decision.d.ts.map +1 -0
  120. package/dist/gates/decision.js +25 -0
  121. package/dist/gates/decision.js.map +1 -0
  122. package/dist/gates/definitions.d.ts +63 -0
  123. package/dist/gates/definitions.d.ts.map +1 -0
  124. package/dist/gates/definitions.js +160 -0
  125. package/dist/gates/definitions.js.map +1 -0
  126. package/dist/gates/effective-gates.d.ts +30 -0
  127. package/dist/gates/effective-gates.d.ts.map +1 -0
  128. package/dist/gates/effective-gates.js +85 -0
  129. package/dist/gates/effective-gates.js.map +1 -0
  130. package/dist/gates/index.d.ts +25 -1
  131. package/dist/gates/index.d.ts.map +1 -1
  132. package/dist/gates/index.js +37 -1
  133. package/dist/gates/index.js.map +1 -1
  134. package/dist/gates/performance.d.ts +8 -2
  135. package/dist/gates/performance.d.ts.map +1 -1
  136. package/dist/gates/performance.js +9 -0
  137. package/dist/gates/performance.js.map +1 -1
  138. package/dist/gates/registry.d.ts +32 -0
  139. package/dist/gates/registry.d.ts.map +1 -0
  140. package/dist/gates/registry.js +90 -0
  141. package/dist/gates/registry.js.map +1 -0
  142. package/dist/gates/review.d.ts +8 -2
  143. package/dist/gates/review.d.ts.map +1 -1
  144. package/dist/gates/review.js +9 -0
  145. package/dist/gates/review.js.map +1 -1
  146. package/dist/gates/runner.d.ts +30 -0
  147. package/dist/gates/runner.d.ts.map +1 -0
  148. package/dist/gates/runner.js +38 -0
  149. package/dist/gates/runner.js.map +1 -0
  150. package/dist/gates/security.d.ts +8 -2
  151. package/dist/gates/security.d.ts.map +1 -1
  152. package/dist/gates/security.js +9 -0
  153. package/dist/gates/security.js.map +1 -1
  154. package/dist/gates/types.d.ts +41 -1
  155. package/dist/gates/types.d.ts.map +1 -1
  156. package/dist/hooks/bootstrap.d.ts.map +1 -1
  157. package/dist/hooks/bootstrap.js +0 -2
  158. package/dist/hooks/bootstrap.js.map +1 -1
  159. package/dist/hooks/config.d.ts +26 -0
  160. package/dist/hooks/config.d.ts.map +1 -0
  161. package/dist/hooks/config.js +30 -0
  162. package/dist/hooks/config.js.map +1 -0
  163. package/dist/hooks/index.d.ts +2 -1
  164. package/dist/hooks/index.d.ts.map +1 -1
  165. package/dist/hooks/index.js +4 -1
  166. package/dist/hooks/index.js.map +1 -1
  167. package/dist/hooks/registry.d.ts +18 -1
  168. package/dist/hooks/registry.d.ts.map +1 -1
  169. package/dist/hooks/registry.js +45 -0
  170. package/dist/hooks/registry.js.map +1 -1
  171. package/dist/hooks/types.d.ts +20 -0
  172. package/dist/hooks/types.d.ts.map +1 -1
  173. package/dist/index.d.ts +5 -8
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +11 -20
  176. package/dist/index.js.map +1 -1
  177. package/dist/knowledge/import.d.ts +2 -2
  178. package/dist/knowledge/import.d.ts.map +1 -1
  179. package/dist/knowledge/ingest.js.map +1 -1
  180. package/dist/knowledge/lifecycle-hooks.d.ts +2 -2
  181. package/dist/knowledge/lifecycle-hooks.d.ts.map +1 -1
  182. package/dist/knowledge/types.d.ts +5 -7
  183. package/dist/knowledge/types.d.ts.map +1 -1
  184. package/dist/knowledge/types.js +1 -1
  185. package/dist/knowledge/types.js.map +1 -1
  186. package/dist/monitoring/constraint-doctor.d.ts +4 -22
  187. package/dist/monitoring/constraint-doctor.d.ts.map +1 -1
  188. package/dist/monitoring/constraint-doctor.js +7 -94
  189. package/dist/monitoring/constraint-doctor.js.map +1 -1
  190. package/dist/presets/standard.d.ts +1 -1
  191. package/dist/presets/standard.d.ts.map +1 -1
  192. package/dist/presets/standard.js +1 -2
  193. package/dist/presets/standard.js.map +1 -1
  194. package/dist/pretool-use-hook.d.ts +16 -0
  195. package/dist/pretool-use-hook.d.ts.map +1 -0
  196. package/dist/pretool-use-hook.js +68 -0
  197. package/dist/pretool-use-hook.js.map +1 -0
  198. package/dist/spec/annotation-checker.d.ts.map +1 -1
  199. package/dist/spec/annotation-checker.js +6 -26
  200. package/dist/spec/annotation-checker.js.map +1 -1
  201. package/dist/tools/index.d.ts +0 -4
  202. package/dist/tools/index.d.ts.map +1 -1
  203. package/dist/tools/index.js +0 -4
  204. package/dist/tools/index.js.map +1 -1
  205. package/dist/types/constraint.d.ts +1 -12
  206. package/dist/types/constraint.d.ts.map +1 -1
  207. package/dist/types/constraint.js +0 -3
  208. package/dist/types/constraint.js.map +1 -1
  209. package/dist/types/project-config.d.ts +0 -2
  210. package/dist/types/project-config.d.ts.map +1 -1
  211. package/dist/utils/file-walk.d.ts +2 -2
  212. package/dist/utils/file-walk.js +2 -2
  213. package/package.json +6 -1
  214. package/src/CONTEXT.md +15 -0
  215. package/src/__tests__/checker-extra.test.ts +2 -59
  216. package/src/__tests__/constraint-doctor.test.ts +1 -140
  217. package/src/__tests__/constraint-handler.test.ts +0 -4
  218. package/src/__tests__/pretool-use-hook.test.ts +82 -0
  219. package/src/__tests__/project-config-loader-extra.test.ts +0 -20
  220. package/src/__tests__/project-config-loader.test.ts +0 -1
  221. package/src/cli/commands/CONTEXT.md +15 -7
  222. package/src/cli/commands/__tests__/check-drift.test.ts +0 -3
  223. package/src/cli/commands/__tests__/check-skip-output.test.ts +0 -5
  224. package/src/cli/commands/__tests__/check.test.ts +7 -75
  225. package/src/cli/commands/__tests__/registry.test.ts +201 -0
  226. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +55 -0
  227. package/src/cli/commands/check.ts +2 -14
  228. package/src/cli/commands/definitions.ts +593 -0
  229. package/src/cli/commands/knowledge.ts +3 -3
  230. package/src/cli/commands/sync-docs/agents-syncer.ts +26 -6
  231. package/src/cli/commands/sync-docs/capabilities-syncer.ts +4 -110
  232. package/src/cli/commands/sync-docs/index.ts +8 -5
  233. package/src/completion-checkers/CONTEXT.md +25 -0
  234. package/src/completion-checkers/__tests__/contract-presence.test.ts +44 -0
  235. package/src/completion-checkers/__tests__/phase-format.test.ts +60 -0
  236. package/src/completion-checkers/__tests__/tdd-chain.test.ts +99 -0
  237. package/src/completion-checkers/classify.ts +47 -0
  238. package/src/completion-checkers/contract-presence.ts +40 -0
  239. package/src/completion-checkers/glob-match.ts +54 -0
  240. package/src/completion-checkers/index.ts +19 -0
  241. package/src/completion-checkers/phase-format.ts +48 -0
  242. package/src/completion-checkers/tdd-chain.ts +63 -0
  243. package/src/completion-checkers/types.ts +84 -0
  244. package/src/context/CONTEXT.md +2 -7
  245. package/src/context/__tests__/session-manager.test.ts +0 -91
  246. package/src/context/index.ts +1 -5
  247. package/src/context/knowledge-injector.ts +3 -3
  248. package/src/context/session-manager.ts +0 -74
  249. package/src/context/types.ts +2 -63
  250. package/src/core/constraints/__tests__/interceptor.test.ts +0 -2
  251. package/src/core/constraints/agent-prompt-renderer.ts +1 -1
  252. package/src/core/constraints/capabilities-parser.ts +95 -2
  253. package/src/core/constraints/checker.ts +8 -53
  254. package/src/core/constraints/definitions.ts +0 -8
  255. package/src/core/constraints/doc-freshness/runner.ts +1 -2
  256. package/src/core/constraints/index.ts +1 -2
  257. package/src/core/constraints/interceptor.ts +1 -6
  258. package/src/core/effective-constraints.ts +0 -1
  259. package/src/core/project-config-loader.ts +1 -7
  260. package/src/dashboard/stats.ts +2 -2
  261. package/src/dashboard/types.ts +2 -2
  262. package/src/failure/constraint-handler.ts +0 -2
  263. package/src/gates/CONTEXT.md +16 -13
  264. package/src/gates/__tests__/checker-gate.test.ts +45 -0
  265. package/src/gates/__tests__/contract.test.ts +73 -0
  266. package/src/gates/__tests__/effective-gates.test.ts +82 -0
  267. package/src/gates/__tests__/gate-interface.test.ts +202 -0
  268. package/src/gates/__tests__/registry.test.ts +87 -0
  269. package/src/gates/__tests__/runner.test.ts +81 -0
  270. package/src/gates/acceptance.ts +24 -1
  271. package/src/gates/checker-gate.ts +54 -0
  272. package/src/gates/command.ts +13 -2
  273. package/src/gates/contract.ts +12 -2
  274. package/src/gates/decision.ts +27 -0
  275. package/src/gates/definitions.ts +207 -0
  276. package/src/gates/effective-gates.ts +106 -0
  277. package/src/gates/index.ts +38 -0
  278. package/src/gates/performance.ts +12 -2
  279. package/src/gates/registry.ts +107 -0
  280. package/src/gates/review.ts +12 -2
  281. package/src/gates/runner.ts +57 -0
  282. package/src/gates/security.ts +12 -2
  283. package/src/gates/types.ts +48 -1
  284. package/src/hooks/CONTEXT.md +12 -2
  285. package/src/hooks/__tests__/bootstrap.test.ts +0 -1
  286. package/src/hooks/__tests__/config.test.ts +19 -0
  287. package/src/hooks/__tests__/pipeline.test.ts +79 -0
  288. package/src/hooks/__tests__/registry.test.ts +67 -0
  289. package/src/hooks/bootstrap.ts +0 -2
  290. package/src/hooks/config.ts +29 -0
  291. package/src/hooks/index.ts +2 -1
  292. package/src/hooks/registry.ts +60 -1
  293. package/src/hooks/types.ts +21 -0
  294. package/src/index.ts +11 -21
  295. package/src/knowledge/import.ts +3 -3
  296. package/src/knowledge/ingest.ts +4 -4
  297. package/src/knowledge/lifecycle-hooks.ts +3 -3
  298. package/src/knowledge/types.ts +5 -8
  299. package/src/monitoring/constraint-doctor.ts +7 -106
  300. package/src/presets/__tests__/standard.test.ts +0 -2
  301. package/src/presets/standard.ts +1 -2
  302. package/src/pretool-use-hook.ts +68 -0
  303. package/src/spec/__tests__/annotation-checker.test.ts +9 -3
  304. package/src/spec/annotation-checker.ts +7 -29
  305. package/src/tools/CONTEXT.md +7 -14
  306. package/src/tools/index.ts +0 -4
  307. package/src/types/constraint.ts +1 -14
  308. package/src/types/project-config.ts +0 -3
  309. package/src/utils/file-walk.ts +2 -2
  310. package/dist/architecture/constraint-engine.d.ts +0 -67
  311. package/dist/architecture/constraint-engine.d.ts.map +0 -1
  312. package/dist/architecture/constraint-engine.js +0 -295
  313. package/dist/architecture/constraint-engine.js.map +0 -1
  314. package/dist/architecture/cross-project-checker.d.ts +0 -54
  315. package/dist/architecture/cross-project-checker.d.ts.map +0 -1
  316. package/dist/architecture/cross-project-checker.js +0 -467
  317. package/dist/architecture/cross-project-checker.js.map +0 -1
  318. package/dist/cli/commands/index.d.ts +0 -30
  319. package/dist/cli/commands/index.d.ts.map +0 -1
  320. package/dist/cli/commands/index.js +0 -91
  321. package/dist/cli/commands/index.js.map +0 -1
  322. package/dist/context/file-budget.d.ts +0 -40
  323. package/dist/context/file-budget.d.ts.map +0 -1
  324. package/dist/context/file-budget.js +0 -147
  325. package/dist/context/file-budget.js.map +0 -1
  326. package/dist/context/progressive-loader.d.ts +0 -109
  327. package/dist/context/progressive-loader.d.ts.map +0 -1
  328. package/dist/context/progressive-loader.js +0 -166
  329. package/dist/context/progressive-loader.js.map +0 -1
  330. package/dist/context/token-pipeline.d.ts +0 -55
  331. package/dist/context/token-pipeline.d.ts.map +0 -1
  332. package/dist/context/token-pipeline.js +0 -220
  333. package/dist/context/token-pipeline.js.map +0 -1
  334. package/dist/context/tool-output-budget.d.ts +0 -59
  335. package/dist/context/tool-output-budget.d.ts.map +0 -1
  336. package/dist/context/tool-output-budget.js +0 -177
  337. package/dist/context/tool-output-budget.js.map +0 -1
  338. package/dist/core/constraints/default-executors.d.ts +0 -10
  339. package/dist/core/constraints/default-executors.d.ts.map +0 -1
  340. package/dist/core/constraints/default-executors.js +0 -120
  341. package/dist/core/constraints/default-executors.js.map +0 -1
  342. package/dist/llm/adapter.d.ts +0 -36
  343. package/dist/llm/adapter.d.ts.map +0 -1
  344. package/dist/llm/adapter.js +0 -118
  345. package/dist/llm/adapter.js.map +0 -1
  346. package/dist/llm/index.d.ts +0 -3
  347. package/dist/llm/index.d.ts.map +0 -1
  348. package/dist/llm/index.js +0 -19
  349. package/dist/llm/index.js.map +0 -1
  350. package/dist/llm/types.d.ts +0 -62
  351. package/dist/llm/types.d.ts.map +0 -1
  352. package/dist/llm/types.js +0 -8
  353. package/dist/llm/types.js.map +0 -1
  354. package/dist/tools/core/index.d.ts +0 -13
  355. package/dist/tools/core/index.d.ts.map +0 -1
  356. package/dist/tools/core/index.js +0 -198
  357. package/dist/tools/core/index.js.map +0 -1
  358. package/dist/tools/loader.d.ts +0 -21
  359. package/dist/tools/loader.d.ts.map +0 -1
  360. package/dist/tools/loader.js +0 -199
  361. package/dist/tools/loader.js.map +0 -1
  362. package/dist/tools/registry.d.ts +0 -59
  363. package/dist/tools/registry.d.ts.map +0 -1
  364. package/dist/tools/registry.js +0 -115
  365. package/dist/tools/registry.js.map +0 -1
  366. package/dist/tools/types.d.ts +0 -38
  367. package/dist/tools/types.d.ts.map +0 -1
  368. package/dist/tools/types.js +0 -6
  369. package/dist/tools/types.js.map +0 -1
  370. package/src/__tests__/architecture-engine.test.ts +0 -619
  371. package/src/__tests__/context/progressive-loader.test.ts +0 -131
  372. package/src/__tests__/cross-project-checker.test.ts +0 -318
  373. package/src/architecture/CONTEXT.md +0 -22
  374. package/src/architecture/constraint-engine.ts +0 -351
  375. package/src/architecture/cross-project-checker.ts +0 -545
  376. package/src/cli/commands/index.ts +0 -30
  377. package/src/context/__tests__/file-budget.test.ts +0 -142
  378. package/src/context/__tests__/progressive-loader.test.ts +0 -264
  379. package/src/context/__tests__/token-pipeline.test.ts +0 -178
  380. package/src/context/__tests__/tool-output-budget.test.ts +0 -95
  381. package/src/context/file-budget.ts +0 -142
  382. package/src/context/progressive-loader.ts +0 -260
  383. package/src/context/token-pipeline.ts +0 -265
  384. package/src/context/tool-output-budget.ts +0 -178
  385. package/src/core/constraints/__tests__/default-executors.test.ts +0 -57
  386. package/src/core/constraints/default-executors.ts +0 -92
  387. package/src/llm/CONTEXT.md +0 -21
  388. package/src/llm/__tests__/adapter.test.ts +0 -172
  389. package/src/llm/adapter.ts +0 -149
  390. package/src/llm/index.ts +0 -2
  391. package/src/llm/types.ts +0 -81
  392. package/src/tools/__tests__/loader.test.ts +0 -252
  393. package/src/tools/__tests__/registry.test.ts +0 -157
  394. package/src/tools/core/__tests__/core.test.ts +0 -122
  395. package/src/tools/core/index.ts +0 -201
  396. package/src/tools/loader.ts +0 -216
  397. package/src/tools/registry.ts +0 -128
  398. package/src/tools/types.ts +0 -46
@@ -0,0 +1,201 @@
1
+ /**
2
+ * 命令注册表闭环测试(H5:命令定义即注册 + per-command 懒加载)
3
+ *
4
+ * - 定义表内每个实现引用(module+export)都必须可解析(构建/测试期断言,
5
+ * 取代 commands barrel 的编译期保护——R6 消灭手工同步后的闭环兜底)
6
+ * - definitions 是纯数据模块:require 它不加载任何命令实现(保 --help/--version 懒加载)
7
+ * - 命令面与 CAPABILITIES.md 的 24 顶层命令一致(防误删回归)
8
+ * - bin/harness.js 端到端冒烟(dist 存在时):--version/--help 零命令实现模块,
9
+ * 单命令执行只加载该命令模块(O2 per-command 懒加载)
10
+ */
11
+
12
+ import * as fs from 'fs';
13
+ import * as os from 'os';
14
+ import * as path from 'path';
15
+ import { spawnSync } from 'child_process';
16
+ import { COMMAND_DEFINITIONS, type CommandDefinition, type CommandImplRef } from '../definitions';
17
+ import { GATE_DEFINITIONS } from '../../../gates/definitions';
18
+
19
+ function collectRefs(defs: CommandDefinition[]): CommandImplRef[] {
20
+ const refs: CommandImplRef[] = [];
21
+ const walk = (def: CommandDefinition) => {
22
+ if (def.action) refs.push(def.action);
23
+ if (def.subcommands) {
24
+ for (const entry of Object.values(def.subcommands)) refs.push(entry.impl);
25
+ }
26
+ if (def.optionRoutes) {
27
+ for (const route of def.optionRoutes) refs.push(route.impl);
28
+ }
29
+ for (const child of def.children || []) walk(child);
30
+ };
31
+ for (const def of defs) walk(def);
32
+ return refs;
33
+ }
34
+
35
+ const EXPECTED_TOP_LEVEL_COMMANDS = [
36
+ 'check', 'validate', 'passes-gate', 'init', 'report', 'status', 'spec',
37
+ 'sync-docs', 'knowledge', 'sdd', 'failure', 'posteval-plan',
38
+ 'update-user-model', 'release', 'analyze-sessions', 'constraints',
39
+ 'doc-freshness-check', 'spec-baseline-check',
40
+ // 6 门禁命令(GATE_DEFINITIONS 驱动)
41
+ 'acceptance', 'command', 'contract', 'performance', 'review', 'security',
42
+ ];
43
+
44
+ describe('命令注册表闭环', () => {
45
+ it('definitions 是纯数据模块:加载时不引入任何命令实现', () => {
46
+ const loaded = Object.keys(require.cache)
47
+ .filter(k => k.includes('/cli/commands/') && k.endsWith('.ts') && !k.includes('__tests__'));
48
+ expect(loaded).toEqual([
49
+ expect.stringContaining('/cli/commands/definitions.ts'),
50
+ ]);
51
+ });
52
+
53
+ it('全部实现引用可解析(module 存在且 export 是函数)', () => {
54
+ const refs = collectRefs(COMMAND_DEFINITIONS);
55
+ for (const def of GATE_DEFINITIONS) {
56
+ refs.push(def.cli.action);
57
+ for (const entry of Object.values(def.cli.subcommands || {})) refs.push(entry);
58
+ }
59
+ expect(refs.length).toBeGreaterThan(0);
60
+
61
+ for (const ref of refs) {
62
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
63
+ const mod = require('../' + ref.module);
64
+ if (typeof mod[ref.export] !== 'function') {
65
+ throw new Error(`实现引用 ${ref.module}.${ref.export} 不存在或不是函数`);
66
+ }
67
+ }
68
+ });
69
+
70
+ it('顶层命令面与预期 24 命令一致(含 6 门禁)', () => {
71
+ const names = [
72
+ ...COMMAND_DEFINITIONS.map(d => d.command.split(' ')[0]),
73
+ ...GATE_DEFINITIONS.map(d => d.cli.command.split(' ')[0]),
74
+ ];
75
+ expect(new Set(names).size).toBe(names.length);
76
+ expect(names.sort()).toEqual([...EXPECTED_TOP_LEVEL_COMMANDS].sort());
77
+ });
78
+
79
+ it('命令定义无重复注册名', () => {
80
+ const names = COMMAND_DEFINITIONS.map(d => d.command);
81
+ expect(new Set(names).size).toBe(names.length);
82
+ });
83
+
84
+ it('全部命令定义的路由构造可执行(mapActionArgs/subcommands.args/optionRoutes.args/afterRun 冒烟)', () => {
85
+ const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => undefined as never);
86
+ try {
87
+ const walk = (def: CommandDefinition) => {
88
+ if (def.mapActionArgs) {
89
+ def.mapActionArgs(['positional'], {});
90
+ def.mapActionArgs([], {});
91
+ }
92
+ for (const entry of Object.values(def.subcommands || {})) {
93
+ if (entry.args) {
94
+ entry.args(['positional'], {});
95
+ entry.args([], {});
96
+ }
97
+ }
98
+ for (const route of def.optionRoutes || []) {
99
+ if (route.args) {
100
+ route.args([], {});
101
+ route.args(['positional'], {});
102
+ }
103
+ }
104
+ if (def.afterRun) {
105
+ def.afterRun(true, {});
106
+ def.afterRun(false, { check: true });
107
+ }
108
+ for (const child of def.children || []) walk(child);
109
+ };
110
+ for (const def of COMMAND_DEFINITIONS) walk(def);
111
+ // sync-docs --check 失败路径确实会请求退出
112
+ expect(exitSpy).toHaveBeenCalled();
113
+ } finally {
114
+ exitSpy.mockRestore();
115
+ }
116
+ });
117
+ });
118
+
119
+ const repoRoot = path.join(__dirname, '..', '..', '..', '..');
120
+ const distBin = path.join(repoRoot, 'bin', 'harness.js');
121
+ const distCommands = path.join(repoRoot, 'dist', 'cli', 'commands');
122
+ const hasDist = fs.existsSync(distCommands);
123
+
124
+ /**
125
+ * 经 NODE_OPTIONS=--require 预加载探针 spawn bin(进程退出时打印加载的
126
+ * 命令实现模块清单)。不用 node -e(commander 在 -e 下走 eval 分支,
127
+ * argv 解析不同,会误判位置参数)。
128
+ */
129
+ function runWithModuleProbe(argv: string[]): { status: number | null; implModules: string[]; stdout: string; stderr: string } {
130
+ const probeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-lazy-probe-'));
131
+ const probeFile = path.join(probeDir, 'probe.js');
132
+ fs.writeFileSync(probeFile, [
133
+ `process.on('exit', () => {`,
134
+ ` const impls = Object.keys(require.cache).filter(k => /dist[\\\\/]cli[\\\\/]commands[\\\\/]/.test(k) && !/definitions\\.js/.test(k)).sort();`,
135
+ ` console.error('IMPL_MODULES=' + impls.join(','));`,
136
+ `});`,
137
+ ].join('\n'));
138
+ try {
139
+ const r = spawnSync(process.execPath, [distBin, ...argv], {
140
+ cwd: repoRoot,
141
+ encoding: 'utf-8',
142
+ timeout: 30000,
143
+ env: { ...process.env, NODE_OPTIONS: `--require ${probeFile}` },
144
+ });
145
+ const match = r.stderr.match(/IMPL_MODULES=(.*)/);
146
+ return {
147
+ status: r.status,
148
+ implModules: match && match[1] ? match[1].split(',').filter(Boolean) : [],
149
+ stdout: r.stdout,
150
+ stderr: r.stderr,
151
+ };
152
+ } finally {
153
+ fs.rmSync(probeDir, { recursive: true, force: true });
154
+ }
155
+ }
156
+
157
+ const smoke = hasDist ? describe : describe.skip;
158
+
159
+ smoke('bin/harness.js 端到端(dist 存在时)', () => {
160
+ it('--version:退出 0,零命令实现模块加载', () => {
161
+ const r = runWithModuleProbe(['--version']);
162
+ expect(r.status).toBe(0);
163
+ expect(r.implModules).toEqual([]);
164
+ });
165
+
166
+ it('--help:退出 0,零命令实现模块加载', () => {
167
+ const r = runWithModuleProbe(['--help']);
168
+ expect(r.status).toBe(0);
169
+ expect(r.implModules).toEqual([]);
170
+ });
171
+
172
+ it('harness constraints --json:只加载 constraints 命令模块', () => {
173
+ const r = runWithModuleProbe(['constraints', '--json']);
174
+ expect(r.status).toBe(0);
175
+ expect(r.implModules).toEqual([
176
+ expect.stringContaining('/dist/cli/commands/constraints.js'),
177
+ ]);
178
+ });
179
+
180
+ it('harness check --list:只加载 check 命令模块(optionRoutes)', () => {
181
+ const r = runWithModuleProbe(['check', '--list']);
182
+ expect(r.status).toBe(0);
183
+ expect(r.implModules).toEqual([
184
+ expect.stringContaining('/dist/cli/commands/check.js'),
185
+ ]);
186
+ });
187
+
188
+ it('harness acceptance:只加载 acceptance 命令模块(门禁注册表)', () => {
189
+ const r = runWithModuleProbe(['acceptance', '--check-all']);
190
+ expect(r.status).toBe(0);
191
+ expect(r.implModules).toEqual([
192
+ expect.stringContaining('/dist/cli/commands/acceptance.js'),
193
+ ]);
194
+ });
195
+
196
+ it('未知子命令报错退出(knowledge 兜底行为保留)', () => {
197
+ const r = runWithModuleProbe(['knowledge', 'bogus']);
198
+ expect(r.status).toBe(1);
199
+ expect(r.stderr).toContain('未知子命令: bogus');
200
+ });
201
+ });
@@ -242,6 +242,61 @@ describe('sync-docs --agents', () => {
242
242
  fs.rmSync(testDir, { recursive: true, force: true });
243
243
  });
244
244
 
245
+ describe('知识入口行:.studio/CONTEXT.md 正本模型(studio #188)', () => {
246
+ it('.studio/CONTEXT.md 存在时生成正本行,替代散置指引(散置文件同时在场也一样),--check 无漂移', async () => {
247
+ const testDir = path.join(tempDir, 'studio-context-model');
248
+ createFixture(testDir, { pnpm: true, withCapabilities: true });
249
+ // 夹具已带散置 src/CONTEXT.md:正本在场时整行替代,与是否残留散置文件无关
250
+ fs.mkdirSync(path.join(testDir, '.studio'), { recursive: true });
251
+ fs.writeFileSync(path.join(testDir, '.studio', 'CONTEXT.md'), '# 模块上下文\n\n## src\n\n职责:夹具\n');
252
+
253
+ await syncDocs({ projectPath: testDir, agents: true });
254
+
255
+ const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
256
+ expect(content).toContain('模块上下文正本:`.studio/CONTEXT.md`(模块锚点组织),改动代码时同步更新');
257
+ expect(content).not.toContain('各源码目录的 `CONTEXT.md`');
258
+ expect(content).not.toContain('缺失目录可由 `harness sync-docs` 生成模板');
259
+ // 知识库行不受影响
260
+ expect(content).toContain('项目知识库,用 `harness knowledge` 查询');
261
+
262
+ // 幂等 + --check 通过(正本模型下无漂移)
263
+ const second = await syncDocs({ projectPath: testDir, agents: true });
264
+ expect(second).toBe(true);
265
+ expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).toBe(true);
266
+
267
+ fs.rmSync(testDir, { recursive: true, force: true });
268
+ });
269
+
270
+ it('.studio/CONTEXT.md 不存在时保持散置模型行,--check 无漂移', async () => {
271
+ const testDir = path.join(tempDir, 'scattered-context-model');
272
+ createFixture(testDir, { pnpm: true, withCapabilities: true });
273
+
274
+ await syncDocs({ projectPath: testDir, agents: true });
275
+
276
+ const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
277
+ expect(content).toContain('各源码目录的 `CONTEXT.md` 是权威模块文档(现有 1 个),改动代码时同步更新');
278
+ expect(content).not.toContain('模块上下文正本');
279
+
280
+ expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).toBe(true);
281
+
282
+ fs.rmSync(testDir, { recursive: true, force: true });
283
+ });
284
+
285
+ it('.studio/CONTEXT.md 是目录而非文件时不视为正本', async () => {
286
+ const testDir = path.join(tempDir, 'studio-context-dir');
287
+ createFixture(testDir, { pnpm: true, withCapabilities: true });
288
+ fs.mkdirSync(path.join(testDir, '.studio', 'CONTEXT.md'), { recursive: true });
289
+
290
+ await syncDocs({ projectPath: testDir, agents: true });
291
+
292
+ const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
293
+ expect(content).toContain('各源码目录的 `CONTEXT.md` 是权威模块文档');
294
+ expect(content).not.toContain('模块上下文正本');
295
+
296
+ fs.rmSync(testDir, { recursive: true, force: true });
297
+ });
298
+ });
299
+
245
300
  it('空项目应该生成兜底内容(无 package.json、无治理配置、无知识库)', async () => {
246
301
  const testDir = path.join(tempDir, 'empty-project');
247
302
  // 只放应被跳过的目录:依赖/构建产物/隐藏目录
@@ -49,7 +49,6 @@ export async function check(options: CheckOptions): Promise<void> {
49
49
  const merged = configLoader.hasCustomConfig()
50
50
  ? configLoader.mergeConstraints()
51
51
  : configLoader.mergeConstraints({ preset: options.preset || 'standard' });
52
- constraintChecker.setCustomConfig(merged);
53
52
  if (merged.custom.length > 0) {
54
53
  console.log(chalk.gray(`自定义约束: ${merged.custom.length} 条`));
55
54
  }
@@ -73,8 +72,8 @@ export async function check(options: CheckOptions): Promise<void> {
73
72
  }
74
73
  console.log(chalk.gray(`触发条件: ${[context.operation, ...(context.extraTriggers ?? [])].join(', ')}`));
75
74
 
76
- // 执行三层检查
77
- const result = await constraintChecker.checkConstraints(context);
75
+ // 执行三层检查(per-request 传 customConfig,避免单例状态污染)
76
+ const result = await constraintChecker.checkConstraints(context, merged);
78
77
 
79
78
  // 输出结果
80
79
  console.log();
@@ -83,7 +82,6 @@ export async function check(options: CheckOptions): Promise<void> {
83
82
  const skippedResults = [
84
83
  ...result.ironLaws,
85
84
  ...result.guidelines,
86
- ...result.tips,
87
85
  ].filter(r => r.skipped);
88
86
 
89
87
  // Iron Laws
@@ -118,16 +116,6 @@ export async function check(options: CheckOptions): Promise<void> {
118
116
  console.log(chalk.green(`✅ 指导原则: ${passedGuidelines}/${evaluatedGuidelines.length} 通过`));
119
117
  }
120
118
 
121
- // Tips
122
- if (result.tipCount > 0) {
123
- console.log(chalk.blue(`💡 提示: ${result.tipCount} 条`));
124
- result.tips.filter(r => !r.satisfied).forEach(r => {
125
- if (r.constraint) {
126
- console.log(chalk.blue(` - ${r.constraint.id}: ${r.constraint.message}`));
127
- }
128
- });
129
- }
130
-
131
119
  // Skipped:约定未采用 / 证据未接线,未评估(不计通过/失败)
132
120
  if (skippedResults.length > 0) {
133
121
  console.log(chalk.gray(`⏭️ 跳过评估: ${skippedResults.length} 条(约定未采用或证据未接线,不计通过/失败)`));