@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
@@ -1,619 +0,0 @@
1
- /**
2
- * ArchitectureConstraintEngine 测试
3
- */
4
-
5
- import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
6
- import { ArchitectureConstraintEngine, loadArchitectureRules, runArchitectureCheck } from '../architecture/constraint-engine';
7
- import type { ArchitectureRule, ArchitectureContext } from '../architecture/constraint-engine';
8
- import * as fs from 'fs';
9
- import * as path from 'path';
10
-
11
- describe('ArchitectureConstraintEngine', () => {
12
- const tempDir = path.join(process.cwd(), 'temp-test-arch');
13
-
14
- beforeEach(() => {
15
- fs.mkdirSync(tempDir, { recursive: true });
16
- });
17
-
18
- afterEach(() => {
19
- try {
20
- fs.rmSync(tempDir, { recursive: true, force: true });
21
- } catch {
22
- // ignore
23
- }
24
- });
25
-
26
- describe('forbidden-pattern 规则', () => {
27
- it('应该检测禁止模式', async () => {
28
- const rules: ArchitectureRule[] = [
29
- {
30
- id: 'no-test-in-src',
31
- type: 'forbidden-pattern',
32
- patterns: ['test'],
33
- severity: 'error',
34
- message: '源码目录不应包含 test',
35
- },
36
- ];
37
-
38
- const engine = new ArchitectureConstraintEngine(rules);
39
- const context: ArchitectureContext = {
40
- files: ['src/utils/test-helper.ts', 'src/utils/helper.ts'],
41
- diff: '',
42
- };
43
-
44
- const result = await engine.check(context);
45
-
46
- expect(result.passed).toBe(false);
47
- expect(result.violations.length).toBe(1);
48
- expect(result.violations[0].ruleId).toBe('no-test-in-src');
49
- });
50
-
51
- it('应该支持 scope 过滤', async () => {
52
- const rules: ArchitectureRule[] = [
53
- {
54
- id: 'no-test-in-core',
55
- type: 'forbidden-pattern',
56
- patterns: ['test'],
57
- scope: 'src/core/*',
58
- severity: 'error',
59
- },
60
- ];
61
-
62
- const engine = new ArchitectureConstraintEngine(rules);
63
- const context: ArchitectureContext = {
64
- files: ['src/utils/test-helper.ts', 'src/core/test.ts'],
65
- diff: '',
66
- };
67
-
68
- const result = await engine.check(context);
69
-
70
- expect(result.violations.length).toBe(1);
71
- expect(result.violations[0].files?.[0]).toBe('src/core/test.ts');
72
- });
73
-
74
- it('警告级别不应该影响 passed', async () => {
75
- const rules: ArchitectureRule[] = [
76
- {
77
- id: 'warning-rule',
78
- type: 'forbidden-pattern',
79
- patterns: ['warn'],
80
- severity: 'warning',
81
- },
82
- ];
83
-
84
- const engine = new ArchitectureConstraintEngine(rules);
85
- const context: ArchitectureContext = {
86
- files: ['src/warning.ts'],
87
- diff: '',
88
- };
89
-
90
- const result = await engine.check(context);
91
-
92
- expect(result.passed).toBe(true);
93
- expect(result.violations.length).toBe(1);
94
- });
95
-
96
- it('多个 pattern 应该全部检测', async () => {
97
- const rules: ArchitectureRule[] = [
98
- {
99
- id: 'no-forbidden',
100
- type: 'forbidden-pattern',
101
- patterns: ['test', 'spec', 'mock'],
102
- severity: 'error',
103
- },
104
- ];
105
-
106
- const engine = new ArchitectureConstraintEngine(rules);
107
- const context: ArchitectureContext = {
108
- files: ['src/test.ts', 'src/spec.ts', 'src/mock.ts', 'src/ok.ts'],
109
- diff: '',
110
- };
111
-
112
- const result = await engine.check(context);
113
-
114
- expect(result.violations.length).toBe(3);
115
- });
116
-
117
- it('大小写不敏感匹配', async () => {
118
- const rules: ArchitectureRule[] = [
119
- {
120
- id: 'no-test',
121
- type: 'forbidden-pattern',
122
- patterns: ['TEST'],
123
- severity: 'error',
124
- },
125
- ];
126
-
127
- const engine = new ArchitectureConstraintEngine(rules);
128
- const context: ArchitectureContext = {
129
- files: ['src/TestFile.ts', 'src/testfile.ts'],
130
- diff: '',
131
- };
132
-
133
- const result = await engine.check(context);
134
-
135
- expect(result.violations.length).toBe(2);
136
- });
137
-
138
- it('glob 模式 **/ 匹配任意前缀', async () => {
139
- const rules: ArchitectureRule[] = [
140
- {
141
- id: 'no-test-anywhere',
142
- type: 'forbidden-pattern',
143
- patterns: ['test'],
144
- scope: '**/core/**',
145
- severity: 'error',
146
- },
147
- ];
148
-
149
- const engine = new ArchitectureConstraintEngine(rules);
150
- const context: ArchitectureContext = {
151
- files: ['packages/lib/core/test.ts', 'src/core/test.ts', 'src/test.ts'],
152
- diff: '',
153
- };
154
-
155
- const result = await engine.check(context);
156
-
157
- // **/core/** 应该匹配 packages/lib/core/ 和 src/core/
158
- expect(result.violations.length).toBeGreaterThanOrEqual(2);
159
- });
160
-
161
- it('空 patterns 不应该报错', async () => {
162
- const rules: ArchitectureRule[] = [
163
- {
164
- id: 'empty-patterns',
165
- type: 'forbidden-pattern',
166
- patterns: [],
167
- severity: 'error',
168
- },
169
- ];
170
-
171
- const engine = new ArchitectureConstraintEngine(rules);
172
- const context: ArchitectureContext = {
173
- files: ['src/any.ts'],
174
- diff: '',
175
- };
176
-
177
- const result = await engine.check(context);
178
-
179
- expect(result.violations.length).toBe(0);
180
- });
181
-
182
- it('自定义 message 应该出现在 violation', async () => {
183
- const rules: ArchitectureRule[] = [
184
- {
185
- id: 'custom-msg',
186
- type: 'forbidden-pattern',
187
- patterns: ['test'],
188
- message: '自定义错误消息',
189
- severity: 'error',
190
- },
191
- ];
192
-
193
- const engine = new ArchitectureConstraintEngine(rules);
194
- const context: ArchitectureContext = {
195
- files: ['src/test.ts'],
196
- diff: '',
197
- };
198
-
199
- const result = await engine.check(context);
200
-
201
- expect(result.violations[0].message).toBe('自定义错误消息');
202
- });
203
- });
204
-
205
- describe('file-count 规则', () => {
206
- it('应该检测文件数超限', async () => {
207
- const rules: ArchitectureRule[] = [
208
- {
209
- id: 'max-10-files',
210
- type: 'file-count',
211
- threshold: 10,
212
- severity: 'error',
213
- message: '单次提交文件数过多',
214
- },
215
- ];
216
-
217
- const engine = new ArchitectureConstraintEngine(rules);
218
- const context: ArchitectureContext = {
219
- files: Array(15).fill('file.ts'),
220
- diff: '',
221
- };
222
-
223
- const result = await engine.check(context);
224
-
225
- expect(result.passed).toBe(false);
226
- expect(result.violations[0].message).toContain('文件数');
227
- });
228
-
229
- it('文件数未超限应该通过', async () => {
230
- const rules: ArchitectureRule[] = [
231
- {
232
- id: 'max-10-files',
233
- type: 'file-count',
234
- threshold: 10,
235
- severity: 'error',
236
- },
237
- ];
238
-
239
- const engine = new ArchitectureConstraintEngine(rules);
240
- const context: ArchitectureContext = {
241
- files: Array(5).fill('file.ts'),
242
- diff: '',
243
- };
244
-
245
- const result = await engine.check(context);
246
-
247
- expect(result.violations.length).toBe(0);
248
- });
249
-
250
- it('正好等于阈值应该通过', async () => {
251
- const rules: ArchitectureRule[] = [
252
- {
253
- id: 'max-10-files',
254
- type: 'file-count',
255
- threshold: 10,
256
- severity: 'error',
257
- },
258
- ];
259
-
260
- const engine = new ArchitectureConstraintEngine(rules);
261
- const context: ArchitectureContext = {
262
- files: Array(10).fill('file.ts'),
263
- diff: '',
264
- };
265
-
266
- const result = await engine.check(context);
267
-
268
- expect(result.violations.length).toBe(0);
269
- });
270
-
271
- it('默认阈值应该是 3', async () => {
272
- const rules: ArchitectureRule[] = [
273
- {
274
- id: 'default-threshold',
275
- type: 'file-count',
276
- severity: 'warning',
277
- },
278
- ];
279
-
280
- const engine = new ArchitectureConstraintEngine(rules);
281
- const context: ArchitectureContext = {
282
- files: Array(5).fill('file.ts'),
283
- diff: '',
284
- };
285
-
286
- const result = await engine.check(context);
287
-
288
- // 默认阈值 3,5 个文件应该触发
289
- expect(result.violations.length).toBe(1);
290
- });
291
- });
292
-
293
- describe('module-boundary 规则', () => {
294
- it('无 boundaries 配置应该通过', async () => {
295
- const rules: ArchitectureRule[] = [
296
- {
297
- id: 'no-cross-module',
298
- type: 'module-boundary',
299
- severity: 'error',
300
- },
301
- ];
302
-
303
- const engine = new ArchitectureConstraintEngine(rules);
304
- const context: ArchitectureContext = {
305
- files: ['src/core/index.ts'],
306
- diff: '+++ b/src/core/index.ts\n+import { foo } from "../cli/bar"',
307
- };
308
-
309
- const result = await engine.check(context);
310
- expect(result.passed).toBe(true);
311
- });
312
-
313
- it('应该检测跨模块导入', async () => {
314
- const rules: ArchitectureRule[] = [
315
- {
316
- id: 'no-core-to-cli',
317
- type: 'module-boundary',
318
- severity: 'error',
319
- boundaries: [
320
- { from: 'src/core/**', denyImport: 'src/cli/**' },
321
- ],
322
- },
323
- ];
324
-
325
- const engine = new ArchitectureConstraintEngine(rules);
326
- const context: ArchitectureContext = {
327
- files: ['src/core/index.ts'],
328
- diff: '+++ b/src/core/index.ts\n+import { bar } from "../cli/bar"',
329
- };
330
-
331
- const result = await engine.check(context);
332
- expect(result.passed).toBe(false);
333
- expect(result.violations.length).toBe(1);
334
- expect(result.violations[0].ruleId).toBe('no-core-to-cli');
335
- });
336
-
337
- it('合规导入不应该报错', async () => {
338
- const rules: ArchitectureRule[] = [
339
- {
340
- id: 'no-core-to-cli',
341
- type: 'module-boundary',
342
- severity: 'error',
343
- boundaries: [
344
- { from: 'src/core/**', denyImport: 'src/cli/**' },
345
- ],
346
- },
347
- ];
348
-
349
- const engine = new ArchitectureConstraintEngine(rules);
350
- const context: ArchitectureContext = {
351
- files: ['src/core/index.ts'],
352
- diff: '+++ b/src/core/index.ts\n+import { util } from "./util"',
353
- };
354
-
355
- const result = await engine.check(context);
356
- expect(result.passed).toBe(true);
357
- });
358
-
359
- it('外部依赖导入应该跳过', async () => {
360
- const rules: ArchitectureRule[] = [
361
- {
362
- id: 'no-core-to-cli',
363
- type: 'module-boundary',
364
- severity: 'error',
365
- boundaries: [
366
- { from: 'src/core/**', denyImport: 'src/cli/**' },
367
- ],
368
- },
369
- ];
370
-
371
- const engine = new ArchitectureConstraintEngine(rules);
372
- const context: ArchitectureContext = {
373
- files: ['src/core/index.ts'],
374
- diff: '+++ b/src/core/index.ts\n+import chalk from "chalk"',
375
- };
376
-
377
- const result = await engine.check(context);
378
- expect(result.passed).toBe(true);
379
- });
380
-
381
- it('多条边界规则应该全部检测', async () => {
382
- const rules: ArchitectureRule[] = [
383
- {
384
- id: 'boundary-rules',
385
- type: 'module-boundary',
386
- severity: 'error',
387
- boundaries: [
388
- { from: 'src/core/**', denyImport: 'src/cli/**' },
389
- { from: 'src/gates/**', denyImport: 'src/core/session/**' },
390
- ],
391
- },
392
- ];
393
-
394
- const engine = new ArchitectureConstraintEngine(rules);
395
- const context: ArchitectureContext = {
396
- files: ['src/core/index.ts', 'src/gates/review.ts'],
397
- diff: [
398
- '+++ b/src/core/index.ts',
399
- '+import { cmd } from "../cli/command"',
400
- '+++ b/src/gates/review.ts',
401
- '+import { session } from "../core/session/startup"',
402
- ].join('\n'),
403
- };
404
-
405
- const result = await engine.check(context);
406
- expect(result.violations.length).toBe(2);
407
- });
408
-
409
- it('只检查变更文件中的 import', async () => {
410
- const rules: ArchitectureRule[] = [
411
- {
412
- id: 'no-core-to-cli',
413
- type: 'module-boundary',
414
- severity: 'error',
415
- boundaries: [
416
- { from: 'src/core/**', denyImport: 'src/cli/**' },
417
- ],
418
- },
419
- ];
420
-
421
- const engine = new ArchitectureConstraintEngine(rules);
422
- // 变更文件是 src/other.ts(不在 from 范围内),diff 中有 src/core 的 import
423
- const context: ArchitectureContext = {
424
- files: ['src/other.ts'],
425
- diff: '+++ b/src/other.ts\n+import { cmd } from "../cli/command"',
426
- };
427
-
428
- const result = await engine.check(context);
429
- expect(result.passed).toBe(true);
430
- });
431
- });
432
-
433
- describe('多规则', () => {
434
- it('应该执行所有规则', async () => {
435
- const rules: ArchitectureRule[] = [
436
- {
437
- id: 'no-test',
438
- type: 'forbidden-pattern',
439
- patterns: ['test'],
440
- severity: 'error',
441
- },
442
- {
443
- id: 'max-files',
444
- type: 'file-count',
445
- threshold: 5,
446
- severity: 'warning',
447
- },
448
- ];
449
-
450
- const engine = new ArchitectureConstraintEngine(rules);
451
- const context: ArchitectureContext = {
452
- files: ['test.ts', 'test2.ts', 'file1.ts', 'file2.ts', 'file3.ts', 'file4.ts'],
453
- diff: '',
454
- };
455
-
456
- const result = await engine.check(context);
457
-
458
- expect(result.violations.length).toBeGreaterThanOrEqual(2);
459
- });
460
- });
461
-
462
- describe('空规则', () => {
463
- it('空规则数组应该返回 passed', async () => {
464
- const engine = new ArchitectureConstraintEngine([]);
465
- const context: ArchitectureContext = {
466
- files: ['any.ts'],
467
- diff: '',
468
- };
469
-
470
- const result = await engine.check(context);
471
-
472
- expect(result.passed).toBe(true);
473
- expect(result.violations).toEqual([]);
474
- });
475
- });
476
-
477
- describe('unknown 规则类型', () => {
478
- it('应该忽略未知类型', async () => {
479
- const rules: ArchitectureRule[] = [
480
- {
481
- id: 'unknown-type',
482
- type: 'custom' as any,
483
- severity: 'error',
484
- },
485
- ];
486
-
487
- const engine = new ArchitectureConstraintEngine(rules);
488
- const context: ArchitectureContext = {
489
- files: ['any.ts'],
490
- diff: '',
491
- };
492
-
493
- const result = await engine.check(context);
494
-
495
- expect(result.violations.length).toBe(0);
496
- });
497
- });
498
-
499
- describe('PR context', () => {
500
- it('应该支持 PR 上下文', async () => {
501
- const engine = new ArchitectureConstraintEngine([]);
502
- const context: ArchitectureContext = {
503
- files: ['file.ts'],
504
- diff: 'diff content',
505
- pr: {
506
- number: 123,
507
- changedFiles: 5,
508
- additions: 100,
509
- deletions: 50,
510
- },
511
- };
512
-
513
- const result = await engine.check(context);
514
-
515
- expect(result).toBeDefined();
516
- });
517
- });
518
-
519
- describe('loadArchitectureRules', () => {
520
- it('应该加载 JSON 配置', async () => {
521
- const configPath = path.join(tempDir, 'rules.json');
522
- fs.writeFileSync(configPath, JSON.stringify({
523
- rules: [
524
- { id: 'rule1', type: 'file-count', threshold: 10 },
525
- ],
526
- }));
527
-
528
- const rules = await loadArchitectureRules(configPath);
529
-
530
- expect(rules.length).toBe(1);
531
- expect(rules[0].id).toBe('rule1');
532
- });
533
-
534
- it('应该加载 YAML 配置', async () => {
535
- const configPath = path.join(tempDir, 'rules.yml');
536
- fs.writeFileSync(configPath, `
537
- rules:
538
- - id: yaml-rule
539
- type: forbidden-pattern
540
- patterns:
541
- - test
542
- - spec
543
- severity: error
544
- message: YAML 规则测试
545
- `);
546
-
547
- const rules = await loadArchitectureRules(configPath);
548
-
549
- expect(rules.length).toBe(1);
550
- expect(rules[0].id).toBe('yaml-rule');
551
- expect(rules[0].patterns?.length).toBe(2);
552
- });
553
-
554
- it('YAML threshold 应该解析为数字', async () => {
555
- const configPath = path.join(tempDir, 'rules.yml');
556
- fs.writeFileSync(configPath, `
557
- rules:
558
- - id: threshold-rule
559
- type: file-count
560
- threshold: 15
561
- `);
562
-
563
- const rules = await loadArchitectureRules(configPath);
564
-
565
- expect(rules[0].threshold).toBe(15);
566
- });
567
-
568
- it('YAML severity 应该解析为字符串', async () => {
569
- const configPath = path.join(tempDir, 'rules.yml');
570
- fs.writeFileSync(configPath, `
571
- rules:
572
- - id: severity-rule
573
- type: file-count
574
- severity: warning
575
- `);
576
-
577
- const rules = await loadArchitectureRules(configPath);
578
-
579
- expect(rules[0].severity).toBe('warning');
580
- });
581
-
582
- it('空文件应该返回空数组', async () => {
583
- const configPath = path.join(tempDir, 'empty.yml');
584
- fs.writeFileSync(configPath, '');
585
-
586
- const rules = await loadArchitectureRules(configPath);
587
-
588
- expect(rules).toEqual([]);
589
- });
590
-
591
- it('无 rules 字段应该返回空数组', async () => {
592
- const configPath = path.join(tempDir, 'no-rules.yml');
593
- fs.writeFileSync(configPath, 'other: value');
594
-
595
- const rules = await loadArchitectureRules(configPath);
596
-
597
- expect(rules).toEqual([]);
598
- });
599
- });
600
-
601
- describe('runArchitectureCheck', () => {
602
- it('应该运行完整检查', async () => {
603
- const configPath = path.join(tempDir, 'rules.json');
604
- fs.writeFileSync(configPath, JSON.stringify({
605
- rules: [
606
- { id: 'rule1', type: 'file-count', threshold: 10 },
607
- ],
608
- }));
609
-
610
- const result = await runArchitectureCheck(configPath, {
611
- files: Array(5).fill('file.ts'),
612
- diff: '',
613
- });
614
-
615
- expect(result).toBeDefined();
616
- expect(result.passed).toBe(true);
617
- });
618
- });
619
- });