@rigour-labs/core 6.7.10 → 6.8.1-rc.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 (346) hide show
  1. package/dist/brief/briefing.d.ts +59 -0
  2. package/dist/brief/briefing.js +126 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +2 -0
  5. package/dist/inference/cloud-provider.js +12 -2
  6. package/dist/review/backtest-init.d.ts +8 -5
  7. package/dist/review/backtest-init.js +27 -9
  8. package/dist/review/backtest-last.js +3 -1
  9. package/dist/review/reviewer/adapters.d.ts +4 -0
  10. package/dist/review/reviewer/adapters.js +23 -0
  11. package/dist/review/reviewer/inputs.d.ts +4 -1
  12. package/dist/review/reviewer/inputs.js +36 -2
  13. package/dist/review/reviewer/record.d.ts +5 -0
  14. package/dist/review/reviewer/record.js +3 -3
  15. package/dist/review/reviewer/verdict.d.ts +14 -0
  16. package/dist/review/reviewer/verdict.js +46 -6
  17. package/dist/review/reviewer.d.ts +2 -0
  18. package/dist/review/reviewer.js +24 -5
  19. package/dist/review-learning/repo-rules.d.ts +14 -2
  20. package/dist/review-learning/repo-rules.js +59 -9
  21. package/dist/task/thread.d.ts +47 -0
  22. package/dist/task/thread.js +234 -0
  23. package/dist/templates/universal-config.js +4 -0
  24. package/dist/types/index.d.ts +21 -0
  25. package/dist/types/index.js +7 -0
  26. package/package.json +11 -8
  27. package/dist/context/automatic-index-cache.test.d.ts +0 -1
  28. package/dist/context/automatic-index-cache.test.js +0 -30
  29. package/dist/context/automatic-index.test.d.ts +0 -1
  30. package/dist/context/automatic-index.test.js +0 -45
  31. package/dist/context/cache-engine.test.d.ts +0 -1
  32. package/dist/context/cache-engine.test.js +0 -99
  33. package/dist/context/dependency-graph.test.d.ts +0 -1
  34. package/dist/context/dependency-graph.test.js +0 -13
  35. package/dist/context/index-status.test.d.ts +0 -1
  36. package/dist/context/index-status.test.js +0 -26
  37. package/dist/context.test.d.ts +0 -1
  38. package/dist/context.test.js +0 -228
  39. package/dist/deep/agent-review.test.d.ts +0 -1
  40. package/dist/deep/agent-review.test.js +0 -53
  41. package/dist/deep/code-context.test.d.ts +0 -1
  42. package/dist/deep/code-context.test.js +0 -48
  43. package/dist/deep/code-pass.test.d.ts +0 -1
  44. package/dist/deep/code-pass.test.js +0 -112
  45. package/dist/deep/code-review-prompt.test.d.ts +0 -1
  46. package/dist/deep/code-review-prompt.test.js +0 -20
  47. package/dist/deep/code-verifier.test.d.ts +0 -1
  48. package/dist/deep/code-verifier.test.js +0 -54
  49. package/dist/deep/diff-tests/calls.test.d.ts +0 -1
  50. package/dist/deep/diff-tests/calls.test.js +0 -33
  51. package/dist/deep/diff-tests/run.test.d.ts +0 -1
  52. package/dist/deep/diff-tests/run.test.js +0 -58
  53. package/dist/deep/fact-extractor.test.d.ts +0 -1
  54. package/dist/deep/fact-extractor.test.js +0 -581
  55. package/dist/deep/parse-findings.test.d.ts +0 -1
  56. package/dist/deep/parse-findings.test.js +0 -25
  57. package/dist/deep/pr-review.test.d.ts +0 -1
  58. package/dist/deep/pr-review.test.js +0 -80
  59. package/dist/deep/prompts.test.d.ts +0 -1
  60. package/dist/deep/prompts.test.js +0 -235
  61. package/dist/deep/reference-pack.test.d.ts +0 -1
  62. package/dist/deep/reference-pack.test.js +0 -46
  63. package/dist/deep/related-changes.test.d.ts +0 -1
  64. package/dist/deep/related-changes.test.js +0 -33
  65. package/dist/deep/review-context-export.test.d.ts +0 -1
  66. package/dist/deep/review-context-export.test.js +0 -32
  67. package/dist/deep/review-tools.test.d.ts +0 -1
  68. package/dist/deep/review-tools.test.js +0 -39
  69. package/dist/deep/risk.test.d.ts +0 -1
  70. package/dist/deep/risk.test.js +0 -101
  71. package/dist/deep/verifier.test.d.ts +0 -1
  72. package/dist/deep/verifier.test.js +0 -635
  73. package/dist/discovery.test.d.ts +0 -1
  74. package/dist/discovery.test.js +0 -93
  75. package/dist/environment.test.d.ts +0 -1
  76. package/dist/environment.test.js +0 -94
  77. package/dist/firewall/firewall.test.d.ts +0 -1
  78. package/dist/firewall/firewall.test.js +0 -117
  79. package/dist/firewall/trust-boundaries.test.d.ts +0 -1
  80. package/dist/firewall/trust-boundaries.test.js +0 -64
  81. package/dist/firewall/trusted-control.test.d.ts +0 -1
  82. package/dist/firewall/trusted-control.test.js +0 -188
  83. package/dist/gates/agent-team.test.d.ts +0 -1
  84. package/dist/gates/agent-team.test.js +0 -113
  85. package/dist/gates/ast.test.d.ts +0 -1
  86. package/dist/gates/ast.test.js +0 -112
  87. package/dist/gates/checkpoint.test.d.ts +0 -1
  88. package/dist/gates/checkpoint.test.js +0 -105
  89. package/dist/gates/content.test.d.ts +0 -1
  90. package/dist/gates/content.test.js +0 -73
  91. package/dist/gates/coverage.test.d.ts +0 -1
  92. package/dist/gates/coverage.test.js +0 -53
  93. package/dist/gates/dedupe-failures.test.d.ts +0 -1
  94. package/dist/gates/dedupe-failures.test.js +0 -12
  95. package/dist/gates/deep-analysis.test.d.ts +0 -1
  96. package/dist/gates/deep-analysis.test.js +0 -86
  97. package/dist/gates/deep-intent.test.d.ts +0 -1
  98. package/dist/gates/deep-intent.test.js +0 -51
  99. package/dist/gates/deep-timeout.test.d.ts +0 -1
  100. package/dist/gates/deep-timeout.test.js +0 -10
  101. package/dist/gates/deprecated-apis.test.d.ts +0 -1
  102. package/dist/gates/deprecated-apis.test.js +0 -318
  103. package/dist/gates/deprecated-dependencies.test.d.ts +0 -1
  104. package/dist/gates/deprecated-dependencies.test.js +0 -55
  105. package/dist/gates/frontend-secret-exposure.test.d.ts +0 -1
  106. package/dist/gates/frontend-secret-exposure.test.js +0 -148
  107. package/dist/gates/hallucinated-imports/framework-modules-nuxt.test.d.ts +0 -1
  108. package/dist/gates/hallucinated-imports/framework-modules-nuxt.test.js +0 -27
  109. package/dist/gates/hallucinated-imports/js-resolver-types.test.d.ts +0 -1
  110. package/dist/gates/hallucinated-imports/js-resolver-types.test.js +0 -14
  111. package/dist/gates/hallucinated-imports-sveltekit.test.d.ts +0 -1
  112. package/dist/gates/hallucinated-imports-sveltekit.test.js +0 -132
  113. package/dist/gates/hallucinated-imports.test.d.ts +0 -1
  114. package/dist/gates/hallucinated-imports.test.js +0 -1206
  115. package/dist/gates/js-style-context.test.d.ts +0 -1
  116. package/dist/gates/js-style-context.test.js +0 -35
  117. package/dist/gates/logic-drift.test.d.ts +0 -1
  118. package/dist/gates/logic-drift.test.js +0 -52
  119. package/dist/gates/phantom-apis.test.d.ts +0 -1
  120. package/dist/gates/phantom-apis.test.js +0 -396
  121. package/dist/gates/promise-safety.test.d.ts +0 -1
  122. package/dist/gates/promise-safety.test.js +0 -34
  123. package/dist/gates/runner.test.d.ts +0 -1
  124. package/dist/gates/runner.test.js +0 -77
  125. package/dist/gates/scoped-gates.test.d.ts +0 -1
  126. package/dist/gates/scoped-gates.test.js +0 -52
  127. package/dist/gates/security-patterns-owasp.test.d.ts +0 -1
  128. package/dist/gates/security-patterns-owasp.test.js +0 -186
  129. package/dist/gates/security-patterns.test.d.ts +0 -1
  130. package/dist/gates/security-patterns.test.js +0 -194
  131. package/dist/gates/semantic-bugs.test.d.ts +0 -1
  132. package/dist/gates/semantic-bugs.test.js +0 -76
  133. package/dist/gates/side-effect-analysis.test.d.ts +0 -1
  134. package/dist/gates/side-effect-analysis.test.js +0 -162
  135. package/dist/gates/style-drift.test.d.ts +0 -1
  136. package/dist/gates/style-drift.test.js +0 -26
  137. package/dist/gates/test-quality.test.d.ts +0 -1
  138. package/dist/gates/test-quality.test.js +0 -325
  139. package/dist/gates/trusted-reviews.test.d.ts +0 -1
  140. package/dist/gates/trusted-reviews.test.js +0 -16
  141. package/dist/gates/unindexed-reads/queries.test.d.ts +0 -1
  142. package/dist/gates/unindexed-reads/queries.test.js +0 -54
  143. package/dist/gates/unindexed-reads/schema.test.d.ts +0 -1
  144. package/dist/gates/unindexed-reads/schema.test.js +0 -81
  145. package/dist/gates/unindexed-reads/unindexed-reads.test.d.ts +0 -1
  146. package/dist/gates/unindexed-reads/unindexed-reads.test.js +0 -90
  147. package/dist/hooks/checker.test.d.ts +0 -1
  148. package/dist/hooks/checker.test.js +0 -159
  149. package/dist/hooks/dlp-confidence.test.d.ts +0 -1
  150. package/dist/hooks/dlp-confidence.test.js +0 -51
  151. package/dist/hooks/dlp-feedback.test.d.ts +0 -1
  152. package/dist/hooks/dlp-feedback.test.js +0 -131
  153. package/dist/hooks/input-validator.test.d.ts +0 -1
  154. package/dist/hooks/input-validator.test.js +0 -329
  155. package/dist/hooks/templates.test.d.ts +0 -1
  156. package/dist/hooks/templates.test.js +0 -27
  157. package/dist/inference/brain-placeholder.test.d.ts +0 -1
  158. package/dist/inference/brain-placeholder.test.js +0 -28
  159. package/dist/inference/cloud-provider.test.d.ts +0 -1
  160. package/dist/inference/cloud-provider.test.js +0 -139
  161. package/dist/inference/executable.test.d.ts +0 -1
  162. package/dist/inference/executable.test.js +0 -41
  163. package/dist/inference/http-download.test.d.ts +0 -1
  164. package/dist/inference/http-download.test.js +0 -109
  165. package/dist/inference/llama-engine-checksum.test.d.ts +0 -1
  166. package/dist/inference/llama-engine-checksum.test.js +0 -27
  167. package/dist/inference/llama-engine.test.d.ts +0 -1
  168. package/dist/inference/llama-engine.test.js +0 -51
  169. package/dist/inference/llama-process.test.d.ts +0 -1
  170. package/dist/inference/llama-process.test.js +0 -61
  171. package/dist/inference/local-model.test.d.ts +0 -1
  172. package/dist/inference/local-model.test.js +0 -23
  173. package/dist/inference/model-download.test.d.ts +0 -1
  174. package/dist/inference/model-download.test.js +0 -125
  175. package/dist/inference/model-manager.test.d.ts +0 -1
  176. package/dist/inference/model-manager.test.js +0 -24
  177. package/dist/inference/types.test.d.ts +0 -1
  178. package/dist/inference/types.test.js +0 -19
  179. package/dist/memory/recall.test.d.ts +0 -1
  180. package/dist/memory/recall.test.js +0 -36
  181. package/dist/pattern-index/indexer.test.d.ts +0 -6
  182. package/dist/pattern-index/indexer.test.js +0 -197
  183. package/dist/pattern-index/matcher.test.d.ts +0 -6
  184. package/dist/pattern-index/matcher.test.js +0 -238
  185. package/dist/pattern-index/pattern-reuse.test.d.ts +0 -1
  186. package/dist/pattern-index/pattern-reuse.test.js +0 -76
  187. package/dist/pattern-index/semantic-runtime.test.d.ts +0 -1
  188. package/dist/pattern-index/semantic-runtime.test.js +0 -31
  189. package/dist/pattern-index/staleness.test.d.ts +0 -6
  190. package/dist/pattern-index/staleness.test.js +0 -211
  191. package/dist/review/agent-fixes.test.d.ts +0 -1
  192. package/dist/review/agent-fixes.test.js +0 -32
  193. package/dist/review/backtest-init.test.d.ts +0 -1
  194. package/dist/review/backtest-init.test.js +0 -98
  195. package/dist/review/backtest-judges.test.d.ts +0 -1
  196. package/dist/review/backtest-judges.test.js +0 -32
  197. package/dist/review/backtest-last.test.d.ts +0 -1
  198. package/dist/review/backtest-last.test.js +0 -109
  199. package/dist/review/backtest.test.d.ts +0 -1
  200. package/dist/review/backtest.test.js +0 -183
  201. package/dist/review/baseline.test.d.ts +0 -1
  202. package/dist/review/baseline.test.js +0 -22
  203. package/dist/review/branch-checks.test.d.ts +0 -1
  204. package/dist/review/branch-checks.test.js +0 -48
  205. package/dist/review/check-outcomes.test.d.ts +0 -1
  206. package/dist/review/check-outcomes.test.js +0 -56
  207. package/dist/review/code-patterns.test.d.ts +0 -1
  208. package/dist/review/code-patterns.test.js +0 -142
  209. package/dist/review/dead-code.test.d.ts +0 -1
  210. package/dist/review/dead-code.test.js +0 -154
  211. package/dist/review/deep-runs.test.d.ts +0 -1
  212. package/dist/review/deep-runs.test.js +0 -23
  213. package/dist/review/effectiveness.test.d.ts +0 -1
  214. package/dist/review/effectiveness.test.js +0 -42
  215. package/dist/review/fix-scope.test.d.ts +0 -1
  216. package/dist/review/fix-scope.test.js +0 -104
  217. package/dist/review/generated-files.test.d.ts +0 -1
  218. package/dist/review/generated-files.test.js +0 -25
  219. package/dist/review/migration-order.test.d.ts +0 -1
  220. package/dist/review/migration-order.test.js +0 -62
  221. package/dist/review/quiet.test.d.ts +0 -1
  222. package/dist/review/quiet.test.js +0 -38
  223. package/dist/review/receipt.test.d.ts +0 -1
  224. package/dist/review/receipt.test.js +0 -60
  225. package/dist/review/review-task.test.d.ts +0 -1
  226. package/dist/review/review-task.test.js +0 -89
  227. package/dist/review/review.test.d.ts +0 -1
  228. package/dist/review/review.test.js +0 -203
  229. package/dist/review/reviewer/adapters.test.d.ts +0 -1
  230. package/dist/review/reviewer/adapters.test.js +0 -60
  231. package/dist/review/reviewer/api-judge.test.d.ts +0 -1
  232. package/dist/review/reviewer/api-judge.test.js +0 -108
  233. package/dist/review/reviewer/background.test.d.ts +0 -1
  234. package/dist/review/reviewer/background.test.js +0 -118
  235. package/dist/review/reviewer/context.test.d.ts +0 -1
  236. package/dist/review/reviewer/context.test.js +0 -45
  237. package/dist/review/reviewer/exec.test.d.ts +0 -1
  238. package/dist/review/reviewer/exec.test.js +0 -59
  239. package/dist/review/reviewer/inputs.test.d.ts +0 -1
  240. package/dist/review/reviewer/inputs.test.js +0 -26
  241. package/dist/review/reviewer/panel.test.d.ts +0 -1
  242. package/dist/review/reviewer/panel.test.js +0 -110
  243. package/dist/review/reviewer/record.test.d.ts +0 -1
  244. package/dist/review/reviewer/record.test.js +0 -32
  245. package/dist/review/reviewer/rule-writer.test.d.ts +0 -1
  246. package/dist/review/reviewer/rule-writer.test.js +0 -52
  247. package/dist/review/reviewer/settings.test.d.ts +0 -1
  248. package/dist/review/reviewer/settings.test.js +0 -57
  249. package/dist/review/reviewer/usage.test.d.ts +0 -1
  250. package/dist/review/reviewer/usage.test.js +0 -14
  251. package/dist/review/reviewer.test.d.ts +0 -1
  252. package/dist/review/reviewer.test.js +0 -705
  253. package/dist/review/stories.test.d.ts +0 -1
  254. package/dist/review/stories.test.js +0 -58
  255. package/dist/review/toolchain.test.d.ts +0 -1
  256. package/dist/review/toolchain.test.js +0 -108
  257. package/dist/review/typed/redundancy.test.d.ts +0 -1
  258. package/dist/review/typed/redundancy.test.js +0 -315
  259. package/dist/review/typed/schema-nullability.test.d.ts +0 -1
  260. package/dist/review/typed/schema-nullability.test.js +0 -63
  261. package/dist/review-learning/human-edits.test.d.ts +0 -1
  262. package/dist/review-learning/human-edits.test.js +0 -47
  263. package/dist/review-learning/repo-rules.test.d.ts +0 -1
  264. package/dist/review-learning/repo-rules.test.js +0 -55
  265. package/dist/review-learning/review-learning.test.d.ts +0 -1
  266. package/dist/review-learning/review-learning.test.js +0 -249
  267. package/dist/safety.test.d.ts +0 -1
  268. package/dist/safety.test.js +0 -42
  269. package/dist/semantic/benchmark.test.d.ts +0 -1
  270. package/dist/semantic/benchmark.test.js +0 -22
  271. package/dist/semantic/intent/intent.test.d.ts +0 -1
  272. package/dist/semantic/intent/intent.test.js +0 -46
  273. package/dist/semantic/learn/learn.test.d.ts +0 -1
  274. package/dist/semantic/learn/learn.test.js +0 -67
  275. package/dist/semantic/origins.test.d.ts +0 -1
  276. package/dist/semantic/origins.test.js +0 -77
  277. package/dist/semantic/project-facts.test.d.ts +0 -1
  278. package/dist/semantic/project-facts.test.js +0 -45
  279. package/dist/semantic/sites/call-sites.test.d.ts +0 -1
  280. package/dist/semantic/sites/call-sites.test.js +0 -46
  281. package/dist/services/adaptive-thresholds.test.d.ts +0 -1
  282. package/dist/services/adaptive-thresholds.test.js +0 -53
  283. package/dist/services/agent-history.test.d.ts +0 -1
  284. package/dist/services/agent-history.test.js +0 -69
  285. package/dist/services/context-scope-summary.test.d.ts +0 -1
  286. package/dist/services/context-scope-summary.test.js +0 -17
  287. package/dist/services/context-telemetry-service.test.d.ts +0 -1
  288. package/dist/services/context-telemetry-service.test.js +0 -182
  289. package/dist/services/cursor-usage-sync.test.d.ts +0 -1
  290. package/dist/services/cursor-usage-sync.test.js +0 -173
  291. package/dist/services/engineering-knowledge-graph.test.d.ts +0 -1
  292. package/dist/services/engineering-knowledge-graph.test.js +0 -76
  293. package/dist/services/model-pricing.test.d.ts +0 -1
  294. package/dist/services/model-pricing.test.js +0 -44
  295. package/dist/services/observed-savings.test.d.ts +0 -1
  296. package/dist/services/observed-savings.test.js +0 -37
  297. package/dist/services/score-history.test.d.ts +0 -1
  298. package/dist/services/score-history.test.js +0 -61
  299. package/dist/smoke.test.d.ts +0 -1
  300. package/dist/smoke.test.js +0 -17
  301. package/dist/storage/cache-cleanup.test.d.ts +0 -1
  302. package/dist/storage/cache-cleanup.test.js +0 -54
  303. package/dist/storage/context-telemetry.test.d.ts +0 -1
  304. package/dist/storage/context-telemetry.test.js +0 -80
  305. package/dist/storage/db.test.d.ts +0 -1
  306. package/dist/storage/db.test.js +0 -46
  307. package/dist/storage/fix-lessons.test.d.ts +0 -1
  308. package/dist/storage/fix-lessons.test.js +0 -61
  309. package/dist/storage/lessons.test.d.ts +0 -1
  310. package/dist/storage/lessons.test.js +0 -81
  311. package/dist/storage/local-encryption.test.d.ts +0 -1
  312. package/dist/storage/local-encryption.test.js +0 -34
  313. package/dist/storage/local-memory.test.d.ts +0 -1
  314. package/dist/storage/local-memory.test.js +0 -55
  315. package/dist/storage/share-memory.test.d.ts +0 -1
  316. package/dist/storage/share-memory.test.js +0 -34
  317. package/dist/storage/team-diagnostics.test.d.ts +0 -1
  318. package/dist/storage/team-diagnostics.test.js +0 -51
  319. package/dist/storage/team-scope.test.d.ts +0 -1
  320. package/dist/storage/team-scope.test.js +0 -22
  321. package/dist/storage/team-store.test.d.ts +0 -1
  322. package/dist/storage/team-store.test.js +0 -11
  323. package/dist/storage/team-sync-scope.test.d.ts +0 -1
  324. package/dist/storage/team-sync-scope.test.js +0 -100
  325. package/dist/storage/team-vector-store.test.d.ts +0 -1
  326. package/dist/storage/team-vector-store.test.js +0 -56
  327. package/dist/storage/telemetry-scope.test.d.ts +0 -1
  328. package/dist/storage/telemetry-scope.test.js +0 -38
  329. package/dist/telemetry/telemetry.test.d.ts +0 -1
  330. package/dist/telemetry/telemetry.test.js +0 -64
  331. package/dist/types/index.test.d.ts +0 -1
  332. package/dist/types/index.test.js +0 -33
  333. package/dist/utils/command-line.test.d.ts +0 -1
  334. package/dist/utils/command-line.test.js +0 -8
  335. package/dist/utils/diff-removed.test.d.ts +0 -1
  336. package/dist/utils/diff-removed.test.js +0 -29
  337. package/dist/utils/diff.test.d.ts +0 -1
  338. package/dist/utils/diff.test.js +0 -38
  339. package/dist/utils/glob-paths.test.d.ts +0 -1
  340. package/dist/utils/glob-paths.test.js +0 -40
  341. package/dist/utils/profile.test.d.ts +0 -1
  342. package/dist/utils/profile.test.js +0 -68
  343. package/dist/utils/scanner.test.d.ts +0 -1
  344. package/dist/utils/scanner.test.js +0 -48
  345. package/dist/utils/scope.test.d.ts +0 -1
  346. package/dist/utils/scope.test.js +0 -38
@@ -1,48 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { buildCodeContext } from './code-context.js';
3
- function fn(name, lineStart, lineEnd) {
4
- return {
5
- name, lineStart, lineEnd, lineCount: lineEnd - lineStart + 1, paramCount: 0, params: [],
6
- maxNesting: 1, hasReturn: true, isAsync: false, isExported: true,
7
- };
8
- }
9
- function facts(path, functions) {
10
- return {
11
- path, language: 'typescript', lineCount: 0, classes: [], functions, imports: [], exports: [],
12
- errorHandling: [], testAssertions: 0, hasTests: false,
13
- };
14
- }
15
- const source = (n) => Array.from({ length: n }, (_, i) => `const line${i + 1} = ${i + 1};`).join('\n');
16
- describe('buildCodeContext', () => {
17
- it('sends a small file whole, with line numbers', () => {
18
- const ctx = buildCodeContext(facts('src/a.ts', []), 'const a = 1;\nexport { a };', { maxChars: 10_000 });
19
- expect(ctx.text).toBe('FILE: src/a.ts (typescript, 2 lines)\n1| const a = 1;\n2| export { a };');
20
- expect(ctx.ranges).toEqual([[1, 2]]);
21
- expect(ctx.source).toContain('export { a }');
22
- });
23
- it('cuts a large file into function segments and names what it omitted', () => {
24
- const content = source(300);
25
- const ctx = buildCodeContext(facts('src/big.ts', [fn('first', 1, 100), fn('second', 101, 200), fn('third', 201, 300)]), content, { maxChars: 4_000 });
26
- expect(ctx.ranges[0]).toEqual([1, 100]);
27
- expect(ctx.text).toMatch(/omitted for size: .*function second \(lines 101-200\)/);
28
- expect(ctx.text).toContain('function third (lines 201-300)');
29
- expect(ctx.source).not.toContain('line150 ');
30
- });
31
- it('puts the segment around changed lines first', () => {
32
- const content = source(300);
33
- const ctx = buildCodeContext(facts('src/big.ts', [fn('first', 1, 100), fn('second', 101, 200), fn('third', 201, 300)]), content, {
34
- maxChars: 4_000, focusLines: [250],
35
- });
36
- expect(ctx.ranges[0]).toEqual([201, 300]);
37
- expect(ctx.text).toContain('function first (lines 1-100)');
38
- });
39
- it('truncates a single oversized function explicitly instead of dropping it', () => {
40
- const content = source(2_000);
41
- const ctx = buildCodeContext(facts('src/huge.ts', [fn('huge', 1, 2_000)]), content, { maxChars: 2_000 });
42
- expect(ctx.ranges).toHaveLength(1);
43
- expect(ctx.ranges[0][0]).toBe(1);
44
- expect(ctx.ranges[0][1]).toBeLessThan(2_000);
45
- expect(ctx.text).toMatch(/… \[\d+ lines omitted\]$/);
46
- expect(ctx.text.length).toBeLessThanOrEqual(2_000);
47
- });
48
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,112 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import { afterEach, describe, expect, it } from 'vitest';
5
- import { runCodePass } from './code-pass.js';
6
- import { parseVerdicts } from './self-check.js';
7
- let dir;
8
- afterEach(() => { if (dir)
9
- fs.rmSync(dir, { recursive: true, force: true }); dir = undefined; });
10
- const SOURCE = 'export function total(items: number[]) {\n let sum = 0;\n for (let i = 0; i <= items.length; i++) sum += items[i];\n return sum;\n}\n';
11
- const facts = { path: 'total.ts', language: 'typescript', classes: [], functions: [] };
12
- function finding(line, category, description) {
13
- return { category, severity: 'high', file: 'total.ts', line, description, suggestion: 's', confidence: 0.9 };
14
- }
15
- const isCheck = (prompt) => /^You reported \d+ defect/.test(prompt);
16
- /** Review passes answer from `reviews` in turn; the self-check withdraws findings whose line is in `withdraw`. */
17
- function fakeProvider(reviews, withdraw) {
18
- const prompts = [];
19
- const provider = {
20
- name: 'fake', isAvailable: async () => true, setup: async () => { }, dispose: () => { },
21
- analyze: async (prompt) => {
22
- prompts.push(prompt);
23
- if (isCheck(prompt)) {
24
- const listed = [...prompt.matchAll(/^(\d+)\. total\.ts:(\d+):/gm)];
25
- return JSON.stringify({ verdicts: listed.map(m => ({ n: Number(m[1]), real: !withdraw.includes(Number(m[2])) })) });
26
- }
27
- return JSON.stringify({ findings: reviews.shift() ?? [] });
28
- },
29
- };
30
- return { provider, prompts };
31
- }
32
- function run(provider, reference) {
33
- dir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-pass-'));
34
- fs.writeFileSync(path.join(dir, 'total.ts'), SOURCE);
35
- return runCodePass(provider, [facts], { cwd: dir, inference: {}, maxSourceChars: 10_000, focusLines: { 'total.ts': [3] }, reference });
36
- }
37
- describe('runCodePass', () => {
38
- it('reviews once without reference material (the small tiers)', async () => {
39
- const { provider, prompts } = fakeProvider([[finding(3, 'correctness', 'off by one on `items`')]], []);
40
- const result = await run(provider);
41
- expect(prompts).toHaveLength(1);
42
- expect(result.findings.map(f => f.line)).toEqual([3]);
43
- expect([result.proposed, result.withdrawn]).toEqual([1, 0]);
44
- });
45
- it('does not repeat an identical pass when there is only one reference section', async () => {
46
- const { provider, prompts } = fakeProvider([[]], []);
47
- await run(provider, { maxChars: 4000, prBody: 'Sum the basket.' });
48
- expect(prompts).toHaveLength(1);
49
- });
50
- it('with reference material, reviews twice in opposite orders, merges, and keeps what one self-check call confirms', async () => {
51
- const { provider, prompts } = fakeProvider([
52
- [finding(3, 'correctness', 'reads past the end of `items`')],
53
- [finding(3, 'correctness', 'same bug seen again'), finding(2, 'consistency', 'style-ish claim about `sum`')],
54
- ], [2]);
55
- const result = await run(provider, {
56
- maxChars: 4000, prBody: 'Sum the basket.',
57
- removed: { 'total.ts': [{ line: 3, text: [' for (let i = 0; i < items.length; i++) sum += items[i];'] }] },
58
- });
59
- const reviews = prompts.filter(p => !isCheck(p));
60
- expect(reviews).toHaveLength(2);
61
- expect(reviews[0].indexOf('PR DESCRIPTION')).toBeLessThan(reviews[0].indexOf('REMOVED by this change'));
62
- expect(reviews[1].indexOf('REMOVED by this change')).toBeLessThan(reviews[1].indexOf('PR DESCRIPTION'));
63
- expect(prompts.filter(isCheck)).toHaveLength(1);
64
- expect(result.findings.map(f => [f.line, f.category])).toEqual([[3, 'correctness']]);
65
- expect([result.proposed, result.withdrawn]).toEqual([2, 1]); // two distinct findings, one withdrawn
66
- });
67
- it('reads only well-formed verdicts from a self-check reply', () => {
68
- expect([...parseVerdicts('Sure! {"verdicts": [{"n": 1, "real": false}, {"n": 2, "real": true}, {"n": "3", "real": false}]}')])
69
- .toEqual([[1, false], [2, true]]);
70
- expect(parseVerdicts('I am not sure').size).toBe(0);
71
- });
72
- it('keeps every finding when the self-check call fails', async () => {
73
- const { provider } = fakeProvider([[finding(3, 'correctness', 'reads past the end of `items`')], []], []);
74
- const analyze = provider.analyze;
75
- provider.analyze = async (prompt, options) => isCheck(prompt) ? Promise.reject(new Error('timeout')) : analyze(prompt, options);
76
- const result = await run(provider, { maxChars: 4000, prBody: 'Sum the basket.', removed: { 'total.ts': [{ line: 3, text: ['x'] }] } });
77
- expect(result.findings.map(f => f.line)).toEqual([3]);
78
- expect(result.withdrawn).toBe(0);
79
- });
80
- it('starts no file after the deadline, and counts what it skipped', async () => {
81
- const { provider, prompts } = fakeProvider([[]], []);
82
- dir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-pass-'));
83
- fs.writeFileSync(path.join(dir, 'total.ts'), SOURCE);
84
- const result = await runCodePass(provider, [facts, facts], { cwd: dir, inference: {}, maxSourceChars: 10_000, deadline: Date.now() - 1 });
85
- expect(prompts).toHaveLength(0);
86
- expect(result.skipped).toBe(2);
87
- });
88
- it('reviews files concurrently but reports them in file order', async () => {
89
- dir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-pass-'));
90
- const names = ['a.ts', 'b.ts', 'c.ts'];
91
- for (const name of names)
92
- fs.writeFileSync(path.join(dir, name), SOURCE);
93
- let inFlight = 0;
94
- let peak = 0;
95
- const provider = {
96
- name: 'fake', isAvailable: async () => true, setup: async () => { }, dispose: () => { },
97
- analyze: async (prompt) => {
98
- inFlight++;
99
- peak = Math.max(peak, inFlight);
100
- const file = names.find(n => prompt.includes(n));
101
- await new Promise(resolve => setTimeout(resolve, file === 'a.ts' ? 30 : 5));
102
- inFlight--;
103
- return JSON.stringify({ findings: [{ ...finding(3, 'correctness', 'off by one'), file }] });
104
- },
105
- };
106
- const many = names.map(name => ({ ...facts, path: name }));
107
- const result = await runCodePass(provider, many, { cwd: dir, inference: {}, maxSourceChars: 10_000, concurrency: 2 });
108
- expect(peak).toBe(2);
109
- expect(result.findings.map(f => f.file)).toEqual(names);
110
- expect(result.contexts.map(c => c.file)).toEqual(names);
111
- });
112
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,20 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { buildCodeReviewPrompt, REVIEW_CATEGORIES } from './code-review-prompt.js';
3
- const context = { file: 'src/a.ts', language: 'typescript', text: 'FILE: src/a.ts\n1| export const a = 1;', ranges: [[1, 1]], source: '' };
4
- describe('buildCodeReviewPrompt', () => {
5
- it('includes every category, the rules and the numbered source', () => {
6
- const prompt = buildCodeReviewPrompt(context);
7
- for (const c of REVIEW_CATEGORIES)
8
- expect(prompt).toContain(`- ${c.key}: ${c.focus}`);
9
- expect(prompt).toContain('Report only defects you can point to');
10
- expect(prompt).toContain('1| export const a = 1;');
11
- expect(prompt).toContain('Review src/a.ts');
12
- });
13
- it('allows an empty answer so the model is not pushed to invent findings', () => {
14
- expect(buildCodeReviewPrompt(context)).toContain('{"findings": []}');
15
- });
16
- it('uses unique category keys', () => {
17
- const keys = REVIEW_CATEGORIES.map(c => c.key);
18
- expect(new Set(keys).size).toBe(keys.length);
19
- });
20
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,54 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { quotedIdentifiers, verifyCodeFindings } from './code-verifier.js';
3
- const context = {
4
- file: 'src/api/report.ts',
5
- language: 'typescript',
6
- text: '',
7
- ranges: [[10, 40]],
8
- source: 'export async function loadReport(days) {\n const rows = await fetchAll(days);\n}',
9
- };
10
- function finding(overrides) {
11
- return {
12
- category: 'scalability', severity: 'high', file: 'src/api/report.ts', line: 12,
13
- description: '`fetchAll` loads every row for the window into memory.', suggestion: 'Aggregate in the database.',
14
- confidence: 0.8, ...overrides,
15
- };
16
- }
17
- describe('verifyCodeFindings', () => {
18
- it('counts every dropped finding by reason, so a drop is never silent', () => {
19
- const rejected = {};
20
- verifyCodeFindings([
21
- finding({}), finding({ file: 'src/other.ts' }), finding({ line: 80 }), finding({ line: undefined }),
22
- finding({ confidence: 0.1 }), finding({ description: '`fetchEverything` has no limit.' }),
23
- ], [context], rejected);
24
- expect(rejected).toEqual({ no_context: 1, out_of_range: 1, no_line: 1, low_confidence: 1, ungrounded_identifier: 1 });
25
- });
26
- it('keeps a finding grounded in the sent source', () => {
27
- const [kept] = verifyCodeFindings([finding({})], [context]);
28
- expect(kept).toMatchObject({ file: 'src/api/report.ts', verified: true });
29
- });
30
- it('resolves a basename-only file for a single-file review', () => {
31
- expect(verifyCodeFindings([finding({ file: 'report.ts' })], [context])).toHaveLength(1);
32
- });
33
- it('drops findings for files that were not sent', () => {
34
- expect(verifyCodeFindings([finding({ file: 'src/other.ts' })], [context])).toHaveLength(0);
35
- });
36
- it('drops findings whose line is outside the sent ranges', () => {
37
- expect(verifyCodeFindings([finding({ line: 80 })], [context])).toHaveLength(0);
38
- });
39
- it('drops findings that cite an identifier the model was never shown', () => {
40
- expect(verifyCodeFindings([finding({ description: '`fetchEverything` has no limit.' })], [context])).toHaveLength(0);
41
- });
42
- it('drops findings that cite no line, however confident', () => {
43
- expect(verifyCodeFindings([finding({ line: undefined, confidence: 0.9 })], [context])).toHaveLength(0);
44
- expect(verifyCodeFindings([finding({ line: null, description: 'The code is well-structured.' })], [context])).toHaveLength(0);
45
- });
46
- it('drops very low confidence findings', () => {
47
- expect(verifyCodeFindings([finding({ confidence: 0.2 })], [context])).toHaveLength(0);
48
- });
49
- });
50
- describe('quotedIdentifiers', () => {
51
- it('extracts identifier-like backticked tokens only', () => {
52
- expect(quotedIdentifiers('`fetchAll()` and `rows.length` but not `a + b` or `"quoted"`')).toEqual(['fetchAll', 'rows.length']);
53
- });
54
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,33 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { safeCalls, testFileSource } from './calls.js';
3
- describe('safeCalls', () => {
4
- it('keeps calls of the function with literal arguments only', () => {
5
- expect(safeCalls('encodePath', [
6
- "encodePath('/a b')",
7
- "encodePath('/x?y', { keepQuery: true, depth: -1 }, [1, null, undefined]);",
8
- 'encodePath(`/%`)',
9
- ])).toEqual(["encodePath('/a b')", "encodePath('/x?y', { keepQuery: true, depth: -1 }, [1, null, undefined])", 'encodePath(`/%`)']);
10
- });
11
- it('drops anything that could do more than call the function on data', () => {
12
- expect(safeCalls('encodePath', [
13
- "require('fs').rmSync('/')",
14
- "encodePath(process.env.HOME)",
15
- "encodePath((() => { fetch('x') })())",
16
- 'encodePath(`${secret}`)',
17
- "other('/a')",
18
- "encodePath('/a'); encodePath('/b')",
19
- "encodePath({ [key]: 1 })",
20
- ])).toEqual([]);
21
- });
22
- });
23
- describe('testFileSource', () => {
24
- it('imports the function, runs each call and records return values or errors without asserting', () => {
25
- const source = testFileSource('vitest', 'encodePath', '../src/path', ["encodePath('/a b')"]);
26
- expect(source).toContain("import { test } from 'vitest';");
27
- expect(source).toContain('import { encodePath } from "../src/path";');
28
- expect(source).toContain(`["encodePath('/a b')", () => encodePath('/a b')],`);
29
- expect(source).toContain('writeFileSync(process.env.RIGOUR_DIFF_OUT as string, JSON.stringify(out));');
30
- expect(source).not.toContain('expect(');
31
- expect(testFileSource('jest', 'f', './f', ['f(1)'])).not.toContain("from 'vitest'");
32
- });
33
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,58 +0,0 @@
1
- import { execFileSync } from 'child_process';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
- import { afterEach, describe, expect, it } from 'vitest';
6
- import { runDiffTests } from './run.js';
7
- // The workspace root's node_modules, where the vitest binary is installed.
8
- const WORKSPACE_MODULES = path.resolve(__dirname, '../../../../../node_modules');
9
- let repo;
10
- afterEach(() => { if (repo)
11
- fs.rmSync(repo, { recursive: true, force: true }); repo = undefined; });
12
- const BEFORE = "export function encodePath(p: string): string {\n return p.replace(/ /g, '%20').replace(/#/g, '%23');\n}\n";
13
- const AFTER = "export function encodePath(p: string): string {\n return p.replace(/#/g, '%23');\n}\n";
14
- function repoWithChange() {
15
- repo = fs.mkdtempSync(path.join(os.tmpdir(), 'diff-tests-'));
16
- const git = (...args) => execFileSync('git', args, { cwd: repo });
17
- git('init', '-q');
18
- git('config', 'user.email', 't@example.com');
19
- git('config', 'user.name', 't');
20
- git('config', 'commit.gpgsign', 'false');
21
- fs.writeFileSync(path.join(repo, 'package.json'), JSON.stringify({ name: 'paths', type: 'module', devDependencies: { vitest: '*' } }));
22
- fs.writeFileSync(path.join(repo, '.gitignore'), 'node_modules\n');
23
- fs.mkdirSync(path.join(repo, 'src'));
24
- fs.writeFileSync(path.join(repo, 'src/encode.ts'), BEFORE);
25
- git('add', '-A');
26
- git('commit', '-qm', 'init');
27
- fs.symlinkSync(WORKSPACE_MODULES, path.join(repo, 'node_modules'), process.platform === 'win32' ? 'junction' : 'dir');
28
- fs.writeFileSync(path.join(repo, 'src/encode.ts'), AFTER);
29
- return repo;
30
- }
31
- function provider(calls, intended = false) {
32
- return {
33
- name: 'fake', isAvailable: async () => true, setup: async () => { }, dispose: () => { },
34
- analyze: async (prompt) => prompt.includes('"intended"') ? JSON.stringify({ intended }) : JSON.stringify({ calls }),
35
- };
36
- }
37
- describe('runDiffTests', () => {
38
- it('reports a call whose outcome changed between the base and the change', async () => {
39
- const cwd = repoWithChange();
40
- const changes = await runDiffTests({
41
- cwd, baseRef: 'HEAD', focusLines: { 'src/encode.ts': [2] }, inference: {},
42
- provider: provider(["encodePath('/a b')", "encodePath('/x#y')", "process.exit(1)"]),
43
- });
44
- expect(changes).toEqual([{
45
- file: 'src/encode.ts', line: 2, name: 'encodePath', call: "encodePath('/a b')",
46
- before: 'returns "/a%20b"', after: 'returns "/a b"',
47
- }]);
48
- expect(fs.readdirSync(path.join(cwd, 'src'))).toEqual(['encode.ts']);
49
- }, 60_000);
50
- it('drops a change the PR description says is intended', async () => {
51
- const cwd = repoWithChange();
52
- const changes = await runDiffTests({
53
- cwd, baseRef: 'HEAD', focusLines: { 'src/encode.ts': [2] }, inference: {}, prBody: 'Stop encoding spaces.',
54
- provider: provider(["encodePath('/a b')"], true),
55
- });
56
- expect(changes).toEqual([]);
57
- }, 60_000);
58
- });
@@ -1 +0,0 @@
1
- export {};