@jevitate/cli 0.1.0 → 0.3.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 (410) hide show
  1. package/README.md +23 -0
  2. package/dist/ai-cli.d.ts +31 -11
  3. package/dist/ai-cli.js +131 -88
  4. package/dist/ai-cli.js.map +1 -1
  5. package/dist/author-journey-cli.d.ts +4 -0
  6. package/dist/author-journey-cli.js +111 -0
  7. package/dist/author-journey-cli.js.map +1 -0
  8. package/dist/bin.js +60349 -16477
  9. package/dist/bin.js.map +1 -1
  10. package/dist/browser-run-options.d.ts +89 -0
  11. package/dist/browser-run-options.js +175 -0
  12. package/dist/browser-run-options.js.map +1 -0
  13. package/dist/build-info.generated.d.ts +2 -0
  14. package/dist/build-info.generated.js +10 -0
  15. package/dist/build-info.generated.js.map +1 -0
  16. package/dist/campaign-api.d.ts +151 -0
  17. package/dist/campaign-api.js +446 -0
  18. package/dist/campaign-api.js.map +1 -0
  19. package/dist/campaign-cli.d.ts +6 -0
  20. package/dist/campaign-cli.js +66 -0
  21. package/dist/campaign-cli.js.map +1 -0
  22. package/dist/check-api.d.ts +5 -0
  23. package/dist/check-api.js +234 -0
  24. package/dist/check-api.js.map +1 -0
  25. package/dist/check-budget.d.ts +26 -0
  26. package/dist/check-budget.js +90 -0
  27. package/dist/check-budget.js.map +1 -0
  28. package/dist/check-cli.d.ts +31 -0
  29. package/dist/check-cli.js +109 -0
  30. package/dist/check-cli.js.map +1 -0
  31. package/dist/check-execute.d.ts +29 -0
  32. package/dist/check-execute.js +420 -0
  33. package/dist/check-execute.js.map +1 -0
  34. package/dist/check-plan.d.ts +118 -0
  35. package/dist/check-plan.js +516 -0
  36. package/dist/check-plan.js.map +1 -0
  37. package/dist/check-suite.d.ts +184 -0
  38. package/dist/check-suite.js +540 -0
  39. package/dist/check-suite.js.map +1 -0
  40. package/dist/check-types.d.ts +181 -0
  41. package/dist/check-types.js +35 -0
  42. package/dist/check-types.js.map +1 -0
  43. package/dist/cli-args.d.ts +26 -0
  44. package/dist/cli-args.js +50 -0
  45. package/dist/cli-args.js.map +1 -0
  46. package/dist/cli-output.d.ts +106 -0
  47. package/dist/cli-output.js +563 -0
  48. package/dist/cli-output.js.map +1 -0
  49. package/dist/cli-reference.d.ts +3 -0
  50. package/dist/cli-reference.js +81 -0
  51. package/dist/cli-reference.js.map +1 -0
  52. package/dist/cli-refusal.d.ts +12 -0
  53. package/dist/cli-refusal.js +52 -0
  54. package/dist/cli-refusal.js.map +1 -0
  55. package/dist/cli-shared.d.ts +340 -0
  56. package/dist/cli-shared.js +537 -0
  57. package/dist/cli-shared.js.map +1 -0
  58. package/dist/cli-surface.d.ts +33 -0
  59. package/dist/cli-surface.js +48 -0
  60. package/dist/cli-surface.js.map +1 -0
  61. package/dist/conversation-options.d.ts +15 -0
  62. package/dist/conversation-options.js +10 -0
  63. package/dist/conversation-options.js.map +1 -0
  64. package/dist/credentials-file.d.ts +15 -0
  65. package/dist/credentials-file.js +56 -0
  66. package/dist/credentials-file.js.map +1 -0
  67. package/dist/data-dir.d.ts +1 -1
  68. package/dist/data-dir.js +1 -1
  69. package/dist/defect-evidence.d.ts +141 -0
  70. package/dist/defect-evidence.js +505 -0
  71. package/dist/defect-evidence.js.map +1 -0
  72. package/dist/demo-aspect-api.d.ts +209 -0
  73. package/dist/demo-aspect-api.js +398 -0
  74. package/dist/demo-aspect-api.js.map +1 -0
  75. package/dist/demo-aspect-cli.d.ts +3 -0
  76. package/dist/demo-aspect-cli.js +243 -0
  77. package/dist/demo-aspect-cli.js.map +1 -0
  78. package/dist/demo-capture.d.ts +142 -0
  79. package/dist/demo-capture.js +537 -0
  80. package/dist/demo-capture.js.map +1 -0
  81. package/dist/engine.d.ts +35 -0
  82. package/dist/engine.js +25 -0
  83. package/dist/engine.js.map +1 -0
  84. package/dist/environments.d.ts +155 -0
  85. package/dist/environments.js +364 -0
  86. package/dist/environments.js.map +1 -0
  87. package/dist/exit-codes.d.ts +46 -0
  88. package/dist/exit-codes.js +91 -0
  89. package/dist/exit-codes.js.map +1 -0
  90. package/dist/explore-adversarial.d.ts +144 -0
  91. package/dist/explore-adversarial.js +227 -0
  92. package/dist/explore-adversarial.js.map +1 -0
  93. package/dist/explore-api.d.ts +7 -187
  94. package/dist/explore-api.js +7 -301
  95. package/dist/explore-api.js.map +1 -1
  96. package/dist/explore-author.d.ts +79 -0
  97. package/dist/explore-author.js +86 -0
  98. package/dist/explore-author.js.map +1 -0
  99. package/dist/explore-cli.d.ts +7 -0
  100. package/dist/explore-cli.js +1199 -0
  101. package/dist/explore-cli.js.map +1 -0
  102. package/dist/explore-coverage.d.ts +173 -0
  103. package/dist/explore-coverage.js +246 -0
  104. package/dist/explore-coverage.js.map +1 -0
  105. package/dist/explore-feature.d.ts +125 -0
  106. package/dist/explore-feature.js +218 -0
  107. package/dist/explore-feature.js.map +1 -0
  108. package/dist/explore-goal.d.ts +271 -0
  109. package/dist/explore-goal.js +417 -0
  110. package/dist/explore-goal.js.map +1 -0
  111. package/dist/explore-shared.d.ts +177 -0
  112. package/dist/explore-shared.js +149 -0
  113. package/dist/explore-shared.js.map +1 -0
  114. package/dist/explore-specs.d.ts +53 -0
  115. package/dist/explore-specs.js +333 -0
  116. package/dist/explore-specs.js.map +1 -0
  117. package/dist/findings-filing.d.ts +64 -0
  118. package/dist/findings-filing.js +108 -0
  119. package/dist/findings-filing.js.map +1 -0
  120. package/dist/fixture-auth.d.ts +63 -0
  121. package/dist/fixture-auth.js +95 -0
  122. package/dist/fixture-auth.js.map +1 -0
  123. package/dist/fixture-cli.d.ts +99 -0
  124. package/dist/fixture-cli.js +292 -0
  125. package/dist/fixture-cli.js.map +1 -0
  126. package/dist/github-issue-filer.d.ts +62 -0
  127. package/dist/github-issue-filer.js +189 -0
  128. package/dist/github-issue-filer.js.map +1 -0
  129. package/dist/host-health-run.d.ts +25 -0
  130. package/dist/host-health-run.js +33 -0
  131. package/dist/host-health-run.js.map +1 -0
  132. package/dist/http-5xx-outcome.d.ts +6 -0
  133. package/dist/http-5xx-outcome.js +39 -0
  134. package/dist/http-5xx-outcome.js.map +1 -0
  135. package/dist/inbox-cli.d.ts +7 -0
  136. package/dist/inbox-cli.js +197 -0
  137. package/dist/inbox-cli.js.map +1 -0
  138. package/dist/index.d.ts +1 -0
  139. package/dist/index.js +1 -0
  140. package/dist/index.js.map +1 -1
  141. package/dist/init-cli.d.ts +4 -0
  142. package/dist/init-cli.js +156 -0
  143. package/dist/init-cli.js.map +1 -0
  144. package/dist/init-keys.d.ts +30 -2
  145. package/dist/init-keys.js +19 -5
  146. package/dist/init-keys.js.map +1 -1
  147. package/dist/init-next-steps.d.ts +35 -0
  148. package/dist/init-next-steps.js +79 -0
  149. package/dist/init-next-steps.js.map +1 -0
  150. package/dist/invariants-file.d.ts +34 -0
  151. package/dist/invariants-file.js +68 -0
  152. package/dist/invariants-file.js.map +1 -0
  153. package/dist/invariants-validate.d.ts +30 -0
  154. package/dist/invariants-validate.js +105 -0
  155. package/dist/invariants-validate.js.map +1 -0
  156. package/dist/journey-annotate-api.d.ts +76 -0
  157. package/dist/journey-annotate-api.js +269 -0
  158. package/dist/journey-annotate-api.js.map +1 -0
  159. package/dist/journey-annotate-cli.d.ts +9 -0
  160. package/dist/journey-annotate-cli.js +181 -0
  161. package/dist/journey-annotate-cli.js.map +1 -0
  162. package/dist/journey-api.d.ts +104 -2
  163. package/dist/journey-api.js +163 -20
  164. package/dist/journey-api.js.map +1 -1
  165. package/dist/journey-cli.d.ts +4 -0
  166. package/dist/journey-cli.js +411 -0
  167. package/dist/journey-cli.js.map +1 -0
  168. package/dist/journey-demo-api.d.ts +114 -0
  169. package/dist/journey-demo-api.js +405 -0
  170. package/dist/journey-demo-api.js.map +1 -0
  171. package/dist/journey-demo-cli.d.ts +10 -0
  172. package/dist/journey-demo-cli.js +158 -0
  173. package/dist/journey-demo-cli.js.map +1 -0
  174. package/dist/journey-prefix.d.ts +194 -0
  175. package/dist/journey-prefix.js +279 -0
  176. package/dist/journey-prefix.js.map +1 -0
  177. package/dist/key-report.d.ts +49 -0
  178. package/dist/key-report.js +101 -0
  179. package/dist/key-report.js.map +1 -0
  180. package/dist/kill-signal.d.ts +193 -0
  181. package/dist/kill-signal.js +283 -0
  182. package/dist/kill-signal.js.map +1 -0
  183. package/dist/launch-armed.d.ts +37 -0
  184. package/dist/launch-armed.js +31 -0
  185. package/dist/launch-armed.js.map +1 -0
  186. package/dist/ledger-api.d.ts +106 -0
  187. package/dist/ledger-api.js +239 -0
  188. package/dist/ledger-api.js.map +1 -0
  189. package/dist/ledger-cli.d.ts +18 -0
  190. package/dist/ledger-cli.js +107 -0
  191. package/dist/ledger-cli.js.map +1 -0
  192. package/dist/load-api.d.ts +29 -11
  193. package/dist/load-api.js +23 -15
  194. package/dist/load-api.js.map +1 -1
  195. package/dist/load-cli.d.ts +4 -0
  196. package/dist/load-cli.js +97 -0
  197. package/dist/load-cli.js.map +1 -0
  198. package/dist/log-correlation.d.ts +200 -0
  199. package/dist/log-correlation.js +394 -0
  200. package/dist/log-correlation.js.map +1 -0
  201. package/dist/log-lines.d.ts +131 -0
  202. package/dist/log-lines.js +389 -0
  203. package/dist/log-lines.js.map +1 -0
  204. package/dist/log-sources.d.ts +71 -0
  205. package/dist/log-sources.js +236 -0
  206. package/dist/log-sources.js.map +1 -0
  207. package/dist/log-trace.d.ts +80 -0
  208. package/dist/log-trace.js +210 -0
  209. package/dist/log-trace.js.map +1 -0
  210. package/dist/logs-cli.d.ts +3 -0
  211. package/dist/logs-cli.js +51 -0
  212. package/dist/logs-cli.js.map +1 -0
  213. package/dist/logs-retention.d.ts +28 -0
  214. package/dist/logs-retention.js +85 -0
  215. package/dist/logs-retention.js.map +1 -0
  216. package/dist/masked-input.d.ts +22 -0
  217. package/dist/masked-input.js +99 -0
  218. package/dist/masked-input.js.map +1 -0
  219. package/dist/mcp-api.d.ts +91 -1
  220. package/dist/mcp-api.js +514 -18
  221. package/dist/mcp-api.js.map +1 -1
  222. package/dist/mcp-args.d.ts +50 -0
  223. package/dist/mcp-args.js +164 -0
  224. package/dist/mcp-args.js.map +1 -0
  225. package/dist/mcp-cli-bridge.d.ts +34 -0
  226. package/dist/mcp-cli-bridge.js +62 -0
  227. package/dist/mcp-cli-bridge.js.map +1 -0
  228. package/dist/mcp-cli-runner.d.ts +29 -0
  229. package/dist/mcp-cli-runner.js +44 -0
  230. package/dist/mcp-cli-runner.js.map +1 -0
  231. package/dist/mcp-cli-tools.d.ts +129 -0
  232. package/dist/mcp-cli-tools.js +737 -0
  233. package/dist/mcp-cli-tools.js.map +1 -0
  234. package/dist/mcp-paths.d.ts +28 -0
  235. package/dist/mcp-paths.js +76 -0
  236. package/dist/mcp-paths.js.map +1 -0
  237. package/dist/mission-actors.d.ts +40 -0
  238. package/dist/mission-actors.js +72 -0
  239. package/dist/mission-actors.js.map +1 -0
  240. package/dist/mission-api.d.ts +35 -0
  241. package/dist/mission-api.js +60 -3
  242. package/dist/mission-api.js.map +1 -1
  243. package/dist/mission-cli.d.ts +4 -0
  244. package/dist/mission-cli.js +248 -0
  245. package/dist/mission-cli.js.map +1 -0
  246. package/dist/mission-exit.d.ts +22 -0
  247. package/dist/mission-exit.js +26 -0
  248. package/dist/mission-exit.js.map +1 -0
  249. package/dist/mission-fixtures.d.ts +234 -0
  250. package/dist/mission-fixtures.js +862 -0
  251. package/dist/mission-fixtures.js.map +1 -0
  252. package/dist/mission-journal.d.ts +60 -0
  253. package/dist/mission-journal.js +115 -0
  254. package/dist/mission-journal.js.map +1 -0
  255. package/dist/mission-queue-cli.d.ts +10 -0
  256. package/dist/mission-queue-cli.js +198 -0
  257. package/dist/mission-queue-cli.js.map +1 -0
  258. package/dist/mission-queue-runner.d.ts +126 -0
  259. package/dist/mission-queue-runner.js +406 -0
  260. package/dist/mission-queue-runner.js.map +1 -0
  261. package/dist/multi-run-cli.d.ts +37 -0
  262. package/dist/multi-run-cli.js +116 -0
  263. package/dist/multi-run-cli.js.map +1 -0
  264. package/dist/multi-run.d.ts +339 -0
  265. package/dist/multi-run.js +619 -0
  266. package/dist/multi-run.js.map +1 -0
  267. package/dist/openrouter-call.d.ts +22 -0
  268. package/dist/openrouter-call.js +64 -0
  269. package/dist/openrouter-call.js.map +1 -0
  270. package/dist/profile-cli.d.ts +4 -0
  271. package/dist/profile-cli.js +57 -0
  272. package/dist/profile-cli.js.map +1 -0
  273. package/dist/program.d.ts +3 -75
  274. package/dist/program.js +123 -1921
  275. package/dist/program.js.map +1 -1
  276. package/dist/project-dir.d.ts +96 -0
  277. package/dist/project-dir.js +221 -0
  278. package/dist/project-dir.js.map +1 -0
  279. package/dist/record-api.d.ts +13 -7
  280. package/dist/record-api.js +44 -30
  281. package/dist/record-api.js.map +1 -1
  282. package/dist/record-cli.d.ts +4 -0
  283. package/dist/record-cli.js +76 -0
  284. package/dist/record-cli.js.map +1 -0
  285. package/dist/recording-cli.d.ts +4 -0
  286. package/dist/recording-cli.js +248 -0
  287. package/dist/recording-cli.js.map +1 -0
  288. package/dist/regression-api.d.ts +107 -0
  289. package/dist/regression-api.js +387 -6
  290. package/dist/regression-api.js.map +1 -1
  291. package/dist/regression-cli.d.ts +4 -0
  292. package/dist/regression-cli.js +284 -0
  293. package/dist/regression-cli.js.map +1 -0
  294. package/dist/report-api.d.ts +146 -0
  295. package/dist/report-api.js +431 -0
  296. package/dist/report-api.js.map +1 -0
  297. package/dist/report-cli.d.ts +12 -0
  298. package/dist/report-cli.js +147 -0
  299. package/dist/report-cli.js.map +1 -0
  300. package/dist/resource-preflight.d.ts +87 -0
  301. package/dist/resource-preflight.js +160 -0
  302. package/dist/resource-preflight.js.map +1 -0
  303. package/dist/result-schema.d.ts +22 -0
  304. package/dist/result-schema.js +28 -0
  305. package/dist/result-schema.js.map +1 -0
  306. package/dist/run-index.d.ts +29 -0
  307. package/dist/run-index.js +70 -0
  308. package/dist/run-index.js.map +1 -0
  309. package/dist/run-key-preflight.d.ts +42 -0
  310. package/dist/run-key-preflight.js +82 -0
  311. package/dist/run-key-preflight.js.map +1 -0
  312. package/dist/run-screenshots.d.ts +123 -0
  313. package/dist/run-screenshots.js +235 -0
  314. package/dist/run-screenshots.js.map +1 -0
  315. package/dist/runtime-env.d.ts +8 -0
  316. package/dist/runtime-env.js +23 -0
  317. package/dist/runtime-env.js.map +1 -0
  318. package/dist/secret-args.d.ts +23 -0
  319. package/dist/secret-args.js +45 -0
  320. package/dist/secret-args.js.map +1 -0
  321. package/dist/serve-cli.d.ts +4 -0
  322. package/dist/serve-cli.js +95 -0
  323. package/dist/serve-cli.js.map +1 -0
  324. package/dist/server-log-verify.d.ts +36 -0
  325. package/dist/server-log-verify.js +120 -0
  326. package/dist/server-log-verify.js.map +1 -0
  327. package/dist/session-check.d.ts +14 -0
  328. package/dist/session-check.js +44 -0
  329. package/dist/session-check.js.map +1 -0
  330. package/dist/site-cli.d.ts +4 -0
  331. package/dist/site-cli.js +127 -0
  332. package/dist/site-cli.js.map +1 -0
  333. package/dist/site-gate-cli.d.ts +28 -0
  334. package/dist/site-gate-cli.js +59 -0
  335. package/dist/site-gate-cli.js.map +1 -0
  336. package/dist/source-api.js +20 -4
  337. package/dist/source-api.js.map +1 -1
  338. package/dist/source-cli.d.ts +4 -0
  339. package/dist/source-cli.js +284 -0
  340. package/dist/source-cli.js.map +1 -0
  341. package/dist/source-run-api.d.ts +27 -1
  342. package/dist/source-run-api.js +22 -11
  343. package/dist/source-run-api.js.map +1 -1
  344. package/dist/storage-state-snapshot.d.ts +50 -0
  345. package/dist/storage-state-snapshot.js +87 -0
  346. package/dist/storage-state-snapshot.js.map +1 -0
  347. package/dist/suite-explore-options.d.ts +321 -0
  348. package/dist/suite-explore-options.js +162 -0
  349. package/dist/suite-explore-options.js.map +1 -0
  350. package/dist/target-config.d.ts +115 -0
  351. package/dist/target-config.js +225 -0
  352. package/dist/target-config.js.map +1 -0
  353. package/dist/transcript-file.d.ts +12 -0
  354. package/dist/transcript-file.js +23 -0
  355. package/dist/transcript-file.js.map +1 -0
  356. package/dist/type-fixture-file.d.ts +9 -0
  357. package/dist/type-fixture-file.js +48 -0
  358. package/dist/type-fixture-file.js.map +1 -0
  359. package/dist/ui-api.d.ts +3 -0
  360. package/dist/ui-api.js +11 -4
  361. package/dist/ui-api.js.map +1 -1
  362. package/dist/usability-capture.d.ts +43 -0
  363. package/dist/usability-capture.js +327 -0
  364. package/dist/usability-capture.js.map +1 -0
  365. package/dist/usage-config.d.ts +36 -0
  366. package/dist/usage-config.js +114 -0
  367. package/dist/usage-config.js.map +1 -0
  368. package/dist/ux-api.d.ts +3 -75
  369. package/dist/ux-api.js +3 -220
  370. package/dist/ux-api.js.map +1 -1
  371. package/dist/ux-claim-probe.d.ts +45 -0
  372. package/dist/ux-claim-probe.js +386 -0
  373. package/dist/ux-claim-probe.js.map +1 -0
  374. package/dist/ux-cli.d.ts +4 -0
  375. package/dist/ux-cli.js +109 -0
  376. package/dist/ux-cli.js.map +1 -0
  377. package/dist/ux-config.d.ts +29 -0
  378. package/dist/ux-config.js +103 -0
  379. package/dist/ux-config.js.map +1 -0
  380. package/dist/ux-evidence.d.ts +54 -0
  381. package/dist/ux-evidence.js +197 -0
  382. package/dist/ux-evidence.js.map +1 -0
  383. package/dist/ux-product.d.ts +14 -0
  384. package/dist/ux-product.js +39 -0
  385. package/dist/ux-product.js.map +1 -0
  386. package/dist/ux-review.d.ts +116 -0
  387. package/dist/ux-review.js +171 -0
  388. package/dist/ux-review.js.map +1 -0
  389. package/dist/ux-usability.d.ts +263 -0
  390. package/dist/ux-usability.js +580 -0
  391. package/dist/ux-usability.js.map +1 -0
  392. package/dist/verify-fix-api.d.ts +194 -0
  393. package/dist/verify-fix-api.js +506 -0
  394. package/dist/verify-fix-api.js.map +1 -0
  395. package/dist/verify-fix-cli.d.ts +4 -0
  396. package/dist/verify-fix-cli.js +115 -0
  397. package/dist/verify-fix-cli.js.map +1 -0
  398. package/package.json +23 -18
  399. package/skills/jevitate-ci-check/SKILL.md +77 -0
  400. package/skills/jevitate-demo/SKILL.md +61 -0
  401. package/skills/jevitate-explore/SKILL.md +96 -87
  402. package/skills/jevitate-getting-started/SKILL.md +89 -0
  403. package/skills/jevitate-load-test/SKILL.md +11 -2
  404. package/skills/jevitate-mission-scope/SKILL.md +19 -11
  405. package/skills/jevitate-record/SKILL.md +23 -5
  406. package/skills/jevitate-run-journey/SKILL.md +61 -17
  407. package/skills/jevitate-sources/SKILL.md +57 -14
  408. package/skills/jevitate-test-campaign/SKILL.md +203 -0
  409. package/skills/jevitate-ux-review/SKILL.md +106 -16
  410. package/skills/jevitate-verify-fix/SKILL.md +76 -0
@@ -0,0 +1,79 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { ENVIRONMENTS_FILE, ENVIRONMENTS_SCAFFOLD } from "./project-dir.js";
4
+ const REGISTERED = new Set(["create", "update", "unchanged", "force-update"]);
5
+ /**
6
+ * The ≤5 "try this next" lines `jevitate init` prints (and returns as `data.nextSteps`). Every
7
+ * command is a real one with real flags (skills-cli-drift.test.ts checks them against the CLI);
8
+ * placeholders are `<…>` so nothing reads as a value we guessed. Tailored, never silent:
9
+ * - keys ready → a goal run, an authored Journey and a demo (all need the model gateway);
10
+ * - keys missing → the key-free adversarial run (`--fake-ai`: misuse is planned in code, the
11
+ * findings are hard signals), a human-recorded flow, and how to add the keys;
12
+ * - the agent line says whether the MCP server was registered, declined (conflict), or skipped.
13
+ */
14
+ export function initNextSteps(input) {
15
+ const url = input.appUrl ?? "<app-url>";
16
+ const env = input.env ?? "<env>";
17
+ const lines = [];
18
+ if (input.keysReady) {
19
+ lines.push(`1. try it: jevitate explore --url ${url} --goal "<a task a user does>" --success "urlIncludes:<done-path>" --real`);
20
+ lines.push(`2. keep it: jevitate explore-author-journey --url ${url} --goal "<task>" --success "<check>" --id <id> --name "<name>" --real`);
21
+ lines.push(`3. demo it: jevitate demo "<aspect>" --env ${env} --success "<check>" --real`);
22
+ }
23
+ else {
24
+ lines.push(`1. try it: jevitate explore --strategy adversarial --url ${url} --fake-ai (no keys: finds 5xx, crashes, hangs)`);
25
+ lines.push(`2. record it: jevitate record --url ${url} (you click; Enter saves a replayable Recording)`);
26
+ lines.push("3. add keys: jevitate ai setup generation && jevitate ai setup judgment (goals, Journeys, demos)");
27
+ }
28
+ lines.push("4. gate CI: jevitate check --suite <suite.json> (JUnit + SARIF; exit 1 = a gating finding)");
29
+ const agent = agentLine(input);
30
+ if (agent !== undefined)
31
+ lines.push(agent);
32
+ return lines;
33
+ }
34
+ function agentLine(input) {
35
+ const would = input.dryRun ? "would be " : "";
36
+ if (input.mcp !== undefined && input.mcp.length > 0) {
37
+ const ok = input.mcp.filter((r) => REGISTERED.has(r.action)).map((r) => r.target);
38
+ const declined = input.mcp.filter((r) => !REGISTERED.has(r.action)).map((r) => r.target);
39
+ if (ok.length > 0) {
40
+ return `agents: MCP server ${would}registered for ${ok.join(", ")}${declined.length > 0 ? ` (not ${declined.join(", ")}: see above)` : ""} — restart the agent, then ask in plain words`;
41
+ }
42
+ return `agents: MCP server NOT registered (${declined.join(", ")}: existing config kept) — rerun with --force, or: jevitate mcp --print-config claude`;
43
+ }
44
+ if (input.skills) {
45
+ return "agents: skills installed (CLI) — for MCP tools too: jevitate mcp --print-config claude|cursor|codex|json";
46
+ }
47
+ return undefined;
48
+ }
49
+ /**
50
+ * Reads `.jevitate/environments.json` for the next-steps block: the first non-production
51
+ * environment's name, and its `baseUrl` only when it is not the untouched scaffold's (so the block
52
+ * never presents the example `http://localhost:3000` as "your app"). Unreadable → nothing: the
53
+ * block keeps its `<app-url>`/`<env>` placeholders.
54
+ */
55
+ export function environmentHint(projectDir) {
56
+ if (projectDir === null)
57
+ return {};
58
+ let parsed;
59
+ try {
60
+ parsed = JSON.parse(readFileSync(join(projectDir, ENVIRONMENTS_FILE), "utf8"));
61
+ }
62
+ catch {
63
+ return {};
64
+ }
65
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
66
+ return {};
67
+ for (const [name, entry] of Object.entries(parsed)) {
68
+ if (name.startsWith("$") || entry === null || typeof entry !== "object")
69
+ continue;
70
+ const e = entry;
71
+ if (e.production === true)
72
+ continue;
73
+ const baseUrl = typeof e.baseUrl === "string" ? e.baseUrl : undefined;
74
+ const isScaffold = name === "local" && baseUrl === ENVIRONMENTS_SCAFFOLD.local.baseUrl;
75
+ return { env: name, ...(baseUrl !== undefined && !isScaffold ? { appUrl: baseUrl } : {}) };
76
+ }
77
+ return {};
78
+ }
79
+ //# sourceMappingURL=init-next-steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-next-steps.js","sourceRoot":"","sources":["../src/init-next-steps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type InvariantSpec } from "@jevitate/recording";
2
+ /**
3
+ * `--invariants <file.json>` (repeatable, #86): loads the app team's declared-invariant files,
4
+ * validates each against the closed schema, merges them, and authorizes every probe against the
5
+ * run's allowlist — all BEFORE any browser opens. A bad file refuses the dispatch with a precise
6
+ * path (`a.json: invariants[2].require: unknown observable "balanse"`), never mid-run.
7
+ */
8
+ export declare class InvariantsFileError extends Error {
9
+ readonly code: "E_EXPLORE_INVARIANTS";
10
+ /** #195: each path-precise problem on its own (`invariants[2].require: …`); the message joins them. */
11
+ readonly problems: readonly string[];
12
+ constructor(message: string, problems?: readonly string[]);
13
+ }
14
+ export interface LoadInvariantsOptions {
15
+ /**
16
+ * The run's authorized origins: every probe must resolve onto one. Omitted (with `baseUrl`) only by
17
+ * `jevitate invariants validate` without `--url` (#195): then every probe/`deniedAs` is REFUSED
18
+ * ("needs the mission's authorized origins") — nothing is ever assumed authorized.
19
+ */
20
+ readonly allowlist?: readonly string[];
21
+ /** What relative probe paths resolve against (the run's start URL). */
22
+ readonly baseUrl?: string;
23
+ /** #147: the registered observer actors (every `--actor` but the primary) cross-actor checks may name. */
24
+ readonly observers?: readonly string[];
25
+ }
26
+ /** Loads, validates and merges invariant files. Returns undefined for no files. Throws `InvariantsFileError`. */
27
+ export declare function loadInvariantFiles(paths: readonly string[], opts: LoadInvariantsOptions): InvariantSpec | undefined;
28
+ /**
29
+ * Resolves every `authFrom.secret` ref (#135, `env:VAR`) a spec's probes use, from `env` — the ONE
30
+ * place this ever happens (the CLI dispatch), matching `--secret-field`'s own `env:VAR` resolution.
31
+ * Throws `InvariantsFileError` (naming the ref, never a value) for an unset/empty variable. Returns
32
+ * a map keyed by the ref itself (`"env:APP_TOKEN"` → its value) for `InvariantMonitorOptions.authTokens`.
33
+ */
34
+ export declare function resolveInvariantAuthTokens(spec: InvariantSpec, env: Readonly<Record<string, string | undefined>>): Map<string, string>;
@@ -0,0 +1,68 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { InvariantSpecError, invariantAuthSecretRefs, mergeInvariantSpecs, validateInvariantSpec, } from "@jevitate/recording";
3
+ /**
4
+ * `--invariants <file.json>` (repeatable, #86): loads the app team's declared-invariant files,
5
+ * validates each against the closed schema, merges them, and authorizes every probe against the
6
+ * run's allowlist — all BEFORE any browser opens. A bad file refuses the dispatch with a precise
7
+ * path (`a.json: invariants[2].require: unknown observable "balanse"`), never mid-run.
8
+ */
9
+ export class InvariantsFileError extends Error {
10
+ code = "E_EXPLORE_INVARIANTS";
11
+ /** #195: each path-precise problem on its own (`invariants[2].require: …`); the message joins them. */
12
+ problems;
13
+ constructor(message, problems = [message]) {
14
+ super(message);
15
+ this.name = "InvariantsFileError";
16
+ this.problems = problems;
17
+ }
18
+ }
19
+ /** Loads, validates and merges invariant files. Returns undefined for no files. Throws `InvariantsFileError`. */
20
+ export function loadInvariantFiles(paths, opts) {
21
+ if (paths.length === 0)
22
+ return undefined;
23
+ const specs = [];
24
+ for (const path of paths) {
25
+ let raw;
26
+ try {
27
+ raw = JSON.parse(readFileSync(path, "utf8"));
28
+ }
29
+ catch (e) {
30
+ throw new InvariantsFileError(`cannot read invariants file ${path}: ${e instanceof Error ? e.message.split("\n")[0] : String(e)}`);
31
+ }
32
+ try {
33
+ specs.push(validateInvariantSpec(raw, opts));
34
+ }
35
+ catch (e) {
36
+ if (e instanceof InvariantSpecError)
37
+ throw new InvariantsFileError(`${path}: ${e.problems.join("; ")}`, e.problems);
38
+ throw e;
39
+ }
40
+ }
41
+ try {
42
+ return mergeInvariantSpecs(specs);
43
+ }
44
+ catch (e) {
45
+ if (e instanceof InvariantSpecError)
46
+ throw new InvariantsFileError(e.problems.join("; "), e.problems);
47
+ throw e;
48
+ }
49
+ }
50
+ /**
51
+ * Resolves every `authFrom.secret` ref (#135, `env:VAR`) a spec's probes use, from `env` — the ONE
52
+ * place this ever happens (the CLI dispatch), matching `--secret-field`'s own `env:VAR` resolution.
53
+ * Throws `InvariantsFileError` (naming the ref, never a value) for an unset/empty variable. Returns
54
+ * a map keyed by the ref itself (`"env:APP_TOKEN"` → its value) for `InvariantMonitorOptions.authTokens`.
55
+ */
56
+ export function resolveInvariantAuthTokens(spec, env) {
57
+ const tokens = new Map();
58
+ for (const ref of invariantAuthSecretRefs(spec)) {
59
+ const name = ref.slice("env:".length);
60
+ const value = env[name];
61
+ if (value === undefined || value === "") {
62
+ throw new InvariantsFileError(`--invariants: authFrom.secret ${ref}: environment variable ${name} is not set`);
63
+ }
64
+ tokens.set(ref, value);
65
+ }
66
+ return tokens;
67
+ }
68
+ //# sourceMappingURL=invariants-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants-file.js","sourceRoot":"","sources":["../src/invariants-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,GAEtB,MAAM,qBAAqB,CAAC;AAE7B;;;;;GAKG;AAEH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,GAAG,sBAA+B,CAAC;IAChD,uGAAuG;IAC9F,QAAQ,CAAoB;IACrC,YAAY,OAAe,EAAE,WAA8B,CAAC,OAAO,CAAC;QAClE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAeD,iHAAiH;AACjH,MAAM,UAAU,kBAAkB,CAAC,KAAwB,EAAE,IAA2B;IACtF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,mBAAmB,CAAC,+BAA+B,IAAI,KAAK,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrI,CAAC;QACD,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,kBAAkB;gBAAE,MAAM,IAAI,mBAAmB,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACpH,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,kBAAkB;YAAE,MAAM,IAAI,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtG,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,IAAmB,EACnB,GAAiD;IAEjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,mBAAmB,CAAC,iCAAiC,GAAG,0BAA0B,IAAI,aAAa,CAAC,CAAC;QACjH,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { Command } from "commander";
2
+ import { type LoadInvariantsOptions } from "./invariants-file.js";
3
+ /**
4
+ * `jevitate invariants validate <file…>` (#195): lints declared-invariant files WITHOUT a browser —
5
+ * the exact loader `explore --invariants` runs before any browser opens (`loadInvariantFiles`: the
6
+ * closed schema, expression/observable cross-references, probe and `deniedAs` origin authorization,
7
+ * the cross-file merge), so CI can gate committed invariant files. No second implementation.
8
+ *
9
+ * Probe/`deniedAs` origins are authorized only against what the caller names (`--url`, `--allow`);
10
+ * without `--url` a spec that makes network probes is refused, never assumed authorized.
11
+ */
12
+ export interface InvariantsFileResult {
13
+ readonly file: string;
14
+ readonly valid: boolean;
15
+ /** The file's declared invariants (when it validated). */
16
+ readonly invariants?: number;
17
+ /** Path-precise problems (`invariants[2].require: unknown observable "balanse"`). */
18
+ readonly problems: string[];
19
+ }
20
+ export interface InvariantsValidation {
21
+ readonly valid: boolean;
22
+ readonly files: InvariantsFileResult[];
23
+ /** Problems merging the (individually valid) files: a repeated id, an observable declared twice differently. */
24
+ readonly merge: string[];
25
+ /** How to fix an origin-authorization refusal, when one occurred. */
26
+ readonly hint?: string;
27
+ }
28
+ /** Validates each file on its own (so every file's problems are reported), then their merge. */
29
+ export declare function validateInvariantFiles(files: readonly string[], opts: LoadInvariantsOptions): InvariantsValidation;
30
+ export declare function registerInvariantsCommands(program: Command): void;
@@ -0,0 +1,105 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { emitJsonOrRefusal } from "./cli-refusal.js";
3
+ import { ok, fail } from "./envelope.js";
4
+ import { resolveExploreAllowlist } from "./explore-api.js";
5
+ import { InvariantsFileError, loadInvariantFiles } from "./invariants-file.js";
6
+ import { EXIT_CODES } from "./exit-codes.js";
7
+ const ORIGIN_HINT = "pass --url <start-url> (and --allow <origin>, repeatable) to authorize probe and deniedAs origins, as `explore --invariants` does";
8
+ /** Validates each file on its own (so every file's problems are reported), then their merge. */
9
+ export function validateInvariantFiles(files, opts) {
10
+ const results = files.map((file) => {
11
+ try {
12
+ const spec = loadInvariantFiles([file], opts);
13
+ return { file, valid: true, invariants: spec?.invariants.length ?? 0, problems: [] };
14
+ }
15
+ catch (e) {
16
+ if (!(e instanceof InvariantsFileError))
17
+ throw e;
18
+ return { file, valid: false, problems: [...e.problems] };
19
+ }
20
+ });
21
+ let merge = [];
22
+ if (files.length > 1 && results.every((r) => r.valid)) {
23
+ try {
24
+ loadInvariantFiles(files, opts);
25
+ }
26
+ catch (e) {
27
+ if (!(e instanceof InvariantsFileError))
28
+ throw e;
29
+ merge = [...e.problems];
30
+ }
31
+ }
32
+ const valid = merge.length === 0 && results.every((r) => r.valid);
33
+ const needsOrigins = results.some((r) => r.problems.some((p) => p.includes("authorized origins to be checked against")));
34
+ return { valid, files: results, merge, ...(needsOrigins ? { hint: ORIGIN_HINT } : {}) };
35
+ }
36
+ /** The envelope (success, or a refusal with --json); a refusal without --json is a human stderr line (#218). */
37
+ function emit(program, envelope, exitCode) {
38
+ emitJsonOrRefusal(program, envelope, exitCode);
39
+ }
40
+ /** The first file that cannot be read at all, with why — unusable input, refused before validating (#218). */
41
+ function unreadableFile(files) {
42
+ for (const file of files) {
43
+ try {
44
+ readFileSync(file, "utf8");
45
+ }
46
+ catch (e) {
47
+ return `cannot read invariants file ${file}: ${e instanceof Error ? e.message.split("\n")[0] : String(e)}`;
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+ const collect = (v, prev) => [...prev, v];
53
+ export function registerInvariantsCommands(program) {
54
+ const invariants = program.command("invariants").description("declared-invariant files (`explore --invariants`)");
55
+ invariants
56
+ .command("validate <files...>")
57
+ .description("validate invariant files without a browser (the same pre-browser check `explore --invariants` runs); exit 1 when any is invalid, 64 when one cannot be read")
58
+ .option("--url <url>", "the run's start URL: relative probe/deniedAs paths resolve against it, and its origin is authorized")
59
+ .option("--allow <origin>", "authorized origin (repeatable; needs --url); REPLACES the URL's own origin, as `explore --allow`", collect, [])
60
+ .option("--observer <name>", "a registered observer actor a probe `as:` / `deniedAs.actor` may name (repeatable; `explore --actor` minus the primary)", collect, [])
61
+ .option("--json", "emit a JSON envelope")
62
+ .action(function (files) {
63
+ const o = this.opts();
64
+ if (o.url === undefined && o.allow.length > 0) {
65
+ emit(program, fail("E_INVARIANTS_ARGS", "--allow needs --url (relative probe paths resolve against it)"), EXIT_CODES.usage);
66
+ return;
67
+ }
68
+ // #218: a file that cannot be read is unusable input (64, like every command), not an invalid one (1).
69
+ const unreadable = unreadableFile(files);
70
+ if (unreadable !== undefined) {
71
+ emit(program, fail("E_INVARIANTS_INPUT", unreadable), EXIT_CODES.usage);
72
+ return;
73
+ }
74
+ // Without --url nothing is authorized: the loader refuses every probe/deniedAs origin itself.
75
+ const opts = o.url === undefined
76
+ ? { observers: o.observer }
77
+ : { allowlist: resolveExploreAllowlist(o.url, o.allow), baseUrl: o.url, observers: o.observer };
78
+ const result = validateInvariantFiles(files, opts);
79
+ const exitCode = result.valid ? EXIT_CODES.ok : EXIT_CODES.defects;
80
+ if (o.json === true) {
81
+ emit(program, ok(result), exitCode);
82
+ return;
83
+ }
84
+ const lines = [];
85
+ for (const f of result.files) {
86
+ if (f.valid)
87
+ lines.push(`valid ${f.file} (${f.invariants ?? 0} invariants)`);
88
+ else {
89
+ lines.push(`invalid ${f.file}`);
90
+ for (const p of f.problems)
91
+ lines.push(` ${p}`);
92
+ }
93
+ }
94
+ if (result.merge.length > 0) {
95
+ lines.push("invalid merge of the files above");
96
+ for (const p of result.merge)
97
+ lines.push(` ${p}`);
98
+ }
99
+ if (result.hint !== undefined)
100
+ lines.push(`hint: ${result.hint}`);
101
+ program.configureOutput().writeOut?.(`${lines.join("\n")}\n`);
102
+ process.exitCode = exitCode;
103
+ });
104
+ }
105
+ //# sourceMappingURL=invariants-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants-validate.js","sourceRoot":"","sources":["../src/invariants-validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { type AnnotationChange, type AnnotationDraft, type IntentCoverage, type Journey } from "@jevitate/journey";
2
+ import { type GenerationPort } from "@jevitate/ai-core";
3
+ import { type RunJourneyProgrammaticallyOptions } from "./journey-api.js";
4
+ export declare class AnnotationDraftNotFoundError extends Error {
5
+ readonly code = "E_JOURNEY_ANNOTATIONS_NOT_FOUND";
6
+ }
7
+ export declare class InvalidAnnotationDraftError extends Error {
8
+ readonly code = "E_INVALID_ANNOTATIONS_DRAFT";
9
+ }
10
+ /** The Journey changed after the draft was made — approving would annotate steps it never saw. */
11
+ export declare class StaleAnnotationDraftError extends Error {
12
+ readonly code = "E_JOURNEY_ANNOTATIONS_STALE";
13
+ }
14
+ /**
15
+ * Where a Journey's draft lives: `<journeys>/.drafts/<id>.annotations.json` (`<ns>/<id>` for a shared
16
+ * Journey). A dot-folder, so `journey list` and namespace discovery never read it as a Journey.
17
+ */
18
+ export declare function annotationDraftPath(journeysDir: string, id: string): string;
19
+ /** The Journey's content hash — what a draft is bound to. */
20
+ export declare function journeyContentHash(journey: Journey): string;
21
+ export interface AnnotateJourneyOptions extends Omit<RunJourneyProgrammaticallyOptions, "interpreter" | "policy" | "selfHealer"> {
22
+ /** The generation gateway that drafts the text (`--real` / `--fake-ai`). */
23
+ gen: GenerationPort;
24
+ /** Testing seam for the draft's timestamp. */
25
+ now?: () => string;
26
+ }
27
+ export interface AnnotateJourneyResult {
28
+ readonly id: string;
29
+ readonly draftPath: string;
30
+ readonly replay: AnnotationDraft["replay"];
31
+ readonly drafted: {
32
+ readonly objectives: number;
33
+ readonly expectedResults: number;
34
+ readonly goal: boolean;
35
+ readonly successCriteria: number;
36
+ };
37
+ /** What approving the draft would change (the same diff `--approve` shows). */
38
+ readonly proposed: AnnotationChange[];
39
+ readonly coverage: IntentCoverage;
40
+ /** #251 `--screenshots`: the replay's masked screenshots and their `index.md`. */
41
+ readonly screenshotPaths?: string[];
42
+ readonly screenshotIndex?: string;
43
+ readonly screenshotsSkipped?: Array<{
44
+ readonly step: number;
45
+ readonly reason: string;
46
+ }>;
47
+ }
48
+ /**
49
+ * Replays the Journey through `runJourneyProgrammatically` (the same session, site policy, fixtures
50
+ * and fail-closed policy as `journey run`) with an observing interpreter, then drafts. A replay that
51
+ * stops early still drafts the steps it reached (`replay.outcome: "stopped"`).
52
+ *
53
+ * Environments (#247): every browser/session option `journey run` takes rides in `opts` and is
54
+ * handed to `runJourneyProgrammatically` unchanged — including `environment` (`--env`/`--base-url`,
55
+ * resolved by `resolveJourneyEnvironment`), so the replay is rebased and allowlisted exactly as a run.
56
+ */
57
+ export declare function annotateJourney(opts: AnnotateJourneyOptions): Promise<AnnotateJourneyResult>;
58
+ export interface ApproveAnnotationsResult {
59
+ readonly id: string;
60
+ readonly draftPath: string;
61
+ readonly changes: AnnotationChange[];
62
+ readonly coverage: IntentCoverage;
63
+ }
64
+ /** Reads and validates a Journey's draft (not found / invalid are typed refusals). */
65
+ export declare function readAnnotationDraft(dir: string, id: string): Promise<{
66
+ draft: AnnotationDraft;
67
+ draftPath: string;
68
+ }>;
69
+ /**
70
+ * The human approval gate (like `journey promote`): applies the reviewed draft to the Journey and
71
+ * removes the draft. Refuses — writing nothing — when the Journey changed since the draft was made
72
+ * (its content hash differs) or the draft names steps the Journey does not have.
73
+ */
74
+ export declare function approveJourneyAnnotations(dir: string, id: string): Promise<ApproveAnnotationsResult>;
75
+ /** `journey run`'s informational intent line (#246): how many steps say why. Never fails a run. */
76
+ export declare function journeyIntentCoverage(dir: string, id: string): Promise<IntentCoverage | undefined>;