claude-test-bench 1.0.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 (314) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +474 -0
  3. package/dist/bin/ctb.d.ts +3 -0
  4. package/dist/bin/ctb.d.ts.map +1 -0
  5. package/dist/bin/ctb.js +107 -0
  6. package/dist/bin/ctb.js.map +1 -0
  7. package/dist/server/index.d.ts +13 -0
  8. package/dist/server/index.d.ts.map +1 -0
  9. package/dist/server/index.js +72 -0
  10. package/dist/server/index.js.map +1 -0
  11. package/dist/server/interfaces/evaluator.d.ts +15 -0
  12. package/dist/server/interfaces/evaluator.d.ts.map +1 -0
  13. package/dist/server/interfaces/evaluator.js +2 -0
  14. package/dist/server/interfaces/evaluator.js.map +1 -0
  15. package/dist/server/interfaces/logger.d.ts +9 -0
  16. package/dist/server/interfaces/logger.d.ts.map +1 -0
  17. package/dist/server/interfaces/logger.js +2 -0
  18. package/dist/server/interfaces/logger.js.map +1 -0
  19. package/dist/server/interfaces/runner.d.ts +9 -0
  20. package/dist/server/interfaces/runner.d.ts.map +1 -0
  21. package/dist/server/interfaces/runner.js +2 -0
  22. package/dist/server/interfaces/runner.js.map +1 -0
  23. package/dist/server/interfaces/storage.d.ts +36 -0
  24. package/dist/server/interfaces/storage.d.ts.map +1 -0
  25. package/dist/server/interfaces/storage.js +2 -0
  26. package/dist/server/interfaces/storage.js.map +1 -0
  27. package/dist/server/interfaces/workspace.d.ts +9 -0
  28. package/dist/server/interfaces/workspace.d.ts.map +1 -0
  29. package/dist/server/interfaces/workspace.js +2 -0
  30. package/dist/server/interfaces/workspace.js.map +1 -0
  31. package/dist/server/routes/eval-queue.d.ts +23 -0
  32. package/dist/server/routes/eval-queue.d.ts.map +1 -0
  33. package/dist/server/routes/eval-queue.js +45 -0
  34. package/dist/server/routes/eval-queue.js.map +1 -0
  35. package/dist/server/routes/evaluations.d.ts +8 -0
  36. package/dist/server/routes/evaluations.d.ts.map +1 -0
  37. package/dist/server/routes/evaluations.js +217 -0
  38. package/dist/server/routes/evaluations.js.map +1 -0
  39. package/dist/server/routes/providers.d.ts +5 -0
  40. package/dist/server/routes/providers.d.ts.map +1 -0
  41. package/dist/server/routes/providers.js +194 -0
  42. package/dist/server/routes/providers.js.map +1 -0
  43. package/dist/server/routes/run-queue.d.ts +17 -0
  44. package/dist/server/routes/run-queue.d.ts.map +1 -0
  45. package/dist/server/routes/run-queue.js +34 -0
  46. package/dist/server/routes/run-queue.js.map +1 -0
  47. package/dist/server/routes/run-sse.d.ts +18 -0
  48. package/dist/server/routes/run-sse.d.ts.map +1 -0
  49. package/dist/server/routes/run-sse.js +57 -0
  50. package/dist/server/routes/run-sse.js.map +1 -0
  51. package/dist/server/routes/runs.d.ts +9 -0
  52. package/dist/server/routes/runs.d.ts.map +1 -0
  53. package/dist/server/routes/runs.js +379 -0
  54. package/dist/server/routes/runs.js.map +1 -0
  55. package/dist/server/routes/scenarios.d.ts +5 -0
  56. package/dist/server/routes/scenarios.d.ts.map +1 -0
  57. package/dist/server/routes/scenarios.js +209 -0
  58. package/dist/server/routes/scenarios.js.map +1 -0
  59. package/dist/server/routes/setups.d.ts +5 -0
  60. package/dist/server/routes/setups.d.ts.map +1 -0
  61. package/dist/server/routes/setups.js +194 -0
  62. package/dist/server/routes/setups.js.map +1 -0
  63. package/dist/server/services/agent-mapper.d.ts +12 -0
  64. package/dist/server/services/agent-mapper.d.ts.map +1 -0
  65. package/dist/server/services/agent-mapper.js +75 -0
  66. package/dist/server/services/agent-mapper.js.map +1 -0
  67. package/dist/server/services/env-builder.d.ts +10 -0
  68. package/dist/server/services/env-builder.d.ts.map +1 -0
  69. package/dist/server/services/env-builder.js +50 -0
  70. package/dist/server/services/env-builder.js.map +1 -0
  71. package/dist/server/services/eval-helpers.d.ts +22 -0
  72. package/dist/server/services/eval-helpers.d.ts.map +1 -0
  73. package/dist/server/services/eval-helpers.js +75 -0
  74. package/dist/server/services/eval-helpers.js.map +1 -0
  75. package/dist/server/services/eval-parsers-debate-impl.d.ts +11 -0
  76. package/dist/server/services/eval-parsers-debate-impl.d.ts.map +1 -0
  77. package/dist/server/services/eval-parsers-debate-impl.js +133 -0
  78. package/dist/server/services/eval-parsers-debate-impl.js.map +1 -0
  79. package/dist/server/services/eval-parsers.d.ts +24 -0
  80. package/dist/server/services/eval-parsers.d.ts.map +1 -0
  81. package/dist/server/services/eval-parsers.js +153 -0
  82. package/dist/server/services/eval-parsers.js.map +1 -0
  83. package/dist/server/services/eval-prompts.d.ts +9 -0
  84. package/dist/server/services/eval-prompts.d.ts.map +1 -0
  85. package/dist/server/services/eval-prompts.js +170 -0
  86. package/dist/server/services/eval-prompts.js.map +1 -0
  87. package/dist/server/services/evaluator.d.ts +10 -0
  88. package/dist/server/services/evaluator.d.ts.map +1 -0
  89. package/dist/server/services/evaluator.js +156 -0
  90. package/dist/server/services/evaluator.js.map +1 -0
  91. package/dist/server/services/fs-adapter.d.ts +20 -0
  92. package/dist/server/services/fs-adapter.d.ts.map +1 -0
  93. package/dist/server/services/fs-adapter.js +13 -0
  94. package/dist/server/services/fs-adapter.js.map +1 -0
  95. package/dist/server/services/instruction-parser.d.ts +26 -0
  96. package/dist/server/services/instruction-parser.d.ts.map +1 -0
  97. package/dist/server/services/instruction-parser.js +121 -0
  98. package/dist/server/services/instruction-parser.js.map +1 -0
  99. package/dist/server/services/log-rotator.d.ts +20 -0
  100. package/dist/server/services/log-rotator.d.ts.map +1 -0
  101. package/dist/server/services/log-rotator.js +60 -0
  102. package/dist/server/services/log-rotator.js.map +1 -0
  103. package/dist/server/services/logger.d.ts +15 -0
  104. package/dist/server/services/logger.d.ts.map +1 -0
  105. package/dist/server/services/logger.js +69 -0
  106. package/dist/server/services/logger.js.map +1 -0
  107. package/dist/server/services/runner.d.ts +12 -0
  108. package/dist/server/services/runner.d.ts.map +1 -0
  109. package/dist/server/services/runner.js +161 -0
  110. package/dist/server/services/runner.js.map +1 -0
  111. package/dist/server/services/seeder.d.ts +5 -0
  112. package/dist/server/services/seeder.d.ts.map +1 -0
  113. package/dist/server/services/seeder.js +79 -0
  114. package/dist/server/services/seeder.js.map +1 -0
  115. package/dist/server/services/storage-test-helpers.d.ts +21 -0
  116. package/dist/server/services/storage-test-helpers.d.ts.map +1 -0
  117. package/dist/server/services/storage-test-helpers.js +158 -0
  118. package/dist/server/services/storage-test-helpers.js.map +1 -0
  119. package/dist/server/services/storage.d.ts +35 -0
  120. package/dist/server/services/storage.d.ts.map +1 -0
  121. package/dist/server/services/storage.js +219 -0
  122. package/dist/server/services/storage.js.map +1 -0
  123. package/dist/server/services/transcript-formatter.d.ts +18 -0
  124. package/dist/server/services/transcript-formatter.d.ts.map +1 -0
  125. package/dist/server/services/transcript-formatter.js +156 -0
  126. package/dist/server/services/transcript-formatter.js.map +1 -0
  127. package/dist/server/services/workspace.d.ts +11 -0
  128. package/dist/server/services/workspace.d.ts.map +1 -0
  129. package/dist/server/services/workspace.js +113 -0
  130. package/dist/server/services/workspace.js.map +1 -0
  131. package/dist/server/types/evaluation.d.ts +108 -0
  132. package/dist/server/types/evaluation.d.ts.map +1 -0
  133. package/dist/server/types/evaluation.js +5 -0
  134. package/dist/server/types/evaluation.js.map +1 -0
  135. package/dist/server/types/index.d.ts +5 -0
  136. package/dist/server/types/index.d.ts.map +1 -0
  137. package/dist/server/types/index.js +5 -0
  138. package/dist/server/types/index.js.map +1 -0
  139. package/dist/server/types/provider.d.ts +99 -0
  140. package/dist/server/types/provider.d.ts.map +1 -0
  141. package/dist/server/types/provider.js +5 -0
  142. package/dist/server/types/provider.js.map +1 -0
  143. package/dist/server/types/run.d.ts +31 -0
  144. package/dist/server/types/run.d.ts.map +1 -0
  145. package/dist/server/types/run.js +5 -0
  146. package/dist/server/types/run.js.map +1 -0
  147. package/dist/server/types/scenario.d.ts +32 -0
  148. package/dist/server/types/scenario.d.ts.map +1 -0
  149. package/dist/server/types/scenario.js +5 -0
  150. package/dist/server/types/scenario.js.map +1 -0
  151. package/dist/server/types/setup.d.ts +99 -0
  152. package/dist/server/types/setup.d.ts.map +1 -0
  153. package/dist/server/types/setup.js +5 -0
  154. package/dist/server/types/setup.js.map +1 -0
  155. package/dist/src/server/index.d.ts +13 -0
  156. package/dist/src/server/index.d.ts.map +1 -0
  157. package/dist/src/server/index.js +72 -0
  158. package/dist/src/server/index.js.map +1 -0
  159. package/dist/src/server/interfaces/evaluator.d.ts +15 -0
  160. package/dist/src/server/interfaces/evaluator.d.ts.map +1 -0
  161. package/dist/src/server/interfaces/evaluator.js +2 -0
  162. package/dist/src/server/interfaces/evaluator.js.map +1 -0
  163. package/dist/src/server/interfaces/logger.d.ts +9 -0
  164. package/dist/src/server/interfaces/logger.d.ts.map +1 -0
  165. package/dist/src/server/interfaces/logger.js +2 -0
  166. package/dist/src/server/interfaces/logger.js.map +1 -0
  167. package/dist/src/server/interfaces/runner.d.ts +9 -0
  168. package/dist/src/server/interfaces/runner.d.ts.map +1 -0
  169. package/dist/src/server/interfaces/runner.js +2 -0
  170. package/dist/src/server/interfaces/runner.js.map +1 -0
  171. package/dist/src/server/interfaces/storage.d.ts +36 -0
  172. package/dist/src/server/interfaces/storage.d.ts.map +1 -0
  173. package/dist/src/server/interfaces/storage.js +2 -0
  174. package/dist/src/server/interfaces/storage.js.map +1 -0
  175. package/dist/src/server/interfaces/workspace.d.ts +9 -0
  176. package/dist/src/server/interfaces/workspace.d.ts.map +1 -0
  177. package/dist/src/server/interfaces/workspace.js +2 -0
  178. package/dist/src/server/interfaces/workspace.js.map +1 -0
  179. package/dist/src/server/routes/eval-queue.d.ts +23 -0
  180. package/dist/src/server/routes/eval-queue.d.ts.map +1 -0
  181. package/dist/src/server/routes/eval-queue.js +45 -0
  182. package/dist/src/server/routes/eval-queue.js.map +1 -0
  183. package/dist/src/server/routes/evaluations.d.ts +8 -0
  184. package/dist/src/server/routes/evaluations.d.ts.map +1 -0
  185. package/dist/src/server/routes/evaluations.js +217 -0
  186. package/dist/src/server/routes/evaluations.js.map +1 -0
  187. package/dist/src/server/routes/providers.d.ts +5 -0
  188. package/dist/src/server/routes/providers.d.ts.map +1 -0
  189. package/dist/src/server/routes/providers.js +194 -0
  190. package/dist/src/server/routes/providers.js.map +1 -0
  191. package/dist/src/server/routes/run-queue.d.ts +17 -0
  192. package/dist/src/server/routes/run-queue.d.ts.map +1 -0
  193. package/dist/src/server/routes/run-queue.js +34 -0
  194. package/dist/src/server/routes/run-queue.js.map +1 -0
  195. package/dist/src/server/routes/run-sse.d.ts +18 -0
  196. package/dist/src/server/routes/run-sse.d.ts.map +1 -0
  197. package/dist/src/server/routes/run-sse.js +57 -0
  198. package/dist/src/server/routes/run-sse.js.map +1 -0
  199. package/dist/src/server/routes/runs.d.ts +9 -0
  200. package/dist/src/server/routes/runs.d.ts.map +1 -0
  201. package/dist/src/server/routes/runs.js +379 -0
  202. package/dist/src/server/routes/runs.js.map +1 -0
  203. package/dist/src/server/routes/scenarios.d.ts +5 -0
  204. package/dist/src/server/routes/scenarios.d.ts.map +1 -0
  205. package/dist/src/server/routes/scenarios.js +209 -0
  206. package/dist/src/server/routes/scenarios.js.map +1 -0
  207. package/dist/src/server/routes/setups.d.ts +5 -0
  208. package/dist/src/server/routes/setups.d.ts.map +1 -0
  209. package/dist/src/server/routes/setups.js +194 -0
  210. package/dist/src/server/routes/setups.js.map +1 -0
  211. package/dist/src/server/services/agent-mapper.d.ts +12 -0
  212. package/dist/src/server/services/agent-mapper.d.ts.map +1 -0
  213. package/dist/src/server/services/agent-mapper.js +75 -0
  214. package/dist/src/server/services/agent-mapper.js.map +1 -0
  215. package/dist/src/server/services/env-builder.d.ts +10 -0
  216. package/dist/src/server/services/env-builder.d.ts.map +1 -0
  217. package/dist/src/server/services/env-builder.js +50 -0
  218. package/dist/src/server/services/env-builder.js.map +1 -0
  219. package/dist/src/server/services/eval-helpers.d.ts +22 -0
  220. package/dist/src/server/services/eval-helpers.d.ts.map +1 -0
  221. package/dist/src/server/services/eval-helpers.js +75 -0
  222. package/dist/src/server/services/eval-helpers.js.map +1 -0
  223. package/dist/src/server/services/eval-parsers-debate-impl.d.ts +11 -0
  224. package/dist/src/server/services/eval-parsers-debate-impl.d.ts.map +1 -0
  225. package/dist/src/server/services/eval-parsers-debate-impl.js +133 -0
  226. package/dist/src/server/services/eval-parsers-debate-impl.js.map +1 -0
  227. package/dist/src/server/services/eval-parsers.d.ts +24 -0
  228. package/dist/src/server/services/eval-parsers.d.ts.map +1 -0
  229. package/dist/src/server/services/eval-parsers.js +153 -0
  230. package/dist/src/server/services/eval-parsers.js.map +1 -0
  231. package/dist/src/server/services/eval-prompts.d.ts +9 -0
  232. package/dist/src/server/services/eval-prompts.d.ts.map +1 -0
  233. package/dist/src/server/services/eval-prompts.js +170 -0
  234. package/dist/src/server/services/eval-prompts.js.map +1 -0
  235. package/dist/src/server/services/evaluator.d.ts +10 -0
  236. package/dist/src/server/services/evaluator.d.ts.map +1 -0
  237. package/dist/src/server/services/evaluator.js +156 -0
  238. package/dist/src/server/services/evaluator.js.map +1 -0
  239. package/dist/src/server/services/fs-adapter.d.ts +20 -0
  240. package/dist/src/server/services/fs-adapter.d.ts.map +1 -0
  241. package/dist/src/server/services/fs-adapter.js +13 -0
  242. package/dist/src/server/services/fs-adapter.js.map +1 -0
  243. package/dist/src/server/services/instruction-parser.d.ts +26 -0
  244. package/dist/src/server/services/instruction-parser.d.ts.map +1 -0
  245. package/dist/src/server/services/instruction-parser.js +121 -0
  246. package/dist/src/server/services/instruction-parser.js.map +1 -0
  247. package/dist/src/server/services/log-rotator.d.ts +20 -0
  248. package/dist/src/server/services/log-rotator.d.ts.map +1 -0
  249. package/dist/src/server/services/log-rotator.js +60 -0
  250. package/dist/src/server/services/log-rotator.js.map +1 -0
  251. package/dist/src/server/services/logger.d.ts +15 -0
  252. package/dist/src/server/services/logger.d.ts.map +1 -0
  253. package/dist/src/server/services/logger.js +69 -0
  254. package/dist/src/server/services/logger.js.map +1 -0
  255. package/dist/src/server/services/runner.d.ts +12 -0
  256. package/dist/src/server/services/runner.d.ts.map +1 -0
  257. package/dist/src/server/services/runner.js +161 -0
  258. package/dist/src/server/services/runner.js.map +1 -0
  259. package/dist/src/server/services/seeder.d.ts +5 -0
  260. package/dist/src/server/services/seeder.d.ts.map +1 -0
  261. package/dist/src/server/services/seeder.js +79 -0
  262. package/dist/src/server/services/seeder.js.map +1 -0
  263. package/dist/src/server/services/storage.d.ts +35 -0
  264. package/dist/src/server/services/storage.d.ts.map +1 -0
  265. package/dist/src/server/services/storage.js +219 -0
  266. package/dist/src/server/services/storage.js.map +1 -0
  267. package/dist/src/server/services/transcript-formatter.d.ts +18 -0
  268. package/dist/src/server/services/transcript-formatter.d.ts.map +1 -0
  269. package/dist/src/server/services/transcript-formatter.js +156 -0
  270. package/dist/src/server/services/transcript-formatter.js.map +1 -0
  271. package/dist/src/server/services/workspace.d.ts +11 -0
  272. package/dist/src/server/services/workspace.d.ts.map +1 -0
  273. package/dist/src/server/services/workspace.js +113 -0
  274. package/dist/src/server/services/workspace.js.map +1 -0
  275. package/dist/src/server/types/evaluation.d.ts +108 -0
  276. package/dist/src/server/types/evaluation.d.ts.map +1 -0
  277. package/dist/src/server/types/evaluation.js +5 -0
  278. package/dist/src/server/types/evaluation.js.map +1 -0
  279. package/dist/src/server/types/index.d.ts +5 -0
  280. package/dist/src/server/types/index.d.ts.map +1 -0
  281. package/dist/src/server/types/index.js +5 -0
  282. package/dist/src/server/types/index.js.map +1 -0
  283. package/dist/src/server/types/provider.d.ts +99 -0
  284. package/dist/src/server/types/provider.d.ts.map +1 -0
  285. package/dist/src/server/types/provider.js +5 -0
  286. package/dist/src/server/types/provider.js.map +1 -0
  287. package/dist/src/server/types/run.d.ts +31 -0
  288. package/dist/src/server/types/run.d.ts.map +1 -0
  289. package/dist/src/server/types/run.js +5 -0
  290. package/dist/src/server/types/run.js.map +1 -0
  291. package/dist/src/server/types/scenario.d.ts +32 -0
  292. package/dist/src/server/types/scenario.d.ts.map +1 -0
  293. package/dist/src/server/types/scenario.js +5 -0
  294. package/dist/src/server/types/scenario.js.map +1 -0
  295. package/dist/src/server/types/setup.d.ts +99 -0
  296. package/dist/src/server/types/setup.d.ts.map +1 -0
  297. package/dist/src/server/types/setup.js +5 -0
  298. package/dist/src/server/types/setup.js.map +1 -0
  299. package/dist/web/assets/index-C4dw8OpW.css +1 -0
  300. package/dist/web/assets/index-wve8IczO.js +76 -0
  301. package/dist/web/index.html +15 -0
  302. package/docs/schemas/provider-api.example.json +16 -0
  303. package/docs/schemas/provider-oauth.example.json +15 -0
  304. package/docs/schemas/provider.example.json +16 -0
  305. package/docs/schemas/scenario-baseline.example.json +35 -0
  306. package/docs/schemas/scenario-carwash-baseline.example.json +33 -0
  307. package/docs/schemas/scenario-carwash-with-claude-md.example.json +40 -0
  308. package/docs/schemas/scenario-golden-rules-baseline.example.json +51 -0
  309. package/docs/schemas/scenario-golden-rules-with-claude-md.example.json +61 -0
  310. package/docs/schemas/scenario-negative-analysis-baseline.example.json +34 -0
  311. package/docs/schemas/scenario-negative-analysis-with-claude-md.example.json +41 -0
  312. package/docs/schemas/scenario-with-claude-md.example.json +41 -0
  313. package/docs/schemas/scenario.example.json +33 -0
  314. package/package.json +92 -0
@@ -0,0 +1,26 @@
1
+ /** A single testable instruction block extracted from rules content. */
2
+ export interface InstructionBlock {
3
+ readonly source: string;
4
+ readonly text: string;
5
+ }
6
+ /**
7
+ * Parse rules/CLAUDE.md content into semantic instruction blocks.
8
+ *
9
+ * Splits on:
10
+ * - Markdown headings (# / ## / ### etc.)
11
+ * - Numbered lists (1. / 2. etc.)
12
+ * - Bulleted lists (- / * / + prefixed lines)
13
+ * - Paragraph breaks (double newlines)
14
+ *
15
+ * Each block is trimmed and deduplicated. Empty blocks are discarded.
16
+ */
17
+ export declare function parseInstructions(content: string, source: string): InstructionBlock[];
18
+ /**
19
+ * Parse multiple sources (e.g. CLAUDE.md files + rule entries) into a
20
+ * combined list of instruction blocks.
21
+ */
22
+ export declare function parseAllInstructions(entries: readonly {
23
+ content: string;
24
+ source: string;
25
+ }[]): InstructionBlock[];
26
+ //# sourceMappingURL=instruction-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-parser.d.ts","sourceRoot":"","sources":["../../../../src/server/services/instruction-parser.ts"],"names":[],"mappings":"AAIA,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAerF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,GACtD,gBAAgB,EAAE,CAMpB"}
@@ -0,0 +1,121 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Instruction Parser — splits CLAUDE.md / rules content into testable blocks
3
+ // ---------------------------------------------------------------------------
4
+ /**
5
+ * Parse rules/CLAUDE.md content into semantic instruction blocks.
6
+ *
7
+ * Splits on:
8
+ * - Markdown headings (# / ## / ### etc.)
9
+ * - Numbered lists (1. / 2. etc.)
10
+ * - Bulleted lists (- / * / + prefixed lines)
11
+ * - Paragraph breaks (double newlines)
12
+ *
13
+ * Each block is trimmed and deduplicated. Empty blocks are discarded.
14
+ */
15
+ export function parseInstructions(content, source) {
16
+ if (!content.trim())
17
+ return [];
18
+ const rawBlocks = splitIntoBlocks(content);
19
+ const seen = new Set();
20
+ const blocks = [];
21
+ for (const raw of rawBlocks) {
22
+ const text = cleanBlock(raw);
23
+ if (!text || seen.has(text))
24
+ continue;
25
+ seen.add(text);
26
+ blocks.push({ source, text });
27
+ }
28
+ return blocks;
29
+ }
30
+ /**
31
+ * Parse multiple sources (e.g. CLAUDE.md files + rule entries) into a
32
+ * combined list of instruction blocks.
33
+ */
34
+ export function parseAllInstructions(entries) {
35
+ const allBlocks = [];
36
+ for (const entry of entries) {
37
+ allBlocks.push(...parseInstructions(entry.content, entry.source));
38
+ }
39
+ return allBlocks;
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Internal helpers
43
+ // ---------------------------------------------------------------------------
44
+ /** Split content into raw blocks using heading/list/paragraph boundaries. */
45
+ function splitIntoBlocks(content) {
46
+ const lines = content.split('\n');
47
+ const blocks = [];
48
+ let current = [];
49
+ let currentHeadingContext = '';
50
+ for (const line of lines) {
51
+ const isHeading = /^#{1,6}\s+/.test(line);
52
+ const isListItem = /^\s*(?:[-*+]|\d+\.)\s+/.test(line);
53
+ const isBlankLine = line.trim() === '';
54
+ if (isHeading || (isListItem && current.length > 0) || isBlankLine) {
55
+ if (current.length > 0) {
56
+ blocks.push(current.join('\n'));
57
+ current = [];
58
+ }
59
+ }
60
+ if (!isBlankLine) {
61
+ if (isHeading) {
62
+ const headingText = line.replace(/^#{1,6}\s+/, '').trim();
63
+ if (headingText && !isOnlyFormatting(headingText)) {
64
+ if (isActionableHeading(headingText)) {
65
+ // Actionable headings are testable instructions on their own
66
+ blocks.push(headingText);
67
+ currentHeadingContext = '';
68
+ }
69
+ else {
70
+ // Non-actionable headings become context for child instructions
71
+ currentHeadingContext = headingText;
72
+ }
73
+ }
74
+ }
75
+ else {
76
+ // Prepend heading context to child instructions for grouping
77
+ if (currentHeadingContext && current.length === 0) {
78
+ current.push(`[${currentHeadingContext}]`);
79
+ }
80
+ current.push(line);
81
+ }
82
+ }
83
+ }
84
+ if (current.length > 0) {
85
+ blocks.push(current.join('\n'));
86
+ }
87
+ return blocks;
88
+ }
89
+ /**
90
+ * Check if heading text contains imperative/actionable language.
91
+ * A heading is actionable if it starts with a verb or contains directive keywords.
92
+ */
93
+ function isActionableHeading(text) {
94
+ const lower = text.toLowerCase();
95
+ // Contains directive keywords
96
+ if (/\b(must|should|always|never|do not|don't|ensure|require|avoid)\b/i.test(lower)) {
97
+ return true;
98
+ }
99
+ // Starts with an imperative verb (common instruction patterns)
100
+ if (/^(use|run|add|set|create|delete|remove|install|configure|enable|disable|check|verify|test|write|read|update|fix|apply|follow|include|exclude|import|export|call|return|throw|handle|log|format|lint|build|deploy|commit|push|pull|merge|rebase)\b/i.test(lower)) {
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ /** Clean up a raw block: strip list markers, collapse whitespace. */
106
+ function cleanBlock(raw) {
107
+ let text = raw.trim();
108
+ // Remove leading list markers
109
+ text = text.replace(/^\s*(?:[-*+]|\d+\.)\s+/, '');
110
+ // Collapse internal whitespace
111
+ text = text.replace(/\s+/g, ' ').trim();
112
+ // Skip very short blocks (likely formatting artifacts)
113
+ if (text.length < 5)
114
+ return '';
115
+ return text;
116
+ }
117
+ /** Check if a string is only formatting characters (dashes, equals, etc.). */
118
+ function isOnlyFormatting(text) {
119
+ return /^[-=_*#~`]+$/.test(text.trim());
120
+ }
121
+ //# sourceMappingURL=instruction-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-parser.js","sourceRoot":"","sources":["../../../../src/server/services/instruction-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface RotationConfig {
2
+ /** Maximum file size in bytes before rotation (default: 2MB). */
3
+ maxBytes: number;
4
+ /** Maximum number of rotated files to keep (default: 25). */
5
+ maxFiles: number;
6
+ }
7
+ export declare const DEFAULT_ROTATION: RotationConfig;
8
+ /**
9
+ * Rotate a log file if it exceeds `config.maxBytes`.
10
+ *
11
+ * Rotation scheme (e.g. for ctb.log):
12
+ * ctb.24.log → deleted
13
+ * ctb.23.log → ctb.24.log
14
+ * ...
15
+ * ctb.1.log → ctb.2.log
16
+ * ctb.log → ctb.1.log
17
+ * (a fresh ctb.log is NOT created here — the caller appends)
18
+ */
19
+ export declare function rotateIfNeeded(filePath: string, config?: RotationConfig): void;
20
+ //# sourceMappingURL=log-rotator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-rotator.d.ts","sourceRoot":"","sources":["../../../../src/server/services/log-rotator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,gBAAgB,EAAE,cAG9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,cAAiC,GACxC,IAAI,CAmCN"}
@@ -0,0 +1,60 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export const DEFAULT_ROTATION = {
4
+ maxBytes: 2 * 1024 * 1024, // 2 MB
5
+ maxFiles: 25,
6
+ };
7
+ /**
8
+ * Rotate a log file if it exceeds `config.maxBytes`.
9
+ *
10
+ * Rotation scheme (e.g. for ctb.log):
11
+ * ctb.24.log → deleted
12
+ * ctb.23.log → ctb.24.log
13
+ * ...
14
+ * ctb.1.log → ctb.2.log
15
+ * ctb.log → ctb.1.log
16
+ * (a fresh ctb.log is NOT created here — the caller appends)
17
+ */
18
+ export function rotateIfNeeded(filePath, config = DEFAULT_ROTATION) {
19
+ let size;
20
+ try {
21
+ const stat = fs.statSync(filePath);
22
+ size = stat.size;
23
+ }
24
+ catch {
25
+ // File does not exist yet — nothing to rotate.
26
+ return;
27
+ }
28
+ if (size < config.maxBytes)
29
+ return;
30
+ const dir = path.dirname(filePath);
31
+ const ext = path.extname(filePath); // .log
32
+ const base = path.basename(filePath, ext); // ctb
33
+ // Shift numbered files: N → N+1. Delete the oldest if at maxFiles.
34
+ for (let i = config.maxFiles; i >= 1; i--) {
35
+ const src = path.join(dir, `${base}.${i}${ext}`);
36
+ if (i === config.maxFiles) {
37
+ // Delete the oldest file
38
+ try {
39
+ fs.unlinkSync(src);
40
+ }
41
+ catch { /* noop */ }
42
+ }
43
+ else {
44
+ const dst = path.join(dir, `${base}.${i + 1}${ext}`);
45
+ try {
46
+ fs.renameSync(src, dst);
47
+ }
48
+ catch { /* noop */ }
49
+ }
50
+ }
51
+ // Move current file → .1
52
+ const firstRotated = path.join(dir, `${base}.1${ext}`);
53
+ try {
54
+ fs.renameSync(filePath, firstRotated);
55
+ }
56
+ catch {
57
+ // If rename fails, continue — the caller will append to the same file.
58
+ }
59
+ }
60
+ //# sourceMappingURL=log-rotator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-rotator.js","sourceRoot":"","sources":["../../../../src/server/services/log-rotator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAS7B,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAG,OAAO;IACnC,QAAQ,EAAE,EAAE;CACb,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,SAAyB,gBAAgB;IAEzC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;QAC/C,OAAO;IACT,CAAC;IAED,IAAI,IAAI,GAAG,MAAM,CAAC,QAAQ;QAAE,OAAO;IAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAW,OAAO;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAK,MAAM;IAErD,oEAAoE;IACpE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC1B,yBAAyB;YACzB,IAAI,CAAC;gBAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC;gBAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ILogger, LogLevel } from '../interfaces/logger.js';
2
+ export declare class JsonLogger implements ILogger {
3
+ private readonly level;
4
+ private readonly baseAttrs;
5
+ private readonly writeFn;
6
+ private readonly logFilePath;
7
+ constructor(level?: LogLevel, baseAttrs?: Record<string, unknown>, writeFn?: (line: string) => void, logFilePath?: string);
8
+ debug(msg: string, attrs?: Record<string, unknown>): void;
9
+ info(msg: string, attrs?: Record<string, unknown>): void;
10
+ warn(msg: string, attrs?: Record<string, unknown>): void;
11
+ error(msg: string, attrs?: Record<string, unknown>): void;
12
+ child(attrs: Record<string, unknown>): ILogger;
13
+ private log;
14
+ }
15
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/server/services/logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAiBjE,qBAAa,UAAW,YAAW,OAAO;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAG/C,KAAK,GAAE,QAAiB,EACxB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACvC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAChC,WAAW,CAAC,EAAE,MAAM;IAYtB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIzD,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAI9C,OAAO,CAAC,GAAG;CAyBZ"}
@@ -0,0 +1,69 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { rotateIfNeeded, DEFAULT_ROTATION } from './log-rotator.js';
4
+ const LOG_LEVEL_ORDER = {
5
+ debug: 0,
6
+ info: 1,
7
+ warn: 2,
8
+ error: 3,
9
+ };
10
+ const LOG_LEVEL_LABEL = {
11
+ debug: 'DEBUG',
12
+ info: 'INFO',
13
+ warn: 'WARN',
14
+ error: 'ERROR',
15
+ };
16
+ export class JsonLogger {
17
+ level;
18
+ baseAttrs;
19
+ writeFn;
20
+ logFilePath;
21
+ constructor(level = 'info', baseAttrs = {}, writeFn, logFilePath) {
22
+ this.level = level;
23
+ this.baseAttrs = baseAttrs;
24
+ this.writeFn = writeFn ?? ((line) => process.stderr.write(line + '\n'));
25
+ this.logFilePath = logFilePath;
26
+ if (logFilePath) {
27
+ fs.mkdirSync(path.dirname(logFilePath), { recursive: true });
28
+ }
29
+ }
30
+ debug(msg, attrs) {
31
+ this.log('debug', msg, attrs);
32
+ }
33
+ info(msg, attrs) {
34
+ this.log('info', msg, attrs);
35
+ }
36
+ warn(msg, attrs) {
37
+ this.log('warn', msg, attrs);
38
+ }
39
+ error(msg, attrs) {
40
+ this.log('error', msg, attrs);
41
+ }
42
+ child(attrs) {
43
+ return new JsonLogger(this.level, { ...this.baseAttrs, ...attrs }, this.writeFn, this.logFilePath);
44
+ }
45
+ log(level, msg, attrs) {
46
+ if (LOG_LEVEL_ORDER[level] < LOG_LEVEL_ORDER[this.level]) {
47
+ return;
48
+ }
49
+ const entry = {
50
+ ...this.baseAttrs,
51
+ ...attrs,
52
+ time: new Date().toISOString(),
53
+ level: LOG_LEVEL_LABEL[level],
54
+ msg,
55
+ };
56
+ const line = JSON.stringify(entry);
57
+ this.writeFn(line);
58
+ if (this.logFilePath) {
59
+ try {
60
+ fs.appendFileSync(this.logFilePath, line + '\n');
61
+ rotateIfNeeded(this.logFilePath, DEFAULT_ROTATION);
62
+ }
63
+ catch {
64
+ // Best-effort file logging — do not crash the process.
65
+ }
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../src/server/services/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IRunner, RunCallbacks } from '../interfaces/runner.js';
2
+ import type { IWorkspaceBuilder } from '../interfaces/workspace.js';
3
+ import type { ILogger } from '../interfaces/logger.js';
4
+ import type { Provider, Scenario, Run } from '../types/index.js';
5
+ export declare class ScenarioRunner implements IRunner {
6
+ private readonly workspace;
7
+ private readonly logger;
8
+ constructor(workspace: IWorkspaceBuilder, logger: ILogger);
9
+ executeRun(provider: Provider, scenario: Scenario, run: Run, callbacks: RunCallbacks, externalAbortController?: AbortController): Promise<Run>;
10
+ private findResultMessage;
11
+ }
12
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../../src/server/services/runner.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAoC,MAAM,mBAAmB,CAAC;AAwBnG,qBAAa,cAAe,YAAW,OAAO;IAE1C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,OAAO;IAG5B,UAAU,CACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,YAAY,EACvB,uBAAuB,CAAC,EAAE,eAAe,GACxC,OAAO,CAAC,GAAG,CAAC;IAqIf,OAAO,CAAC,iBAAiB;CAW1B"}
@@ -0,0 +1,161 @@
1
+ // ---------------------------------------------------------------------------
2
+ // ScenarioRunner — executes a single run via the Claude Agent SDK
3
+ // ---------------------------------------------------------------------------
4
+ import { query } from '@anthropic-ai/claude-agent-sdk';
5
+ import { buildRunEnv } from './env-builder.js';
6
+ import { buildAgentsMap, buildMcpMap } from './agent-mapper.js';
7
+ // ---------------------------------------------------------------------------
8
+ // Thinking config conversion
9
+ // ---------------------------------------------------------------------------
10
+ function toSDKThinking(cfg) {
11
+ if (!cfg)
12
+ return undefined;
13
+ switch (cfg.kind) {
14
+ case 'adaptive':
15
+ return { type: 'adaptive' };
16
+ case 'enabled':
17
+ return { type: 'enabled', budgetTokens: cfg.budgetTokens };
18
+ case 'disabled':
19
+ return { type: 'disabled' };
20
+ }
21
+ }
22
+ // ---------------------------------------------------------------------------
23
+ // Implementation
24
+ // ---------------------------------------------------------------------------
25
+ export class ScenarioRunner {
26
+ workspace;
27
+ logger;
28
+ constructor(workspace, logger) {
29
+ this.workspace = workspace;
30
+ this.logger = logger;
31
+ }
32
+ async executeRun(provider, scenario, run, callbacks, externalAbortController) {
33
+ const startTime = Date.now();
34
+ const messages = [];
35
+ const abortController = externalAbortController ?? new AbortController();
36
+ let timeoutId;
37
+ let ws;
38
+ try {
39
+ // Create workspace first — timeout starts only after workspace is ready
40
+ ws = await this.workspace.createWorkspace(scenario);
41
+ // Set up timeout after workspace creation succeeds
42
+ const timeoutMs = provider.timeoutSeconds * 1000;
43
+ timeoutId = setTimeout(() => abortController.abort(), timeoutMs);
44
+ callbacks.onStatusChange('running');
45
+ // Build SDK options — provider/model/thinking/effort from provider, agent config from scenario
46
+ const env = buildRunEnv(provider.provider);
47
+ const agents = await buildAgentsMap(scenario.subagents);
48
+ const mcpServers = buildMcpMap(scenario.mcpServers);
49
+ const options = {
50
+ cwd: ws.workspacePath,
51
+ model: provider.provider.model,
52
+ env,
53
+ settingSources: ['project'],
54
+ permissionMode: scenario.permissionMode,
55
+ allowDangerouslySkipPermissions: scenario.permissionMode === 'bypassPermissions',
56
+ sandbox: { enabled: true, autoAllowBashIfSandboxed: true },
57
+ persistSession: false,
58
+ abortController,
59
+ maxTurns: scenario.maxTurns,
60
+ thinking: toSDKThinking(provider.thinking),
61
+ effort: provider.effort === 'none' ? undefined : provider.effort,
62
+ };
63
+ if (scenario.allowedTools && scenario.allowedTools.length > 0) {
64
+ options.allowedTools = [...scenario.allowedTools];
65
+ }
66
+ if (scenario.disallowedTools && scenario.disallowedTools.length > 0) {
67
+ options.disallowedTools = [...scenario.disallowedTools];
68
+ }
69
+ if (Object.keys(agents).length > 0) {
70
+ options.agents = agents;
71
+ }
72
+ if (Object.keys(mcpServers).length > 0) {
73
+ options.mcpServers = mcpServers;
74
+ }
75
+ // Execute query
76
+ const q = query({ prompt: scenario.prompt, options });
77
+ for await (const msg of q) {
78
+ const record = {
79
+ timestamp: new Date().toISOString(),
80
+ message: msg,
81
+ };
82
+ messages.push(record);
83
+ callbacks.onMessage(record);
84
+ }
85
+ // Find result message
86
+ const resultMsg = this.findResultMessage(messages);
87
+ const durationMs = Date.now() - startTime;
88
+ if (resultMsg && resultMsg.subtype === 'success') {
89
+ const successResult = resultMsg;
90
+ const completedRun = {
91
+ ...run,
92
+ status: 'completed',
93
+ messages,
94
+ resultText: successResult.result ?? '',
95
+ totalCostUsd: successResult.total_cost_usd ?? 0,
96
+ durationMs,
97
+ numTurns: successResult.num_turns ?? 0,
98
+ updatedAt: new Date().toISOString(),
99
+ };
100
+ callbacks.onStatusChange('completed');
101
+ return completedRun;
102
+ }
103
+ // Error result
104
+ const errorResult = resultMsg;
105
+ const failedRun = {
106
+ ...run,
107
+ status: 'failed',
108
+ messages,
109
+ resultText: '',
110
+ totalCostUsd: errorResult?.total_cost_usd ?? 0,
111
+ durationMs,
112
+ numTurns: errorResult?.num_turns ?? 0,
113
+ error: errorResult?.errors?.join('; ') ?? 'Unknown error — no result message',
114
+ updatedAt: new Date().toISOString(),
115
+ };
116
+ callbacks.onStatusChange('failed');
117
+ return failedRun;
118
+ }
119
+ catch (err) {
120
+ const durationMs = Date.now() - startTime;
121
+ const errorMessage = err instanceof Error ? err.message : String(err);
122
+ const isAbort = abortController.signal.aborted;
123
+ const errorRun = {
124
+ ...run,
125
+ status: isAbort ? 'cancelled' : 'failed',
126
+ messages,
127
+ resultText: '',
128
+ totalCostUsd: 0,
129
+ durationMs,
130
+ numTurns: 0,
131
+ error: isAbort ? `Timeout after ${provider.timeoutSeconds}s` : errorMessage,
132
+ updatedAt: new Date().toISOString(),
133
+ };
134
+ callbacks.onStatusChange(errorRun.status);
135
+ return errorRun;
136
+ }
137
+ finally {
138
+ if (timeoutId !== undefined)
139
+ clearTimeout(timeoutId);
140
+ if (ws) {
141
+ await ws.cleanup().catch((cleanupErr) => {
142
+ this.logger.warn('Failed to clean up workspace', {
143
+ runId: run.id,
144
+ error: String(cleanupErr),
145
+ });
146
+ });
147
+ }
148
+ }
149
+ }
150
+ // ─── Helpers ────────────────────────────────────────────────────────
151
+ findResultMessage(messages) {
152
+ for (let i = messages.length - 1; i >= 0; i--) {
153
+ const msg = messages[i].message;
154
+ if (msg['type'] === 'result') {
155
+ return msg;
156
+ }
157
+ }
158
+ return undefined;
159
+ }
160
+ }
161
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../src/server/services/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { IStorage } from '../interfaces/storage.js';
2
+ import type { ILogger } from '../interfaces/logger.js';
3
+ /** Seed storage with example scenarios and providers when empty. */
4
+ export declare function seedIfEmpty(storage: IStorage, logger: ILogger): Promise<void>;
5
+ //# sourceMappingURL=seeder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeder.d.ts","sourceRoot":"","sources":["../../../../src/server/services/seeder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA8CvD,oEAAoE;AACpE,wBAAsB,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCnF"}
@@ -0,0 +1,79 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Seed files that ship with the project under docs/schemas/.
5
+ * Each entry maps a source file to the storage method used to persist it.
6
+ * Seeding only runs when the respective list is empty — existing data is never overwritten.
7
+ */
8
+ const SEED_SCENARIOS = [
9
+ 'scenario-baseline.example.json',
10
+ 'scenario-with-claude-md.example.json',
11
+ 'scenario-carwash-baseline.example.json',
12
+ 'scenario-carwash-with-claude-md.example.json',
13
+ 'scenario-negative-analysis-baseline.example.json',
14
+ 'scenario-negative-analysis-with-claude-md.example.json',
15
+ 'scenario-golden-rules-baseline.example.json',
16
+ 'scenario-golden-rules-with-claude-md.example.json',
17
+ ];
18
+ const SEED_PROVIDERS = [
19
+ 'provider-oauth.example.json',
20
+ 'provider-api.example.json',
21
+ ];
22
+ function resolveSchemasDir() {
23
+ // Try common locations: relative to cwd, relative to this file's compiled location
24
+ const candidates = [
25
+ path.join(process.cwd(), 'docs', 'schemas'),
26
+ path.join(process.cwd(), '..', 'docs', 'schemas'),
27
+ ];
28
+ for (const dir of candidates) {
29
+ if (fs.existsSync(dir))
30
+ return dir;
31
+ }
32
+ return candidates[0]; // fallback
33
+ }
34
+ function loadJsonFile(filePath) {
35
+ try {
36
+ const raw = fs.readFileSync(filePath, 'utf-8');
37
+ return JSON.parse(raw);
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ }
43
+ /** Seed storage with example scenarios and providers when empty. */
44
+ export async function seedIfEmpty(storage, logger) {
45
+ const schemasDir = resolveSchemasDir();
46
+ // Seed scenarios
47
+ const existingScenarios = await storage.listScenarios();
48
+ if (existingScenarios.length === 0) {
49
+ let seeded = 0;
50
+ for (const file of SEED_SCENARIOS) {
51
+ const scenario = loadJsonFile(path.join(schemasDir, file));
52
+ if (scenario) {
53
+ await storage.saveScenario(scenario);
54
+ seeded++;
55
+ logger.info('Seeded scenario', { name: scenario.name, id: scenario.id });
56
+ }
57
+ }
58
+ if (seeded === 0) {
59
+ logger.info('No seed scenarios found in ' + schemasDir);
60
+ }
61
+ }
62
+ // Seed providers
63
+ const existingProviders = await storage.listProviders();
64
+ if (existingProviders.length === 0) {
65
+ let seeded = 0;
66
+ for (const file of SEED_PROVIDERS) {
67
+ const provider = loadJsonFile(path.join(schemasDir, file));
68
+ if (provider) {
69
+ await storage.saveProvider(provider);
70
+ seeded++;
71
+ logger.info('Seeded provider', { name: provider.name, id: provider.id });
72
+ }
73
+ }
74
+ if (seeded === 0) {
75
+ logger.info('No seed providers found in ' + schemasDir);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=seeder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeder.js","sourceRoot":"","sources":["../../../../src/server/services/seeder.ts"],"names":[],"mappings":"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"}