@jevitate/cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. package/README.md +23 -0
  2. package/dist/ai-cli.js +40 -30
  3. package/dist/ai-cli.js.map +1 -1
  4. package/dist/author-journey-cli.d.ts +4 -0
  5. package/dist/author-journey-cli.js +109 -0
  6. package/dist/author-journey-cli.js.map +1 -0
  7. package/dist/bin.js +58077 -22454
  8. package/dist/bin.js.map +1 -1
  9. package/dist/browser-run-options.d.ts +58 -0
  10. package/dist/browser-run-options.js +106 -0
  11. package/dist/browser-run-options.js.map +1 -0
  12. package/dist/build-info.generated.d.ts +2 -0
  13. package/dist/build-info.generated.js +10 -0
  14. package/dist/build-info.generated.js.map +1 -0
  15. package/dist/check-api.d.ts +5 -0
  16. package/dist/check-api.js +233 -0
  17. package/dist/check-api.js.map +1 -0
  18. package/dist/check-budget.d.ts +26 -0
  19. package/dist/check-budget.js +89 -0
  20. package/dist/check-budget.js.map +1 -0
  21. package/dist/check-cli.d.ts +31 -0
  22. package/dist/check-cli.js +109 -0
  23. package/dist/check-cli.js.map +1 -0
  24. package/dist/check-execute.d.ts +25 -0
  25. package/dist/check-execute.js +385 -0
  26. package/dist/check-execute.js.map +1 -0
  27. package/dist/check-plan.d.ts +113 -0
  28. package/dist/check-plan.js +448 -0
  29. package/dist/check-plan.js.map +1 -0
  30. package/dist/check-suite.d.ts +171 -0
  31. package/dist/check-suite.js +515 -0
  32. package/dist/check-suite.js.map +1 -0
  33. package/dist/check-types.d.ts +181 -0
  34. package/dist/check-types.js +35 -0
  35. package/dist/check-types.js.map +1 -0
  36. package/dist/cli-args.d.ts +26 -0
  37. package/dist/cli-args.js +50 -0
  38. package/dist/cli-args.js.map +1 -0
  39. package/dist/cli-output.d.ts +102 -0
  40. package/dist/cli-output.js +516 -0
  41. package/dist/cli-output.js.map +1 -0
  42. package/dist/cli-reference.d.ts +3 -0
  43. package/dist/cli-reference.js +81 -0
  44. package/dist/cli-reference.js.map +1 -0
  45. package/dist/cli-refusal.d.ts +12 -0
  46. package/dist/cli-refusal.js +52 -0
  47. package/dist/cli-refusal.js.map +1 -0
  48. package/dist/cli-shared.d.ts +330 -0
  49. package/dist/cli-shared.js +492 -0
  50. package/dist/cli-shared.js.map +1 -0
  51. package/dist/cli-surface.d.ts +33 -0
  52. package/dist/cli-surface.js +48 -0
  53. package/dist/cli-surface.js.map +1 -0
  54. package/dist/conversation-options.d.ts +15 -0
  55. package/dist/conversation-options.js +10 -0
  56. package/dist/conversation-options.js.map +1 -0
  57. package/dist/credentials-file.d.ts +15 -0
  58. package/dist/credentials-file.js +56 -0
  59. package/dist/credentials-file.js.map +1 -0
  60. package/dist/data-dir.d.ts +1 -1
  61. package/dist/data-dir.js +1 -1
  62. package/dist/defect-evidence.d.ts +141 -0
  63. package/dist/defect-evidence.js +502 -0
  64. package/dist/defect-evidence.js.map +1 -0
  65. package/dist/demo-aspect-api.d.ts +209 -0
  66. package/dist/demo-aspect-api.js +397 -0
  67. package/dist/demo-aspect-api.js.map +1 -0
  68. package/dist/demo-aspect-cli.d.ts +3 -0
  69. package/dist/demo-aspect-cli.js +241 -0
  70. package/dist/demo-aspect-cli.js.map +1 -0
  71. package/dist/demo-capture.d.ts +108 -0
  72. package/dist/demo-capture.js +438 -0
  73. package/dist/demo-capture.js.map +1 -0
  74. package/dist/engine.d.ts +35 -0
  75. package/dist/engine.js +25 -0
  76. package/dist/engine.js.map +1 -0
  77. package/dist/environments.d.ts +155 -0
  78. package/dist/environments.js +364 -0
  79. package/dist/environments.js.map +1 -0
  80. package/dist/exit-codes.d.ts +46 -0
  81. package/dist/exit-codes.js +91 -0
  82. package/dist/exit-codes.js.map +1 -0
  83. package/dist/explore-adversarial.d.ts +137 -0
  84. package/dist/explore-adversarial.js +218 -0
  85. package/dist/explore-adversarial.js.map +1 -0
  86. package/dist/explore-api.d.ts +7 -187
  87. package/dist/explore-api.js +7 -301
  88. package/dist/explore-api.js.map +1 -1
  89. package/dist/explore-author.d.ts +79 -0
  90. package/dist/explore-author.js +86 -0
  91. package/dist/explore-author.js.map +1 -0
  92. package/dist/explore-cli.d.ts +7 -0
  93. package/dist/explore-cli.js +963 -0
  94. package/dist/explore-cli.js.map +1 -0
  95. package/dist/explore-coverage.d.ts +158 -0
  96. package/dist/explore-coverage.js +240 -0
  97. package/dist/explore-coverage.js.map +1 -0
  98. package/dist/explore-feature.d.ts +127 -0
  99. package/dist/explore-feature.js +220 -0
  100. package/dist/explore-feature.js.map +1 -0
  101. package/dist/explore-goal.d.ts +253 -0
  102. package/dist/explore-goal.js +374 -0
  103. package/dist/explore-goal.js.map +1 -0
  104. package/dist/explore-shared.d.ts +152 -0
  105. package/dist/explore-shared.js +129 -0
  106. package/dist/explore-shared.js.map +1 -0
  107. package/dist/explore-specs.d.ts +53 -0
  108. package/dist/explore-specs.js +333 -0
  109. package/dist/explore-specs.js.map +1 -0
  110. package/dist/findings-filing.d.ts +64 -0
  111. package/dist/findings-filing.js +108 -0
  112. package/dist/findings-filing.js.map +1 -0
  113. package/dist/fixture-auth.d.ts +52 -0
  114. package/dist/fixture-auth.js +82 -0
  115. package/dist/fixture-auth.js.map +1 -0
  116. package/dist/fixture-cli.d.ts +70 -0
  117. package/dist/fixture-cli.js +178 -0
  118. package/dist/fixture-cli.js.map +1 -0
  119. package/dist/github-issue-filer.d.ts +62 -0
  120. package/dist/github-issue-filer.js +188 -0
  121. package/dist/github-issue-filer.js.map +1 -0
  122. package/dist/host-health-run.d.ts +24 -0
  123. package/dist/host-health-run.js +27 -0
  124. package/dist/host-health-run.js.map +1 -0
  125. package/dist/http-5xx-outcome.d.ts +6 -0
  126. package/dist/http-5xx-outcome.js +39 -0
  127. package/dist/http-5xx-outcome.js.map +1 -0
  128. package/dist/inbox-cli.d.ts +7 -0
  129. package/dist/inbox-cli.js +197 -0
  130. package/dist/inbox-cli.js.map +1 -0
  131. package/dist/index.d.ts +1 -0
  132. package/dist/index.js +1 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/init-cli.d.ts +4 -0
  135. package/dist/init-cli.js +127 -0
  136. package/dist/init-cli.js.map +1 -0
  137. package/dist/init-keys.d.ts +19 -2
  138. package/dist/init-keys.js +15 -4
  139. package/dist/init-keys.js.map +1 -1
  140. package/dist/init-next-steps.d.ts +35 -0
  141. package/dist/init-next-steps.js +79 -0
  142. package/dist/init-next-steps.js.map +1 -0
  143. package/dist/invariants-file.d.ts +34 -0
  144. package/dist/invariants-file.js +68 -0
  145. package/dist/invariants-file.js.map +1 -0
  146. package/dist/invariants-validate.d.ts +30 -0
  147. package/dist/invariants-validate.js +105 -0
  148. package/dist/invariants-validate.js.map +1 -0
  149. package/dist/journey-annotate-api.d.ts +76 -0
  150. package/dist/journey-annotate-api.js +256 -0
  151. package/dist/journey-annotate-api.js.map +1 -0
  152. package/dist/journey-annotate-cli.d.ts +9 -0
  153. package/dist/journey-annotate-cli.js +179 -0
  154. package/dist/journey-annotate-cli.js.map +1 -0
  155. package/dist/journey-api.d.ts +79 -2
  156. package/dist/journey-api.js +136 -19
  157. package/dist/journey-api.js.map +1 -1
  158. package/dist/journey-cli.d.ts +4 -0
  159. package/dist/journey-cli.js +370 -0
  160. package/dist/journey-cli.js.map +1 -0
  161. package/dist/journey-demo-api.d.ts +112 -0
  162. package/dist/journey-demo-api.js +392 -0
  163. package/dist/journey-demo-api.js.map +1 -0
  164. package/dist/journey-demo-cli.d.ts +10 -0
  165. package/dist/journey-demo-cli.js +155 -0
  166. package/dist/journey-demo-cli.js.map +1 -0
  167. package/dist/kill-signal.d.ts +193 -0
  168. package/dist/kill-signal.js +284 -0
  169. package/dist/kill-signal.js.map +1 -0
  170. package/dist/launch-armed.d.ts +37 -0
  171. package/dist/launch-armed.js +31 -0
  172. package/dist/launch-armed.js.map +1 -0
  173. package/dist/ledger-api.d.ts +106 -0
  174. package/dist/ledger-api.js +237 -0
  175. package/dist/ledger-api.js.map +1 -0
  176. package/dist/ledger-cli.d.ts +18 -0
  177. package/dist/ledger-cli.js +107 -0
  178. package/dist/ledger-cli.js.map +1 -0
  179. package/dist/load-api.d.ts +29 -11
  180. package/dist/load-api.js +23 -15
  181. package/dist/load-api.js.map +1 -1
  182. package/dist/load-cli.d.ts +4 -0
  183. package/dist/load-cli.js +97 -0
  184. package/dist/load-cli.js.map +1 -0
  185. package/dist/log-correlation.d.ts +147 -0
  186. package/dist/log-correlation.js +325 -0
  187. package/dist/log-correlation.js.map +1 -0
  188. package/dist/log-lines.d.ts +131 -0
  189. package/dist/log-lines.js +389 -0
  190. package/dist/log-lines.js.map +1 -0
  191. package/dist/log-sources.d.ts +71 -0
  192. package/dist/log-sources.js +235 -0
  193. package/dist/log-sources.js.map +1 -0
  194. package/dist/logs-cli.d.ts +3 -0
  195. package/dist/logs-cli.js +51 -0
  196. package/dist/logs-cli.js.map +1 -0
  197. package/dist/logs-retention.d.ts +28 -0
  198. package/dist/logs-retention.js +84 -0
  199. package/dist/logs-retention.js.map +1 -0
  200. package/dist/mcp-api.d.ts +89 -1
  201. package/dist/mcp-api.js +472 -18
  202. package/dist/mcp-api.js.map +1 -1
  203. package/dist/mcp-args.d.ts +38 -0
  204. package/dist/mcp-args.js +131 -0
  205. package/dist/mcp-args.js.map +1 -0
  206. package/dist/mcp-cli-bridge.d.ts +34 -0
  207. package/dist/mcp-cli-bridge.js +62 -0
  208. package/dist/mcp-cli-bridge.js.map +1 -0
  209. package/dist/mcp-cli-runner.d.ts +29 -0
  210. package/dist/mcp-cli-runner.js +44 -0
  211. package/dist/mcp-cli-runner.js.map +1 -0
  212. package/dist/mcp-cli-tools.d.ts +125 -0
  213. package/dist/mcp-cli-tools.js +680 -0
  214. package/dist/mcp-cli-tools.js.map +1 -0
  215. package/dist/mcp-paths.d.ts +28 -0
  216. package/dist/mcp-paths.js +76 -0
  217. package/dist/mcp-paths.js.map +1 -0
  218. package/dist/mission-actors.d.ts +40 -0
  219. package/dist/mission-actors.js +72 -0
  220. package/dist/mission-actors.js.map +1 -0
  221. package/dist/mission-api.d.ts +35 -0
  222. package/dist/mission-api.js +58 -2
  223. package/dist/mission-api.js.map +1 -1
  224. package/dist/mission-cli.d.ts +4 -0
  225. package/dist/mission-cli.js +247 -0
  226. package/dist/mission-cli.js.map +1 -0
  227. package/dist/mission-exit.d.ts +22 -0
  228. package/dist/mission-exit.js +26 -0
  229. package/dist/mission-exit.js.map +1 -0
  230. package/dist/mission-fixtures.d.ts +225 -0
  231. package/dist/mission-fixtures.js +828 -0
  232. package/dist/mission-fixtures.js.map +1 -0
  233. package/dist/mission-journal.d.ts +60 -0
  234. package/dist/mission-journal.js +115 -0
  235. package/dist/mission-journal.js.map +1 -0
  236. package/dist/mission-queue-cli.d.ts +10 -0
  237. package/dist/mission-queue-cli.js +198 -0
  238. package/dist/mission-queue-cli.js.map +1 -0
  239. package/dist/mission-queue-runner.d.ts +126 -0
  240. package/dist/mission-queue-runner.js +397 -0
  241. package/dist/mission-queue-runner.js.map +1 -0
  242. package/dist/multi-run-cli.d.ts +37 -0
  243. package/dist/multi-run-cli.js +110 -0
  244. package/dist/multi-run-cli.js.map +1 -0
  245. package/dist/multi-run.d.ts +339 -0
  246. package/dist/multi-run.js +619 -0
  247. package/dist/multi-run.js.map +1 -0
  248. package/dist/openrouter-call.d.ts +22 -0
  249. package/dist/openrouter-call.js +63 -0
  250. package/dist/openrouter-call.js.map +1 -0
  251. package/dist/profile-cli.d.ts +4 -0
  252. package/dist/profile-cli.js +57 -0
  253. package/dist/profile-cli.js.map +1 -0
  254. package/dist/program.d.ts +3 -75
  255. package/dist/program.js +119 -1921
  256. package/dist/program.js.map +1 -1
  257. package/dist/project-dir.d.ts +96 -0
  258. package/dist/project-dir.js +220 -0
  259. package/dist/project-dir.js.map +1 -0
  260. package/dist/record-api.d.ts +10 -6
  261. package/dist/record-api.js +39 -28
  262. package/dist/record-api.js.map +1 -1
  263. package/dist/record-cli.d.ts +4 -0
  264. package/dist/record-cli.js +64 -0
  265. package/dist/record-cli.js.map +1 -0
  266. package/dist/recording-cli.d.ts +4 -0
  267. package/dist/recording-cli.js +248 -0
  268. package/dist/recording-cli.js.map +1 -0
  269. package/dist/regression-api.d.ts +101 -0
  270. package/dist/regression-api.js +384 -5
  271. package/dist/regression-api.js.map +1 -1
  272. package/dist/regression-cli.d.ts +4 -0
  273. package/dist/regression-cli.js +232 -0
  274. package/dist/regression-cli.js.map +1 -0
  275. package/dist/report-api.d.ts +146 -0
  276. package/dist/report-api.js +430 -0
  277. package/dist/report-api.js.map +1 -0
  278. package/dist/report-cli.d.ts +12 -0
  279. package/dist/report-cli.js +147 -0
  280. package/dist/report-cli.js.map +1 -0
  281. package/dist/result-schema.d.ts +22 -0
  282. package/dist/result-schema.js +28 -0
  283. package/dist/result-schema.js.map +1 -0
  284. package/dist/run-index.d.ts +29 -0
  285. package/dist/run-index.js +70 -0
  286. package/dist/run-index.js.map +1 -0
  287. package/dist/run-screenshots.d.ts +123 -0
  288. package/dist/run-screenshots.js +229 -0
  289. package/dist/run-screenshots.js.map +1 -0
  290. package/dist/runtime-env.d.ts +8 -0
  291. package/dist/runtime-env.js +22 -0
  292. package/dist/runtime-env.js.map +1 -0
  293. package/dist/secret-args.d.ts +23 -0
  294. package/dist/secret-args.js +45 -0
  295. package/dist/secret-args.js.map +1 -0
  296. package/dist/serve-cli.d.ts +4 -0
  297. package/dist/serve-cli.js +95 -0
  298. package/dist/serve-cli.js.map +1 -0
  299. package/dist/server-log-verify.d.ts +34 -0
  300. package/dist/server-log-verify.js +115 -0
  301. package/dist/server-log-verify.js.map +1 -0
  302. package/dist/session-check.d.ts +14 -0
  303. package/dist/session-check.js +44 -0
  304. package/dist/session-check.js.map +1 -0
  305. package/dist/site-cli.d.ts +4 -0
  306. package/dist/site-cli.js +127 -0
  307. package/dist/site-cli.js.map +1 -0
  308. package/dist/site-gate-cli.d.ts +28 -0
  309. package/dist/site-gate-cli.js +58 -0
  310. package/dist/site-gate-cli.js.map +1 -0
  311. package/dist/source-api.js +18 -3
  312. package/dist/source-api.js.map +1 -1
  313. package/dist/source-cli.d.ts +4 -0
  314. package/dist/source-cli.js +284 -0
  315. package/dist/source-cli.js.map +1 -0
  316. package/dist/source-run-api.d.ts +27 -1
  317. package/dist/source-run-api.js +22 -11
  318. package/dist/source-run-api.js.map +1 -1
  319. package/dist/storage-state-snapshot.d.ts +50 -0
  320. package/dist/storage-state-snapshot.js +87 -0
  321. package/dist/storage-state-snapshot.js.map +1 -0
  322. package/dist/suite-explore-options.d.ts +289 -0
  323. package/dist/suite-explore-options.js +140 -0
  324. package/dist/suite-explore-options.js.map +1 -0
  325. package/dist/target-config.d.ts +109 -0
  326. package/dist/target-config.js +216 -0
  327. package/dist/target-config.js.map +1 -0
  328. package/dist/transcript-file.d.ts +12 -0
  329. package/dist/transcript-file.js +23 -0
  330. package/dist/transcript-file.js.map +1 -0
  331. package/dist/ui-api.d.ts +3 -0
  332. package/dist/ui-api.js +7 -1
  333. package/dist/ui-api.js.map +1 -1
  334. package/dist/usability-capture.d.ts +43 -0
  335. package/dist/usability-capture.js +326 -0
  336. package/dist/usability-capture.js.map +1 -0
  337. package/dist/usage-config.d.ts +36 -0
  338. package/dist/usage-config.js +114 -0
  339. package/dist/usage-config.js.map +1 -0
  340. package/dist/ux-api.d.ts +3 -75
  341. package/dist/ux-api.js +3 -220
  342. package/dist/ux-api.js.map +1 -1
  343. package/dist/ux-cli.d.ts +4 -0
  344. package/dist/ux-cli.js +102 -0
  345. package/dist/ux-cli.js.map +1 -0
  346. package/dist/ux-config.d.ts +29 -0
  347. package/dist/ux-config.js +103 -0
  348. package/dist/ux-config.js.map +1 -0
  349. package/dist/ux-evidence.d.ts +54 -0
  350. package/dist/ux-evidence.js +197 -0
  351. package/dist/ux-evidence.js.map +1 -0
  352. package/dist/ux-review.d.ts +112 -0
  353. package/dist/ux-review.js +151 -0
  354. package/dist/ux-review.js.map +1 -0
  355. package/dist/ux-usability.d.ts +238 -0
  356. package/dist/ux-usability.js +494 -0
  357. package/dist/ux-usability.js.map +1 -0
  358. package/dist/verify-fix-api.d.ts +173 -0
  359. package/dist/verify-fix-api.js +454 -0
  360. package/dist/verify-fix-api.js.map +1 -0
  361. package/dist/verify-fix-cli.d.ts +4 -0
  362. package/dist/verify-fix-cli.js +110 -0
  363. package/dist/verify-fix-cli.js.map +1 -0
  364. package/package.json +19 -14
  365. package/skills/jevitate-ci-check/SKILL.md +77 -0
  366. package/skills/jevitate-demo/SKILL.md +61 -0
  367. package/skills/jevitate-explore/SKILL.md +88 -87
  368. package/skills/jevitate-getting-started/SKILL.md +88 -0
  369. package/skills/jevitate-load-test/SKILL.md +11 -2
  370. package/skills/jevitate-mission-scope/SKILL.md +19 -11
  371. package/skills/jevitate-record/SKILL.md +23 -5
  372. package/skills/jevitate-run-journey/SKILL.md +61 -17
  373. package/skills/jevitate-sources/SKILL.md +57 -14
  374. package/skills/jevitate-ux-review/SKILL.md +106 -16
  375. package/skills/jevitate-verify-fix/SKILL.md +76 -0
@@ -0,0 +1,397 @@
1
+ import { existsSync } from "node:fs";
2
+ import { hostname } from "node:os";
3
+ import { basename } from "node:path";
4
+ import { validateInvariantSpec } from "@jevitate/recording";
5
+ import { resolveEmulation } from "@jevitate/playwright";
6
+ import { targetAllowlist, } from "@jevitate/missions";
7
+ import { CLI_ADVERSARIAL_STRATEGIES, runAdversarialCliMission, runCoverageMission, runExploration, runFeatureCliMission, } from "./explore-api.js";
8
+ import { parseSecretField, secretFieldSecrets } from "@jevitate/explore";
9
+ import { runWithMissionKillListener } from "./kill-signal.js";
10
+ import { resolveTargetConfig } from "./target-config.js";
11
+ import { parseLogSourceSpecs } from "./log-sources.js";
12
+ import { parseLogDefectSpecs, parseLogIgnoreSpecs } from "./log-correlation.js";
13
+ import { buildMissionFixtures, checkSetupRefs } from "./fixture-cli.js";
14
+ import { substituteSetupRefs } from "./mission-fixtures.js";
15
+ /** `<dir>/<stem>.result.json` → `<stem>`: the id `get_mission_result` takes. */
16
+ export function resultIdFromPath(resultPath) {
17
+ const name = basename(resultPath);
18
+ return name.endsWith(".result.json") ? name.slice(0, -".result.json".length) : name;
19
+ }
20
+ /** Strategies that need the judgment/generation gateways (every one but the model-free feature mission). */
21
+ export function needsModel(mission) {
22
+ return mission.strategy !== "feature" && !(mission.strategy === "goal-based" && mission.feature !== undefined);
23
+ }
24
+ /**
25
+ * Drains every mission currently `queued`, oldest first, one at a time. A mission another drain
26
+ * already claimed is left alone. Never throws for a single mission: its failure is recorded on its
27
+ * queue record (`failed` + `error`) and the drain moves on.
28
+ */
29
+ export async function drainMissionQueue(opts) {
30
+ const now = opts.nowIso ?? (() => new Date().toISOString());
31
+ const self = opts.owner ?? { pid: process.pid, host: hostname() };
32
+ const recovered = await recoverOrphans(opts, self, now);
33
+ const queued = (await opts.queue.list())
34
+ .filter((m) => m.status === "queued")
35
+ .sort((a, b) => a.enqueuedAtIso.localeCompare(b.enqueuedAtIso));
36
+ const ran = [];
37
+ const skipped = [];
38
+ for (const candidate of queued) {
39
+ const accepted = opts.accepts?.(candidate) ?? true;
40
+ if (accepted !== true) {
41
+ skipped.push({ missionId: candidate.id, reason: accepted });
42
+ continue;
43
+ }
44
+ if (!(await opts.queue.claim(candidate.id, { ...self, claimedAtIso: now() })))
45
+ continue; // another drain owns it
46
+ const mission = await opts.queue.get(candidate.id);
47
+ if (mission === null || mission.status !== "queued")
48
+ continue;
49
+ const running = { ...mission, status: "running", startedAtIso: now() };
50
+ await opts.queue.update(running);
51
+ let drained;
52
+ // Killed mid-mission (SIGTERM/SIGINT): the kill switch writes the run's partial `inconclusive`
53
+ // result; record it on the queue record in the same synchronous turn, so the mission reads as
54
+ // done-with-that-result rather than `running` forever.
55
+ // Scoped to THIS item: with several missions in one process, a kill records each queue item
56
+ // with its own mission's result, never another's.
57
+ const onKilled = ({ resultPath, exitCode }) => {
58
+ opts.queue.updateSync({
59
+ ...running,
60
+ status: "done",
61
+ finishedAtIso: now(),
62
+ resultId: resultIdFromPath(resultPath),
63
+ missionOutcome: "inconclusive",
64
+ exitCode,
65
+ });
66
+ };
67
+ try {
68
+ const target = await opts.targets.resolve(mission.target); // promoted-only, re-checked at run time
69
+ const run = await runWithMissionKillListener(onKilled, () => opts.execute({ mission: running, target, allowlist: targetAllowlist(target) }));
70
+ const resultId = resultIdFromPath(run.resultPath);
71
+ await opts.queue.update({
72
+ ...running,
73
+ status: "done",
74
+ finishedAtIso: now(),
75
+ resultId,
76
+ missionOutcome: run.missionOutcome,
77
+ ...(run.goalOutcome === undefined ? {} : { goalOutcome: run.goalOutcome }),
78
+ exitCode: run.exitCode,
79
+ });
80
+ drained = {
81
+ missionId: mission.id,
82
+ strategy: mission.strategy,
83
+ status: "done",
84
+ resultId,
85
+ missionOutcome: run.missionOutcome,
86
+ ...(run.goalOutcome === undefined ? {} : { goalOutcome: run.goalOutcome }),
87
+ exitCode: run.exitCode,
88
+ };
89
+ }
90
+ catch (err) {
91
+ const error = err instanceof Error ? err.message : String(err);
92
+ await opts.queue.update({ ...running, status: "failed", finishedAtIso: now(), error });
93
+ drained = { missionId: mission.id, strategy: mission.strategy, status: "failed", error };
94
+ }
95
+ ran.push(drained);
96
+ opts.onMission?.(drained);
97
+ }
98
+ return { ran, recovered, skipped };
99
+ }
100
+ /** Default: 12h — well past any bounded mission (stall timeouts, action caps), short of a lost week. */
101
+ const ORPHAN_AFTER_MS = 12 * 60 * 60 * 1000;
102
+ function processAlive(pid) {
103
+ try {
104
+ process.kill(pid, 0);
105
+ return true;
106
+ }
107
+ catch (err) {
108
+ // EPERM: it exists, owned by another user. Only ESRCH means it is gone.
109
+ return !(typeof err === "object" && err !== null && "code" in err && err.code === "ESRCH");
110
+ }
111
+ }
112
+ /**
113
+ * A drain that dies hard (SIGKILL, OOM, reboot) leaves its mission `running` forever, and
114
+ * `get_mission_result` would tell an agent to poll again indefinitely. Before claiming new work,
115
+ * a drain records such missions `failed`: when the claiming process on this host is gone, or —
116
+ * when that cannot be checked (another host, a claim from before owners were recorded) — once the
117
+ * mission has been running longer than `orphanAfterMs`. Never re-run: it may already have sent
118
+ * writes; the error says to enqueue it again.
119
+ */
120
+ async function recoverOrphans(opts, self, now) {
121
+ const isAlive = opts.isAlive ?? processAlive;
122
+ const orphanAfterMs = opts.orphanAfterMs ?? ORPHAN_AFTER_MS;
123
+ const out = [];
124
+ for (const m of await opts.queue.list()) {
125
+ if (m.status !== "running")
126
+ continue;
127
+ const owner = await opts.queue.claimOwner(m.id);
128
+ if (owner !== null && owner.host === self.host && owner.pid === self.pid)
129
+ continue; // this drain's own
130
+ const checkable = owner !== null && owner.host === self.host;
131
+ const startedMs = Date.parse(m.startedAtIso ?? owner?.claimedAtIso ?? m.enqueuedAtIso);
132
+ const dead = checkable ? !isAlive(owner.pid) : Date.parse(now()) - startedMs > orphanAfterMs;
133
+ if (!dead)
134
+ continue;
135
+ const who = owner === null ? "its drain" : `its drain (pid ${owner.pid} on ${owner.host})`;
136
+ const error = checkable
137
+ ? `${who} stopped without finishing it; it was not re-run, since it may already have sent writes — enqueue it again to retry`
138
+ : `${who} has not finished it after ${Math.round(orphanAfterMs / 3_600_000)}h; recorded failed, not re-run, since it may already have sent writes — enqueue it again to retry`;
139
+ await opts.queue.update({ ...m, status: "failed", finishedAtIso: now(), error });
140
+ out.push({ missionId: m.id, error });
141
+ }
142
+ return out;
143
+ }
144
+ /**
145
+ * #175: a queued mission never carries a credential (a `QueuedMission` cannot name a path or a
146
+ * secret), so its session is only ever the OPERATOR's: the mission target record (`mission target
147
+ * add|update --storage-state/--save-storage-state/--secret-field`) first, then the
148
+ * `~/.jevitate/targets.json` entry for the target's origin — field by field. `saveStorageState: true`
149
+ * writes back to the effective `storageState`, so the next queued mission (they run one at a time)
150
+ * starts from the rotated session. Throws — the caller records a `failed` mission — when the
151
+ * declared file is missing or a variable is unset (naming the path or variable, never a value);
152
+ * never silently runs logged out.
153
+ */
154
+ function queuedAuth(target, targets, env, persona) {
155
+ let config = {};
156
+ if (targets !== undefined) {
157
+ try {
158
+ config = resolveTargetConfig(targets, new URL(target.baseUrl).origin);
159
+ }
160
+ catch {
161
+ config = {};
162
+ }
163
+ }
164
+ // #255: a queued persona NAME selects the operator's `personas.<name>` session for this origin
165
+ // (targets.json) — it wins over the target's default session. Unknown: the mission fails, never
166
+ // silently runs as the default user.
167
+ if (persona !== undefined) {
168
+ const p = config.personas?.[persona];
169
+ if (p === undefined) {
170
+ const known = Object.keys(config.personas ?? {});
171
+ throw new Error(`persona '${persona}' is not declared for ${target.authorizedOrigin} in ~/.jevitate/targets.json (personas)` +
172
+ (known.length === 0 ? "" : ` — known personas: ${known.join(", ")}`));
173
+ }
174
+ if (p.storageState !== undefined && !existsSync(p.storageState)) {
175
+ throw new Error(`targets.json persona '${persona}' for ${target.authorizedOrigin}: storageState not found: ${p.storageState}`);
176
+ }
177
+ const secretFields = (p.secretFields ?? []).map((s) => parseSecretField(s, "value", env));
178
+ return {
179
+ ...(p.storageState === undefined ? {} : { storageState: p.storageState }),
180
+ secretFields,
181
+ ...(config.fixtures === undefined ? {} : { fixtures: config.fixtures }),
182
+ };
183
+ }
184
+ const fromRecord = target.storageState !== undefined;
185
+ const storageState = target.storageState ?? config.storageState;
186
+ if (storageState !== undefined && !existsSync(storageState)) {
187
+ throw new Error(`${fromRecord ? `mission target ${target.id}` : `targets.json entry for ${target.authorizedOrigin}`}: storageState not found: ${storageState}`);
188
+ }
189
+ const save = target.saveStorageState ?? config.saveStorageState;
190
+ if (save === true && storageState === undefined)
191
+ throw new Error(`mission target ${target.id}: saveStorageState needs a storageState to write back to`);
192
+ const saveStorageState = save === true ? storageState : save;
193
+ const secretFields = (target.secretFields ?? config.secretFields ?? []).map((s) => parseSecretField(s, "value", env));
194
+ return {
195
+ ...(storageState === undefined ? {} : { storageState }),
196
+ ...(saveStorageState === undefined ? {} : { saveStorageState }),
197
+ secretFields,
198
+ ...(config.fixtures === undefined ? {} : { fixtures: config.fixtures }),
199
+ };
200
+ }
201
+ /** The operator's targets.json config for `baseUrl`'s origin, or undefined when there is no targets file. */
202
+ function targetConfigFor(targets, baseUrl) {
203
+ if (targets === undefined)
204
+ return undefined;
205
+ try {
206
+ return resolveTargetConfig(targets, new URL(baseUrl).origin);
207
+ }
208
+ catch {
209
+ return undefined;
210
+ }
211
+ }
212
+ /** The operator-declared `--log-source`/`--log-defect` for one origin, already parsed (#142 follow-up).
213
+ * Throws (via `parseLogSourceSpecs`/`parseLogDefectSpecs`) on a malformed targets.json entry — the
214
+ * caller's existing per-mission try/catch turns that into a `failed` queue record, never a crash. */
215
+ export function serverLogFromTargetConfig(targets, baseUrl) {
216
+ if (targets === undefined)
217
+ return undefined;
218
+ let origin;
219
+ try {
220
+ origin = new URL(baseUrl).origin;
221
+ }
222
+ catch {
223
+ return undefined;
224
+ }
225
+ const config = resolveTargetConfig(targets, origin);
226
+ if ((config.logSources?.length ?? 0) === 0 && (config.logDefect?.length ?? 0) === 0)
227
+ return undefined;
228
+ const allowLogCmd = config.allowLogCmd === true;
229
+ return {
230
+ sources: parseLogSourceSpecs(config.logSources ?? [], allowLogCmd),
231
+ logDefect: parseLogDefectSpecs(config.logDefect ?? []),
232
+ allowLogCmd,
233
+ quietOk: config.logQuietOk ?? [],
234
+ logIgnore: parseLogIgnoreSpecs(config.logIgnore ?? []),
235
+ };
236
+ }
237
+ /**
238
+ * Maps a queued mission onto the runner its strategy uses on the CLI. The start URL is the
239
+ * target's `baseUrl`; `route` is an in-scope glob for coverage/adversarial/feature.
240
+ */
241
+ export function realQueuedMissionExecutor(opts) {
242
+ const common = {
243
+ outDir: opts.outDir,
244
+ ...(opts.browserPortFactory === undefined ? {} : { browserPortFactory: opts.browserPortFactory }),
245
+ ...(opts.browser === undefined ? {} : { browser: opts.browser }),
246
+ };
247
+ return async ({ mission, target, allowlist }) => {
248
+ const bounds = mission.budget;
249
+ // Re-checked against the target as it is NOW (its origins may have changed since the enqueue):
250
+ // a probe may only ever read one of the run's own authorized origins.
251
+ if (mission.invariants !== undefined) {
252
+ validateInvariantSpec(mission.invariants, { allowlist, baseUrl: target.baseUrl });
253
+ }
254
+ const invariants = mission.invariants === undefined ? {} : { invariants: mission.invariants };
255
+ const routeGlobs = mission.route === undefined ? [] : [mission.route];
256
+ const serverLog = serverLogFromTargetConfig(opts.targets, target.baseUrl);
257
+ const withServerLog = serverLog === undefined ? {} : { serverLog };
258
+ // The operator's targets.json entry for this origin — safety (deny/paid/allowDestructive/
259
+ // readRequests/hangReplayWrites), settle, hangs, timing — applies to a queued mission exactly as
260
+ // to `explore` on the CLI. Never from the request.
261
+ const config = targetConfigFor(opts.targets, target.baseUrl);
262
+ const withTarget = config === undefined ? {} : { target: config };
263
+ const withSafety = config?.safety === undefined ? {} : { safety: config.safety };
264
+ // #175: the operator's session for this target (never the request's): every strategy starts
265
+ // from its storage state; a goal mission also types its secret fields and runs its fixtures.
266
+ const auth = queuedAuth(target, opts.targets, opts.env ?? process.env, mission.persona);
267
+ const withStorageState = {
268
+ ...(auth.storageState === undefined ? {} : { storageState: auth.storageState }),
269
+ ...(auth.saveStorageState === undefined ? {} : { saveStorageState: auth.saveStorageState }),
270
+ };
271
+ // #149: per-mission viewport/device emulation. `MissionRequestSchema` already refused an
272
+ // unknown --device / viewport+device together at enqueue time; `resolveEmulation` here is a
273
+ // second, defense-in-depth check — refused BEFORE any browser opens — since a device could in
274
+ // principle have been dropped from Playwright's registry between enqueue and drain.
275
+ const missionEmulation = mission.viewport === undefined && mission.device === undefined
276
+ ? undefined
277
+ : {
278
+ ...(mission.viewport === undefined ? {} : { viewport: mission.viewport }),
279
+ ...(mission.device === undefined ? {} : { device: mission.device }),
280
+ };
281
+ if (missionEmulation !== undefined)
282
+ resolveEmulation(missionEmulation);
283
+ const withEmulation = missionEmulation === undefined ? {} : { emulation: missionEmulation };
284
+ // #255: the media a queued mission asked for — always next to its result (a request never names
285
+ // a path), still headless and overlay-free.
286
+ const withMedia = {
287
+ ...(mission.recordVideo === true ? { browser: { ...opts.browser, recordVideo: {} } } : {}),
288
+ ...(mission.screenshots === undefined ? {} : { screenshots: { mode: mission.screenshots } }),
289
+ ...(mission.evidenceVideo === true ? { evidenceVideo: true } : {}),
290
+ };
291
+ if (mission.strategy === "feature" || (mission.strategy === "goal-based" && mission.feature !== undefined)) {
292
+ const r = await runFeatureCliMission({
293
+ ...common,
294
+ seedUrl: target.baseUrl,
295
+ allowlist,
296
+ capability: mission.feature,
297
+ routeGlobs,
298
+ bounds,
299
+ ...invariants,
300
+ ...withSafety,
301
+ ...withServerLog,
302
+ ...withEmulation,
303
+ ...withStorageState,
304
+ ...withMedia,
305
+ });
306
+ return { resultPath: r.resultPath, missionOutcome: r.missionOutcome, exitCode: r.exitCode };
307
+ }
308
+ if (mission.strategy === "goal-based" && mission.goal === undefined) {
309
+ throw new Error("a goal-based mission with only a route has no runner: queue it as strategy coverage or adversarial with that route");
310
+ }
311
+ const { judge, gen, usage } = await opts.gateways();
312
+ if (mission.strategy === "coverage" || mission.strategy === "exploratory") {
313
+ const r = await runCoverageMission({
314
+ ...common,
315
+ strategy: mission.strategy,
316
+ url: target.baseUrl,
317
+ allowlist,
318
+ judge,
319
+ gen,
320
+ usage,
321
+ bounds,
322
+ ...(routeGlobs.length > 0 ? { routeGlobs } : {}),
323
+ ...invariants,
324
+ ...withTarget,
325
+ ...withServerLog,
326
+ ...withEmulation,
327
+ ...withStorageState,
328
+ ...withMedia,
329
+ });
330
+ return { resultPath: r.resultPath, missionOutcome: r.missionOutcome, exitCode: r.exitCode };
331
+ }
332
+ if (mission.strategy === "adversarial") {
333
+ const r = await runAdversarialCliMission({
334
+ ...common,
335
+ seedUrl: target.baseUrl,
336
+ allowlist,
337
+ strategies: CLI_ADVERSARIAL_STRATEGIES,
338
+ judgment: judge,
339
+ generation: gen,
340
+ usage,
341
+ bounds,
342
+ ...(routeGlobs.length > 0 ? { routeGlobs } : {}),
343
+ ...invariants,
344
+ ...withTarget,
345
+ ...withServerLog,
346
+ ...withEmulation,
347
+ ...withStorageState,
348
+ ...withMedia,
349
+ });
350
+ return { resultPath: r.resultPath, missionOutcome: r.outcome, exitCode: r.exitCode };
351
+ }
352
+ // A goal mission runs the target's fixtures around it (authenticated from the same session and
353
+ // secret fields; validated before any browser) — as `explore --fixtures` does on the CLI.
354
+ const fx = buildMissionFixtures({}, {
355
+ allowlist,
356
+ baseUrl: target.baseUrl,
357
+ ...(auth.storageState === undefined ? {} : { storageState: auth.storageState }),
358
+ secretFields: auth.secretFields,
359
+ secrets: secretFieldSecrets(auth.secretFields),
360
+ ...(auth.fixtures === undefined ? {} : { targetFixtures: auth.fixtures }),
361
+ });
362
+ let goal = mission.goal;
363
+ checkSetupRefs({ goal }, fx);
364
+ try {
365
+ // A failed setup throws (`fixture setup failed: …`, redacted): the mission is recorded
366
+ // `failed` and never runs on unknown state.
367
+ if (fx !== undefined) {
368
+ await fx.setup();
369
+ goal = substituteSetupRefs(goal, fx.bindings(), { where: "goal" });
370
+ }
371
+ const r = await runExploration({
372
+ ...common,
373
+ url: target.baseUrl,
374
+ goal,
375
+ ...(mission.successAssertion === undefined ? {} : { successAssertion: mission.successAssertion }),
376
+ allowlist,
377
+ judge,
378
+ gen,
379
+ usage,
380
+ bounds,
381
+ ...invariants,
382
+ ...withTarget,
383
+ ...withServerLog,
384
+ ...withEmulation,
385
+ ...withStorageState,
386
+ ...withMedia,
387
+ ...(auth.secretFields.length === 0 ? {} : { secretFields: auth.secretFields }),
388
+ ...(fx === undefined ? {} : { fixtures: fx }),
389
+ });
390
+ return { resultPath: r.resultPath, missionOutcome: r.missionOutcome, goalOutcome: r.goalOutcome, exitCode: r.exitCode };
391
+ }
392
+ finally {
393
+ await fx?.restore();
394
+ }
395
+ };
396
+ }
397
+ //# sourceMappingURL=mission-queue-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mission-queue-runner.js","sourceRoot":"","sources":["../src/mission-queue-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { Command } from "commander";
2
+ import { type MultiRunPlan, type MultiRunResult, type RunEnvelope } from "./multi-run.js";
3
+ /**
4
+ * The command line a single run is re-invoked with: every option the user actually gave (source
5
+ * `cli`), minus the orchestrator's own and `omit`. Values are forwarded as given; storage-state
6
+ * CONTENTS are never read here (only their paths travel).
7
+ */
8
+ export declare function forwardedArgv(cmd: Command, omit?: ReadonlySet<string>): string[];
9
+ /** A run's own command failed before its mission could run (bad args, missing keys, …): stop the multi-run. */
10
+ export declare class MultiRunAbortedError extends Error {
11
+ readonly envelope: Extract<RunEnvelope, {
12
+ ok: false;
13
+ }>;
14
+ constructor(envelope: Extract<RunEnvelope, {
15
+ ok: false;
16
+ }>);
17
+ }
18
+ /** The last JSON envelope a run wrote (`{v, ok, …}`), or a typed failure when it wrote none. */
19
+ export declare function lastEnvelope(lines: readonly string[]): RunEnvelope;
20
+ export interface ExploreMultiRunArgs {
21
+ /** The `explore` command being run (its parsed options are forwarded). */
22
+ readonly cmd: Command;
23
+ /** A fresh, unparsed program built from the same deps. */
24
+ readonly newProgram: () => Command;
25
+ readonly plan: MultiRunPlan;
26
+ readonly strategy: string;
27
+ /** `--out`: the multi-run directory (default `~/.jevitate/multi-runs/multi-<stamp>`). */
28
+ readonly out?: string;
29
+ readonly nowIso?: () => string;
30
+ /**
31
+ * #220: what a SIGTERM/SIGINT prints for the whole multi-run (the command's own output rule: the
32
+ * envelope with --json, else the human summary) — instead of the killed run's own envelope.
33
+ * Absent: a kill prints the multi-run nothing (a library caller that owns stdout).
34
+ */
35
+ readonly killOutput?: (partial: MultiRunResult) => string;
36
+ }
37
+ export declare function runExploreMultiRun(args: ExploreMultiRunArgs): Promise<MultiRunResult>;
@@ -0,0 +1,110 @@
1
+ import { join } from "node:path";
2
+ import { logsDirFor } from "./project-dir.js";
3
+ import { artifactStamp } from "./mission-journal.js";
4
+ import { runMultiRun } from "./multi-run.js";
5
+ import { setKillSummary } from "./kill-signal.js";
6
+ /**
7
+ * The `explore --repeat/--persona` CLI glue (#141/#143): each run is the SAME `explore` command,
8
+ * re-parsed in a fresh program with the multi-run flags removed and `--out` (plus a persona's
9
+ * `--storage-state`) set per run — so every run goes through exactly the validation, gateways,
10
+ * invariants and checks a single run does, and opens its own fresh browser context.
11
+ */
12
+ /** Flags the orchestrator owns: never forwarded to an individual run. */
13
+ const MULTI_RUN_ATTRS = new Set(["repeat", "minAgreement", "persona", "personas", "out", "json"]);
14
+ /**
15
+ * The command line a single run is re-invoked with: every option the user actually gave (source
16
+ * `cli`), minus the orchestrator's own and `omit`. Values are forwarded as given; storage-state
17
+ * CONTENTS are never read here (only their paths travel).
18
+ */
19
+ export function forwardedArgv(cmd, omit = new Set()) {
20
+ const opts = cmd.opts();
21
+ const argv = [];
22
+ for (const opt of cmd.options) {
23
+ const attr = opt.attributeName();
24
+ if (opt.long === undefined || MULTI_RUN_ATTRS.has(attr) || omit.has(attr))
25
+ continue;
26
+ if (cmd.getOptionValueSource(attr) !== "cli")
27
+ continue;
28
+ const value = opts[attr];
29
+ if (opt.negate) {
30
+ if (value === false)
31
+ argv.push(opt.long);
32
+ }
33
+ else if (opt.isBoolean()) {
34
+ if (value === true)
35
+ argv.push(opt.long);
36
+ }
37
+ else if (Array.isArray(value)) {
38
+ for (const v of value)
39
+ argv.push(opt.long, String(v));
40
+ }
41
+ else if (value !== undefined) {
42
+ argv.push(opt.long, String(value));
43
+ }
44
+ }
45
+ return argv;
46
+ }
47
+ /** A run's own command failed before its mission could run (bad args, missing keys, …): stop the multi-run. */
48
+ export class MultiRunAbortedError extends Error {
49
+ envelope;
50
+ constructor(envelope) {
51
+ super(envelope.error.message);
52
+ this.envelope = envelope;
53
+ this.name = "MultiRunAbortedError";
54
+ }
55
+ }
56
+ /** The last JSON envelope a run wrote (`{v, ok, …}`), or a typed failure when it wrote none. */
57
+ export function lastEnvelope(lines) {
58
+ const text = lines.join("");
59
+ const candidates = text.split("\n").filter((l) => l.trim() !== "");
60
+ for (let i = candidates.length - 1; i >= 0; i--) {
61
+ try {
62
+ const parsed = JSON.parse(candidates[i]);
63
+ if (parsed !== null && typeof parsed === "object" && typeof parsed.ok === "boolean") {
64
+ return parsed;
65
+ }
66
+ }
67
+ catch {
68
+ // not an envelope line
69
+ }
70
+ }
71
+ return { ok: false, error: { code: "E_EXPLORE_RUN", message: "the run wrote no result envelope" } };
72
+ }
73
+ export async function runExploreMultiRun(args) {
74
+ const { cmd, plan } = args;
75
+ const outDir = args.out ?? join(logsDirFor((args.nowIso ?? (() => new Date().toISOString()))()), `multi-${artifactStamp((args.nowIso ?? (() => new Date().toISOString()))())}`);
76
+ // With personas, each run's --storage-state is the persona's; otherwise the mission's own is kept.
77
+ const base = forwardedArgv(cmd, plan.personas === null ? new Set() : new Set(["storageState"]));
78
+ return runMultiRun({
79
+ plan,
80
+ strategy: args.strategy,
81
+ outDir,
82
+ // #220: a kill writes (and prints) the multi-run's partial aggregate — the interrupted run
83
+ // included — synchronously, then the process exits 130/143 like a single run.
84
+ armKill: (onKill) => setKillSummary(({ signal, exitCode, missions }) => {
85
+ const partial = onKill({ signal, exitCode, ...(missions[0] === undefined ? {} : { partial: missions[0].partial }) });
86
+ return args.killOutput?.(partial);
87
+ }),
88
+ runOnce: async ({ storageState, outDir: runDir }) => {
89
+ const lines = [];
90
+ const child = args.newProgram();
91
+ child.exitOverride();
92
+ child.configureOutput({ writeOut: (s) => lines.push(s), writeErr: () => undefined });
93
+ const argv = ["explore", ...base, ...(storageState === undefined ? [] : ["--storage-state", storageState]), "--out", runDir, "--json"];
94
+ let envelope;
95
+ try {
96
+ await child.parseAsync(argv, { from: "user" });
97
+ envelope = lastEnvelope(lines);
98
+ }
99
+ catch (err) {
100
+ envelope = { ok: false, error: { code: "E_EXPLORE_RUN", message: String(err instanceof Error ? err.message : err) } };
101
+ }
102
+ // A command-level failure (arguments, AI setup, an unauthorized target) repeats identically on
103
+ // every run: stop instead of recording N copies of it. A run that broke mid-mission is kept.
104
+ if (!envelope.ok && envelope.error.code !== "E_EXPLORE_RUN")
105
+ throw new MultiRunAbortedError(envelope);
106
+ return envelope;
107
+ },
108
+ });
109
+ }
110
+ //# sourceMappingURL=multi-run-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-run-cli.js","sourceRoot":"","sources":["../src/multi-run-cli.ts"],"names":[],"mappings":"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"}