@dommaker/harness 1.1.1 → 1.2.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 (373) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -4
  3. package/bin/harness.js +12 -37
  4. package/dist/cli/commands/check.d.ts +2 -2
  5. package/dist/cli/commands/check.d.ts.map +1 -1
  6. package/dist/cli/commands/check.js +8 -33
  7. package/dist/cli/commands/check.js.map +1 -1
  8. package/dist/cli/commands/constraints-report.js +1 -1
  9. package/dist/cli/commands/constraints-report.js.map +1 -1
  10. package/dist/cli/commands/constraints-retire.d.ts +6 -3
  11. package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
  12. package/dist/cli/commands/constraints-retire.js +34 -25
  13. package/dist/cli/commands/constraints-retire.js.map +1 -1
  14. package/dist/cli/commands/definitions.d.ts +2 -0
  15. package/dist/cli/commands/definitions.d.ts.map +1 -1
  16. package/dist/cli/commands/definitions.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts +21 -1
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +118 -40
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  22. package/dist/cli/commands/knowledge.js +1 -12
  23. package/dist/cli/commands/knowledge.js.map +1 -1
  24. package/dist/cli/commands/report.d.ts.map +1 -1
  25. package/dist/cli/commands/report.js +0 -2
  26. package/dist/cli/commands/report.js.map +1 -1
  27. package/dist/cli/commands/status.js +2 -2
  28. package/dist/cli/commands/status.js.map +1 -1
  29. package/dist/context/index.d.ts +9 -6
  30. package/dist/context/index.d.ts.map +1 -1
  31. package/dist/context/index.js +18 -20
  32. package/dist/context/index.js.map +1 -1
  33. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  34. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  35. package/dist/core/constraints/capabilities-parser.js +25 -47
  36. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  37. package/dist/core/constraints/checker.d.ts +29 -32
  38. package/dist/core/constraints/checker.d.ts.map +1 -1
  39. package/dist/core/constraints/checker.js +34 -126
  40. package/dist/core/constraints/checker.js.map +1 -1
  41. package/dist/core/constraints/checkers/governance-presence.d.ts +20 -0
  42. package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -0
  43. package/dist/core/constraints/checkers/governance-presence.js +76 -0
  44. package/dist/core/constraints/checkers/governance-presence.js.map +1 -0
  45. package/dist/core/constraints/checkers/index.d.ts +2 -1
  46. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  47. package/dist/core/constraints/checkers/index.js +5 -0
  48. package/dist/core/constraints/checkers/index.js.map +1 -1
  49. package/dist/core/constraints/checkers/types.d.ts +25 -0
  50. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  51. package/dist/core/constraints/checkers/types.js +24 -0
  52. package/dist/core/constraints/checkers/types.js.map +1 -1
  53. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  54. package/dist/core/constraints/definitions/guidelines.js +21 -2
  55. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  56. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  57. package/dist/core/constraints/definitions/prompts.js +0 -5
  58. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  59. package/dist/core/constraints/index.d.ts +1 -2
  60. package/dist/core/constraints/index.d.ts.map +1 -1
  61. package/dist/core/constraints/index.js +1 -7
  62. package/dist/core/constraints/index.js.map +1 -1
  63. package/dist/core/constraints/injection-drift.d.ts +29 -4
  64. package/dist/core/constraints/injection-drift.d.ts.map +1 -1
  65. package/dist/core/constraints/injection-drift.js +52 -20
  66. package/dist/core/constraints/injection-drift.js.map +1 -1
  67. package/dist/core/constraints/usage-report.d.ts +1 -2
  68. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  69. package/dist/core/constraints/usage-report.js +2 -5
  70. package/dist/core/constraints/usage-report.js.map +1 -1
  71. package/dist/core/effective-constraints.d.ts +24 -4
  72. package/dist/core/effective-constraints.d.ts.map +1 -1
  73. package/dist/core/effective-constraints.js +28 -7
  74. package/dist/core/effective-constraints.js.map +1 -1
  75. package/dist/core/effective-set.d.ts +30 -0
  76. package/dist/core/effective-set.d.ts.map +1 -0
  77. package/dist/core/effective-set.js +35 -0
  78. package/dist/core/effective-set.js.map +1 -0
  79. package/dist/core/index.d.ts +13 -6
  80. package/dist/core/index.d.ts.map +1 -1
  81. package/dist/core/index.js +44 -21
  82. package/dist/core/index.js.map +1 -1
  83. package/dist/core/project-config-loader.d.ts +3 -6
  84. package/dist/core/project-config-loader.d.ts.map +1 -1
  85. package/dist/core/project-config-loader.js +47 -61
  86. package/dist/core/project-config-loader.js.map +1 -1
  87. package/dist/failure/constraint-handler.d.ts +1 -1
  88. package/dist/failure/constraint-handler.js +1 -1
  89. package/dist/gates/checker-gate.d.ts +1 -4
  90. package/dist/gates/checker-gate.d.ts.map +1 -1
  91. package/dist/gates/checker-gate.js +3 -11
  92. package/dist/gates/checker-gate.js.map +1 -1
  93. package/dist/gates/definitions.d.ts +9 -38
  94. package/dist/gates/definitions.d.ts.map +1 -1
  95. package/dist/gates/definitions.js +24 -13
  96. package/dist/gates/definitions.js.map +1 -1
  97. package/dist/gates/effective-gates.d.ts.map +1 -1
  98. package/dist/gates/effective-gates.js +14 -18
  99. package/dist/gates/effective-gates.js.map +1 -1
  100. package/dist/gates/index.d.ts +1 -1
  101. package/dist/gates/index.d.ts.map +1 -1
  102. package/dist/gates/index.js.map +1 -1
  103. package/dist/hooks/bootstrap.d.ts.map +1 -1
  104. package/dist/hooks/bootstrap.js +0 -3
  105. package/dist/hooks/bootstrap.js.map +1 -1
  106. package/dist/index.d.ts +43 -60
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +180 -143
  109. package/dist/index.js.map +1 -1
  110. package/dist/knowledge/query.d.ts +15 -0
  111. package/dist/knowledge/query.d.ts.map +1 -1
  112. package/dist/knowledge/query.js +23 -0
  113. package/dist/knowledge/query.js.map +1 -1
  114. package/dist/monitoring/analyzer-base.d.ts +0 -4
  115. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  116. package/dist/monitoring/analyzer-base.js +0 -21
  117. package/dist/monitoring/analyzer-base.js.map +1 -1
  118. package/dist/monitoring/index.d.ts +6 -12
  119. package/dist/monitoring/index.d.ts.map +1 -1
  120. package/dist/monitoring/index.js +13 -29
  121. package/dist/monitoring/index.js.map +1 -1
  122. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  123. package/dist/monitoring/trace-analyzer.js +2 -68
  124. package/dist/monitoring/trace-analyzer.js.map +1 -1
  125. package/dist/monitoring/traces.d.ts +0 -4
  126. package/dist/monitoring/traces.d.ts.map +1 -1
  127. package/dist/monitoring/traces.js +0 -14
  128. package/dist/monitoring/traces.js.map +1 -1
  129. package/dist/presets/index.d.ts +2 -2
  130. package/dist/presets/index.d.ts.map +1 -1
  131. package/dist/presets/index.js +3 -4
  132. package/dist/presets/index.js.map +1 -1
  133. package/dist/presets/standard.d.ts +10 -22
  134. package/dist/presets/standard.d.ts.map +1 -1
  135. package/dist/presets/standard.js +15 -75
  136. package/dist/presets/standard.js.map +1 -1
  137. package/dist/types/constraint.d.ts +1 -29
  138. package/dist/types/constraint.d.ts.map +1 -1
  139. package/dist/types/constraint.js +1 -1
  140. package/dist/types/constraint.js.map +1 -1
  141. package/dist/types/index.d.ts +0 -3
  142. package/dist/types/index.d.ts.map +1 -1
  143. package/dist/types/index.js +0 -4
  144. package/dist/types/index.js.map +1 -1
  145. package/dist/types/project-config.d.ts +4 -8
  146. package/dist/types/project-config.d.ts.map +1 -1
  147. package/dist/types/trace.d.ts +5 -18
  148. package/dist/types/trace.d.ts.map +1 -1
  149. package/package.json +2 -2
  150. package/src/CONTEXT.md +4 -5
  151. package/src/__tests__/checker-extra.test.ts +33 -139
  152. package/src/__tests__/checker.test.ts +0 -376
  153. package/src/__tests__/governance-presence.test.ts +129 -0
  154. package/src/__tests__/iron-laws.test.ts +7 -7
  155. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  156. package/src/__tests__/public-exports.test.ts +138 -0
  157. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  158. package/src/__tests__/trace-analyzer.test.ts +4 -5
  159. package/src/__tests__/trace-collector.test.ts +0 -11
  160. package/src/__tests__/traces.test.ts +3 -22
  161. package/src/cli/commands/CONTEXT.md +6 -3
  162. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  163. package/src/cli/commands/__tests__/check.test.ts +29 -69
  164. package/src/cli/commands/__tests__/constraints-report.test.ts +3 -3
  165. package/src/cli/commands/__tests__/constraints-retire.test.ts +45 -4
  166. package/src/cli/commands/__tests__/init-injection.test.ts +202 -0
  167. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  168. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  169. package/src/cli/commands/__tests__/status-extra.test.ts +6 -6
  170. package/src/cli/commands/__tests__/status.test.ts +6 -6
  171. package/src/cli/commands/__tests__/sync-docs-agents.test.ts +28 -0
  172. package/src/cli/commands/check.ts +9 -35
  173. package/src/cli/commands/constraints-report.ts +1 -1
  174. package/src/cli/commands/constraints-retire.ts +38 -27
  175. package/src/cli/commands/definitions.ts +2 -0
  176. package/src/cli/commands/init.ts +129 -40
  177. package/src/cli/commands/knowledge.ts +1 -16
  178. package/src/cli/commands/report.ts +0 -2
  179. package/src/cli/commands/status.ts +2 -2
  180. package/src/context/index.ts +29 -6
  181. package/src/core/CONTEXT.md +4 -3
  182. package/src/core/__tests__/effective-set.test.ts +80 -0
  183. package/src/core/constraints/__tests__/injection-drift.test.ts +90 -0
  184. package/src/core/constraints/capabilities-parser.ts +43 -49
  185. package/src/core/constraints/checker.ts +51 -145
  186. package/src/core/constraints/checkers/governance-presence.ts +74 -0
  187. package/src/core/constraints/checkers/index.ts +4 -1
  188. package/src/core/constraints/checkers/types.ts +42 -0
  189. package/src/core/constraints/definitions/guidelines.ts +22 -2
  190. package/src/core/constraints/definitions/prompts.ts +0 -5
  191. package/src/core/constraints/index.ts +2 -17
  192. package/src/core/constraints/injection-drift.ts +60 -21
  193. package/src/core/constraints/usage-report.ts +5 -8
  194. package/src/core/effective-constraints.ts +35 -7
  195. package/src/core/effective-set.ts +56 -0
  196. package/src/core/index.ts +80 -6
  197. package/src/core/project-config-loader.ts +53 -68
  198. package/src/failure/CONTEXT.md +1 -1
  199. package/src/failure/constraint-handler.ts +1 -1
  200. package/src/gates/CONTEXT.md +3 -3
  201. package/src/gates/checker-gate.ts +4 -12
  202. package/src/gates/definitions.ts +27 -50
  203. package/src/gates/effective-gates.ts +14 -21
  204. package/src/gates/index.ts +1 -1
  205. package/src/hooks/bootstrap.ts +0 -3
  206. package/src/index.ts +384 -148
  207. package/src/knowledge/CONTEXT.md +2 -2
  208. package/src/knowledge/__tests__/query.test.ts +64 -0
  209. package/src/knowledge/query.ts +28 -0
  210. package/src/monitoring/CONTEXT.md +7 -13
  211. package/src/monitoring/__tests__/traces.test.ts +0 -10
  212. package/src/monitoring/analyzer-base.ts +0 -22
  213. package/src/monitoring/index.ts +6 -12
  214. package/src/monitoring/trace-analyzer.ts +2 -73
  215. package/src/monitoring/traces.ts +0 -20
  216. package/src/presets/__tests__/standard.test.ts +48 -69
  217. package/src/presets/index.ts +3 -5
  218. package/src/presets/standard.ts +14 -79
  219. package/src/spec/CONTEXT.md +5 -13
  220. package/src/types/constraint.ts +1 -51
  221. package/src/types/index.ts +0 -12
  222. package/src/types/project-config.ts +4 -10
  223. package/src/types/trace.ts +5 -30
  224. package/dist/core/constraints/interceptor.d.ts +0 -39
  225. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  226. package/dist/core/constraints/interceptor.js +0 -166
  227. package/dist/core/constraints/interceptor.js.map +0 -1
  228. package/dist/dashboard/data.d.ts +0 -31
  229. package/dist/dashboard/data.d.ts.map +0 -1
  230. package/dist/dashboard/data.js +0 -81
  231. package/dist/dashboard/data.js.map +0 -1
  232. package/dist/dashboard/index.d.ts +0 -4
  233. package/dist/dashboard/index.d.ts.map +0 -1
  234. package/dist/dashboard/index.js +0 -20
  235. package/dist/dashboard/index.js.map +0 -1
  236. package/dist/dashboard/stats.d.ts +0 -20
  237. package/dist/dashboard/stats.d.ts.map +0 -1
  238. package/dist/dashboard/stats.js +0 -115
  239. package/dist/dashboard/stats.js.map +0 -1
  240. package/dist/dashboard/types.d.ts +0 -110
  241. package/dist/dashboard/types.d.ts.map +0 -1
  242. package/dist/dashboard/types.js +0 -8
  243. package/dist/dashboard/types.js.map +0 -1
  244. package/dist/monitoring/constraint-doctor.d.ts +0 -76
  245. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  246. package/dist/monitoring/constraint-doctor.js +0 -189
  247. package/dist/monitoring/constraint-doctor.js.map +0 -1
  248. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  249. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  250. package/dist/monitoring/diagnosis-rules.js +0 -119
  251. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  252. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  253. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  254. package/dist/monitoring/knowledge-doctor.js +0 -266
  255. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  256. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  257. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  258. package/dist/monitoring/knowledge-evolver.js +0 -205
  259. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  260. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  261. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  262. package/dist/monitoring/performance-analyzer.js +0 -343
  263. package/dist/monitoring/performance-analyzer.js.map +0 -1
  264. package/dist/monitoring/performance-collector.d.ts +0 -103
  265. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  266. package/dist/monitoring/performance-collector.js +0 -298
  267. package/dist/monitoring/performance-collector.js.map +0 -1
  268. package/dist/safety/index.d.ts +0 -6
  269. package/dist/safety/index.d.ts.map +0 -1
  270. package/dist/safety/index.js +0 -22
  271. package/dist/safety/index.js.map +0 -1
  272. package/dist/safety/input-guardrail.d.ts +0 -36
  273. package/dist/safety/input-guardrail.d.ts.map +0 -1
  274. package/dist/safety/input-guardrail.js +0 -118
  275. package/dist/safety/input-guardrail.js.map +0 -1
  276. package/dist/safety/output-guardrail.d.ts +0 -39
  277. package/dist/safety/output-guardrail.d.ts.map +0 -1
  278. package/dist/safety/output-guardrail.js +0 -147
  279. package/dist/safety/output-guardrail.js.map +0 -1
  280. package/dist/safety/sandbox.d.ts +0 -45
  281. package/dist/safety/sandbox.d.ts.map +0 -1
  282. package/dist/safety/sandbox.js +0 -134
  283. package/dist/safety/sandbox.js.map +0 -1
  284. package/dist/safety/tool-guardrail.d.ts +0 -51
  285. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  286. package/dist/safety/tool-guardrail.js +0 -147
  287. package/dist/safety/tool-guardrail.js.map +0 -1
  288. package/dist/safety/types.d.ts +0 -104
  289. package/dist/safety/types.d.ts.map +0 -1
  290. package/dist/safety/types.js +0 -6
  291. package/dist/safety/types.js.map +0 -1
  292. package/dist/spec/annotation-checker.d.ts +0 -47
  293. package/dist/spec/annotation-checker.d.ts.map +0 -1
  294. package/dist/spec/annotation-checker.js +0 -279
  295. package/dist/spec/annotation-checker.js.map +0 -1
  296. package/dist/types/enforcement.d.ts +0 -42
  297. package/dist/types/enforcement.d.ts.map +0 -1
  298. package/dist/types/enforcement.js +0 -6
  299. package/dist/types/enforcement.js.map +0 -1
  300. package/dist/types/monitoring-types.d.ts +0 -53
  301. package/dist/types/monitoring-types.d.ts.map +0 -1
  302. package/dist/types/monitoring-types.js +0 -10
  303. package/dist/types/monitoring-types.js.map +0 -1
  304. package/dist/types/performance.d.ts +0 -204
  305. package/dist/types/performance.d.ts.map +0 -1
  306. package/dist/types/performance.js +0 -12
  307. package/dist/types/performance.js.map +0 -1
  308. package/dist/verification/index.d.ts +0 -4
  309. package/dist/verification/index.d.ts.map +0 -1
  310. package/dist/verification/index.js +0 -20
  311. package/dist/verification/index.js.map +0 -1
  312. package/dist/verification/loop.d.ts +0 -30
  313. package/dist/verification/loop.d.ts.map +0 -1
  314. package/dist/verification/loop.js +0 -114
  315. package/dist/verification/loop.js.map +0 -1
  316. package/dist/verification/rules-based.d.ts +0 -40
  317. package/dist/verification/rules-based.d.ts.map +0 -1
  318. package/dist/verification/rules-based.js +0 -130
  319. package/dist/verification/rules-based.js.map +0 -1
  320. package/dist/verification/types.d.ts +0 -69
  321. package/dist/verification/types.d.ts.map +0 -1
  322. package/dist/verification/types.js +0 -6
  323. package/dist/verification/types.js.map +0 -1
  324. package/src/__tests__/annotation-checker.test.ts +0 -183
  325. package/src/__tests__/constraint-doctor.test.ts +0 -271
  326. package/src/__tests__/doctor-extra.test.ts +0 -155
  327. package/src/__tests__/extend-exceptions.test.ts +0 -149
  328. package/src/__tests__/interceptor.test.ts +0 -89
  329. package/src/__tests__/performance-analyzer.test.ts +0 -499
  330. package/src/__tests__/performance-collector.test.ts +0 -276
  331. package/src/__tests__/presets.test.ts +0 -65
  332. package/src/core/constraints/__tests__/interceptor.test.ts +0 -267
  333. package/src/core/constraints/interceptor.ts +0 -217
  334. package/src/dashboard/CONTEXT.md +0 -21
  335. package/src/dashboard/__tests__/data.test.ts +0 -111
  336. package/src/dashboard/__tests__/stats.test.ts +0 -159
  337. package/src/dashboard/data.ts +0 -103
  338. package/src/dashboard/index.ts +0 -3
  339. package/src/dashboard/stats.ts +0 -127
  340. package/src/dashboard/types.ts +0 -130
  341. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  342. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  343. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  344. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  345. package/src/monitoring/constraint-doctor.ts +0 -228
  346. package/src/monitoring/diagnosis-rules.ts +0 -132
  347. package/src/monitoring/knowledge-doctor.ts +0 -322
  348. package/src/monitoring/knowledge-evolver.ts +0 -289
  349. package/src/monitoring/performance-analyzer.ts +0 -400
  350. package/src/monitoring/performance-collector.ts +0 -326
  351. package/src/safety/CONTEXT.md +0 -23
  352. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  353. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  354. package/src/safety/__tests__/sandbox.test.ts +0 -158
  355. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  356. package/src/safety/index.ts +0 -5
  357. package/src/safety/input-guardrail.ts +0 -133
  358. package/src/safety/output-guardrail.ts +0 -170
  359. package/src/safety/sandbox.ts +0 -148
  360. package/src/safety/tool-guardrail.ts +0 -176
  361. package/src/safety/types.ts +0 -124
  362. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  363. package/src/spec/annotation-checker.ts +0 -320
  364. package/src/types/enforcement.ts +0 -48
  365. package/src/types/monitoring-types.ts +0 -68
  366. package/src/types/performance.ts +0 -295
  367. package/src/verification/CONTEXT.md +0 -23
  368. package/src/verification/__tests__/loop.test.ts +0 -303
  369. package/src/verification/__tests__/rules-based.test.ts +0 -240
  370. package/src/verification/index.ts +0 -3
  371. package/src/verification/loop.ts +0 -137
  372. package/src/verification/rules-based.ts +0 -152
  373. package/src/verification/types.ts +0 -81
@@ -1,294 +0,0 @@
1
- /**
2
- * AnnotationChecker 测试
3
- */
4
-
5
- import { checkFile, checkDirectory, generateReport } from '../annotation-checker';
6
- import * as fs from 'fs';
7
-
8
- // Mock fs
9
- jest.mock('fs', () => ({
10
- readFileSync: jest.fn(),
11
- readdirSync: jest.fn(),
12
- statSync: jest.fn(),
13
- existsSync: jest.fn(),
14
- }));
15
-
16
- const mockFs = fs as jest.Mocked<typeof fs>;
17
-
18
- describe('AnnotationChecker', () => {
19
- const tempDir = '/test/project';
20
-
21
- beforeEach(() => {
22
- jest.clearAllMocks();
23
- });
24
-
25
- describe('checkFile', () => {
26
- it('应该检查有效的 JSDoc 注释', () => {
27
- mockFs.readFileSync.mockReturnValue(`
28
- /**
29
- * @spec AR-001
30
- * @implements feature-auth
31
- * @acceptance AC-001
32
- * @author test
33
- * @since 2026-04-28
34
- */
35
- export function auth() {}
36
- `);
37
-
38
- const result = checkFile('/test/file.ts');
39
-
40
- expect(result.annotations.length).toBe(1);
41
- expect(result.annotations[0]?.specId).toBe('AR-001');
42
- expect(result.annotations[0]?.implements).toContain('feature-auth');
43
- expect(result.annotations[0]?.acceptance).toContain('AC-001');
44
- expect(result.annotations[0]?.author).toBe('test');
45
- expect(result.annotations[0]?.since).toBe('2026-04-28');
46
- });
47
-
48
- it('应该检查行内注释', () => {
49
- mockFs.readFileSync.mockReturnValue(`
50
- // @spec AR-002
51
- const x = 1;
52
- `);
53
-
54
- const result = checkFile('/test/file.ts');
55
-
56
- expect(result.annotations.length).toBe(1);
57
- expect(result.annotations[0]?.specId).toBe('AR-002');
58
- expect(result.annotations[0]?.type).toBe('inline');
59
- });
60
-
61
- it('应该检测无效 Spec ID 格式', () => {
62
- mockFs.readFileSync.mockReturnValue(`
63
- /**
64
- * @spec INVALID-ID
65
- */
66
- export function test() {}
67
- `);
68
-
69
- const result = checkFile('/test/file.ts');
70
-
71
- expect(result.errors.length).toBeGreaterThan(0);
72
- expect(result.errors[0]?.code).toBe('INVALID_SPEC_FORMAT');
73
- });
74
-
75
- it('应该警告缺少 @implements', () => {
76
- mockFs.readFileSync.mockReturnValue(`
77
- /**
78
- * @spec AR-003
79
- */
80
- class MyClass {}
81
- `);
82
-
83
- const result = checkFile('/test/file.ts');
84
-
85
- expect(result.warnings.length).toBeGreaterThan(0);
86
- expect(result.warnings.some(w => w.code === 'MISSING_IMPLEMENTS')).toBe(true);
87
- });
88
-
89
- it('应该警告缺少 @acceptance', () => {
90
- mockFs.readFileSync.mockReturnValue(`
91
- /**
92
- * @spec AR-004
93
- * @implements feat
94
- */
95
- function myFunc() {}
96
- `);
97
-
98
- const result = checkFile('/test/file.ts');
99
-
100
- expect(result.warnings.some(w => w.code === 'MISSING_ACCEPTANCE')).toBe(true);
101
- });
102
-
103
- it('应该推断注释类型', () => {
104
- mockFs.readFileSync.mockReturnValue(`
105
- /**
106
- * @spec AR-005
107
- */
108
- class MyClass {}
109
- `);
110
-
111
- const result = checkFile('/test/file.ts');
112
-
113
- expect(result.annotations[0]?.type).toBeDefined();
114
- });
115
-
116
- it('应该推断 function 类型', () => {
117
- mockFs.readFileSync.mockReturnValue(`
118
- /**
119
- * @spec AR-006
120
- */
121
- async function myAsync() {}
122
- `);
123
-
124
- const result = checkFile('/test/file.ts');
125
-
126
- expect(result.annotations[0]?.type).toBeDefined();
127
- });
128
-
129
- it('应该推断 method 类型', () => {
130
- mockFs.readFileSync.mockReturnValue(`
131
- /**
132
- * @spec AR-007
133
- */
134
- myMethod() {}
135
- `);
136
-
137
- const result = checkFile('/test/file.ts');
138
-
139
- expect(result.annotations[0]?.type).toBeDefined();
140
- });
141
-
142
- it('应该检查公共导出缺少 @spec', () => {
143
- mockFs.readFileSync.mockReturnValue(`
144
- export class NoSpecClass {}
145
- export function noSpecFunc() {}
146
- `);
147
-
148
- const result = checkFile('/test/file.ts');
149
-
150
- // 公共导出可能触发 MISSING_SPEC 警告(通过 checkPublicExports)
151
- expect(result.warnings.length + result.errors.length).toBeGreaterThanOrEqual(0);
152
- });
153
- });
154
-
155
- describe('checkDirectory', () => {
156
- it('应该递归检查目录', () => {
157
- // 需要更完整的 mock,简化测试
158
- mockFs.readdirSync.mockReturnValue([] as any);
159
-
160
- const results = checkDirectory(tempDir);
161
-
162
- expect(Array.isArray(results)).toBe(true);
163
- });
164
-
165
- it('应该跳过 node_modules 和 dist', () => {
166
- mockFs.readFileSync.mockReturnValue('');
167
- mockFs.readdirSync.mockReturnValue([
168
- { name: 'node_modules', isDirectory: () => true, isFile: () => false },
169
- { name: 'dist', isDirectory: () => true, isFile: () => false },
170
- { name: 'file.ts', isDirectory: () => false, isFile: () => true },
171
- ] as any);
172
-
173
- const results = checkDirectory(tempDir);
174
-
175
- // 只收集 file.ts,跳过 node_modules 与 dist 目录
176
- expect(results).toHaveLength(1);
177
- expect(results[0].file).toBe('/test/project/file.ts');
178
- });
179
-
180
- it('应该处理空目录', () => {
181
- mockFs.readdirSync.mockReturnValue([]);
182
-
183
- const results = checkDirectory(tempDir);
184
-
185
- expect(results.length).toBe(0);
186
- });
187
- });
188
-
189
- describe('generateReport', () => {
190
- it('应该生成报告', () => {
191
- const results = [
192
- {
193
- valid: true,
194
- file: '/test/file.ts',
195
- annotations: [],
196
- errors: [],
197
- warnings: [],
198
- },
199
- {
200
- valid: false,
201
- file: '/test/bad.ts',
202
- annotations: [],
203
- errors: [{ line: 1, message: 'Error', code: 'INVALID_SPEC_FORMAT' as const }],
204
- warnings: [{ line: 2, message: 'Warning', code: 'MISSING_ACCEPTANCE' as const }],
205
- },
206
- ];
207
-
208
- const report = generateReport(results);
209
-
210
- expect(report).toContain('注释规范检查报告');
211
- expect(report).toContain('检查文件: 2');
212
- expect(report).toContain('通过: 1');
213
- expect(report).toContain('错误: 1');
214
- expect(report).toContain('警告: 1');
215
- });
216
-
217
- it('应该处理空结果', () => {
218
- const report = generateReport([]);
219
-
220
- expect(report).toContain('检查文件: 0');
221
- expect(report).toContain('通过: 0');
222
- });
223
-
224
- it('应该截断警告显示(最多5条)', () => {
225
- const results = [{
226
- valid: true,
227
- file: '/test/file.ts',
228
- annotations: [],
229
- errors: [],
230
- warnings: Array(10).fill({ line: 1, message: 'Warning', code: 'MISSING_ACCEPTANCE' as const }),
231
- }];
232
-
233
- const report = generateReport(results);
234
-
235
- expect(report).toContain('警告');
236
- });
237
- });
238
-
239
- describe('边缘情况', () => {
240
- it('应该处理空文件', () => {
241
- mockFs.readFileSync.mockReturnValue('');
242
-
243
- const result = checkFile('/test/empty.ts');
244
-
245
- expect(result.annotations.length).toBe(0);
246
- expect(result.errors.length).toBe(0);
247
- });
248
-
249
- it('应该处理多行 JSDoc', () => {
250
- mockFs.readFileSync.mockReturnValue(`
251
- /**
252
- * First line
253
- * Second line
254
- * @spec AR-009
255
- * Third line
256
- */
257
- export function multi() {}
258
- `);
259
-
260
- const result = checkFile('/test/file.ts');
261
-
262
- expect(result.annotations.length).toBe(1);
263
- expect(result.annotations[0]?.specId).toBe('AR-009');
264
- });
265
-
266
- it('应该处理多个 @implements', () => {
267
- mockFs.readFileSync.mockReturnValue(`
268
- /**
269
- * @spec AR-010
270
- * @implements feat1, feat2, feat3
271
- */
272
- export function multiImpl() {}
273
- `);
274
-
275
- const result = checkFile('/test/file.ts');
276
-
277
- expect(result.annotations[0]?.implements?.length).toBeGreaterThanOrEqual(3);
278
- });
279
-
280
- it('应该处理 @dependencies', () => {
281
- mockFs.readFileSync.mockReturnValue(`
282
- /**
283
- * @spec AR-011
284
- * @dependencies lib1, lib2
285
- */
286
- export function withDeps() {}
287
- `);
288
-
289
- const result = checkFile('/test/file.ts');
290
-
291
- expect(result.annotations[0]?.dependencies?.length).toBeGreaterThan(0);
292
- });
293
- });
294
- });
@@ -1,320 +0,0 @@
1
- /**
2
- * 代码注释规范检查器
3
- *
4
- * 检查代码中的 @spec 注释是否规范
5
- */
6
-
7
- import { readFileSync } from 'fs';
8
- import * as path from 'path';
9
- import { walkFiles } from '../utils/file-walk';
10
-
11
- export interface AnnotationCheckResult {
12
- valid: boolean;
13
- file: string;
14
- annotations: SpecAnnotation[];
15
- errors: AnnotationError[];
16
- warnings: AnnotationWarning[];
17
- }
18
-
19
- export interface SpecAnnotation {
20
- specId: string;
21
- implements?: string[];
22
- acceptance?: string[];
23
- dependencies?: string[];
24
- author?: string;
25
- since?: string;
26
- line: number;
27
- type: 'class' | 'method' | 'function' | 'inline';
28
- }
29
-
30
- export interface AnnotationError {
31
- line: number;
32
- message: string;
33
- code: 'MISSING_SPEC' | 'INVALID_SPEC_FORMAT' | 'SPEC_NOT_APPROVED' | 'IMPLEMENTS_NOT_FOUND';
34
- }
35
-
36
- export interface AnnotationWarning {
37
- line: number;
38
- message: string;
39
- code: 'MISSING_IMPLEMENTS' | 'MISSING_ACCEPTANCE' | 'MISSING_AUTHOR';
40
- }
41
-
42
- // Spec ID 格式: AR-XXX, WS-XXX, etc.
43
- const SPEC_ID_REGEX = /^[A-Z]{2,3}-\d{3}$/;
44
-
45
- /**
46
- * 检查单个文件
47
- */
48
- export function checkFile(filePath: string): AnnotationCheckResult {
49
- const content = readFileSync(filePath, 'utf-8');
50
- const lines = content.split('\n');
51
-
52
- const result: AnnotationCheckResult = {
53
- valid: true,
54
- file: filePath,
55
- annotations: [],
56
- errors: [],
57
- warnings: [],
58
- };
59
-
60
- let inJSDoc = false;
61
- let currentJSDoc: string[] = [];
62
- let currentJSDocStartLine = 0;
63
-
64
- for (let i = 0; i < lines.length; i++) {
65
- const line = lines[i].trim();
66
-
67
- // JSDoc 开始
68
- if (line.startsWith('/**')) {
69
- inJSDoc = true;
70
- currentJSDoc = [line];
71
- currentJSDocStartLine = i + 1;
72
- continue;
73
- }
74
-
75
- // JSDoc 结束
76
- if (inJSDoc && line.endsWith('*/')) {
77
- inJSDoc = false;
78
- currentJSDoc.push(line);
79
-
80
- const annotation = parseJSDoc(currentJSDoc, currentJSDocStartLine);
81
- if (annotation) {
82
- result.annotations.push(annotation);
83
- validateAnnotation(annotation, result);
84
- }
85
-
86
- currentJSDoc = [];
87
- continue;
88
- }
89
-
90
- // JSDoc 中间
91
- if (inJSDoc) {
92
- currentJSDoc.push(line);
93
- }
94
-
95
- // 行内注释 // @spec AR-001
96
- const inlineMatch = line.match(/\/\/\s*@spec\s+(\S+)/);
97
- if (inlineMatch) {
98
- const specId = inlineMatch[1];
99
- const annotation: SpecAnnotation = {
100
- specId,
101
- line: i + 1,
102
- type: 'inline',
103
- };
104
- result.annotations.push(annotation);
105
- validateAnnotation(annotation, result);
106
- }
107
- }
108
-
109
- // 检查公共导出是否有注释
110
- checkPublicExports(content, result);
111
-
112
- result.valid = result.errors.length === 0;
113
- return result;
114
- }
115
-
116
- /**
117
- * 解析 JSDoc 注释
118
- */
119
- function parseJSDoc(lines: string[], startLine: number): SpecAnnotation | null {
120
- const content = lines.join('\n');
121
-
122
- // 检查是否有 @spec
123
- const specMatch = content.match(/@spec\s+(\S+)/);
124
- if (!specMatch) {
125
- return null;
126
- }
127
-
128
- const specId = specMatch[1];
129
-
130
- // 解析其他标签
131
- const annotation: SpecAnnotation = {
132
- specId,
133
- line: startLine,
134
- type: inferType(content),
135
- };
136
-
137
- // @implements
138
- const implementsMatch = content.match(/@implements\s+([\w\-_,\s]+)/);
139
- if (implementsMatch) {
140
- annotation.implements = implementsMatch[1]
141
- .split(/[,\s]+/)
142
- .map(s => s.trim())
143
- .filter(Boolean);
144
- }
145
-
146
- // @acceptance
147
- const acceptanceMatch = content.match(/@acceptance\s+([\w\-_,\s]+)/);
148
- if (acceptanceMatch) {
149
- annotation.acceptance = acceptanceMatch[1]
150
- .split(/[,\s]+/)
151
- .map(s => s.trim())
152
- .filter(Boolean);
153
- }
154
-
155
- // @dependencies
156
- const depsMatch = content.match(/@dependencies\s+([\w\-_,\s/]+)/);
157
- if (depsMatch) {
158
- annotation.dependencies = depsMatch[1]
159
- .split(/[,\s]+/)
160
- .map(s => s.trim())
161
- .filter(Boolean);
162
- }
163
-
164
- // @author
165
- const authorMatch = content.match(/@author\s+(\S+)/);
166
- if (authorMatch) {
167
- annotation.author = authorMatch[1];
168
- }
169
-
170
- // @since
171
- const sinceMatch = content.match(/@since\s+(\d{4}-\d{2}-\d{2})/);
172
- if (sinceMatch) {
173
- annotation.since = sinceMatch[1];
174
- }
175
-
176
- return annotation;
177
- }
178
-
179
- /**
180
- * 推断注释类型
181
- */
182
- function inferType(content: string): SpecAnnotation['type'] {
183
- if (content.includes('class ')) return 'class';
184
- if (content.includes('async ') || content.includes('function ')) return 'function';
185
- return 'method';
186
- }
187
-
188
- /**
189
- * 验证注释
190
- */
191
- function validateAnnotation(
192
- annotation: SpecAnnotation,
193
- result: AnnotationCheckResult
194
- ): void {
195
- // 检查 Spec ID 格式
196
- if (!SPEC_ID_REGEX.test(annotation.specId)) {
197
- result.errors.push({
198
- line: annotation.line,
199
- message: `Invalid spec ID format: ${annotation.specId}`,
200
- code: 'INVALID_SPEC_FORMAT',
201
- });
202
- }
203
-
204
- // 警告:建议标记 @implements
205
- if (!annotation.implements && annotation.type !== 'inline') {
206
- result.warnings.push({
207
- line: annotation.line,
208
- message: 'Missing @implements tag',
209
- code: 'MISSING_IMPLEMENTS',
210
- });
211
- }
212
-
213
- // 警告:建议标记 @acceptance
214
- if (!annotation.acceptance) {
215
- result.warnings.push({
216
- line: annotation.line,
217
- message: 'Missing @acceptance tag',
218
- code: 'MISSING_ACCEPTANCE',
219
- });
220
- }
221
- }
222
-
223
- /**
224
- * 检查公共导出是否有注释
225
- */
226
- function checkPublicExports(content: string, result: AnnotationCheckResult): void {
227
- // 查找 export class/function 但没有 @spec 的
228
- const exportRegex = /^(export\s+(?:abstract\s+)?(?:class|interface|function|const|let|var))\s+(\w+)/gm;
229
- let match;
230
-
231
- while ((match = exportRegex.exec(content)) !== null) {
232
- const line = content.substring(0, match.index).split('\n').length;
233
- const name = match[2];
234
-
235
- // 检查前10行是否有 @spec
236
- const beforeContent = content.substring(
237
- Math.max(0, match.index - 500),
238
- match.index
239
- );
240
-
241
- if (!beforeContent.includes('@spec')) {
242
- result.warnings.push({
243
- line,
244
- message: `Public export "${name}" missing @spec annotation`,
245
- code: 'MISSING_SPEC' as any,
246
- });
247
- }
248
- }
249
- }
250
-
251
- /**
252
- * 递归获取目录下所有文件(收敛到 utils/file-walk 的 walkFiles,工单 O3)
253
- */
254
- function getFilesRecursively(dir: string, extensions: string[]): string[] {
255
- return walkFiles(dir, {
256
- skipDirs: ['node_modules', 'dist'],
257
- filter: (name) => extensions.includes(path.extname(name)) && !name.endsWith('.d.ts'),
258
- });
259
- }
260
-
261
- /**
262
- * 批量检查目录
263
- */
264
- export function checkDirectory(
265
- dir: string,
266
- options: { extensions?: string[] } = {}
267
- ): AnnotationCheckResult[] {
268
- const extensions = options.extensions || ['.ts', '.tsx', '.js', '.jsx'];
269
- const files = getFilesRecursively(dir, extensions);
270
-
271
- return files.map(file => checkFile(file));
272
- }
273
-
274
- /**
275
- * 生成报告
276
- */
277
- export function generateReport(results: AnnotationCheckResult[]): string {
278
- const totalFiles = results.length;
279
- const validFiles = results.filter(r => r.valid).length;
280
- const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
281
- const totalWarnings = results.reduce((sum, r) => sum + r.warnings.length, 0);
282
-
283
- let report = `## 注释规范检查报告\n\n`;
284
- report += `- 检查文件: ${totalFiles}\n`;
285
- report += `- 通过: ${validFiles}/${totalFiles}\n`;
286
- report += `- 错误: ${totalErrors}\n`;
287
- report += `- 警告: ${totalWarnings}\n\n`;
288
-
289
- if (totalErrors > 0) {
290
- report += `### ❌ 错误\n\n`;
291
- for (const result of results) {
292
- for (const error of result.errors) {
293
- report += `- ${result.file}:${error.line} - ${error.message}\n`;
294
- }
295
- }
296
- report += '\n';
297
- }
298
-
299
- if (totalWarnings > 0) {
300
- report += `### ⚠️ 警告\n\n`;
301
- for (const result of results) {
302
- for (const warning of result.warnings.slice(0, 5)) {
303
- report += `- ${result.file}:${warning.line} - ${warning.message}\n`;
304
- }
305
- }
306
- }
307
-
308
- return report;
309
- }
310
-
311
- // CLI 入口
312
- if (require.main === module) {
313
- const args = process.argv.slice(2);
314
- const dir = args[0] || process.cwd();
315
-
316
- const results = checkDirectory(dir);
317
- console.log(generateReport(results));
318
- const hasErrors = results.some(r => r.errors.length > 0);
319
- process.exit(hasErrors ? 1 : 0);
320
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Enforcement 执行器类型定义
3
- */
4
-
5
- import type { Constraint, ConstraintContext } from './constraint';
6
-
7
- export type EnforcementId = string;
8
-
9
- export interface EnforcementContext extends ConstraintContext {
10
- enforcementId: EnforcementId;
11
- constraint: Constraint;
12
- params?: Record<string, any>;
13
- }
14
-
15
- export interface EnforcementResult {
16
- passed: boolean;
17
- evidence?: string;
18
- message?: string;
19
- error?: string;
20
- duration?: number;
21
- validatedAt?: Date;
22
- }
23
-
24
- export interface EnforcementExecutor {
25
- execute(context: EnforcementContext): Promise<EnforcementResult>;
26
- description?: string;
27
- supportedParams?: string[];
28
- }
29
-
30
- export interface EnforcementRegistration {
31
- id: EnforcementId;
32
- executor: EnforcementExecutor;
33
- registeredAt: Date;
34
- source?: string;
35
- }
36
-
37
- export interface InterceptionResult {
38
- passed: boolean;
39
- constraints: {
40
- constraint: Constraint;
41
- enforcementResult?: EnforcementResult;
42
- skipped?: boolean;
43
- skipReason?: string;
44
- }[];
45
- violations: Constraint[];
46
- message?: string;
47
- interceptedAt: Date;
48
- }