@dommaker/harness 1.1.0 → 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 (349) hide show
  1. package/CHANGELOG.md +19 -2
  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.d.ts.map +1 -1
  21. package/dist/cli/commands/status.js +2 -11
  22. package/dist/cli/commands/status.js.map +1 -1
  23. package/dist/context/index.d.ts +9 -6
  24. package/dist/context/index.d.ts.map +1 -1
  25. package/dist/context/index.js +18 -20
  26. package/dist/context/index.js.map +1 -1
  27. package/dist/core/constraints/capabilities-parser.d.ts +3 -2
  28. package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
  29. package/dist/core/constraints/capabilities-parser.js +25 -47
  30. package/dist/core/constraints/capabilities-parser.js.map +1 -1
  31. package/dist/core/constraints/checker.d.ts +32 -33
  32. package/dist/core/constraints/checker.d.ts.map +1 -1
  33. package/dist/core/constraints/checker.js +38 -128
  34. package/dist/core/constraints/checker.js.map +1 -1
  35. package/dist/core/constraints/checkers/index.d.ts +2 -1
  36. package/dist/core/constraints/checkers/index.d.ts.map +1 -1
  37. package/dist/core/constraints/checkers/index.js +3 -0
  38. package/dist/core/constraints/checkers/index.js.map +1 -1
  39. package/dist/core/constraints/checkers/types.d.ts +25 -0
  40. package/dist/core/constraints/checkers/types.d.ts.map +1 -1
  41. package/dist/core/constraints/checkers/types.js +24 -0
  42. package/dist/core/constraints/checkers/types.js.map +1 -1
  43. package/dist/core/constraints/definitions/guidelines.d.ts.map +1 -1
  44. package/dist/core/constraints/definitions/guidelines.js +0 -2
  45. package/dist/core/constraints/definitions/guidelines.js.map +1 -1
  46. package/dist/core/constraints/definitions/prompts.d.ts.map +1 -1
  47. package/dist/core/constraints/definitions/prompts.js +0 -5
  48. package/dist/core/constraints/definitions/prompts.js.map +1 -1
  49. package/dist/core/constraints/index.d.ts +1 -2
  50. package/dist/core/constraints/index.d.ts.map +1 -1
  51. package/dist/core/constraints/index.js +1 -7
  52. package/dist/core/constraints/index.js.map +1 -1
  53. package/dist/core/constraints/usage-report.d.ts +1 -2
  54. package/dist/core/constraints/usage-report.d.ts.map +1 -1
  55. package/dist/core/constraints/usage-report.js +2 -5
  56. package/dist/core/constraints/usage-report.js.map +1 -1
  57. package/dist/core/effective-constraints.d.ts +24 -4
  58. package/dist/core/effective-constraints.d.ts.map +1 -1
  59. package/dist/core/effective-constraints.js +28 -7
  60. package/dist/core/effective-constraints.js.map +1 -1
  61. package/dist/core/effective-set.d.ts +30 -0
  62. package/dist/core/effective-set.d.ts.map +1 -0
  63. package/dist/core/effective-set.js +35 -0
  64. package/dist/core/effective-set.js.map +1 -0
  65. package/dist/core/index.d.ts +13 -6
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +44 -21
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/project-config-loader.d.ts +3 -6
  70. package/dist/core/project-config-loader.d.ts.map +1 -1
  71. package/dist/core/project-config-loader.js +47 -61
  72. package/dist/core/project-config-loader.js.map +1 -1
  73. package/dist/failure/constraint-handler.d.ts +1 -1
  74. package/dist/failure/constraint-handler.js +1 -1
  75. package/dist/gates/checker-gate.d.ts +1 -4
  76. package/dist/gates/checker-gate.d.ts.map +1 -1
  77. package/dist/gates/checker-gate.js +3 -11
  78. package/dist/gates/checker-gate.js.map +1 -1
  79. package/dist/gates/definitions.d.ts +9 -38
  80. package/dist/gates/definitions.d.ts.map +1 -1
  81. package/dist/gates/definitions.js +24 -13
  82. package/dist/gates/definitions.js.map +1 -1
  83. package/dist/gates/effective-gates.d.ts.map +1 -1
  84. package/dist/gates/effective-gates.js +14 -18
  85. package/dist/gates/effective-gates.js.map +1 -1
  86. package/dist/gates/index.d.ts +1 -1
  87. package/dist/gates/index.d.ts.map +1 -1
  88. package/dist/gates/index.js.map +1 -1
  89. package/dist/hooks/bootstrap.d.ts.map +1 -1
  90. package/dist/hooks/bootstrap.js +0 -3
  91. package/dist/hooks/bootstrap.js.map +1 -1
  92. package/dist/index.d.ts +43 -53
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +180 -138
  95. package/dist/index.js.map +1 -1
  96. package/dist/knowledge/query.d.ts +15 -0
  97. package/dist/knowledge/query.d.ts.map +1 -1
  98. package/dist/knowledge/query.js +23 -0
  99. package/dist/knowledge/query.js.map +1 -1
  100. package/dist/monitoring/analyzer-base.d.ts +0 -4
  101. package/dist/monitoring/analyzer-base.d.ts.map +1 -1
  102. package/dist/monitoring/analyzer-base.js +0 -21
  103. package/dist/monitoring/analyzer-base.js.map +1 -1
  104. package/dist/monitoring/index.d.ts +6 -12
  105. package/dist/monitoring/index.d.ts.map +1 -1
  106. package/dist/monitoring/index.js +13 -29
  107. package/dist/monitoring/index.js.map +1 -1
  108. package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
  109. package/dist/monitoring/trace-analyzer.js +2 -68
  110. package/dist/monitoring/trace-analyzer.js.map +1 -1
  111. package/dist/monitoring/traces.d.ts +2 -6
  112. package/dist/monitoring/traces.d.ts.map +1 -1
  113. package/dist/monitoring/traces.js +0 -14
  114. package/dist/monitoring/traces.js.map +1 -1
  115. package/dist/presets/index.d.ts +2 -2
  116. package/dist/presets/index.d.ts.map +1 -1
  117. package/dist/presets/index.js +3 -4
  118. package/dist/presets/index.js.map +1 -1
  119. package/dist/presets/standard.d.ts +10 -22
  120. package/dist/presets/standard.d.ts.map +1 -1
  121. package/dist/presets/standard.js +15 -75
  122. package/dist/presets/standard.js.map +1 -1
  123. package/dist/types/constraint.d.ts +1 -29
  124. package/dist/types/constraint.d.ts.map +1 -1
  125. package/dist/types/constraint.js +1 -1
  126. package/dist/types/constraint.js.map +1 -1
  127. package/dist/types/index.d.ts +0 -3
  128. package/dist/types/index.d.ts.map +1 -1
  129. package/dist/types/index.js +0 -4
  130. package/dist/types/index.js.map +1 -1
  131. package/dist/types/project-config.d.ts +4 -8
  132. package/dist/types/project-config.d.ts.map +1 -1
  133. package/dist/types/trace.d.ts +9 -22
  134. package/dist/types/trace.d.ts.map +1 -1
  135. package/package.json +2 -2
  136. package/src/CONTEXT.md +5 -7
  137. package/src/__tests__/checker-extra.test.ts +80 -139
  138. package/src/__tests__/checker.test.ts +0 -376
  139. package/src/__tests__/project-config-loader-extra.test.ts +42 -29
  140. package/src/__tests__/public-exports.test.ts +138 -0
  141. package/src/__tests__/trace-analyzer-extra.test.ts +6 -86
  142. package/src/__tests__/trace-analyzer.test.ts +4 -5
  143. package/src/__tests__/trace-collector.test.ts +0 -11
  144. package/src/__tests__/traces.test.ts +3 -22
  145. package/src/cli/commands/CONTEXT.md +2 -2
  146. package/src/cli/commands/__tests__/check-skip-output.test.ts +10 -7
  147. package/src/cli/commands/__tests__/check.test.ts +29 -69
  148. package/src/cli/commands/__tests__/constraints-report.test.ts +1 -1
  149. package/src/cli/commands/__tests__/knowledge.test.ts +90 -1
  150. package/src/cli/commands/__tests__/registry.test.ts +8 -6
  151. package/src/cli/commands/__tests__/status-extra.test.ts +6 -28
  152. package/src/cli/commands/__tests__/status.test.ts +6 -21
  153. package/src/cli/commands/check.ts +8 -34
  154. package/src/cli/commands/definitions.ts +2 -0
  155. package/src/cli/commands/init.ts +6 -37
  156. package/src/cli/commands/knowledge.ts +1 -16
  157. package/src/cli/commands/report.ts +0 -2
  158. package/src/cli/commands/status.ts +2 -12
  159. package/src/context/index.ts +29 -6
  160. package/src/core/CONTEXT.md +4 -3
  161. package/src/core/__tests__/effective-set.test.ts +80 -0
  162. package/src/core/constraints/capabilities-parser.ts +43 -49
  163. package/src/core/constraints/checker.ts +56 -147
  164. package/src/core/constraints/checkers/index.ts +2 -1
  165. package/src/core/constraints/checkers/types.ts +42 -0
  166. package/src/core/constraints/definitions/guidelines.ts +0 -2
  167. package/src/core/constraints/definitions/prompts.ts +0 -5
  168. package/src/core/constraints/index.ts +2 -17
  169. package/src/core/constraints/usage-report.ts +5 -8
  170. package/src/core/effective-constraints.ts +35 -7
  171. package/src/core/effective-set.ts +56 -0
  172. package/src/core/index.ts +80 -6
  173. package/src/core/project-config-loader.ts +53 -68
  174. package/src/failure/CONTEXT.md +1 -1
  175. package/src/failure/constraint-handler.ts +1 -1
  176. package/src/gates/CONTEXT.md +3 -3
  177. package/src/gates/checker-gate.ts +4 -12
  178. package/src/gates/definitions.ts +27 -50
  179. package/src/gates/effective-gates.ts +14 -21
  180. package/src/gates/index.ts +1 -1
  181. package/src/hooks/bootstrap.ts +0 -3
  182. package/src/index.ts +384 -137
  183. package/src/knowledge/CONTEXT.md +2 -2
  184. package/src/knowledge/__tests__/query.test.ts +64 -0
  185. package/src/knowledge/query.ts +28 -0
  186. package/src/monitoring/CONTEXT.md +7 -13
  187. package/src/monitoring/__tests__/traces.test.ts +0 -10
  188. package/src/monitoring/analyzer-base.ts +0 -22
  189. package/src/monitoring/index.ts +6 -12
  190. package/src/monitoring/trace-analyzer.ts +2 -73
  191. package/src/monitoring/traces.ts +2 -22
  192. package/src/presets/__tests__/standard.test.ts +48 -69
  193. package/src/presets/index.ts +3 -5
  194. package/src/presets/standard.ts +14 -79
  195. package/src/spec/CONTEXT.md +5 -13
  196. package/src/types/constraint.ts +1 -51
  197. package/src/types/index.ts +0 -12
  198. package/src/types/project-config.ts +4 -10
  199. package/src/types/trace.ts +9 -34
  200. package/dist/core/constraints/interceptor.d.ts +0 -38
  201. package/dist/core/constraints/interceptor.d.ts.map +0 -1
  202. package/dist/core/constraints/interceptor.js +0 -166
  203. package/dist/core/constraints/interceptor.js.map +0 -1
  204. package/dist/dashboard/data.d.ts +0 -31
  205. package/dist/dashboard/data.d.ts.map +0 -1
  206. package/dist/dashboard/data.js +0 -81
  207. package/dist/dashboard/data.js.map +0 -1
  208. package/dist/dashboard/index.d.ts +0 -4
  209. package/dist/dashboard/index.d.ts.map +0 -1
  210. package/dist/dashboard/index.js +0 -20
  211. package/dist/dashboard/index.js.map +0 -1
  212. package/dist/dashboard/stats.d.ts +0 -20
  213. package/dist/dashboard/stats.d.ts.map +0 -1
  214. package/dist/dashboard/stats.js +0 -115
  215. package/dist/dashboard/stats.js.map +0 -1
  216. package/dist/dashboard/types.d.ts +0 -110
  217. package/dist/dashboard/types.d.ts.map +0 -1
  218. package/dist/dashboard/types.js +0 -8
  219. package/dist/dashboard/types.js.map +0 -1
  220. package/dist/monitoring/constraint-doctor.d.ts +0 -82
  221. package/dist/monitoring/constraint-doctor.d.ts.map +0 -1
  222. package/dist/monitoring/constraint-doctor.js +0 -191
  223. package/dist/monitoring/constraint-doctor.js.map +0 -1
  224. package/dist/monitoring/diagnosis-rules.d.ts +0 -18
  225. package/dist/monitoring/diagnosis-rules.d.ts.map +0 -1
  226. package/dist/monitoring/diagnosis-rules.js +0 -119
  227. package/dist/monitoring/diagnosis-rules.js.map +0 -1
  228. package/dist/monitoring/knowledge-doctor.d.ts +0 -78
  229. package/dist/monitoring/knowledge-doctor.d.ts.map +0 -1
  230. package/dist/monitoring/knowledge-doctor.js +0 -266
  231. package/dist/monitoring/knowledge-doctor.js.map +0 -1
  232. package/dist/monitoring/knowledge-evolver.d.ts +0 -72
  233. package/dist/monitoring/knowledge-evolver.d.ts.map +0 -1
  234. package/dist/monitoring/knowledge-evolver.js +0 -205
  235. package/dist/monitoring/knowledge-evolver.js.map +0 -1
  236. package/dist/monitoring/performance-analyzer.d.ts +0 -92
  237. package/dist/monitoring/performance-analyzer.d.ts.map +0 -1
  238. package/dist/monitoring/performance-analyzer.js +0 -343
  239. package/dist/monitoring/performance-analyzer.js.map +0 -1
  240. package/dist/monitoring/performance-collector.d.ts +0 -103
  241. package/dist/monitoring/performance-collector.d.ts.map +0 -1
  242. package/dist/monitoring/performance-collector.js +0 -298
  243. package/dist/monitoring/performance-collector.js.map +0 -1
  244. package/dist/safety/index.d.ts +0 -6
  245. package/dist/safety/index.d.ts.map +0 -1
  246. package/dist/safety/index.js +0 -22
  247. package/dist/safety/index.js.map +0 -1
  248. package/dist/safety/input-guardrail.d.ts +0 -36
  249. package/dist/safety/input-guardrail.d.ts.map +0 -1
  250. package/dist/safety/input-guardrail.js +0 -118
  251. package/dist/safety/input-guardrail.js.map +0 -1
  252. package/dist/safety/output-guardrail.d.ts +0 -39
  253. package/dist/safety/output-guardrail.d.ts.map +0 -1
  254. package/dist/safety/output-guardrail.js +0 -147
  255. package/dist/safety/output-guardrail.js.map +0 -1
  256. package/dist/safety/sandbox.d.ts +0 -45
  257. package/dist/safety/sandbox.d.ts.map +0 -1
  258. package/dist/safety/sandbox.js +0 -134
  259. package/dist/safety/sandbox.js.map +0 -1
  260. package/dist/safety/tool-guardrail.d.ts +0 -51
  261. package/dist/safety/tool-guardrail.d.ts.map +0 -1
  262. package/dist/safety/tool-guardrail.js +0 -147
  263. package/dist/safety/tool-guardrail.js.map +0 -1
  264. package/dist/safety/types.d.ts +0 -104
  265. package/dist/safety/types.d.ts.map +0 -1
  266. package/dist/safety/types.js +0 -6
  267. package/dist/safety/types.js.map +0 -1
  268. package/dist/spec/annotation-checker.d.ts +0 -47
  269. package/dist/spec/annotation-checker.d.ts.map +0 -1
  270. package/dist/spec/annotation-checker.js +0 -279
  271. package/dist/spec/annotation-checker.js.map +0 -1
  272. package/dist/types/enforcement.d.ts +0 -42
  273. package/dist/types/enforcement.d.ts.map +0 -1
  274. package/dist/types/enforcement.js +0 -6
  275. package/dist/types/enforcement.js.map +0 -1
  276. package/dist/types/monitoring-types.d.ts +0 -53
  277. package/dist/types/monitoring-types.d.ts.map +0 -1
  278. package/dist/types/monitoring-types.js +0 -10
  279. package/dist/types/monitoring-types.js.map +0 -1
  280. package/dist/types/performance.d.ts +0 -204
  281. package/dist/types/performance.d.ts.map +0 -1
  282. package/dist/types/performance.js +0 -12
  283. package/dist/types/performance.js.map +0 -1
  284. package/dist/verification/index.d.ts +0 -4
  285. package/dist/verification/index.d.ts.map +0 -1
  286. package/dist/verification/index.js +0 -20
  287. package/dist/verification/index.js.map +0 -1
  288. package/dist/verification/loop.d.ts +0 -30
  289. package/dist/verification/loop.d.ts.map +0 -1
  290. package/dist/verification/loop.js +0 -114
  291. package/dist/verification/loop.js.map +0 -1
  292. package/dist/verification/rules-based.d.ts +0 -40
  293. package/dist/verification/rules-based.d.ts.map +0 -1
  294. package/dist/verification/rules-based.js +0 -130
  295. package/dist/verification/rules-based.js.map +0 -1
  296. package/dist/verification/types.d.ts +0 -69
  297. package/dist/verification/types.d.ts.map +0 -1
  298. package/dist/verification/types.js +0 -6
  299. package/dist/verification/types.js.map +0 -1
  300. package/src/__tests__/annotation-checker.test.ts +0 -183
  301. package/src/__tests__/constraint-doctor.test.ts +0 -271
  302. package/src/__tests__/doctor-extra.test.ts +0 -155
  303. package/src/__tests__/extend-exceptions.test.ts +0 -149
  304. package/src/__tests__/interceptor.test.ts +0 -89
  305. package/src/__tests__/performance-analyzer.test.ts +0 -499
  306. package/src/__tests__/performance-collector.test.ts +0 -276
  307. package/src/__tests__/presets.test.ts +0 -65
  308. package/src/core/constraints/__tests__/interceptor.test.ts +0 -253
  309. package/src/core/constraints/interceptor.ts +0 -214
  310. package/src/dashboard/CONTEXT.md +0 -21
  311. package/src/dashboard/__tests__/data.test.ts +0 -111
  312. package/src/dashboard/__tests__/stats.test.ts +0 -159
  313. package/src/dashboard/data.ts +0 -103
  314. package/src/dashboard/index.ts +0 -3
  315. package/src/dashboard/stats.ts +0 -127
  316. package/src/dashboard/types.ts +0 -130
  317. package/src/monitoring/__tests__/knowledge-doctor.test.ts +0 -278
  318. package/src/monitoring/__tests__/knowledge-evolver.test.ts +0 -368
  319. package/src/monitoring/__tests__/performance-analyzer.test.ts +0 -137
  320. package/src/monitoring/__tests__/performance-collector.test.ts +0 -331
  321. package/src/monitoring/constraint-doctor.ts +0 -239
  322. package/src/monitoring/diagnosis-rules.ts +0 -132
  323. package/src/monitoring/knowledge-doctor.ts +0 -322
  324. package/src/monitoring/knowledge-evolver.ts +0 -289
  325. package/src/monitoring/performance-analyzer.ts +0 -400
  326. package/src/monitoring/performance-collector.ts +0 -326
  327. package/src/safety/CONTEXT.md +0 -23
  328. package/src/safety/__tests__/input-guardrail.test.ts +0 -105
  329. package/src/safety/__tests__/output-guardrail.test.ts +0 -108
  330. package/src/safety/__tests__/sandbox.test.ts +0 -158
  331. package/src/safety/__tests__/tool-guardrail.test.ts +0 -127
  332. package/src/safety/index.ts +0 -5
  333. package/src/safety/input-guardrail.ts +0 -133
  334. package/src/safety/output-guardrail.ts +0 -170
  335. package/src/safety/sandbox.ts +0 -148
  336. package/src/safety/tool-guardrail.ts +0 -176
  337. package/src/safety/types.ts +0 -124
  338. package/src/spec/__tests__/annotation-checker.test.ts +0 -294
  339. package/src/spec/annotation-checker.ts +0 -320
  340. package/src/types/enforcement.ts +0 -48
  341. package/src/types/monitoring-types.ts +0 -68
  342. package/src/types/performance.ts +0 -295
  343. package/src/verification/CONTEXT.md +0 -23
  344. package/src/verification/__tests__/loop.test.ts +0 -303
  345. package/src/verification/__tests__/rules-based.test.ts +0 -240
  346. package/src/verification/index.ts +0 -3
  347. package/src/verification/loop.ts +0 -137
  348. package/src/verification/rules-based.ts +0 -152
  349. 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
- }