@dommaker/harness 1.1.1 → 1.2.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 (348) hide show
  1. package/CHANGELOG.md +10 -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 +7 -32
  7. package/dist/cli/commands/check.js.map +1 -1
  8. package/dist/cli/commands/definitions.d.ts +2 -0
  9. package/dist/cli/commands/definitions.d.ts.map +1 -1
  10. package/dist/cli/commands/definitions.js.map +1 -1
  11. package/dist/cli/commands/init.d.ts.map +1 -1
  12. package/dist/cli/commands/init.js +6 -37
  13. package/dist/cli/commands/init.js.map +1 -1
  14. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  15. package/dist/cli/commands/knowledge.js +1 -12
  16. package/dist/cli/commands/knowledge.js.map +1 -1
  17. package/dist/cli/commands/report.d.ts.map +1 -1
  18. package/dist/cli/commands/report.js +0 -2
  19. package/dist/cli/commands/report.js.map +1 -1
  20. package/dist/cli/commands/status.js +2 -2
  21. package/dist/cli/commands/status.js.map +1 -1
  22. package/dist/context/index.d.ts +9 -6
  23. package/dist/context/index.d.ts.map +1 -1
  24. package/dist/context/index.js +18 -20
  25. package/dist/context/index.js.map +1 -1
  26. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  27. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  28. package/dist/core/constraints/capabilities-parser.js +25 -47
  29. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  30. package/dist/core/constraints/checker.d.ts +29 -32
  31. package/dist/core/constraints/checker.d.ts.map +1 -1
  32. package/dist/core/constraints/checker.js +34 -126
  33. package/dist/core/constraints/checker.js.map +1 -1
  34. package/dist/core/constraints/checkers/index.d.ts +2 -1
  35. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  36. package/dist/core/constraints/checkers/index.js +3 -0
  37. package/dist/core/constraints/checkers/index.js.map +1 -1
  38. package/dist/core/constraints/checkers/types.d.ts +25 -0
  39. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  40. package/dist/core/constraints/checkers/types.js +24 -0
  41. package/dist/core/constraints/checkers/types.js.map +1 -1
  42. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  43. package/dist/core/constraints/definitions/guidelines.js +0 -2
  44. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  45. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  46. package/dist/core/constraints/definitions/prompts.js +0 -5
  47. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  48. package/dist/core/constraints/index.d.ts +1 -2
  49. package/dist/core/constraints/index.d.ts.map +1 -1
  50. package/dist/core/constraints/index.js +1 -7
  51. package/dist/core/constraints/index.js.map +1 -1
  52. package/dist/core/constraints/usage-report.d.ts +1 -2
  53. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  54. package/dist/core/constraints/usage-report.js +2 -5
  55. package/dist/core/constraints/usage-report.js.map +1 -1
  56. package/dist/core/effective-constraints.d.ts +24 -4
  57. package/dist/core/effective-constraints.d.ts.map +1 -1
  58. package/dist/core/effective-constraints.js +28 -7
  59. package/dist/core/effective-constraints.js.map +1 -1
  60. package/dist/core/effective-set.d.ts +30 -0
  61. package/dist/core/effective-set.d.ts.map +1 -0
  62. package/dist/core/effective-set.js +35 -0
  63. package/dist/core/effective-set.js.map +1 -0
  64. package/dist/core/index.d.ts +13 -6
  65. package/dist/core/index.d.ts.map +1 -1
  66. package/dist/core/index.js +44 -21
  67. package/dist/core/index.js.map +1 -1
  68. package/dist/core/project-config-loader.d.ts +3 -6
  69. package/dist/core/project-config-loader.d.ts.map +1 -1
  70. package/dist/core/project-config-loader.js +47 -61
  71. package/dist/core/project-config-loader.js.map +1 -1
  72. package/dist/failure/constraint-handler.d.ts +1 -1
  73. package/dist/failure/constraint-handler.js +1 -1
  74. package/dist/gates/checker-gate.d.ts +1 -4
  75. package/dist/gates/checker-gate.d.ts.map +1 -1
  76. package/dist/gates/checker-gate.js +3 -11
  77. package/dist/gates/checker-gate.js.map +1 -1
  78. package/dist/gates/definitions.d.ts +9 -38
  79. package/dist/gates/definitions.d.ts.map +1 -1
  80. package/dist/gates/definitions.js +24 -13
  81. package/dist/gates/definitions.js.map +1 -1
  82. package/dist/gates/effective-gates.d.ts.map +1 -1
  83. package/dist/gates/effective-gates.js +14 -18
  84. package/dist/gates/effective-gates.js.map +1 -1
  85. package/dist/gates/index.d.ts +1 -1
  86. package/dist/gates/index.d.ts.map +1 -1
  87. package/dist/gates/index.js.map +1 -1
  88. package/dist/hooks/bootstrap.d.ts.map +1 -1
  89. package/dist/hooks/bootstrap.js +0 -3
  90. package/dist/hooks/bootstrap.js.map +1 -1
  91. package/dist/index.d.ts +43 -60
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +180 -143
  94. package/dist/index.js.map +1 -1
  95. package/dist/knowledge/query.d.ts +15 -0
  96. package/dist/knowledge/query.d.ts.map +1 -1
  97. package/dist/knowledge/query.js +23 -0
  98. package/dist/knowledge/query.js.map +1 -1
  99. package/dist/monitoring/analyzer-base.d.ts +0 -4
  100. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  101. package/dist/monitoring/analyzer-base.js +0 -21
  102. package/dist/monitoring/analyzer-base.js.map +1 -1
  103. package/dist/monitoring/index.d.ts +6 -12
  104. package/dist/monitoring/index.d.ts.map +1 -1
  105. package/dist/monitoring/index.js +13 -29
  106. package/dist/monitoring/index.js.map +1 -1
  107. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  108. package/dist/monitoring/trace-analyzer.js +2 -68
  109. package/dist/monitoring/trace-analyzer.js.map +1 -1
  110. package/dist/monitoring/traces.d.ts +0 -4
  111. package/dist/monitoring/traces.d.ts.map +1 -1
  112. package/dist/monitoring/traces.js +0 -14
  113. package/dist/monitoring/traces.js.map +1 -1
  114. package/dist/presets/index.d.ts +2 -2
  115. package/dist/presets/index.d.ts.map +1 -1
  116. package/dist/presets/index.js +3 -4
  117. package/dist/presets/index.js.map +1 -1
  118. package/dist/presets/standard.d.ts +10 -22
  119. package/dist/presets/standard.d.ts.map +1 -1
  120. package/dist/presets/standard.js +15 -75
  121. package/dist/presets/standard.js.map +1 -1
  122. package/dist/types/constraint.d.ts +1 -29
  123. package/dist/types/constraint.d.ts.map +1 -1
  124. package/dist/types/constraint.js +1 -1
  125. package/dist/types/constraint.js.map +1 -1
  126. package/dist/types/index.d.ts +0 -3
  127. package/dist/types/index.d.ts.map +1 -1
  128. package/dist/types/index.js +0 -4
  129. package/dist/types/index.js.map +1 -1
  130. package/dist/types/project-config.d.ts +4 -8
  131. package/dist/types/project-config.d.ts.map +1 -1
  132. package/dist/types/trace.d.ts +5 -18
  133. package/dist/types/trace.d.ts.map +1 -1
  134. package/package.json +2 -2
  135. package/src/CONTEXT.md +4 -5
  136. package/src/__tests__/checker-extra.test.ts +33 -139
  137. package/src/__tests__/checker.test.ts +0 -376
  138. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  139. package/src/__tests__/public-exports.test.ts +138 -0
  140. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  141. package/src/__tests__/trace-analyzer.test.ts +4 -5
  142. package/src/__tests__/trace-collector.test.ts +0 -11
  143. package/src/__tests__/traces.test.ts +3 -22
  144. package/src/cli/commands/CONTEXT.md +2 -2
  145. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  146. package/src/cli/commands/__tests__/check.test.ts +29 -69
  147. package/src/cli/commands/__tests__/constraints-report.test.ts +1 -1
  148. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  149. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  150. package/src/cli/commands/__tests__/status-extra.test.ts +6 -6
  151. package/src/cli/commands/__tests__/status.test.ts +6 -6
  152. package/src/cli/commands/check.ts +8 -34
  153. package/src/cli/commands/definitions.ts +2 -0
  154. package/src/cli/commands/init.ts +6 -37
  155. package/src/cli/commands/knowledge.ts +1 -16
  156. package/src/cli/commands/report.ts +0 -2
  157. package/src/cli/commands/status.ts +2 -2
  158. package/src/context/index.ts +29 -6
  159. package/src/core/CONTEXT.md +4 -3
  160. package/src/core/__tests__/effective-set.test.ts +80 -0
  161. package/src/core/constraints/capabilities-parser.ts +43 -49
  162. package/src/core/constraints/checker.ts +51 -145
  163. package/src/core/constraints/checkers/index.ts +2 -1
  164. package/src/core/constraints/checkers/types.ts +42 -0
  165. package/src/core/constraints/definitions/guidelines.ts +0 -2
  166. package/src/core/constraints/definitions/prompts.ts +0 -5
  167. package/src/core/constraints/index.ts +2 -17
  168. package/src/core/constraints/usage-report.ts +5 -8
  169. package/src/core/effective-constraints.ts +35 -7
  170. package/src/core/effective-set.ts +56 -0
  171. package/src/core/index.ts +80 -6
  172. package/src/core/project-config-loader.ts +53 -68
  173. package/src/failure/CONTEXT.md +1 -1
  174. package/src/failure/constraint-handler.ts +1 -1
  175. package/src/gates/CONTEXT.md +3 -3
  176. package/src/gates/checker-gate.ts +4 -12
  177. package/src/gates/definitions.ts +27 -50
  178. package/src/gates/effective-gates.ts +14 -21
  179. package/src/gates/index.ts +1 -1
  180. package/src/hooks/bootstrap.ts +0 -3
  181. package/src/index.ts +384 -148
  182. package/src/knowledge/CONTEXT.md +2 -2
  183. package/src/knowledge/__tests__/query.test.ts +64 -0
  184. package/src/knowledge/query.ts +28 -0
  185. package/src/monitoring/CONTEXT.md +7 -13
  186. package/src/monitoring/__tests__/traces.test.ts +0 -10
  187. package/src/monitoring/analyzer-base.ts +0 -22
  188. package/src/monitoring/index.ts +6 -12
  189. package/src/monitoring/trace-analyzer.ts +2 -73
  190. package/src/monitoring/traces.ts +0 -20
  191. package/src/presets/__tests__/standard.test.ts +48 -69
  192. package/src/presets/index.ts +3 -5
  193. package/src/presets/standard.ts +14 -79
  194. package/src/spec/CONTEXT.md +5 -13
  195. package/src/types/constraint.ts +1 -51
  196. package/src/types/index.ts +0 -12
  197. package/src/types/project-config.ts +4 -10
  198. package/src/types/trace.ts +5 -30
  199. package/dist/core/constraints/interceptor.d.ts +0 -39
  200. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  201. package/dist/core/constraints/interceptor.js +0 -166
  202. package/dist/core/constraints/interceptor.js.map +0 -1
  203. package/dist/dashboard/data.d.ts +0 -31
  204. package/dist/dashboard/data.d.ts.map +0 -1
  205. package/dist/dashboard/data.js +0 -81
  206. package/dist/dashboard/data.js.map +0 -1
  207. package/dist/dashboard/index.d.ts +0 -4
  208. package/dist/dashboard/index.d.ts.map +0 -1
  209. package/dist/dashboard/index.js +0 -20
  210. package/dist/dashboard/index.js.map +0 -1
  211. package/dist/dashboard/stats.d.ts +0 -20
  212. package/dist/dashboard/stats.d.ts.map +0 -1
  213. package/dist/dashboard/stats.js +0 -115
  214. package/dist/dashboard/stats.js.map +0 -1
  215. package/dist/dashboard/types.d.ts +0 -110
  216. package/dist/dashboard/types.d.ts.map +0 -1
  217. package/dist/dashboard/types.js +0 -8
  218. package/dist/dashboard/types.js.map +0 -1
  219. package/dist/monitoring/constraint-doctor.d.ts +0 -76
  220. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  221. package/dist/monitoring/constraint-doctor.js +0 -189
  222. package/dist/monitoring/constraint-doctor.js.map +0 -1
  223. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  224. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  225. package/dist/monitoring/diagnosis-rules.js +0 -119
  226. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  227. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  228. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  229. package/dist/monitoring/knowledge-doctor.js +0 -266
  230. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  231. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  232. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  233. package/dist/monitoring/knowledge-evolver.js +0 -205
  234. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  235. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  236. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  237. package/dist/monitoring/performance-analyzer.js +0 -343
  238. package/dist/monitoring/performance-analyzer.js.map +0 -1
  239. package/dist/monitoring/performance-collector.d.ts +0 -103
  240. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  241. package/dist/monitoring/performance-collector.js +0 -298
  242. package/dist/monitoring/performance-collector.js.map +0 -1
  243. package/dist/safety/index.d.ts +0 -6
  244. package/dist/safety/index.d.ts.map +0 -1
  245. package/dist/safety/index.js +0 -22
  246. package/dist/safety/index.js.map +0 -1
  247. package/dist/safety/input-guardrail.d.ts +0 -36
  248. package/dist/safety/input-guardrail.d.ts.map +0 -1
  249. package/dist/safety/input-guardrail.js +0 -118
  250. package/dist/safety/input-guardrail.js.map +0 -1
  251. package/dist/safety/output-guardrail.d.ts +0 -39
  252. package/dist/safety/output-guardrail.d.ts.map +0 -1
  253. package/dist/safety/output-guardrail.js +0 -147
  254. package/dist/safety/output-guardrail.js.map +0 -1
  255. package/dist/safety/sandbox.d.ts +0 -45
  256. package/dist/safety/sandbox.d.ts.map +0 -1
  257. package/dist/safety/sandbox.js +0 -134
  258. package/dist/safety/sandbox.js.map +0 -1
  259. package/dist/safety/tool-guardrail.d.ts +0 -51
  260. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  261. package/dist/safety/tool-guardrail.js +0 -147
  262. package/dist/safety/tool-guardrail.js.map +0 -1
  263. package/dist/safety/types.d.ts +0 -104
  264. package/dist/safety/types.d.ts.map +0 -1
  265. package/dist/safety/types.js +0 -6
  266. package/dist/safety/types.js.map +0 -1
  267. package/dist/spec/annotation-checker.d.ts +0 -47
  268. package/dist/spec/annotation-checker.d.ts.map +0 -1
  269. package/dist/spec/annotation-checker.js +0 -279
  270. package/dist/spec/annotation-checker.js.map +0 -1
  271. package/dist/types/enforcement.d.ts +0 -42
  272. package/dist/types/enforcement.d.ts.map +0 -1
  273. package/dist/types/enforcement.js +0 -6
  274. package/dist/types/enforcement.js.map +0 -1
  275. package/dist/types/monitoring-types.d.ts +0 -53
  276. package/dist/types/monitoring-types.d.ts.map +0 -1
  277. package/dist/types/monitoring-types.js +0 -10
  278. package/dist/types/monitoring-types.js.map +0 -1
  279. package/dist/types/performance.d.ts +0 -204
  280. package/dist/types/performance.d.ts.map +0 -1
  281. package/dist/types/performance.js +0 -12
  282. package/dist/types/performance.js.map +0 -1
  283. package/dist/verification/index.d.ts +0 -4
  284. package/dist/verification/index.d.ts.map +0 -1
  285. package/dist/verification/index.js +0 -20
  286. package/dist/verification/index.js.map +0 -1
  287. package/dist/verification/loop.d.ts +0 -30
  288. package/dist/verification/loop.d.ts.map +0 -1
  289. package/dist/verification/loop.js +0 -114
  290. package/dist/verification/loop.js.map +0 -1
  291. package/dist/verification/rules-based.d.ts +0 -40
  292. package/dist/verification/rules-based.d.ts.map +0 -1
  293. package/dist/verification/rules-based.js +0 -130
  294. package/dist/verification/rules-based.js.map +0 -1
  295. package/dist/verification/types.d.ts +0 -69
  296. package/dist/verification/types.d.ts.map +0 -1
  297. package/dist/verification/types.js +0 -6
  298. package/dist/verification/types.js.map +0 -1
  299. package/src/__tests__/annotation-checker.test.ts +0 -183
  300. package/src/__tests__/constraint-doctor.test.ts +0 -271
  301. package/src/__tests__/doctor-extra.test.ts +0 -155
  302. package/src/__tests__/extend-exceptions.test.ts +0 -149
  303. package/src/__tests__/interceptor.test.ts +0 -89
  304. package/src/__tests__/performance-analyzer.test.ts +0 -499
  305. package/src/__tests__/performance-collector.test.ts +0 -276
  306. package/src/__tests__/presets.test.ts +0 -65
  307. package/src/core/constraints/__tests__/interceptor.test.ts +0 -267
  308. package/src/core/constraints/interceptor.ts +0 -217
  309. package/src/dashboard/CONTEXT.md +0 -21
  310. package/src/dashboard/__tests__/data.test.ts +0 -111
  311. package/src/dashboard/__tests__/stats.test.ts +0 -159
  312. package/src/dashboard/data.ts +0 -103
  313. package/src/dashboard/index.ts +0 -3
  314. package/src/dashboard/stats.ts +0 -127
  315. package/src/dashboard/types.ts +0 -130
  316. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  317. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  318. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  319. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  320. package/src/monitoring/constraint-doctor.ts +0 -228
  321. package/src/monitoring/diagnosis-rules.ts +0 -132
  322. package/src/monitoring/knowledge-doctor.ts +0 -322
  323. package/src/monitoring/knowledge-evolver.ts +0 -289
  324. package/src/monitoring/performance-analyzer.ts +0 -400
  325. package/src/monitoring/performance-collector.ts +0 -326
  326. package/src/safety/CONTEXT.md +0 -23
  327. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  328. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  329. package/src/safety/__tests__/sandbox.test.ts +0 -158
  330. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  331. package/src/safety/index.ts +0 -5
  332. package/src/safety/input-guardrail.ts +0 -133
  333. package/src/safety/output-guardrail.ts +0 -170
  334. package/src/safety/sandbox.ts +0 -148
  335. package/src/safety/tool-guardrail.ts +0 -176
  336. package/src/safety/types.ts +0 -124
  337. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  338. package/src/spec/annotation-checker.ts +0 -320
  339. package/src/types/enforcement.ts +0 -48
  340. package/src/types/monitoring-types.ts +0 -68
  341. package/src/types/performance.ts +0 -295
  342. package/src/verification/CONTEXT.md +0 -23
  343. package/src/verification/__tests__/loop.test.ts +0 -303
  344. package/src/verification/__tests__/rules-based.test.ts +0 -240
  345. package/src/verification/index.ts +0 -3
  346. package/src/verification/loop.ts +0 -137
  347. package/src/verification/rules-based.ts +0 -152
  348. package/src/verification/types.ts +0 -81
@@ -1,240 +0,0 @@
1
- /**
2
- * RulesBasedVerification 测试
3
- */
4
-
5
- import { RulesBasedVerification } from '../rules-based';
6
- import type { VerificationRule, VerificationContext } from '../types';
7
-
8
- describe('RulesBasedVerification', () => {
9
- const context: VerificationContext = {
10
- projectRoot: process.cwd(),
11
- };
12
-
13
- describe('verifyAll', () => {
14
- it('应该通过空规则列表', async () => {
15
- const verifier = new RulesBasedVerification([]);
16
- const results = await verifier.verifyAll(context);
17
- expect(results.length).toBe(0);
18
- });
19
-
20
- it('应该执行所有规则', async () => {
21
- const rules: VerificationRule[] = [
22
- {
23
- id: 'rule-1',
24
- type: 'custom',
25
- name: 'Rule 1',
26
- description: 'Always pass',
27
- verify: async () => ({ passed: true, ruleId: 'rule-1', duration: 0 }),
28
- },
29
- {
30
- id: 'rule-2',
31
- type: 'custom',
32
- name: 'Rule 2',
33
- description: 'Always pass',
34
- verify: async () => ({ passed: true, ruleId: 'rule-2', duration: 0 }),
35
- },
36
- ];
37
-
38
- const verifier = new RulesBasedVerification(rules);
39
- const results = await verifier.verifyAll(context);
40
- expect(results.length).toBe(2);
41
- expect(results.every(r => r.passed)).toBe(true);
42
- });
43
-
44
- it('应该收集失败结果', async () => {
45
- const rules: VerificationRule[] = [
46
- {
47
- id: 'pass',
48
- type: 'custom',
49
- name: 'Pass',
50
- description: '',
51
- verify: async () => ({ passed: true, ruleId: 'pass', duration: 0 }),
52
- },
53
- {
54
- id: 'fail',
55
- type: 'custom',
56
- name: 'Fail',
57
- description: '',
58
- verify: async () => ({ passed: false, ruleId: 'fail', message: 'failed', duration: 0 }),
59
- },
60
- ];
61
-
62
- const verifier = new RulesBasedVerification(rules);
63
- const results = await verifier.verifyAll(context);
64
- expect(results.some(r => r.passed)).toBe(true);
65
- expect(results.some(r => !r.passed)).toBe(true);
66
- });
67
- });
68
-
69
- describe('command rules', () => {
70
- it('应该执行成功的命令', async () => {
71
- const rules: VerificationRule[] = [
72
- {
73
- id: 'echo',
74
- type: 'test',
75
- name: 'Echo Test',
76
- description: 'Run echo',
77
- command: 'echo "hello"',
78
- },
79
- ];
80
-
81
- const verifier = new RulesBasedVerification(rules);
82
- const results = await verifier.verifyAll(context);
83
- expect(results[0].passed).toBe(true);
84
- expect(results[0].details).toContain('hello');
85
- });
86
-
87
- it('应该处理失败的命令', async () => {
88
- const rules: VerificationRule[] = [
89
- {
90
- id: 'fail-cmd',
91
- type: 'test',
92
- name: 'Fail Test',
93
- description: 'Run failing command',
94
- command: 'exit 1',
95
- },
96
- ];
97
-
98
- const verifier = new RulesBasedVerification(rules);
99
- const results = await verifier.verifyAll(context);
100
- expect(results[0].passed).toBe(false);
101
- });
102
-
103
- it('应该处理缺少 command 的规则', async () => {
104
- const rules: VerificationRule[] = [
105
- {
106
- id: 'no-cmd',
107
- type: 'lint',
108
- name: 'No Command',
109
- description: 'Missing command',
110
- },
111
- ];
112
-
113
- const verifier = new RulesBasedVerification(rules);
114
- const results = await verifier.verifyAll(context);
115
- expect(results[0].passed).toBe(false);
116
- expect(results[0].message).toContain('缺少 command');
117
- });
118
- });
119
-
120
- describe('custom rules', () => {
121
- it('应该执行自定义验证函数', async () => {
122
- const rules: VerificationRule[] = [
123
- {
124
- id: 'custom',
125
- type: 'custom',
126
- name: 'Custom Check',
127
- description: 'Check changed files',
128
- verify: async (ctx) => ({
129
- passed: (ctx.changedFiles?.length ?? 0) > 0,
130
- ruleId: 'custom',
131
- message: '需要变更文件',
132
- duration: 0,
133
- }),
134
- },
135
- ];
136
-
137
- const verifier = new RulesBasedVerification(rules);
138
-
139
- // 没有变更文件 -> 失败
140
- const failResults = await verifier.verifyAll(context);
141
- expect(failResults[0].passed).toBe(false);
142
-
143
- // 有变更文件 -> 通过
144
- const passResults = await verifier.verifyAll({ ...context, changedFiles: ['a.ts'] });
145
- expect(passResults[0].passed).toBe(true);
146
- });
147
-
148
- it('应该处理缺少 verify 的 custom 规则', async () => {
149
- const rules: VerificationRule[] = [
150
- {
151
- id: 'no-verify',
152
- type: 'custom',
153
- name: 'No Verify',
154
- description: 'Missing verify function',
155
- },
156
- ];
157
-
158
- const verifier = new RulesBasedVerification(rules);
159
- const results = await verifier.verifyAll(context);
160
- expect(results[0].passed).toBe(false);
161
- expect(results[0].message).toContain('缺少 verify');
162
- });
163
- });
164
-
165
- describe('rule management', () => {
166
- it('应该添加规则', () => {
167
- const verifier = new RulesBasedVerification([]);
168
- verifier.addRule({
169
- id: 'new',
170
- type: 'custom',
171
- name: 'New',
172
- description: '',
173
- verify: async () => ({ passed: true, ruleId: 'new', duration: 0 }),
174
- });
175
- expect(verifier.getRules().length).toBe(1);
176
- });
177
-
178
- it('应该移除规则', () => {
179
- const verifier = new RulesBasedVerification([
180
- { id: 'a', type: 'custom', name: 'A', description: '' },
181
- { id: 'b', type: 'custom', name: 'B', description: '' },
182
- ]);
183
- verifier.removeRule('a');
184
- expect(verifier.getRules().length).toBe(1);
185
- expect(verifier.getRules()[0].id).toBe('b');
186
- });
187
- });
188
-
189
- describe('error handling', () => {
190
- it('应该处理验证函数抛出异常', async () => {
191
- const rules: VerificationRule[] = [
192
- {
193
- id: 'throw',
194
- type: 'custom',
195
- name: 'Throw',
196
- description: '',
197
- verify: async () => { throw new Error('boom'); },
198
- },
199
- ];
200
-
201
- const verifier = new RulesBasedVerification(rules);
202
- const results = await verifier.verifyAll(context);
203
- expect(results[0].passed).toBe(false);
204
- expect(results[0].message).toContain('boom');
205
- });
206
-
207
- it('应该处理未知规则类型', async () => {
208
- const rules: VerificationRule[] = [
209
- {
210
- id: 'unknown',
211
- type: 'unknown' as any,
212
- name: 'Unknown',
213
- description: '',
214
- },
215
- ];
216
-
217
- const verifier = new RulesBasedVerification(rules);
218
- const results = await verifier.verifyAll(context);
219
- expect(results[0].passed).toBe(false);
220
- expect(results[0].message).toContain('未知');
221
- });
222
-
223
- it('应该处理命令执行超时', async () => {
224
- const rules: VerificationRule[] = [
225
- {
226
- id: 'timeout',
227
- type: 'test',
228
- name: 'Timeout Test',
229
- description: '',
230
- command: 'sleep 10',
231
- timeout: 100,
232
- },
233
- ];
234
-
235
- const verifier = new RulesBasedVerification(rules);
236
- const results = await verifier.verifyAll(context);
237
- expect(results[0].passed).toBe(false);
238
- }, 10000);
239
- });
240
- });
@@ -1,3 +0,0 @@
1
- export * from './types';
2
- export * from './rules-based';
3
- export * from './loop';
@@ -1,137 +0,0 @@
1
- /**
2
- * 验证循环(Gather-Act-Verify)
3
- *
4
- * 编排验证流程:
5
- * 1. Gather:收集当前状态
6
- * 2. Act:执行动作
7
- * 3. Verify:验证结果
8
- * 失败时重试,最多 N 次
9
- */
10
-
11
- import type {
12
- VerificationLoopConfig,
13
- LoopSnapshot,
14
- LoopStatus,
15
- VerificationResult,
16
- GatherState,
17
- ActAction,
18
- VerificationContext,
19
- } from './types';
20
- import { RulesBasedVerification } from './rules-based';
21
-
22
- export type GatherFn = (attempt: number) => Promise<GatherState>;
23
- export type ActFn = (state: GatherState, results: VerificationResult[]) => Promise<ActAction>;
24
-
25
- export class VerificationLoop {
26
- private config: VerificationLoopConfig;
27
- private verifier: RulesBasedVerification;
28
- private status: LoopStatus = 'idle';
29
- private attempt = 0;
30
- private results: VerificationResult[] = [];
31
- private lastError?: string;
32
-
33
- constructor(config: VerificationLoopConfig) {
34
- this.config = config;
35
- this.verifier = new RulesBasedVerification(config.rules);
36
- }
37
-
38
- /**
39
- * 执行验证循环
40
- */
41
- async run(
42
- context: VerificationContext,
43
- gather: GatherFn,
44
- act?: ActFn,
45
- ): Promise<LoopSnapshot> {
46
- this.status = 'idle';
47
- this.attempt = 0;
48
- this.results = [];
49
- this.lastError = undefined;
50
-
51
- while (this.attempt < this.config.maxRetries) {
52
- this.attempt++;
53
-
54
- // Gather
55
- this.status = 'gathering';
56
- let gatherState: GatherState;
57
- try {
58
- gatherState = await gather(this.attempt);
59
- } catch (error) {
60
- this.lastError = `Gather 失败: ${error instanceof Error ? error.message : String(error)}`;
61
- this.status = 'failed';
62
- return this.snapshot();
63
- }
64
-
65
- // Act(可选)
66
- if (act && this.attempt > 1) {
67
- this.status = 'acting';
68
- try {
69
- const action = await act(gatherState, this.results);
70
- if (action.type === 'abort') {
71
- this.lastError = `Act 中止: ${action.description}`;
72
- this.status = 'failed';
73
- return this.snapshot();
74
- }
75
- if (action.type === 'skip') {
76
- this.status = 'passed';
77
- return this.snapshot();
78
- }
79
- } catch (error) {
80
- this.lastError = `Act 失败: ${error instanceof Error ? error.message : String(error)}`;
81
- this.status = 'failed';
82
- return this.snapshot();
83
- }
84
- }
85
-
86
- // Verify
87
- this.status = 'verifying';
88
- try {
89
- this.results = await this.verifier.verifyAll(context);
90
- } catch (error) {
91
- this.lastError = `Verify 失败: ${error instanceof Error ? error.message : String(error)}`;
92
- this.status = 'failed';
93
- return this.snapshot();
94
- }
95
-
96
- const allPassed = this.results.every(r => r.passed);
97
- if (allPassed) {
98
- this.status = 'passed';
99
- return this.snapshot();
100
- }
101
-
102
- // failFast: 首次失败立即停止
103
- if (this.config.failFast) {
104
- this.lastError = '验证失败 (failFast)';
105
- this.status = 'failed';
106
- return this.snapshot();
107
- }
108
- }
109
-
110
- this.lastError = `达到最大重试次数 (${this.config.maxRetries})`;
111
- this.status = 'failed';
112
- return this.snapshot();
113
- }
114
-
115
- private snapshot(): LoopSnapshot {
116
- return {
117
- status: this.status,
118
- attempt: this.attempt,
119
- maxRetries: this.config.maxRetries,
120
- results: this.results,
121
- lastError: this.lastError,
122
- timestamp: new Date().toISOString(),
123
- };
124
- }
125
-
126
- getStatus(): LoopStatus {
127
- return this.status;
128
- }
129
-
130
- getAttempt(): number {
131
- return this.attempt;
132
- }
133
-
134
- getResults(): VerificationResult[] {
135
- return [...this.results];
136
- }
137
- }
@@ -1,152 +0,0 @@
1
- /**
2
- * 基于规则的确定性验证
3
- *
4
- * 执行 test / lint / typecheck / custom 规则
5
- * 纯确定性验证,不依赖 LLM
6
- */
7
-
8
- import { execSync } from 'child_process';
9
- import type {
10
- VerificationRule,
11
- VerificationContext,
12
- VerificationResult,
13
- } from './types';
14
-
15
- export class RulesBasedVerification {
16
- private rules: VerificationRule[];
17
-
18
- constructor(rules: VerificationRule[]) {
19
- this.rules = rules;
20
- }
21
-
22
- /**
23
- * 执行所有规则验证
24
- */
25
- async verifyAll(context: VerificationContext): Promise<VerificationResult[]> {
26
- const results: VerificationResult[] = [];
27
-
28
- for (const rule of this.rules) {
29
- const result = await this.verifyRule(rule, context);
30
- results.push(result);
31
- }
32
-
33
- return results;
34
- }
35
-
36
- /**
37
- * 执行单条规则验证
38
- */
39
- async verifyRule(rule: VerificationRule, context: VerificationContext): Promise<VerificationResult> {
40
- const start = Date.now();
41
-
42
- try {
43
- switch (rule.type) {
44
- case 'test':
45
- case 'lint':
46
- case 'typecheck':
47
- return await this.executeCommand(rule, context, start);
48
- case 'custom':
49
- return await this.executeCustom(rule, context, start);
50
- default:
51
- return {
52
- passed: false,
53
- ruleId: rule.id,
54
- message: `未知的规则类型: ${rule.type}`,
55
- duration: Date.now() - start,
56
- };
57
- }
58
- } catch (error) {
59
- return {
60
- passed: false,
61
- ruleId: rule.id,
62
- message: `验证执行失败: ${error instanceof Error ? error.message : String(error)}`,
63
- duration: Date.now() - start,
64
- };
65
- }
66
- }
67
-
68
- /**
69
- * 执行命令类规则
70
- */
71
- private async executeCommand(
72
- rule: VerificationRule,
73
- context: VerificationContext,
74
- start: number,
75
- ): Promise<VerificationResult> {
76
- if (!rule.command) {
77
- return {
78
- passed: false,
79
- ruleId: rule.id,
80
- message: `规则 ${rule.id} 缺少 command`,
81
- duration: Date.now() - start,
82
- };
83
- }
84
-
85
- try {
86
- const output = execSync(rule.command, {
87
- cwd: context.projectRoot,
88
- timeout: rule.timeout ?? 30000,
89
- encoding: 'utf-8',
90
- stdio: ['pipe', 'pipe', 'pipe'],
91
- });
92
-
93
- return {
94
- passed: true,
95
- ruleId: rule.id,
96
- message: `${rule.name} 通过`,
97
- details: output.slice(0, 1000),
98
- duration: Date.now() - start,
99
- };
100
- } catch (error: unknown) {
101
- const execError = error as { status?: number; stderr?: string; stdout?: string };
102
- return {
103
- passed: false,
104
- ruleId: rule.id,
105
- message: `${rule.name} 失败 (exit ${execError.status ?? 'unknown'})`,
106
- details: (execError.stderr ?? execError.stdout ?? '').slice(0, 1000),
107
- duration: Date.now() - start,
108
- };
109
- }
110
- }
111
-
112
- /**
113
- * 执行自定义规则
114
- */
115
- private async executeCustom(
116
- rule: VerificationRule,
117
- context: VerificationContext,
118
- start: number,
119
- ): Promise<VerificationResult> {
120
- if (!rule.verify) {
121
- return {
122
- passed: false,
123
- ruleId: rule.id,
124
- message: `规则 ${rule.id} 缺少 verify 函数`,
125
- duration: Date.now() - start,
126
- };
127
- }
128
-
129
- return rule.verify(context);
130
- }
131
-
132
- /**
133
- * 添加规则
134
- */
135
- addRule(rule: VerificationRule): void {
136
- this.rules.push(rule);
137
- }
138
-
139
- /**
140
- * 移除规则
141
- */
142
- removeRule(ruleId: string): void {
143
- this.rules = this.rules.filter(r => r.id !== ruleId);
144
- }
145
-
146
- /**
147
- * 获取规则列表
148
- */
149
- getRules(): VerificationRule[] {
150
- return [...this.rules];
151
- }
152
- }
@@ -1,81 +0,0 @@
1
- /**
2
- * Verification Loop 类型定义
3
- */
4
-
5
- // ── 验证规则 ─────────────────────────────────────────────
6
-
7
- /** 验证规则类型 */
8
- export type VerificationRuleType = 'test' | 'lint' | 'typecheck' | 'custom';
9
-
10
- /** 验证规则 */
11
- export interface VerificationRule {
12
- id: string;
13
- type: VerificationRuleType;
14
- name: string;
15
- description: string;
16
- /** 执行命令(用于 test/lint/typecheck) */
17
- command?: string;
18
- /** 自定义验证函数(用于 custom) */
19
- verify?: (context: VerificationContext) => Promise<VerificationResult>;
20
- /** 超时(ms) */
21
- timeout?: number;
22
- }
23
-
24
- /** 验证上下文 */
25
- export interface VerificationContext {
26
- /** 项目根目录 */
27
- projectRoot: string;
28
- /** 变更的文件列表 */
29
- changedFiles?: string[];
30
- /** 额外元数据 */
31
- metadata?: Record<string, unknown>;
32
- }
33
-
34
- /** 单条规则的验证结果 */
35
- export interface VerificationResult {
36
- passed: boolean;
37
- ruleId: string;
38
- message?: string;
39
- details?: string;
40
- duration: number;
41
- }
42
-
43
- // ── 验证循环 ─────────────────────────────────────────────
44
-
45
- /** 验证循环状态 */
46
- export type LoopStatus = 'idle' | 'gathering' | 'acting' | 'verifying' | 'passed' | 'failed';
47
-
48
- /** 验证循环配置 */
49
- export interface VerificationLoopConfig {
50
- /** 最大重试次数 */
51
- maxRetries: number;
52
- /** 验证规则 */
53
- rules: VerificationRule[];
54
- /** 是否在首次失败时立即停止 */
55
- failFast?: boolean;
56
- }
57
-
58
- /** 验证循环快照 */
59
- export interface LoopSnapshot {
60
- status: LoopStatus;
61
- attempt: number;
62
- maxRetries: number;
63
- results: VerificationResult[];
64
- lastError?: string;
65
- timestamp: string;
66
- }
67
-
68
- /** Gather 阶段的状态 */
69
- export interface GatherState {
70
- changedFiles: string[];
71
- testResults?: string;
72
- lintResults?: string;
73
- metadata: Record<string, unknown>;
74
- }
75
-
76
- /** Act 阶段的动作 */
77
- export interface ActAction {
78
- type: 'fix' | 'retry' | 'skip' | 'abort';
79
- description: string;
80
- target?: string;
81
- }