@velum-labs/routekit-eval-setup 1.3.2 → 1.5.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 (342) hide show
  1. package/dist/adapters/authoring-responses-request.d.ts +5 -0
  2. package/dist/adapters/authoring-responses-request.js +38 -0
  3. package/dist/adapters/evaluation-evidence-freshness.d.ts +7 -0
  4. package/dist/adapters/evaluation-evidence-freshness.js +76 -0
  5. package/dist/adapters/git-task-history.d.ts +67 -0
  6. package/dist/adapters/git-task-history.js +171 -0
  7. package/dist/adapters/integrated-repository-history.d.ts +21 -0
  8. package/dist/adapters/integrated-repository-history.js +175 -0
  9. package/dist/adapters/repository-command-diagnostic.d.ts +8 -0
  10. package/dist/adapters/repository-command-diagnostic.js +46 -0
  11. package/dist/adapters/repository-command-evidence.d.ts +13 -0
  12. package/dist/adapters/repository-command-evidence.js +102 -0
  13. package/dist/adapters/repository-command-runner.d.ts +238 -0
  14. package/dist/adapters/repository-command-runner.js +1483 -0
  15. package/dist/adapters/repository-import-context.d.ts +47 -0
  16. package/dist/adapters/repository-import-context.js +469 -0
  17. package/dist/adapters/repository-node-test-reporter.d.ts +3 -0
  18. package/dist/adapters/repository-node-test-reporter.js +27 -0
  19. package/dist/adapters/repository-review-evidence.d.ts +39 -0
  20. package/dist/adapters/repository-review-evidence.js +632 -0
  21. package/dist/adapters/repository-seed-selection.d.ts +7 -0
  22. package/dist/adapters/repository-seed-selection.js +79 -0
  23. package/dist/adapters/repository-solution-edits.d.ts +49 -0
  24. package/dist/adapters/repository-solution-edits.js +136 -0
  25. package/dist/adapters/repository-vitest-phase-adapter.d.ts +8 -0
  26. package/dist/adapters/repository-vitest-phase-adapter.js +310 -0
  27. package/dist/adapters/repository-vitest-reporter.d.ts +24 -0
  28. package/dist/adapters/repository-vitest-reporter.js +314 -0
  29. package/dist/adapters/strict-authoring-schema.d.ts +5 -0
  30. package/dist/adapters/strict-authoring-schema.js +158 -0
  31. package/dist/adapters/test-discovery.d.ts +30 -0
  32. package/dist/adapters/test-discovery.js +124 -0
  33. package/dist/adapters/typescript-repository-index.d.ts +51 -0
  34. package/dist/adapters/typescript-repository-index.js +226 -0
  35. package/dist/agentic-capabilities-protocol.d.ts +1373 -0
  36. package/dist/agentic-capabilities-protocol.js +786 -0
  37. package/dist/case-checkpoint-store.d.ts +29 -0
  38. package/dist/case-checkpoint-store.js +133 -0
  39. package/dist/case-pipeline-protocol-v2.d.ts +184 -0
  40. package/dist/case-pipeline-protocol-v2.js +193 -0
  41. package/dist/case-pipeline-protocol.d.ts +2626 -0
  42. package/dist/case-pipeline-protocol.js +371 -0
  43. package/dist/effect-api.d.ts +74 -10
  44. package/dist/effect-api.js +56 -6
  45. package/dist/errors.d.ts +31 -0
  46. package/dist/errors.js +10 -0
  47. package/dist/eval-capability-execution-envelope.d.ts +64 -0
  48. package/dist/eval-capability-execution-envelope.js +98 -0
  49. package/dist/eval-capability-policy.d.ts +90 -0
  50. package/dist/eval-capability-policy.js +107 -0
  51. package/dist/eval-event-log.d.ts +140 -0
  52. package/dist/eval-event-log.js +220 -0
  53. package/dist/evaluation-authoring-policy.d.ts +18 -0
  54. package/dist/evaluation-authoring-policy.js +19 -0
  55. package/dist/evaluation-authoring-validation.d.ts +22 -0
  56. package/dist/evaluation-authoring-validation.js +72 -0
  57. package/dist/evaluation-evidence.d.ts +20 -0
  58. package/dist/evaluation-evidence.js +319 -0
  59. package/dist/evaluation-grader-calibration-protocol.d.ts +108 -0
  60. package/dist/evaluation-grader-calibration-protocol.js +80 -0
  61. package/dist/evaluation-grader-calibration.d.ts +18 -0
  62. package/dist/evaluation-grader-calibration.js +334 -0
  63. package/dist/evaluation-grading-policy.d.ts +24 -0
  64. package/dist/evaluation-grading-policy.js +54 -0
  65. package/dist/evaluation-proposal-policy.d.ts +4 -0
  66. package/dist/evaluation-proposal-policy.js +91 -0
  67. package/dist/evaluation-source-retrieval.d.ts +68 -0
  68. package/dist/evaluation-source-retrieval.js +513 -0
  69. package/dist/evaluation-structure-policy.d.ts +29 -0
  70. package/dist/evaluation-structure-policy.js +138 -0
  71. package/dist/index.d.ts +124 -17
  72. package/dist/index.js +69 -11
  73. package/dist/inspection.js +2 -3
  74. package/dist/project-artifacts.d.ts +7 -2
  75. package/dist/project-artifacts.js +49 -136
  76. package/dist/project-authoring.d.ts +66 -5
  77. package/dist/project-authoring.js +783 -109
  78. package/dist/project-contracts.d.ts +419 -84
  79. package/dist/project-contracts.js +160 -52
  80. package/dist/project-store.js +2 -1
  81. package/dist/project-workflow.d.ts +5 -4
  82. package/dist/project-workflow.js +154 -35
  83. package/dist/repository-adversary-protocol.d.ts +64 -0
  84. package/dist/repository-adversary-protocol.js +105 -0
  85. package/dist/repository-behavior-protocol.d.ts +188 -0
  86. package/dist/repository-behavior-protocol.js +202 -0
  87. package/dist/repository-benchmark-protocol.d.ts +487 -0
  88. package/dist/repository-benchmark-protocol.js +96 -0
  89. package/dist/repository-execution-protocol.d.ts +150 -0
  90. package/dist/repository-execution-protocol.js +38 -0
  91. package/dist/repository-fixture-instructions.d.ts +3 -0
  92. package/dist/repository-fixture-instructions.js +91 -0
  93. package/dist/repository-fixture-protocol.d.ts +79 -0
  94. package/dist/repository-fixture-protocol.js +79 -0
  95. package/dist/repository-foundry-plan-protocol.d.ts +118 -0
  96. package/dist/repository-foundry-plan-protocol.js +296 -0
  97. package/dist/repository-foundry-progress-protocol.d.ts +52 -0
  98. package/dist/repository-foundry-progress-protocol.js +52 -0
  99. package/dist/repository-improvement-protocol.d.ts +100 -0
  100. package/dist/repository-improvement-protocol.js +106 -0
  101. package/dist/repository-language-model-protocol.d.ts +43 -0
  102. package/dist/repository-language-model-protocol.js +146 -0
  103. package/dist/repository-oracle-coverage-protocol.d.ts +18 -0
  104. package/dist/repository-oracle-coverage-protocol.js +39 -0
  105. package/dist/repository-oracle-execution-binding.d.ts +27 -0
  106. package/dist/repository-oracle-execution-binding.js +59 -0
  107. package/dist/repository-oracle-protocol.d.ts +230 -0
  108. package/dist/repository-oracle-protocol.js +156 -0
  109. package/dist/repository-oracle-scope-policy.d.ts +22 -0
  110. package/dist/repository-oracle-scope-policy.js +92 -0
  111. package/dist/repository-quality-policy.d.ts +15 -0
  112. package/dist/repository-quality-policy.js +357 -0
  113. package/dist/repository-routing-benchmark-protocol.d.ts +176 -0
  114. package/dist/repository-routing-benchmark-protocol.js +103 -0
  115. package/dist/repository-routing-model-protocol.d.ts +36 -0
  116. package/dist/repository-routing-model-protocol.js +89 -0
  117. package/dist/repository-routing-plan-protocol.d.ts +112 -0
  118. package/dist/repository-routing-plan-protocol.js +58 -0
  119. package/dist/repository-routing-quality-policy.d.ts +9 -0
  120. package/dist/repository-routing-quality-policy.js +191 -0
  121. package/dist/repository-seed-qualification-progress-protocol.d.ts +205 -0
  122. package/dist/repository-seed-qualification-progress-protocol.js +28 -0
  123. package/dist/repository-semantic-calibration-protocol.d.ts +768 -0
  124. package/dist/repository-semantic-calibration-protocol.js +276 -0
  125. package/dist/repository-semantic-calibration.d.ts +163 -0
  126. package/dist/repository-semantic-calibration.js +581 -0
  127. package/dist/repository-specification-contract-facts-protocol.d.ts +224 -0
  128. package/dist/repository-specification-contract-facts-protocol.js +276 -0
  129. package/dist/repository-specification-critique-protocol.d.ts +189 -0
  130. package/dist/repository-specification-critique-protocol.js +103 -0
  131. package/dist/repository-task-family-protocol.d.ts +24 -0
  132. package/dist/repository-task-family-protocol.js +37 -0
  133. package/dist/repository-task-seed-protocol.d.ts +384 -0
  134. package/dist/repository-task-seed-protocol.js +236 -0
  135. package/dist/repository-trajectory-protocol.d.ts +20 -0
  136. package/dist/repository-trajectory-protocol.js +42 -0
  137. package/dist/service.js +1 -1
  138. package/dist/services/adversary/service.d.ts +64 -0
  139. package/dist/services/adversary/service.js +330 -0
  140. package/dist/services/benchmark-compiler/service.d.ts +450 -0
  141. package/dist/services/benchmark-compiler/service.js +9 -0
  142. package/dist/services/budgeted-model/service.d.ts +118 -0
  143. package/dist/services/budgeted-model/service.js +460 -0
  144. package/dist/services/case-authoring/service.d.ts +163 -0
  145. package/dist/services/case-authoring/service.js +1456 -0
  146. package/dist/services/case-finalization/service.d.ts +283 -0
  147. package/dist/services/case-finalization/service.js +370 -0
  148. package/dist/services/case-generation/service.d.ts +619 -0
  149. package/dist/services/case-generation/service.js +2628 -0
  150. package/dist/services/case-pipeline/service.d.ts +31 -0
  151. package/dist/services/case-pipeline/service.js +485 -0
  152. package/dist/services/case-pipeline-v2/service.d.ts +70 -0
  153. package/dist/services/case-pipeline-v2/service.js +477 -0
  154. package/dist/services/command-observability/service.d.ts +13 -0
  155. package/dist/services/command-observability/service.js +3 -0
  156. package/dist/services/dimension-labeling/service.d.ts +77 -0
  157. package/dist/services/dimension-labeling/service.js +188 -0
  158. package/dist/services/eval-candidate/service.d.ts +208 -0
  159. package/dist/services/eval-candidate/service.js +64 -0
  160. package/dist/services/eval-capabilities/service.d.ts +183 -0
  161. package/dist/services/eval-capabilities/service.js +1433 -0
  162. package/dist/services/eval-environment/service.d.ts +173 -0
  163. package/dist/services/eval-environment/service.js +127 -0
  164. package/dist/services/evidence-reconstruction/service.d.ts +36 -0
  165. package/dist/services/evidence-reconstruction/service.js +145 -0
  166. package/dist/services/fixture-builder/service.d.ts +62 -0
  167. package/dist/services/fixture-builder/service.js +36 -0
  168. package/dist/services/fixture-validation/service.d.ts +75 -0
  169. package/dist/services/fixture-validation/service.js +295 -0
  170. package/dist/services/foundry/service.d.ts +831 -0
  171. package/dist/services/foundry/service.js +442 -0
  172. package/dist/services/foundry-progress/service.d.ts +62 -0
  173. package/dist/services/foundry-progress/service.js +149 -0
  174. package/dist/services/foundry-v2/service.d.ts +54 -0
  175. package/dist/services/foundry-v2/service.js +28 -0
  176. package/dist/services/grounded-authoring/service.d.ts +126 -0
  177. package/dist/services/grounded-authoring/service.js +822 -0
  178. package/dist/services/historical-case/service.d.ts +722 -0
  179. package/dist/services/historical-case/service.js +177 -0
  180. package/dist/services/improvement-loop/service.d.ts +59 -0
  181. package/dist/services/improvement-loop/service.js +176 -0
  182. package/dist/services/language-model/service.d.ts +52 -0
  183. package/dist/services/language-model/service.js +194 -0
  184. package/dist/services/oracle-builder/service.d.ts +146 -0
  185. package/dist/services/oracle-builder/service.js +513 -0
  186. package/dist/services/oracle-coverage/service.d.ts +28 -0
  187. package/dist/services/oracle-coverage/service.js +50 -0
  188. package/dist/services/oracle-coverage-witness/service.d.ts +130 -0
  189. package/dist/services/oracle-coverage-witness/service.js +538 -0
  190. package/dist/services/pipeline-challenge/service.d.ts +551 -0
  191. package/dist/services/pipeline-challenge/service.js +427 -0
  192. package/dist/services/pipeline-controls/service.d.ts +130 -0
  193. package/dist/services/pipeline-controls/service.js +483 -0
  194. package/dist/services/pipeline-oracle/service.d.ts +8 -0
  195. package/dist/services/pipeline-oracle/service.js +256 -0
  196. package/dist/services/pipeline-seed/service.d.ts +298 -0
  197. package/dist/services/pipeline-seed/service.js +428 -0
  198. package/dist/services/pipeline-spec/service.d.ts +103 -0
  199. package/dist/services/pipeline-spec/service.js +619 -0
  200. package/dist/services/pipeline-tournament/service.d.ts +258 -0
  201. package/dist/services/pipeline-tournament/service.js +476 -0
  202. package/dist/services/quality-gate/service.d.ts +233 -0
  203. package/dist/services/quality-gate/service.js +136 -0
  204. package/dist/services/repository-bundle/service.d.ts +33 -0
  205. package/dist/services/repository-bundle/service.js +114 -0
  206. package/dist/services/repository-model/service.d.ts +105 -0
  207. package/dist/services/repository-model/service.js +250 -0
  208. package/dist/services/repository-public-artifact/service.d.ts +133 -0
  209. package/dist/services/repository-public-artifact/service.js +330 -0
  210. package/dist/services/routing-benchmark/service.d.ts +362 -0
  211. package/dist/services/routing-benchmark/service.js +96 -0
  212. package/dist/services/specification-critic/service.d.ts +92 -0
  213. package/dist/services/specification-critic/service.js +172 -0
  214. package/dist/services/task-family/service.d.ts +40 -0
  215. package/dist/services/task-family/service.js +55 -0
  216. package/dist/services/task-seed/service.d.ts +906 -0
  217. package/dist/services/task-seed/service.js +1406 -0
  218. package/dist/services/task-specification/service.d.ts +27 -0
  219. package/dist/services/task-specification/service.js +40 -0
  220. package/dist/services/trajectory-policy/service.d.ts +110 -0
  221. package/dist/services/trajectory-policy/service.js +216 -0
  222. package/dist/test/agentic-capabilities-protocol.test.d.ts +1 -0
  223. package/dist/test/agentic-capabilities-protocol.test.js +570 -0
  224. package/dist/test/agentic-capabilities.test.d.ts +1 -0
  225. package/dist/test/agentic-capabilities.test.js +1461 -0
  226. package/dist/test/agentic-environment.test.d.ts +1 -0
  227. package/dist/test/agentic-environment.test.js +213 -0
  228. package/dist/test/case-pipeline-foundation.test.d.ts +1 -0
  229. package/dist/test/case-pipeline-foundation.test.js +535 -0
  230. package/dist/test/case-pipeline-protocol-v2.test.d.ts +1 -0
  231. package/dist/test/case-pipeline-protocol-v2.test.js +124 -0
  232. package/dist/test/case-pipeline-v2.test.d.ts +1 -0
  233. package/dist/test/case-pipeline-v2.test.js +286 -0
  234. package/dist/test/case-pipeline.test.d.ts +1 -0
  235. package/dist/test/case-pipeline.test.js +851 -0
  236. package/dist/test/eval-capability-policy.test.d.ts +1 -0
  237. package/dist/test/eval-capability-policy.test.js +50 -0
  238. package/dist/test/eval-event-log.test.d.ts +1 -0
  239. package/dist/test/eval-event-log.test.js +125 -0
  240. package/dist/test/evaluation-evidence-freshness.test.d.ts +1 -0
  241. package/dist/test/evaluation-evidence-freshness.test.js +44 -0
  242. package/dist/test/evaluation-evidence.test.d.ts +1 -0
  243. package/dist/test/evaluation-evidence.test.js +230 -0
  244. package/dist/test/evaluation-grader-calibration.test.d.ts +1 -0
  245. package/dist/test/evaluation-grader-calibration.test.js +373 -0
  246. package/dist/test/evaluation-proposal-digest.test.d.ts +1 -0
  247. package/dist/test/evaluation-proposal-digest.test.js +187 -0
  248. package/dist/test/evaluation-source-retrieval.test.d.ts +1 -0
  249. package/dist/test/evaluation-source-retrieval.test.js +237 -0
  250. package/dist/test/evaluation-structure-policy.test.d.ts +1 -0
  251. package/dist/test/evaluation-structure-policy.test.js +196 -0
  252. package/dist/test/fixtures/repository-resource-panel.d.ts +39 -0
  253. package/dist/test/fixtures/repository-resource-panel.js +111 -0
  254. package/dist/test/fixtures/vitest-boundary-panel.d.ts +84 -0
  255. package/dist/test/fixtures/vitest-boundary-panel.js +120 -0
  256. package/dist/test/fixtures/vitest-phase-panel.d.ts +135 -0
  257. package/dist/test/fixtures/vitest-phase-panel.js +213 -0
  258. package/dist/test/fixtures/vitest-reporter-results.d.ts +76 -0
  259. package/dist/test/fixtures/vitest-reporter-results.js +94 -0
  260. package/dist/test/grounded-authoring.test.d.ts +1 -0
  261. package/dist/test/grounded-authoring.test.js +565 -0
  262. package/dist/test/integrated-repository-history.test.d.ts +1 -0
  263. package/dist/test/integrated-repository-history.test.js +227 -0
  264. package/dist/test/project-authoring.test.js +593 -43
  265. package/dist/test/project-workflow.test.js +419 -40
  266. package/dist/test/repository-authoring-artifacts.test.d.ts +1 -0
  267. package/dist/test/repository-authoring-artifacts.test.js +185 -0
  268. package/dist/test/repository-bundle.test.d.ts +1 -0
  269. package/dist/test/repository-bundle.test.js +52 -0
  270. package/dist/test/repository-case-generation.test.d.ts +1 -0
  271. package/dist/test/repository-case-generation.test.js +3465 -0
  272. package/dist/test/repository-command-diagnostic.test.d.ts +1 -0
  273. package/dist/test/repository-command-diagnostic.test.js +55 -0
  274. package/dist/test/repository-command-signals.test.d.ts +1 -0
  275. package/dist/test/repository-command-signals.test.js +124 -0
  276. package/dist/test/repository-fixture-scope-coverage.test.d.ts +1 -0
  277. package/dist/test/repository-fixture-scope-coverage.test.js +127 -0
  278. package/dist/test/repository-fixture-validation.test.d.ts +1 -0
  279. package/dist/test/repository-fixture-validation.test.js +362 -0
  280. package/dist/test/repository-foundry-progress.test.d.ts +1 -0
  281. package/dist/test/repository-foundry-progress.test.js +110 -0
  282. package/dist/test/repository-foundry-quality.test.d.ts +1 -0
  283. package/dist/test/repository-foundry-quality.test.js +1138 -0
  284. package/dist/test/repository-import-context.test.d.ts +1 -0
  285. package/dist/test/repository-import-context.test.js +354 -0
  286. package/dist/test/repository-model-authoring.test.d.ts +1 -0
  287. package/dist/test/repository-model-authoring.test.js +544 -0
  288. package/dist/test/repository-model.test.d.ts +1 -0
  289. package/dist/test/repository-model.test.js +2195 -0
  290. package/dist/test/repository-node-test-reporter.test.d.ts +1 -0
  291. package/dist/test/repository-node-test-reporter.test.js +104 -0
  292. package/dist/test/repository-oracle-concurrency.test.d.ts +1 -0
  293. package/dist/test/repository-oracle-concurrency.test.js +542 -0
  294. package/dist/test/repository-oracle-coverage-witness.test.d.ts +1 -0
  295. package/dist/test/repository-oracle-coverage-witness.test.js +511 -0
  296. package/dist/test/repository-oracle-coverage.test.d.ts +1 -0
  297. package/dist/test/repository-oracle-coverage.test.js +168 -0
  298. package/dist/test/repository-oracle-evidence.test.d.ts +1 -0
  299. package/dist/test/repository-oracle-evidence.test.js +185 -0
  300. package/dist/test/repository-oracle-plan.test.d.ts +1 -0
  301. package/dist/test/repository-oracle-plan.test.js +176 -0
  302. package/dist/test/repository-overlay-isolation.test.d.ts +1 -0
  303. package/dist/test/repository-overlay-isolation.test.js +85 -0
  304. package/dist/test/repository-preparation-cache.test.d.ts +1 -0
  305. package/dist/test/repository-preparation-cache.test.js +414 -0
  306. package/dist/test/repository-public-artifact.test.d.ts +1 -0
  307. package/dist/test/repository-public-artifact.test.js +273 -0
  308. package/dist/test/repository-qualification-diagnostics.test.d.ts +1 -0
  309. package/dist/test/repository-qualification-diagnostics.test.js +524 -0
  310. package/dist/test/repository-reference-authoring.test.d.ts +1 -0
  311. package/dist/test/repository-reference-authoring.test.js +1633 -0
  312. package/dist/test/repository-review-evidence-v2.test.d.ts +1 -0
  313. package/dist/test/repository-review-evidence-v2.test.js +183 -0
  314. package/dist/test/repository-review-evidence.test.d.ts +1 -0
  315. package/dist/test/repository-review-evidence.test.js +124 -0
  316. package/dist/test/repository-seed-exclusions.test.d.ts +1 -0
  317. package/dist/test/repository-seed-exclusions.test.js +96 -0
  318. package/dist/test/repository-seed-selection.test.d.ts +1 -0
  319. package/dist/test/repository-seed-selection.test.js +504 -0
  320. package/dist/test/repository-semantic-calibration.test.d.ts +1 -0
  321. package/dist/test/repository-semantic-calibration.test.js +688 -0
  322. package/dist/test/repository-solution-edits.test.d.ts +1 -0
  323. package/dist/test/repository-solution-edits.test.js +377 -0
  324. package/dist/test/repository-specification-budget.test.d.ts +1 -0
  325. package/dist/test/repository-specification-budget.test.js +171 -0
  326. package/dist/test/repository-specification-contract-checkpoint.test.d.ts +1 -0
  327. package/dist/test/repository-specification-contract-checkpoint.test.js +228 -0
  328. package/dist/test/repository-specification-contract-facts.test.d.ts +1 -0
  329. package/dist/test/repository-specification-contract-facts.test.js +177 -0
  330. package/dist/test/repository-trajectory-authoring.test.d.ts +1 -0
  331. package/dist/test/repository-trajectory-authoring.test.js +176 -0
  332. package/dist/test/repository-valid-control-plan.test.d.ts +1 -0
  333. package/dist/test/repository-valid-control-plan.test.js +45 -0
  334. package/dist/test/repository-vitest-phase.test.d.ts +1 -0
  335. package/dist/test/repository-vitest-phase.test.js +848 -0
  336. package/dist/test/repository-vitest-reporter.test.d.ts +1 -0
  337. package/dist/test/repository-vitest-reporter.test.js +158 -0
  338. package/dist/test/repository-workspace-build.test.d.ts +1 -0
  339. package/dist/test/repository-workspace-build.test.js +160 -0
  340. package/dist/test/strict-authoring-schema.test.d.ts +1 -0
  341. package/dist/test/strict-authoring-schema.test.js +169 -0
  342. package/package.json +48 -6
@@ -0,0 +1,314 @@
1
+ const REPORT_PREFIX = "ROUTEKIT_VITEST_PHASE_EVIDENCE_V1 ";
2
+ const LEGACY_REPORT_PREFIX = "ROUTEKIT_VITEST_EVIDENCE_V1 ";
3
+ /** Only the explicitly recognized, one-shot Vitest execution receives this reporter. */
4
+ export function repositoryVitestTestArgumentsV1(recipe, reporterPath) {
5
+ const offset = recipe.executable === "corepack" &&
6
+ /^pnpm(?:@[^/\s]+)?$/u.test(recipe.args[0] ?? "") &&
7
+ recipe.args[1] === "exec" &&
8
+ recipe.args[2] === "vitest"
9
+ ? 3
10
+ : recipe.executable === "pnpm" && recipe.args[0] === "exec" && recipe.args[1] === "vitest"
11
+ ? 2
12
+ : undefined;
13
+ if (offset === undefined || recipe.args[offset] !== "run")
14
+ return undefined;
15
+ const args = recipe.args.slice(0, offset + 1);
16
+ for (let index = offset + 1; index < recipe.args.length; index += 1) {
17
+ const value = recipe.args[index];
18
+ if (/^--(?:reporters?|outputFile|output-file|api\.host)$/u.test(value)) {
19
+ index += 1;
20
+ }
21
+ else if (!/^--(?:reporters?|outputFile|output-file)[=.]/u.test(value) &&
22
+ !/^--api\.(?:host|middlewareMode)(?:=|$)/u.test(value)) {
23
+ args.push(value);
24
+ }
25
+ }
26
+ // Vite resolves its default "localhost" even without starting an HTTP server.
27
+ // A literal host avoids that DNS operation in the offline sandbox. Setting
28
+ // middlewareMode explicitly preserves Vitest's normal no-listener run mode.
29
+ args.push("--api.host=127.0.0.1", "--api.middlewareMode", "--reporter", reporterPath);
30
+ return args;
31
+ }
32
+ /**
33
+ * Written outside the candidate-writable checkout. The parent reporter observes
34
+ * worker results; a completed process or assertion-looking console text is not
35
+ * sufficient evidence. The private phased frame is emitted only after installing
36
+ * the pinned host callback adapter at the resolved-config boundary. Historical
37
+ * unphased frames are preserved but cannot retain semantic credit.
38
+ */
39
+ export function repositoryVitestReporterSourceV1(input) {
40
+ return `const phaseRunnerPath = ${JSON.stringify(input.phaseAdapterPath)};\n` +
41
+ `const phaseRuntimeSupported = ${JSON.stringify(input.runtimeSupported)};\n` +
42
+ REPOSITORY_VITEST_REPORTER_SOURCE;
43
+ }
44
+ const REPOSITORY_VITEST_REPORTER_SOURCE = String.raw `
45
+ const prefix = "ROUTEKIT_VITEST_PHASE_EVIDENCE_V1 ";
46
+ const errors = values => {
47
+ if (values == null) return [];
48
+ if (!Array.isArray(values)) throw new Error("invalid error inventory");
49
+ return values.map(error => ({
50
+ name: typeof error?.name === "string" ? error.name : "UnknownError",
51
+ ...(typeof error?.code === "string" ? { code: error.code } : {})
52
+ }));
53
+ };
54
+ const hooks = entity => {
55
+ const value = entity.task.result?.hooks;
56
+ if (value == null) return [];
57
+ if (typeof value !== "object" || Array.isArray(value)) throw new Error("invalid hooks");
58
+ return Object.values(value);
59
+ };
60
+ const testSnapshot = entity => {
61
+ const result = entity.result();
62
+ const diagnostic = entity.diagnostic();
63
+ return {
64
+ id: entity.id,
65
+ name: entity.name,
66
+ state: result.state,
67
+ errors: errors(result.errors),
68
+ hooks: hooks(entity),
69
+ diagnostic: diagnostic == null ? null : {
70
+ retryCount: diagnostic.retryCount,
71
+ repeatCount: diagnostic.repeatCount,
72
+ flaky: diagnostic.flaky,
73
+ duration: diagnostic.duration
74
+ }
75
+ };
76
+ };
77
+ export default class RepositoryEvidenceReporter {
78
+ starts = 0;
79
+ ends = 0;
80
+ hookBalance = new Map();
81
+ completedTests = new Set();
82
+ eventIntegrity = true;
83
+ phaseReady = false;
84
+ refused = false;
85
+ context;
86
+ phaseConfigs = new Set();
87
+ refuse(reason) {
88
+ if (!this.refused) {
89
+ this.refused = true;
90
+ process.stdout.write("\n" + prefix + JSON.stringify({ version: 1, complete: false, error: reason }) + "\n");
91
+ }
92
+ const error = new Error(reason);
93
+ error.name = "RouteKitVitestPhaseContractError";
94
+ error.code = "ROUTEKIT_VITEST_PHASE_CONTRACT_UNSUPPORTED";
95
+ throw error;
96
+ }
97
+ onInit(context) {
98
+ this.context = context;
99
+ if (!phaseRuntimeSupported || context?.version !== "3.2.7") {
100
+ this.refuse("unsupported-vitest-phase-runtime");
101
+ }
102
+ if (this.phaseReady || !Array.isArray(context.projects) || context.projects.length === 0) {
103
+ this.refuse("missing-vitest-resolved-config");
104
+ }
105
+ const configs = new Set([context.config, ...context.projects.map(project => project.config)]);
106
+ // This examines the ORIGINAL resolved values, before any host override.
107
+ // A configured custom runner is rejected before workers can load it.
108
+ if ([...configs].some(config => config?.runner !== undefined)) {
109
+ this.refuse("unsupported-vitest-custom-runner");
110
+ }
111
+ if ([...configs].some(config => !config || config.mode !== "test" ||
112
+ config.pool !== "forks" || config.isolate !== true || config.environment !== "node" ||
113
+ config.watch || config.mergeReports || config.browser?.enabled || config.typecheck?.enabled ||
114
+ config.coverage?.enabled || config.sequence?.concurrent || (config.retry ?? 0) !== 0) ||
115
+ Object.values(context.configOverride ?? {}).some(value => value !== undefined)) {
116
+ this.refuse("unsupported-vitest-phase-config");
117
+ }
118
+ for (const config of configs) {
119
+ if (!Reflect.set(config, "runner", phaseRunnerPath) || config.runner !== phaseRunnerPath) {
120
+ this.refuse("unavailable-vitest-phase-adapter");
121
+ }
122
+ }
123
+ this.phaseConfigs = configs;
124
+ this.phaseReady = true;
125
+ }
126
+ onTestRunStart(specifications) {
127
+ this.starts += 1;
128
+ if (!this.phaseReady || !Array.isArray(specifications) || specifications.length === 0 ||
129
+ specifications.some(specification => specification.pool !== "forks" ||
130
+ !this.phaseConfigs.has(specification.project?.config) ||
131
+ specification.project.config.runner !== phaseRunnerPath) ||
132
+ Object.values(this.context?.configOverride ?? {}).some(value => value !== undefined)) {
133
+ this.refuse("unavailable-vitest-phase-adapter");
134
+ }
135
+ }
136
+ onHookStart(context) {
137
+ const key = context.entity.id + "\0" + context.name;
138
+ this.hookBalance.set(key, (this.hookBalance.get(key) ?? 0) + 1);
139
+ }
140
+ onHookEnd(context) {
141
+ const key = context.entity.id + "\0" + context.name;
142
+ const count = this.hookBalance.get(key) ?? 0;
143
+ if (count < 1) this.eventIntegrity = false;
144
+ this.hookBalance.set(key, count - 1);
145
+ }
146
+ onTestCaseResult(entity) {
147
+ if (this.completedTests.has(entity.id)) this.eventIntegrity = false;
148
+ this.completedTests.add(entity.id);
149
+ }
150
+ onTestRunEnd(modules, unhandledErrors, reason) {
151
+ if (this.refused) return;
152
+ this.ends += 1;
153
+ let report;
154
+ try {
155
+ report = {
156
+ version: 1,
157
+ complete: true,
158
+ starts: this.starts,
159
+ ends: this.ends,
160
+ reason,
161
+ eventIntegrity: this.eventIntegrity,
162
+ unfinishedHooks: [...this.hookBalance.values()].some(count => count !== 0),
163
+ completedTestIds: [...this.completedTests],
164
+ unhandledErrors: errors(unhandledErrors),
165
+ modules: modules.map(module => ({
166
+ id: module.id,
167
+ state: module.state(),
168
+ errors: errors(module.errors()),
169
+ hooks: hooks(module),
170
+ suites: [...module.children.allSuites()].map(suite => ({
171
+ id: suite.id,
172
+ state: suite.state(),
173
+ errors: errors(suite.task.result?.errors),
174
+ hooks: hooks(suite)
175
+ })),
176
+ tests: [...module.children.allTests()].map(testSnapshot)
177
+ }))
178
+ };
179
+ } catch {
180
+ report = { version: 1, complete: false, error: "reporter-contract-unavailable" };
181
+ }
182
+ process.stdout.write("\n" + prefix + JSON.stringify(report) + "\n");
183
+ }
184
+ }
185
+ `;
186
+ const object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
187
+ const strings = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
188
+ const errorInventory = (value) => Array.isArray(value) &&
189
+ value.every((entry) => object(entry) &&
190
+ typeof entry.name === "string" &&
191
+ (entry.code === undefined || typeof entry.code === "string"));
192
+ const terminalState = (value) => value === "passed" || value === "failed" || value === "skipped";
193
+ const healthyHooks = (value) => Array.isArray(value) && value.every((state) => state === "pass");
194
+ /** Undefined means that this command did not emit the host's Vitest protocol. */
195
+ export function repositoryVitestTestEvidenceV1(result, output) {
196
+ const unknown = (detail) => ({ outcome: "unknown", detail });
197
+ const lines = output.split("\n");
198
+ if (lines.some((line) => line.startsWith(LEGACY_REPORT_PREFIX))) {
199
+ return unknown("legacy Vitest evidence has no host-owned phase attribution");
200
+ }
201
+ const frames = lines.filter((line) => line.startsWith(REPORT_PREFIX));
202
+ if (frames.length === 0)
203
+ return undefined;
204
+ if (frames.length !== 1)
205
+ return unknown("ambiguous Vitest reporter evidence");
206
+ let report;
207
+ try {
208
+ report = JSON.parse(frames[0].slice(REPORT_PREFIX.length));
209
+ }
210
+ catch {
211
+ return unknown("invalid Vitest reporter evidence");
212
+ }
213
+ if (!object(report) ||
214
+ report.version !== 1 ||
215
+ report.complete !== true ||
216
+ report.starts !== 1 ||
217
+ report.ends !== 1 ||
218
+ report.eventIntegrity !== true ||
219
+ report.unfinishedHooks !== false ||
220
+ !strings(report.completedTestIds) ||
221
+ new Set(report.completedTestIds).size !== report.completedTestIds.length ||
222
+ !errorInventory(report.unhandledErrors) ||
223
+ report.unhandledErrors.length !== 0 ||
224
+ !Array.isArray(report.modules) ||
225
+ report.modules.length === 0 ||
226
+ (report.reason !== "passed" && report.reason !== "failed")) {
227
+ return unknown("Vitest did not complete one unambiguous run without hook or unhandled errors");
228
+ }
229
+ const completedTestIds = report.completedTestIds;
230
+ const tests = [];
231
+ const moduleIds = new Set();
232
+ for (const module of report.modules) {
233
+ if (!object(module) ||
234
+ typeof module.id !== "string" ||
235
+ moduleIds.has(module.id) ||
236
+ !terminalState(module.state) ||
237
+ !errorInventory(module.errors) ||
238
+ module.errors.length !== 0 ||
239
+ !healthyHooks(module.hooks) ||
240
+ !Array.isArray(module.suites) ||
241
+ !Array.isArray(module.tests)) {
242
+ return unknown("Vitest module collection, setup or result evidence is incomplete");
243
+ }
244
+ moduleIds.add(module.id);
245
+ for (const suite of module.suites) {
246
+ if (!object(suite) ||
247
+ !terminalState(suite.state) ||
248
+ !errorInventory(suite.errors) ||
249
+ suite.errors.length !== 0 ||
250
+ !healthyHooks(suite.hooks)) {
251
+ return unknown("Vitest suite setup or result evidence is incomplete");
252
+ }
253
+ }
254
+ for (const test of module.tests) {
255
+ if (!object(test) ||
256
+ typeof test.id !== "string" ||
257
+ typeof test.name !== "string" ||
258
+ test.name.trim().length === 0 ||
259
+ !terminalState(test.state) ||
260
+ !errorInventory(test.errors) ||
261
+ !healthyHooks(test.hooks)) {
262
+ return unknown("Vitest test discovery, hooks or results are incomplete");
263
+ }
264
+ if (test.state !== "skipped") {
265
+ const diagnostic = test.diagnostic;
266
+ if (!object(diagnostic) ||
267
+ diagnostic.retryCount !== 0 ||
268
+ diagnostic.repeatCount !== 0 ||
269
+ diagnostic.flaky !== false ||
270
+ typeof diagnostic.duration !== "number" ||
271
+ !Number.isFinite(diagnostic.duration) ||
272
+ diagnostic.duration < 0) {
273
+ return unknown("Vitest test retries, repeats or missing diagnostics prevent stable evidence");
274
+ }
275
+ }
276
+ tests.push(test);
277
+ }
278
+ const failed = module.tests.some((test) => object(test) && test.state === "failed");
279
+ if ((module.state === "failed" && !failed) || (module.state === "passed" && failed)) {
280
+ return unknown("Vitest module status disagrees with its test outcomes");
281
+ }
282
+ }
283
+ const ids = tests.map((test) => test.id);
284
+ if (new Set(ids).size !== ids.length ||
285
+ ids.length !== completedTestIds.length ||
286
+ ids.some((id) => !completedTestIds.includes(id))) {
287
+ return unknown("Vitest did not report completion for every discovered test");
288
+ }
289
+ const passed = tests.filter((test) => test.state === "passed");
290
+ const failed = tests.filter((test) => test.state === "failed");
291
+ if (passed.length + failed.length === 0 ||
292
+ passed.some((test) => test.errors.length !== 0)) {
293
+ return unknown("Vitest did not execute cleanly attributable tests");
294
+ }
295
+ if (result.exitCode === 0 && report.reason === "passed" && failed.length === 0) {
296
+ return { outcome: "pass", detail: `executed=${passed.length}; failed=0; reporter=vitest` };
297
+ }
298
+ if (result.exitCode === 1 && report.reason === "failed" && failed.length > 0) {
299
+ const assertionsOnly = failed.every((test) => test.errors.length > 0 &&
300
+ test.errors.every((error) => error.name === "AssertionError" &&
301
+ (error.code === undefined || error.code === "ERR_ASSERTION")));
302
+ if (assertionsOnly) {
303
+ return {
304
+ outcome: "fail",
305
+ detail: `executed=${passed.length + failed.length}; assertionFailures=${failed.length}; reporter=vitest`
306
+ };
307
+ }
308
+ return {
309
+ ...unknown("Vitest failed without attributable test-body assertions for every failed test"),
310
+ inconclusiveReason: "unattributed-test-failure"
311
+ };
312
+ }
313
+ return unknown("Vitest exit status disagrees with completed test evidence");
314
+ }
@@ -0,0 +1,5 @@
1
+ /** Adapt only the model wire contract; domain codecs and saved files stay unchanged. */
2
+ export declare function strictAuthoringSchema(document: Record<string, unknown>): {
3
+ readonly jsonSchema: Record<string, unknown>;
4
+ readonly normalizeResponse: (value: unknown) => unknown;
5
+ };
@@ -0,0 +1,158 @@
1
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
2
+ ? value
3
+ : undefined;
4
+ /** Adapt only the model wire contract; domain codecs and saved files stay unchanged. */
5
+ export function strictAuthoringSchema(document) {
6
+ const resolve = (schema, seen = new Set()) => {
7
+ if (typeof schema !== "object" || typeof schema.$ref !== "string")
8
+ return schema;
9
+ const reference = schema.$ref;
10
+ if (!reference.startsWith("#/") || seen.has(reference))
11
+ throw new Error("authoring schema requires resolvable local references");
12
+ let target = document;
13
+ for (const part of reference.slice(2).split("/"))
14
+ target = record(target)?.[part.replaceAll("~1", "/").replaceAll("~0", "~")];
15
+ if (typeof target !== "boolean" && record(target) === undefined)
16
+ throw new Error("authoring schema contains an unresolved reference");
17
+ return resolve(target, new Set([...seen, reference]));
18
+ };
19
+ const acceptsNull = (input) => {
20
+ const schema = resolve(input);
21
+ if (typeof schema === "boolean")
22
+ return schema;
23
+ if (Array.isArray(schema.anyOf))
24
+ return schema.anyOf.some(acceptsNull);
25
+ if (Array.isArray(schema.enum))
26
+ return schema.enum.includes(null);
27
+ if (Object.hasOwn(schema, "const"))
28
+ return schema.const === null;
29
+ return schema.type === "null" || (Array.isArray(schema.type) && schema.type.includes("null"));
30
+ };
31
+ const convert = (input) => {
32
+ if (typeof input === "boolean")
33
+ return input;
34
+ if ([
35
+ "oneOf",
36
+ "allOf",
37
+ "not",
38
+ "if",
39
+ "then",
40
+ "else",
41
+ "prefixItems",
42
+ "contains",
43
+ "dependentSchemas",
44
+ "patternProperties",
45
+ "unevaluatedProperties"
46
+ ].some((key) => Object.hasOwn(input, key)))
47
+ throw new Error("authoring schema uses a shape outside the supported strict conversion");
48
+ const output = { ...input };
49
+ if (typeof input.$ref === "string")
50
+ resolve(input);
51
+ if (Array.isArray(input.anyOf))
52
+ output.anyOf = input.anyOf.map(convert);
53
+ if (record(input.items) || typeof input.items === "boolean")
54
+ output.items = convert(input.items);
55
+ if (record(input.$defs))
56
+ output.$defs = Object.fromEntries(Object.entries(input.$defs).map(([key, value]) => [
57
+ key,
58
+ convert(value)
59
+ ]));
60
+ const properties = record(input.properties);
61
+ if (input.type === "object" || properties !== undefined) {
62
+ if (input.additionalProperties !== false || properties === undefined)
63
+ throw new Error("strict authoring output requires closed objects with named properties");
64
+ const required = new Set(Array.isArray(input.required) ? input.required : []);
65
+ output.properties = Object.fromEntries(Object.entries(properties).map(([key, value]) => {
66
+ const converted = convert(value);
67
+ return [
68
+ key,
69
+ required.has(key) || acceptsNull(value)
70
+ ? converted
71
+ : { anyOf: [converted, { type: "null" }] }
72
+ ];
73
+ }));
74
+ output.required = Object.keys(properties);
75
+ output.additionalProperties = false;
76
+ }
77
+ return output;
78
+ };
79
+ // Select the matching encoded union branch before restoring optional fields.
80
+ // This is a shape discriminator; the original Effect codec remains the final
81
+ // validator for refinements and the complete domain contract.
82
+ const matches = (input, value, wire) => {
83
+ const schema = resolve(input);
84
+ if (typeof schema === "boolean")
85
+ return schema;
86
+ if (Array.isArray(schema.anyOf))
87
+ return schema.anyOf.some((branch) => matches(branch, value, wire));
88
+ if (Array.isArray(schema.enum) &&
89
+ !schema.enum.some((entry) => JSON.stringify(entry) === JSON.stringify(value)))
90
+ return false;
91
+ if (Object.hasOwn(schema, "const") && schema.const !== value)
92
+ return false;
93
+ const type = schema.type;
94
+ if (Array.isArray(type))
95
+ return type.some((item) => matches({ ...schema, type: item }, value, wire));
96
+ if (type === "null")
97
+ return value === null;
98
+ if (type === "string")
99
+ return typeof value === "string";
100
+ if (type === "boolean")
101
+ return typeof value === "boolean";
102
+ if (type === "number" || type === "integer")
103
+ return (typeof value === "number" &&
104
+ Number.isFinite(value) &&
105
+ (type !== "integer" || Number.isInteger(value)));
106
+ if (type === "array")
107
+ return (Array.isArray(value) &&
108
+ value.every((item) => matches((schema.items ?? true), item, wire)));
109
+ if (type === "object") {
110
+ const object = record(value);
111
+ if (!object)
112
+ return false;
113
+ const properties = record(schema.properties) ?? {};
114
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
115
+ if (schema.additionalProperties === false &&
116
+ Object.keys(object).some((key) => !Object.hasOwn(properties, key)))
117
+ return false;
118
+ return Object.entries(properties).every(([key, property]) => {
119
+ if (!Object.hasOwn(object, key))
120
+ return !required.has(key);
121
+ return ((wire && !required.has(key) && object[key] === null) ||
122
+ matches(property, object[key], wire));
123
+ });
124
+ }
125
+ return true;
126
+ };
127
+ const normalize = (input, value) => {
128
+ const schema = resolve(input);
129
+ if (typeof schema === "boolean")
130
+ return value;
131
+ if (Array.isArray(schema.anyOf)) {
132
+ // Prefer already-valid original values so an explicitly nullable branch
133
+ // never loses a meaningful null merely because another branch is optional.
134
+ const branch = schema.anyOf.find((item) => matches(item, value, false)) ??
135
+ schema.anyOf.find((item) => matches(item, value, true));
136
+ return branch === undefined ? value : normalize(branch, value);
137
+ }
138
+ if (Array.isArray(value) && schema.type === "array")
139
+ return value.map((item) => normalize((schema.items ?? true), item));
140
+ const properties = record(schema.properties);
141
+ const object = record(value);
142
+ if (!properties || !object)
143
+ return value;
144
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
145
+ return Object.fromEntries(Object.entries(object).flatMap(([key, child]) => {
146
+ const property = properties[key];
147
+ if (property === undefined)
148
+ return [[key, child]];
149
+ if (child === null && !required.has(key) && !acceptsNull(property))
150
+ return [];
151
+ return [[key, normalize(property, child)]];
152
+ }));
153
+ };
154
+ return {
155
+ jsonSchema: convert(document),
156
+ normalizeResponse: (value) => normalize(document, value)
157
+ };
158
+ }
@@ -0,0 +1,30 @@
1
+ import { Effect } from "effect";
2
+ import type { RepositoryCommandRecipeV1, RepositoryPackageNodeV1, RepositoryProtocolNodeV1, RepositoryPublicSurfaceV1, RepositoryTestBindingV1, RepositoryTestNodeV1 } from "../repository-behavior-protocol.js";
3
+ import { type GitTreeSnapshotV1 } from "./git-task-history.js";
4
+ export type RepositoryTestDiscoveryV1 = {
5
+ readonly tests: readonly RepositoryTestNodeV1[];
6
+ readonly testBindings: readonly RepositoryTestBindingV1[];
7
+ readonly unmappedTestPaths: readonly string[];
8
+ };
9
+ export declare const discoverRepositoryTestsV1: (input: {
10
+ readonly snapshot: GitTreeSnapshotV1;
11
+ readonly packages: readonly RepositoryPackageNodeV1[];
12
+ readonly publicSurfaces: readonly RepositoryPublicSurfaceV1[];
13
+ readonly protocols: readonly RepositoryProtocolNodeV1[];
14
+ readonly commands: readonly RepositoryCommandRecipeV1[];
15
+ readonly excludedPackageRoots?: readonly string[];
16
+ }) => Effect.Effect<{
17
+ tests: {
18
+ readonly id: string;
19
+ readonly path: string;
20
+ readonly names: readonly string[];
21
+ readonly commandIds: readonly string[];
22
+ }[];
23
+ testBindings: {
24
+ readonly testId: string;
25
+ readonly targetIds: readonly string[];
26
+ readonly signals: readonly ("direct-import" | "symbol-reference" | "fixture-reference" | "package-ownership" | "git-cochange" | "coverage" | "reviewed-hypothesis")[];
27
+ readonly confidence: "high" | "medium" | "hypothesis";
28
+ }[];
29
+ unmappedTestPaths: string[];
30
+ }, import("../errors.js").RepositoryFoundryError, never>;
@@ -0,0 +1,124 @@
1
+ import path from "node:path";
2
+ import { Effect } from "effect";
3
+ import { readGitTreeFileV1 } from "./git-task-history.js";
4
+ const testPath = (value) => {
5
+ const lower = value.toLowerCase();
6
+ const base = lower.split("/").at(-1) ?? lower;
7
+ return (/(?:^|[._-])(?:test|spec)(?:[._-]|$)/u.test(base) ||
8
+ /(^|\/)(?:test|tests|__tests__)(\/|$)/u.test(lower));
9
+ };
10
+ const pathWithinRoot = (path, root) => path === root || path.startsWith(`${root}/`);
11
+ const stableId = (prefix, value) => `${prefix}-${value
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9]+/gu, "-")
14
+ .replace(/^-|-$/gu, "")}`;
15
+ const packageForPath = (packages, filePath) => [...packages]
16
+ .filter((entry) => entry.path === "." ||
17
+ filePath === entry.path ||
18
+ filePath.startsWith(`${entry.path}/`))
19
+ .sort((left, right) => right.path.length - left.path.length)[0];
20
+ const testCommandIdsForPath = (commands, filePath) => {
21
+ const candidates = commands.filter((command) => command.kind === "test" &&
22
+ (command.cwd === "." || pathWithinRoot(filePath, command.cwd)));
23
+ if (candidates.length === 0)
24
+ return [];
25
+ const deepestRootLength = Math.max(...candidates.map((command) => (command.cwd === "." ? 0 : command.cwd.length)));
26
+ return candidates
27
+ .filter((command) => (command.cwd === "." ? 0 : command.cwd.length) === deepestRootLength)
28
+ .sort((left, right) => left.id.localeCompare(right.id))
29
+ .map((command) => command.id);
30
+ };
31
+ const testNames = (content) => [
32
+ ...new Set([
33
+ ...[...content.matchAll(/\b(?:test|it|describe)\s*\(\s*["'`]([^"'`]+)["'`]/gu)]
34
+ .map((match) => match[1])
35
+ .filter((value) => value !== undefined),
36
+ ...[...content.matchAll(/\bdef\s+(test_[A-Za-z0-9_]+)/gu)]
37
+ .map((match) => match[1])
38
+ .filter((value) => value !== undefined)
39
+ ])
40
+ ];
41
+ const importedPaths = (content) => [
42
+ ...new Set([
43
+ ...content.matchAll(/\b(?:from\s+|import\s*\(\s*|require\s*\(\s*)["'`]([^"'`]+)["'`]/gu)
44
+ ]
45
+ .map((match) => match[1])
46
+ .filter((value) => value !== undefined))
47
+ ];
48
+ const resolveRelativeImport = (snapshot, testFile, specifier) => {
49
+ if (!specifier.startsWith("."))
50
+ return undefined;
51
+ const base = path.posix.normalize(path.posix.join(path.posix.dirname(testFile), specifier));
52
+ const sourceBase = base.replace(/\.(?:[cm]?js|jsx)$/u, "");
53
+ for (const candidate of [
54
+ base,
55
+ `${sourceBase}.ts`,
56
+ `${sourceBase}.tsx`,
57
+ `${sourceBase}.mts`,
58
+ `${sourceBase}.cts`,
59
+ `${sourceBase}.js`,
60
+ `${sourceBase}.jsx`,
61
+ `${sourceBase}/index.ts`,
62
+ `${sourceBase}/index.js`
63
+ ]) {
64
+ if (snapshot.files.includes(candidate))
65
+ return candidate;
66
+ }
67
+ return undefined;
68
+ };
69
+ export const discoverRepositoryTestsV1 = Effect.fn("RepositoryFoundry.discoverRepositoryTests")(function* (input) {
70
+ const tests = [];
71
+ const testBindings = [];
72
+ const unmappedTestPaths = [];
73
+ for (const filePath of input.snapshot.files.filter((path) => testPath(path) &&
74
+ !input.excludedPackageRoots?.some((root) => pathWithinRoot(path, root)))) {
75
+ if (!/\.(?:[cm]?[jt]sx?|py|go|rs)$/u.test(filePath.toLowerCase())) {
76
+ continue;
77
+ }
78
+ const content = yield* readGitTreeFileV1({
79
+ snapshot: input.snapshot,
80
+ path: filePath
81
+ });
82
+ const owner = packageForPath(input.packages, filePath);
83
+ const commandIds = testCommandIdsForPath(input.commands, filePath);
84
+ const id = stableId("test", filePath);
85
+ tests.push({
86
+ id,
87
+ path: filePath,
88
+ names: testNames(content),
89
+ commandIds
90
+ });
91
+ const relativeTargets = importedPaths(content)
92
+ .map((specifier) => resolveRelativeImport(input.snapshot, filePath, specifier))
93
+ .filter((value) => value !== undefined);
94
+ const protocolIds = input.protocols
95
+ .filter((protocol) => relativeTargets.includes(protocol.path))
96
+ .map((protocol) => protocol.id);
97
+ const surfaceIds = input.publicSurfaces
98
+ .filter((surface) => relativeTargets.includes(surface.path))
99
+ .map((surface) => surface.id);
100
+ const targetIds = [
101
+ ...protocolIds,
102
+ ...surfaceIds,
103
+ ...(owner === undefined ? [] : [owner.id])
104
+ ].filter((value, index, values) => values.indexOf(value) === index);
105
+ if (targetIds.length === 0) {
106
+ unmappedTestPaths.push(filePath);
107
+ continue;
108
+ }
109
+ testBindings.push({
110
+ testId: id,
111
+ targetIds,
112
+ signals: [
113
+ ...(relativeTargets.length > 0 ? ["direct-import"] : []),
114
+ ...(owner === undefined ? [] : ["package-ownership"])
115
+ ],
116
+ confidence: relativeTargets.length > 0 ? "high" : "medium"
117
+ });
118
+ }
119
+ return {
120
+ tests: tests.sort((left, right) => left.path.localeCompare(right.path)),
121
+ testBindings: testBindings.sort((left, right) => left.testId.localeCompare(right.testId)),
122
+ unmappedTestPaths: unmappedTestPaths.sort()
123
+ };
124
+ });