@crvouga/atlas 0.4.0 → 0.6.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 (444) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +191 -611
  3. package/dist/bun/src/driver.d.ts +41 -7
  4. package/dist/bun/src/driver.js +47 -6
  5. package/dist/bun/src/index.d.ts +8 -0
  6. package/dist/bun/src/index.js +8 -0
  7. package/dist/core/src/cli.d.ts +14 -1
  8. package/dist/core/src/cli.js +35 -1
  9. package/dist/core/src/config.d.ts +77 -4
  10. package/dist/core/src/config.js +110 -17
  11. package/dist/core/src/events/cloudevents.d.ts +54 -9
  12. package/dist/core/src/events/cloudevents.js +60 -9
  13. package/dist/core/src/graph.d.ts +21 -0
  14. package/dist/core/src/graph.js +26 -0
  15. package/dist/core/src/index.d.ts +11 -0
  16. package/dist/core/src/index.js +11 -0
  17. package/dist/core/src/lint.d.ts +30 -0
  18. package/dist/core/src/lint.js +13 -0
  19. package/dist/core/src/plan.d.ts +39 -1
  20. package/dist/core/src/plan.js +28 -1
  21. package/dist/core/src/privacy.d.ts +29 -2
  22. package/dist/core/src/privacy.js +19 -2
  23. package/dist/core/src/report/formats.d.ts +34 -4
  24. package/dist/core/src/report/formats.js +24 -4
  25. package/dist/core/src/report/markdown.d.ts +15 -0
  26. package/dist/core/src/report/markdown.js +8 -0
  27. package/dist/core/src/run/clients.d.ts +44 -5
  28. package/dist/core/src/run/clients.js +46 -2
  29. package/dist/core/src/run/execute.d.ts +75 -16
  30. package/dist/core/src/run/execute.js +71 -18
  31. package/dist/core/src/run/frames.d.ts +13 -4
  32. package/dist/core/src/run/frames.js +19 -4
  33. package/dist/core/src/run/http.d.ts +34 -1
  34. package/dist/core/src/run/http.js +14 -1
  35. package/dist/core/src/run/types.d.ts +76 -3
  36. package/dist/core/src/run/types.js +19 -3
  37. package/dist/core/src/signals.d.ts +49 -5
  38. package/dist/core/src/signals.js +22 -5
  39. package/dist/core/src/spec/compose.d.ts +23 -1
  40. package/dist/core/src/spec/compose.js +10 -1
  41. package/dist/core/src/spec/index.d.ts +9 -1
  42. package/dist/core/src/spec/index.js +9 -1
  43. package/dist/core/src/spec/load.d.ts +22 -1
  44. package/dist/core/src/spec/load.js +31 -1
  45. package/dist/core/src/spec/parse.d.ts +16 -2
  46. package/dist/core/src/spec/parse.js +25 -2
  47. package/dist/core/src/spec/scxml.d.ts +25 -4
  48. package/dist/core/src/spec/scxml.js +36 -4
  49. package/dist/core/src/spec/types.d.ts +52 -1
  50. package/dist/core/src/spec/types.js +24 -0
  51. package/dist/detox/src/index.d.ts +54 -11
  52. package/dist/detox/src/index.js +45 -7
  53. package/dist/playwright/src/driver.d.ts +39 -3
  54. package/dist/playwright/src/driver.js +27 -3
  55. package/dist/playwright/src/index.d.ts +10 -0
  56. package/dist/playwright/src/index.js +10 -0
  57. package/dist/playwright/src/media.d.ts +50 -4
  58. package/dist/playwright/src/media.js +55 -4
  59. package/dist/playwright/src/signals.d.ts +44 -5
  60. package/dist/playwright/src/signals.js +29 -5
  61. package/dist/reports/src/attachment-files.d.ts +44 -0
  62. package/dist/reports/src/attachment-files.js +121 -0
  63. package/dist/reports/src/attachment-response.d.ts +31 -0
  64. package/dist/reports/src/attachment-response.js +55 -0
  65. package/dist/reports/src/aws-credentials.d.ts +48 -0
  66. package/dist/reports/src/aws-credentials.js +221 -0
  67. package/dist/reports/src/browser-navigation.d.ts +14 -0
  68. package/dist/reports/src/browser-navigation.js +7 -0
  69. package/dist/reports/src/bundle.d.ts +34 -2
  70. package/dist/reports/src/bundle.js +38 -2
  71. package/dist/reports/src/catalog.d.ts +34 -3
  72. package/dist/reports/src/catalog.js +17 -3
  73. package/dist/reports/src/cli-stores.d.ts +36 -0
  74. package/dist/reports/src/cli-stores.js +73 -0
  75. package/dist/reports/src/clock.d.ts +7 -2
  76. package/dist/reports/src/clock.js +5 -2
  77. package/dist/reports/src/completion-order.d.ts +18 -5
  78. package/dist/reports/src/completion-order.js +18 -5
  79. package/dist/reports/src/compose.d.ts +80 -0
  80. package/dist/reports/src/compose.js +117 -0
  81. package/dist/reports/src/copy-store.d.ts +29 -0
  82. package/dist/reports/src/copy-store.js +52 -0
  83. package/dist/reports/src/directory-outline.d.ts +38 -0
  84. package/dist/reports/src/directory-outline.js +103 -0
  85. package/dist/reports/src/directory-store.d.ts +20 -0
  86. package/dist/reports/src/directory-store.js +166 -0
  87. package/dist/reports/src/doctor.d.ts +29 -0
  88. package/dist/reports/src/doctor.js +85 -0
  89. package/dist/reports/src/effective-delta.d.ts +34 -0
  90. package/dist/reports/src/effective-delta.js +25 -0
  91. package/dist/reports/src/evidence-detail.d.ts +64 -0
  92. package/dist/reports/src/evidence-detail.js +92 -0
  93. package/dist/reports/src/evidence-live.d.ts +35 -5
  94. package/dist/reports/src/evidence-live.js +18 -2
  95. package/dist/reports/src/evidence-types.d.ts +68 -1
  96. package/dist/reports/src/evidence-types.js +5 -1
  97. package/dist/reports/src/evidence-view.d.ts +43 -4
  98. package/dist/reports/src/evidence-view.js +13 -2
  99. package/dist/reports/src/explorer-types.d.ts +40 -3
  100. package/dist/reports/src/explorer-types.js +8 -0
  101. package/dist/reports/src/explorer-versions.d.ts +9 -1
  102. package/dist/reports/src/explorer-versions.js +18 -1
  103. package/dist/reports/src/export-evidence.d.ts +16 -1
  104. package/dist/reports/src/export-evidence.js +52 -1
  105. package/dist/reports/src/fetcher.d.ts +27 -3
  106. package/dist/reports/src/fetcher.js +11 -3
  107. package/dist/reports/src/format-date.d.ts +6 -0
  108. package/dist/reports/src/format-date.js +6 -0
  109. package/dist/reports/src/format.d.ts +16 -0
  110. package/dist/reports/src/format.js +10 -0
  111. package/dist/reports/src/frames.d.ts +36 -3
  112. package/dist/reports/src/frames.js +22 -3
  113. package/dist/reports/src/hash.d.ts +18 -0
  114. package/dist/reports/src/hash.js +13 -0
  115. package/dist/reports/src/host.d.ts +29 -0
  116. package/dist/reports/src/host.js +64 -0
  117. package/dist/reports/src/html-frame.d.ts +5 -6
  118. package/dist/reports/src/html-frame.js +12 -1
  119. package/dist/reports/src/http-store.d.ts +56 -0
  120. package/dist/reports/src/http-store.js +148 -0
  121. package/dist/reports/src/http.d.ts +7 -0
  122. package/dist/reports/src/http.js +6 -0
  123. package/dist/reports/src/ingest.d.ts +54 -0
  124. package/dist/reports/src/ingest.js +210 -0
  125. package/dist/reports/src/init.d.ts +40 -0
  126. package/dist/reports/src/init.js +369 -0
  127. package/dist/reports/src/junit.d.ts +33 -6
  128. package/dist/reports/src/junit.js +87 -21
  129. package/dist/reports/src/keyboard.d.ts +20 -0
  130. package/dist/reports/src/keyboard.js +11 -0
  131. package/dist/reports/src/keys.d.ts +21 -3
  132. package/dist/reports/src/keys.js +21 -3
  133. package/dist/reports/src/layer-axes.d.ts +35 -5
  134. package/dist/reports/src/layer-axes.js +25 -5
  135. package/dist/reports/src/layer-catalog.d.ts +28 -1
  136. package/dist/reports/src/layer-catalog.js +18 -1
  137. package/dist/reports/src/layer-merge.d.ts +98 -9
  138. package/dist/reports/src/layer-merge.js +147 -31
  139. package/dist/reports/src/layer-source.d.ts +18 -0
  140. package/dist/reports/src/layer-source.js +11 -0
  141. package/dist/reports/src/layer-store.d.ts +42 -0
  142. package/dist/reports/src/layer-store.js +63 -5
  143. package/dist/reports/src/layer-types.d.ts +32 -1
  144. package/dist/reports/src/layers-route.d.ts +47 -4
  145. package/dist/reports/src/layers-route.js +86 -7
  146. package/dist/reports/src/live-reporter.d.ts +34 -0
  147. package/dist/reports/src/live-reporter.js +122 -0
  148. package/dist/reports/src/media-types.d.ts +11 -0
  149. package/dist/reports/src/media-types.js +22 -0
  150. package/dist/reports/src/namespace-guard.d.ts +10 -1
  151. package/dist/reports/src/namespace-guard.js +10 -1
  152. package/dist/reports/src/navigation.d.ts +12 -0
  153. package/dist/reports/src/navigation.js +7 -0
  154. package/dist/reports/src/object-io.d.ts +11 -4
  155. package/dist/reports/src/object-io.js +4 -4
  156. package/dist/reports/src/object-store-conformance.d.ts +27 -0
  157. package/dist/reports/src/object-store-conformance.js +87 -0
  158. package/dist/reports/src/object-store.d.ts +33 -24
  159. package/dist/reports/src/object-store.js +17 -24
  160. package/dist/reports/src/parse-with.d.ts +16 -0
  161. package/dist/reports/src/parse-with.js +14 -0
  162. package/dist/reports/src/performance-part.d.ts +25 -1
  163. package/dist/reports/src/performance-part.js +15 -1
  164. package/dist/reports/src/performance.d.ts +22 -2
  165. package/dist/reports/src/performance.js +12 -2
  166. package/dist/reports/src/persist.d.ts +12 -3
  167. package/dist/reports/src/persist.js +12 -3
  168. package/dist/reports/src/phone.d.ts +18 -1
  169. package/dist/reports/src/phone.js +18 -1
  170. package/dist/reports/src/protocol.d.ts +26 -4
  171. package/dist/reports/src/protocol.js +15 -4
  172. package/dist/reports/src/publication.d.ts +21 -1
  173. package/dist/reports/src/publication.js +21 -1
  174. package/dist/reports/src/publish-checks.d.ts +35 -0
  175. package/dist/reports/src/publish-checks.js +122 -0
  176. package/dist/reports/src/publish.d.ts +42 -9
  177. package/dist/reports/src/publish.js +36 -7
  178. package/dist/reports/src/read.d.ts +46 -16
  179. package/dist/reports/src/read.js +38 -14
  180. package/dist/reports/src/recording-bundle.d.ts +13 -2
  181. package/dist/reports/src/recording-bundle.js +4 -2
  182. package/dist/reports/src/recording-keys.d.ts +15 -1
  183. package/dist/reports/src/recording-keys.js +15 -1
  184. package/dist/reports/src/remote-report.d.ts +28 -7
  185. package/dist/reports/src/remote-report.js +15 -7
  186. package/dist/reports/src/report-cli.d.ts +51 -0
  187. package/dist/reports/src/report-cli.js +486 -0
  188. package/dist/reports/src/report-index.d.ts +99 -0
  189. package/dist/reports/src/report-index.js +337 -0
  190. package/dist/reports/src/report-loader.d.ts +10 -0
  191. package/dist/reports/src/report-loader.js +6 -0
  192. package/dist/reports/src/report-parts.d.ts +29 -3
  193. package/dist/reports/src/report-parts.js +37 -3
  194. package/dist/reports/src/report-status.d.ts +48 -0
  195. package/dist/reports/src/report-status.js +156 -0
  196. package/dist/reports/src/report-types.d.ts +73 -0
  197. package/dist/reports/src/report-types.js +3 -0
  198. package/dist/reports/src/reporter.d.ts +67 -0
  199. package/dist/reports/src/reporter.js +128 -0
  200. package/dist/reports/src/reports-explorer-route.d.ts +541 -0
  201. package/dist/reports/src/reports-explorer-route.js +11 -0
  202. package/dist/reports/src/reports-list-route.d.ts +9 -0
  203. package/dist/reports/src/reports-list-route.js +9 -0
  204. package/dist/reports/src/reports-route.d.ts +561 -22
  205. package/dist/reports/src/reports-route.js +11 -3
  206. package/dist/reports/src/reports-store.d.ts +19 -2
  207. package/dist/reports/src/reports-store.js +10 -2
  208. package/dist/reports/src/resilient-cache.d.ts +14 -1
  209. package/dist/reports/src/resilient-cache.js +8 -1
  210. package/dist/reports/src/retention.d.ts +17 -1
  211. package/dist/reports/src/retention.js +5 -1
  212. package/dist/reports/src/run-bundle.d.ts +63 -0
  213. package/dist/reports/src/run-bundle.js +159 -0
  214. package/dist/reports/src/s3-store.d.ts +79 -0
  215. package/dist/reports/src/s3-store.js +295 -0
  216. package/dist/reports/src/scenario.d.ts +14 -4
  217. package/dist/reports/src/scenario.js +5 -4
  218. package/dist/reports/src/sigv4.d.ts +72 -0
  219. package/dist/reports/src/sigv4.js +96 -0
  220. package/dist/reports/src/snapshot-bundle.d.ts +24 -1
  221. package/dist/reports/src/snapshot-bundle.js +27 -2
  222. package/dist/reports/src/snapshot-surface.d.ts +20 -9
  223. package/dist/reports/src/snapshot-surface.js +32 -19
  224. package/dist/reports/src/source-content.d.ts +23 -0
  225. package/dist/reports/src/source-content.js +30 -1
  226. package/dist/reports/src/source-entries.d.ts +13 -0
  227. package/dist/reports/src/source-entries.js +6 -0
  228. package/dist/reports/src/source-part.d.ts +15 -0
  229. package/dist/reports/src/source-part.js +8 -0
  230. package/dist/reports/src/source-reader.d.ts +11 -0
  231. package/dist/reports/src/source-reader.js +5 -0
  232. package/dist/reports/src/spec-evidence.d.ts +12 -2
  233. package/dist/reports/src/spec-evidence.js +6 -2
  234. package/dist/reports/src/spec-inventory.d.ts +15 -1
  235. package/dist/reports/src/spec-inventory.js +22 -1
  236. package/dist/reports/src/spec-link.d.ts +28 -0
  237. package/dist/reports/src/spec-link.js +70 -0
  238. package/dist/reports/src/spec-set.d.ts +63 -0
  239. package/dist/reports/src/spec-set.js +177 -0
  240. package/dist/reports/src/status.d.ts +10 -0
  241. package/dist/reports/src/status.js +5 -0
  242. package/dist/reports/src/store-prefix.d.ts +28 -0
  243. package/dist/reports/src/store-prefix.js +22 -0
  244. package/dist/reports/src/store-url.d.ts +89 -0
  245. package/dist/reports/src/store-url.js +160 -0
  246. package/dist/reports/src/test-catalog-entity.d.ts +11 -0
  247. package/dist/reports/src/test-catalog-entity.js +6 -0
  248. package/dist/reports/src/types.d.ts +6 -1
  249. package/dist/reports/src/use-report-nav.d.ts +35 -0
  250. package/dist/reports/src/use-report-nav.js +12 -0
  251. package/dist/runners/src/codecept.d.ts +14 -0
  252. package/dist/runners/src/codecept.js +16 -0
  253. package/dist/runners/src/jest.d.ts +50 -0
  254. package/dist/runners/src/jest.js +52 -0
  255. package/dist/runners/src/mocha.d.ts +40 -0
  256. package/dist/runners/src/mocha.js +39 -0
  257. package/dist/runners/src/node-test.d.ts +28 -0
  258. package/dist/runners/src/node-test.js +44 -0
  259. package/dist/runners/src/publish.d.ts +30 -0
  260. package/dist/runners/src/publish.js +68 -0
  261. package/dist/schema/src/api.d.ts +800 -0
  262. package/dist/schema/src/api.js +201 -0
  263. package/dist/schema/src/cli-results.d.ts +210 -0
  264. package/dist/schema/src/cli-results.js +124 -0
  265. package/dist/schema/src/common.d.ts +53 -0
  266. package/dist/schema/src/common.js +42 -0
  267. package/dist/schema/src/index.d.ts +16 -0
  268. package/dist/schema/src/index.js +16 -0
  269. package/dist/schema/src/layer.d.ts +2273 -0
  270. package/dist/schema/src/layer.js +462 -0
  271. package/dist/schema/src/live-run.d.ts +123 -0
  272. package/dist/schema/src/live-run.js +30 -0
  273. package/dist/schema/src/manifest.d.ts +97 -2
  274. package/dist/schema/src/manifest.js +84 -0
  275. package/dist/schema/src/project.d.ts +20 -0
  276. package/dist/schema/src/project.js +10 -0
  277. package/dist/schema/src/report-sources.d.ts +29 -0
  278. package/dist/schema/src/report-sources.js +27 -1
  279. package/dist/schema/src/runs-index.d.ts +17 -1
  280. package/dist/schema/src/runs-index.js +15 -0
  281. package/dist/schema/src/server-config.d.ts +177 -0
  282. package/dist/schema/src/server-config.js +85 -0
  283. package/dist/schema/src/spec.d.ts +69 -0
  284. package/dist/schema/src/spec.js +58 -0
  285. package/dist/server/src/app.d.ts +72 -0
  286. package/dist/server/src/app.js +557 -0
  287. package/dist/server/src/auth.d.ts +41 -0
  288. package/dist/server/src/auth.js +59 -0
  289. package/dist/server/src/config.d.ts +83 -0
  290. package/dist/server/src/config.js +204 -0
  291. package/dist/server/src/dev.d.ts +12 -0
  292. package/dist/server/src/dev.js +89 -0
  293. package/dist/server/src/events.d.ts +29 -0
  294. package/dist/server/src/events.js +101 -0
  295. package/dist/server/src/host.d.ts +30 -0
  296. package/dist/server/src/host.js +115 -0
  297. package/dist/server/src/index.d.ts +18 -0
  298. package/dist/server/src/index.js +18 -0
  299. package/dist/server/src/live-runs.d.ts +52 -0
  300. package/dist/server/src/live-runs.js +229 -0
  301. package/dist/server/src/llms.d.ts +19 -0
  302. package/dist/server/src/llms.js +63 -0
  303. package/dist/server/src/main.d.ts +30 -0
  304. package/dist/server/src/main.js +114 -0
  305. package/dist/server/src/openapi.d.ts +56 -0
  306. package/dist/server/src/openapi.js +438 -0
  307. package/dist/server/src/problem.d.ts +8 -0
  308. package/dist/server/src/problem.js +39 -0
  309. package/dist/server/src/projects.d.ts +3 -0
  310. package/dist/server/src/projects.js +154 -0
  311. package/dist/server/src/settings-page.d.ts +9 -0
  312. package/dist/server/src/settings-page.js +93 -0
  313. package/dist/server/src/settings.d.ts +23 -0
  314. package/dist/server/src/settings.js +72 -0
  315. package/dist/server/src/site.d.ts +15 -0
  316. package/dist/server/src/site.js +78 -0
  317. package/dist/server/src/store-api.d.ts +28 -0
  318. package/dist/server/src/store-api.js +180 -0
  319. package/dist/server/src/validate.d.ts +71 -0
  320. package/dist/server/src/validate.js +197 -0
  321. package/dist/vitest/src/index.d.ts +27 -5
  322. package/dist/vitest/src/index.js +18 -5
  323. package/dist/webdriver/src/driver.d.ts +63 -11
  324. package/dist/webdriver/src/driver.js +57 -6
  325. package/dist/webdriver/src/index.d.ts +8 -0
  326. package/dist/webdriver/src/index.js +1 -0
  327. package/dist/webdriver/src/protocol.d.ts +75 -6
  328. package/dist/webdriver/src/protocol.js +79 -6
  329. package/docs/agents.md +137 -0
  330. package/docs/deploying.md +345 -0
  331. package/docs/dogfooding.md +175 -0
  332. package/docs/extending.md +242 -0
  333. package/docs/integrating.md +485 -0
  334. package/docs/reference/bun.md +141 -0
  335. package/docs/reference/cli.md +148 -0
  336. package/docs/reference/core.md +2432 -0
  337. package/docs/reference/detox.md +150 -0
  338. package/docs/reference/http-api.md +799 -0
  339. package/docs/reference/playwright.md +303 -0
  340. package/docs/reference/reports.md +7152 -0
  341. package/docs/reference/runners.md +169 -0
  342. package/docs/reference/schema.md +1762 -0
  343. package/docs/reference/server.md +825 -0
  344. package/docs/reference/vitest.md +45 -0
  345. package/docs/reference/webdriver.md +330 -0
  346. package/docs/report-backends.md +144 -0
  347. package/docs/report-contract.md +400 -0
  348. package/docs/reporting-issues.md +160 -0
  349. package/docs/runners.md +69 -0
  350. package/docs/server.md +321 -0
  351. package/docs/statecharts.md +643 -0
  352. package/llms-full.txt +4114 -0
  353. package/llms.txt +49 -0
  354. package/package.json +61 -11
  355. package/packages/core/README.md +2 -1
  356. package/packages/reports/README.md +65 -0
  357. package/packages/reports/STORAGE.md +4 -0
  358. package/packages/runners/README.md +6 -0
  359. package/packages/runners/compat/codecept.cjs +2 -0
  360. package/packages/runners/compat/jest.cjs +2 -0
  361. package/packages/runners/compat/mocha.cjs +2 -0
  362. package/packages/schema/README.md +14 -0
  363. package/packages/schema/schemas/atlas-change.schema.json +4 -0
  364. package/packages/schema/schemas/check-detail.schema.json +1032 -0
  365. package/packages/schema/schemas/checks-result.schema.json +26 -0
  366. package/packages/schema/schemas/command-error.schema.json +35 -0
  367. package/packages/schema/schemas/doctor-result.schema.json +60 -0
  368. package/packages/schema/schemas/effective-delta.schema.json +490 -0
  369. package/packages/schema/schemas/effective-evidence.schema.json +471 -0
  370. package/packages/schema/schemas/evidence-page.schema.json +271 -0
  371. package/packages/schema/schemas/hello-event.schema.json +26 -0
  372. package/packages/schema/schemas/init-plan.schema.json +347 -0
  373. package/packages/schema/schemas/layer-rows.schema.json +199 -0
  374. package/packages/schema/schemas/layer.schema.json +2888 -0
  375. package/packages/schema/schemas/live-run-start.schema.json +42 -0
  376. package/packages/schema/schemas/live-run-update.schema.json +93 -0
  377. package/packages/schema/schemas/live-run.schema.json +225 -0
  378. package/packages/schema/schemas/merge-result.schema.json +40 -0
  379. package/packages/schema/schemas/outline.schema.json +62 -0
  380. package/packages/schema/schemas/problem.schema.json +37 -0
  381. package/packages/schema/schemas/project-slug.schema.json +8 -0
  382. package/packages/schema/schemas/project.schema.json +22 -0
  383. package/packages/schema/schemas/projects.schema.json +33 -0
  384. package/packages/schema/schemas/publish-checks.schema.json +1413 -0
  385. package/packages/schema/schemas/publish-result.schema.json +168 -0
  386. package/packages/schema/schemas/ready.schema.json +68 -0
  387. package/packages/schema/schemas/report-event.schema.json +100 -0
  388. package/packages/schema/schemas/report-status.schema.json +370 -0
  389. package/packages/schema/schemas/server-config.schema.json +208 -0
  390. package/packages/schema/schemas/server-editable-settings.schema.json +132 -0
  391. package/packages/schema/schemas/server-info.schema.json +114 -0
  392. package/packages/schema/schemas/server-settings-snapshot.schema.json +285 -0
  393. package/packages/schema/schemas/spec-set.schema.json +103 -0
  394. package/packages/schema/schemas/store-listing.schema.json +29 -0
  395. package/packages/schema/schemas/store-write-result.schema.json +28 -0
  396. package/packages/schema/schemas/stream-result.schema.json +59 -0
  397. package/packages/server/README.md +43 -0
  398. package/packages/server/openapi.json +11021 -0
  399. package/packages/visualizer/README.md +32 -11
  400. package/packages/visualizer/bin/atlas-client.mjs +176 -0
  401. package/packages/visualizer/bin/atlas-visualizer.mjs +2 -175
  402. package/packages/visualizer/src/app/AppShell.tsx +32 -16
  403. package/packages/visualizer/src/app/report-sources.tsx +7 -4
  404. package/packages/visualizer/src/app/router.tsx +3 -3
  405. package/packages/visualizer/src/components/ActivityIndicator.module.css +4 -0
  406. package/packages/visualizer/src/components/ActivityIndicator.tsx +6 -0
  407. package/packages/visualizer/src/components/Header.module.css +101 -192
  408. package/packages/visualizer/src/components/Header.tsx +88 -13
  409. package/packages/visualizer/src/components/ProjectPicker.tsx +64 -0
  410. package/packages/visualizer/src/data/adapters/adapter.ts +5 -17
  411. package/packages/visualizer/src/data/adapters/index.ts +10 -1
  412. package/packages/visualizer/src/data/adapters/report-backend.test.ts +3 -2
  413. package/packages/visualizer/src/data/adapters/report-backend.ts +1 -1
  414. package/packages/visualizer/src/data/queries.ts +14 -7
  415. package/packages/visualizer/src/evidence/api.ts +16 -3
  416. package/packages/visualizer/src/evidence/artifacts.module.css +213 -0
  417. package/packages/visualizer/src/evidence/artifacts.tsx +272 -0
  418. package/packages/visualizer/src/evidence/check-detail.tsx +21 -4
  419. package/packages/visualizer/src/evidence/document-page.tsx +6 -2
  420. package/packages/visualizer/src/evidence/evidence-context.tsx +79 -12
  421. package/packages/visualizer/src/evidence/evidence.module.css +11 -1
  422. package/packages/visualizer/src/evidence/feature-page.tsx +7 -3
  423. package/packages/visualizer/src/evidence/model-page.tsx +6 -2
  424. package/packages/visualizer/src/evidence/project-home.tsx +45 -0
  425. package/packages/visualizer/src/evidence/recording-page.tsx +4 -1
  426. package/packages/visualizer/src/evidence/spec-index.tsx +2 -1
  427. package/packages/visualizer/src/evidence/spec-page.tsx +23 -16
  428. package/packages/visualizer/src/evidence/test-filter.tsx +21 -0
  429. package/packages/visualizer/src/find/Finder.tsx +1 -7
  430. package/packages/visualizer/src/find/open.ts +4 -0
  431. package/packages/visualizer/src/live/live-query.ts +21 -0
  432. package/packages/visualizer/src/live/live-runs.tsx +69 -0
  433. package/packages/visualizer/src/live/live-stream.ts +225 -0
  434. package/packages/visualizer/src/live/report-progress.ts +62 -0
  435. package/packages/visualizer/src/live/test-progress.tsx +34 -0
  436. package/packages/visualizer/src/runtime.ts +35 -0
  437. package/packages/visualizer/src/state/ui-store.ts +3 -2
  438. package/packages/visualizer/src/views/ChartPage.tsx +2 -0
  439. package/packages/visualizer/src/views/ChartTests.tsx +43 -0
  440. package/packages/visualizer/src/views/SidePanel.tsx +2 -0
  441. package/packages/visualizer/vite/atlas-files.test.ts +4 -4
  442. package/packages/visualizer/vite/atlas-files.ts +1 -5
  443. package/packages/visualizer/vite/atlas-server-proxy.ts +37 -0
  444. package/packages/visualizer/vite.config.ts +11 -3
@@ -37,6 +37,7 @@ export type WebViewContext = SignalContext & {
37
37
  press(key: string, label?: string): Promise<void>;
38
38
  };
39
39
  };
40
+ /** Options of `bunWebViewDriver`; every field is optional. */
40
41
  export type BunWebViewDriverOptions = {
41
42
  /** Where `goto` paths resolve; the implementation's setup decides where to open. */
42
43
  baseUrl?: string | (() => string | Promise<string>);
@@ -47,7 +48,10 @@ export type BunWebViewDriverOptions = {
47
48
  backend?: 'webkit' | 'chrome';
48
49
  /** How long a tap waits for its target to show, in milliseconds (default 10 000). */
49
50
  actionTimeoutMs?: number;
50
- /** Showcase pacing, in milliseconds. */
51
+ /**
52
+ * Showcase pacing, in milliseconds: the hold before each event runs and after its state shows (default 400 and
53
+ * 900).
54
+ */
51
55
  pacing?: {
52
56
  before: number;
53
57
  after: number;
@@ -56,12 +60,42 @@ export type BunWebViewDriverOptions = {
56
60
  concurrency?: number;
57
61
  };
58
62
  /**
59
- * Drive a web app in Bun's built-in headless browser: the system WebKit on macOS (nothing to
60
- * install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about
61
- * ten, so it is the quickest way to run a chart against a real page. Clips are encoded from
62
- * screenshots with FFmpeg. Needs the Bun runtime; there is no fake clock, so time events use the
63
- * app's own controls.
63
+ * Drives a web app in Bun's built-in headless browser for `atlas run`: the system WebKit on macOS (nothing to
64
+ * install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about ten, so it is the
65
+ * quickest way to run a chart against a real page. Each path attempt gets its own view, closed afterwards. Screenshots
66
+ * are PNG files without a thumbnail. Clips are encoded from screenshots with FFmpeg (no clip is recorded without it).
67
+ * `user.tap` and `user.type` wait up to `actionTimeoutMs` for the target signal to show, then click its centre; a
68
+ * target that never shows fails the step with "<signal> is not on screen". Needs the Bun runtime (run
69
+ * `bun --bun atlas run`), and throws on open without it. There is no fake clock, so time events use the app's own
70
+ * controls.
71
+ *
72
+ * @see docs/statecharts.md
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { defineConfig } from '@crvouga/atlas';
77
+ * import { bunWebViewDriver, screen, text } from '@crvouga/atlas/bun';
78
+ *
79
+ * export default defineConfig({
80
+ * specs: './specs',
81
+ * driver: () => bunWebViewDriver({ baseUrl: 'http://127.0.0.1:4317' }),
82
+ * implementation: {
83
+ * async setup(ctx) { await ctx.goto('/'); },
84
+ * events: {
85
+ * // one entry per event of the spec
86
+ * },
87
+ * states: { 'No todos': screen({ all: [text('Nothing to do yet')] }) }
88
+ * }
89
+ * });
90
+ * ```
64
91
  */
65
92
  export declare function bunWebViewDriver(options?: BunWebViewDriverOptions): Driver<WebViewContext>;
66
- /** A state recognised from its signals in the page: every `all` visible and no `none` visible. */
93
+ /**
94
+ * Builds a state implementation for a `WebViewContext` from its signals in the page: every `all` signal visible, one
95
+ * `any` signal visible (when given), no `none` signal visible. It is core's `signatureScreen` over `ctx.isVisible`, so
96
+ * it takes the same spec as `screen` from `@crvouga/atlas/signals` (`checks`, `transient`, `sameAs`, `lookIn`,
97
+ * `settle` included).
98
+ *
99
+ * @see docs/statecharts.md
100
+ */
67
101
  export declare const screen: (spec: import('../../core/src/signals.js').ScreenSpec<WebViewContext, Signal>) => import('../../core/src/index.js').StateImplementation<WebViewContext>;
@@ -1,3 +1,14 @@
1
+ /**
2
+ * @module Bun WebView driver
3
+ *
4
+ * `bunWebViewDriver()` is the core `Driver` that runs a statechart's paths in Bun's built-in headless browser
5
+ * (`Bun.WebView`), the quickest way to run a chart against a real page. It provides a `WebViewContext` whose
6
+ * `user.tap` and `user.type` act on `Signal`s, found by the shared in-page DOM probe from core, so an implementation
7
+ * written against `SignalContext` runs here and on the other web drivers unchanged. `Bun.WebView` is typed
8
+ * structurally (`BunWebView`), so this package builds without Bun's types; at run time the Bun runtime is required.
9
+ *
10
+ * @see docs/statecharts.md
11
+ */
1
12
  import { mkdirSync, writeFileSync } from 'node:fs';
2
13
  import path from 'node:path';
3
14
  import { recordFrames } from '../../core/src/index.js';
@@ -51,11 +62,34 @@ function contextFor(view, baseUrl, timeline, options) {
51
62
  return ctx;
52
63
  }
53
64
  /**
54
- * Drive a web app in Bun's built-in headless browser: the system WebKit on macOS (nothing to
55
- * install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about
56
- * ten, so it is the quickest way to run a chart against a real page. Clips are encoded from
57
- * screenshots with FFmpeg. Needs the Bun runtime; there is no fake clock, so time events use the
58
- * app's own controls.
65
+ * Drives a web app in Bun's built-in headless browser for `atlas run`: the system WebKit on macOS (nothing to
66
+ * install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about ten, so it is the
67
+ * quickest way to run a chart against a real page. Each path attempt gets its own view, closed afterwards. Screenshots
68
+ * are PNG files without a thumbnail. Clips are encoded from screenshots with FFmpeg (no clip is recorded without it).
69
+ * `user.tap` and `user.type` wait up to `actionTimeoutMs` for the target signal to show, then click its centre; a
70
+ * target that never shows fails the step with "<signal> is not on screen". Needs the Bun runtime (run
71
+ * `bun --bun atlas run`), and throws on open without it. There is no fake clock, so time events use the app's own
72
+ * controls.
73
+ *
74
+ * @see docs/statecharts.md
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * import { defineConfig } from '@crvouga/atlas';
79
+ * import { bunWebViewDriver, screen, text } from '@crvouga/atlas/bun';
80
+ *
81
+ * export default defineConfig({
82
+ * specs: './specs',
83
+ * driver: () => bunWebViewDriver({ baseUrl: 'http://127.0.0.1:4317' }),
84
+ * implementation: {
85
+ * async setup(ctx) { await ctx.goto('/'); },
86
+ * events: {
87
+ * // one entry per event of the spec
88
+ * },
89
+ * states: { 'No todos': screen({ all: [text('Nothing to do yet')] }) }
90
+ * }
91
+ * });
92
+ * ```
59
93
  */
60
94
  export function bunWebViewDriver(options = {}) {
61
95
  const width = options.width ?? 390;
@@ -86,5 +120,12 @@ export function bunWebViewDriver(options = {}) {
86
120
  hold: (_ctx, ms) => new Promise((r) => setTimeout(r, ms))
87
121
  };
88
122
  }
89
- /** A state recognised from its signals in the page: every `all` visible and no `none` visible. */
123
+ /**
124
+ * Builds a state implementation for a `WebViewContext` from its signals in the page: every `all` signal visible, one
125
+ * `any` signal visible (when given), no `none` signal visible. It is core's `signatureScreen` over `ctx.isVisible`, so
126
+ * it takes the same spec as `screen` from `@crvouga/atlas/signals` (`checks`, `transient`, `sameAs`, `lookIn`,
127
+ * `settle` included).
128
+ *
129
+ * @see docs/statecharts.md
130
+ */
90
131
  export const screen = signatureScreen((ctx, signal) => ctx.isVisible(signal), describeSignal);
@@ -1,2 +1,10 @@
1
+ /**
2
+ * @module Bun WebView driver entry point (`@crvouga/atlas/bun`)
3
+ *
4
+ * Re-exports the Bun WebView driver for statechart runs (`bunWebViewDriver`), its context and option types, `screen`
5
+ * for recognising states from signals, and the signal constructors. Needs the Bun runtime.
6
+ *
7
+ * @see docs/statecharts.md
8
+ */
1
9
  export { bunWebViewDriver, screen, type BunWebView, type BunWebViewDriverOptions, type WebViewContext } from './driver.js';
2
10
  export { css, label, role, testId, text, describeSignal, type Signal } from '../../core/src/signals.js';
@@ -1,2 +1,10 @@
1
+ /**
2
+ * @module Bun WebView driver entry point (`@crvouga/atlas/bun`)
3
+ *
4
+ * Re-exports the Bun WebView driver for statechart runs (`bunWebViewDriver`), its context and option types, `screen`
5
+ * for recognising states from signals, and the signal constructors. Needs the Bun runtime.
6
+ *
7
+ * @see docs/statecharts.md
8
+ */
1
9
  export { bunWebViewDriver, screen } from './driver.js';
2
10
  export { css, label, role, testId, text, describeSignal } from '../../core/src/signals.js';
@@ -1 +1,14 @@
1
- export declare function main(argv?: string[]): Promise<0 | 1 | 2>;
1
+ /**
2
+ * @module The `atlas` command
3
+ *
4
+ * Dispatches `atlas <command>`: the statechart commands (`lint`, `plan`, `run`, `merge`, `export`) and, loaded on demand so
5
+ * they cost nothing otherwise, `serve`, `dev`, `init` and `report`. Statechart configuration is `atlas.config.ts` (see
6
+ * `defineConfig`). A command that is wrong prints a message and exits 2; a plan, lint or run that finds problems exits 1.
7
+ *
8
+ * @see docs/statecharts.md
9
+ * @see docs/reference/cli.md
10
+ */
11
+ /** The text `atlas --help` prints: every command, and the flags of the statechart commands. */
12
+ export declare const USAGE = "atlas \u2014 executable statecharts\n\n atlas lint [--config atlas.config.ts | --specs <dir>] [--require-implementations]\n atlas plan [--config atlas.config.ts] [--state <name>]\n atlas run [--config atlas.config.ts] [--mode fast|showcase] [--workers n] [--state <name>]\n [--seed <name>]... [--paths id,id] [--shard i/n] [--rerun-failed | --reuse <run-dir>]\n [--no-retry] [--output <dir>]\n atlas merge [--config atlas.config.ts] [--output <dir>] <run-dir> <run-dir>...\n atlas export --specs <dir> --format scxml|mermaid|markdown|json [--out <file>]\n atlas server [--data <dir>] [--port 8080] [--store <url>]... one Atlas node: API, projects and client\n atlas client build [--no-data] [--out <dir>] build the project-agnostic Atlas client\n atlas dev [--port 5180] develop the Atlas server and client on one host\n atlas init [--server <url>] [--write] integrate this project: detect its suites, print the plan (atlas init --help)\n atlas report publish|stream|status|merge|doctor|policy \u2026 layered evidence for any kind of spec (atlas report --help)\n\n --workers path attempts that run at once (default: one per CPU, capped by the driver)\n --seed only paths that start from this seed (\"start\" for paths setup starts); repeatable\n --shard 2/4 run the second quarter of the plan; merge the shards' runs afterwards\n --rerun-failed keep the newest run's passed paths and run only the rest\n";
13
+ /** Runs `atlas` with `argv` (default: the process arguments) and returns the exit code. Throws for a command that is wrong, which the `atlas` binary reports as a message and exit code 2. */
14
+ export declare function main(argv?: string[]): Promise<number>;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * @module The `atlas` command
3
+ *
4
+ * Dispatches `atlas <command>`: the statechart commands (`lint`, `plan`, `run`, `merge`, `export`) and, loaded on demand so
5
+ * they cost nothing otherwise, `serve`, `dev`, `init` and `report`. Statechart configuration is `atlas.config.ts` (see
6
+ * `defineConfig`). A command that is wrong prints a message and exits 2; a plan, lint or run that finds problems exits 1.
7
+ *
8
+ * @see docs/statecharts.md
9
+ * @see docs/reference/cli.md
10
+ */
1
11
  import { writeFileSync } from 'node:fs';
2
12
  import path from 'node:path';
3
13
  import { pathToFileURL } from 'node:url';
@@ -8,7 +18,8 @@ import { toMarkdown } from './report/markdown.js';
8
18
  import { composeCharts } from './spec/compose.js';
9
19
  import { loadSpecDirectory } from './spec/load.js';
10
20
  import { machineToScxml } from './spec/scxml.js';
11
- const USAGE = `atlas — executable statecharts
21
+ /** The text `atlas --help` prints: every command, and the flags of the statechart commands. */
22
+ export const USAGE = `atlas — executable statecharts
12
23
 
13
24
  atlas lint [--config atlas.config.ts | --specs <dir>] [--require-implementations]
14
25
  atlas plan [--config atlas.config.ts] [--state <name>]
@@ -17,6 +28,11 @@ const USAGE = `atlas — executable statecharts
17
28
  [--no-retry] [--output <dir>]
18
29
  atlas merge [--config atlas.config.ts] [--output <dir>] <run-dir> <run-dir>...
19
30
  atlas export --specs <dir> --format scxml|mermaid|markdown|json [--out <file>]
31
+ atlas server [--data <dir>] [--port 8080] [--store <url>]... one Atlas node: API, projects and client
32
+ atlas client build [--no-data] [--out <dir>] build the project-agnostic Atlas client
33
+ atlas dev [--port 5180] develop the Atlas server and client on one host
34
+ atlas init [--server <url>] [--write] integrate this project: detect its suites, print the plan (atlas init --help)
35
+ atlas report publish|stream|status|merge|doctor|policy … layered evidence for any kind of spec (atlas report --help)
20
36
 
21
37
  --workers path attempts that run at once (default: one per CPU, capped by the driver)
22
38
  --seed only paths that start from this seed ("start" for paths setup starts); repeatable
@@ -69,8 +85,26 @@ async function loadConfig(file) {
69
85
  throw new Error(`${file} has no default export (use defineConfig)`);
70
86
  return { config: mod.default, base: path.dirname(absolute) };
71
87
  }
88
+ /** Runs `atlas` with `argv` (default: the process arguments) and returns the exit code. Throws for a command that is wrong, which the `atlas` binary reports as a message and exit code 2. */
72
89
  export async function main(argv = process.argv.slice(2)) {
73
90
  const [command] = argv;
91
+ // Loaded on demand: lint, plan and run do not pay for the reports.
92
+ if (command === 'serve' || command === 'server') {
93
+ const { serveMain } = await import('../../server/src/main.js');
94
+ return serveMain(argv.slice(1), { out: text => process.stdout.write(text) });
95
+ }
96
+ if (command === 'client') {
97
+ const { clientMain } = await import('../../server/src/site.js');
98
+ return clientMain(argv.slice(1));
99
+ }
100
+ if (command === 'dev') {
101
+ const { devMain } = await import('../../server/src/dev.js');
102
+ return devMain(argv.slice(1), { out: text => process.stdout.write(text) });
103
+ }
104
+ if (command === 'init')
105
+ return (await import('../../reports/src/init.js')).initMain(argv.slice(1), { out: text => process.stdout.write(text) });
106
+ if (command === 'report')
107
+ return (await import('../../reports/src/report-cli.js')).runReportCommand(argv.slice(1));
74
108
  const configFile = flag(argv, 'config') ?? 'atlas.config.ts';
75
109
  const specs = flag(argv, 'specs');
76
110
  const output = flag(argv, 'output');
@@ -1,13 +1,21 @@
1
+ import { type LiveReporterOptions } from '../../reports/src/live-reporter.js';
1
2
  import type { StateValue } from './graph.js';
2
3
  import type { Shard } from './run/execute.js';
3
4
  import type { Driver, EventMatcher, EventSource, Implementation, PrivacyRules, RunMode } from './run/types.js';
5
+ /**
6
+ * Everything a project says about running its specs. `C` is the type of the driver's context
7
+ * (a Playwright `Page`, a model, ...), which events and states receive.
8
+ */
4
9
  export type AtlasConfig<C = unknown> = {
5
10
  /** The directory holding the charts (`*.scxml`, `*.machine.{json,yaml}`) and `journeys.yaml`. */
6
11
  specs: string;
12
+ /** Live reporting endpoint. Defaults to ATLAS_SERVER_URL when set; false disables streaming. */
13
+ reporting?: LiveReporterOptions | false;
7
14
  /** The chart to run; the root chart when omitted. */
8
15
  chart?: string;
9
16
  /** Where generated paths start (an XState state value); the initial state when omitted. */
10
17
  start?: StateValue;
18
+ /** A phrase describing `start` in reports; `The start of the chart` when omitted. */
11
19
  startLabel?: string;
12
20
  /** Only these events enter the chart from outside it. */
13
21
  entryEvents?: string[];
@@ -17,27 +25,61 @@ export type AtlasConfig<C = unknown> = {
17
25
  workers?: number;
18
26
  /** Runs once before any path: prepare what every seed relies on (reference data, config). */
19
27
  beforeRun?: () => Promise<void> | void;
28
+ /** The driver, or a function that creates it (called once per run, after `beforeRun`). */
20
29
  driver: Driver<C> | (() => Driver<C> | Promise<Driver<C>>);
30
+ /** How to make each event happen and recognise each state. */
21
31
  implementation: Implementation<C>;
22
32
  /** Where runs are written; `atlas-runs` beside the config when omitted. */
23
33
  output?: string;
34
+ /** Creates the business event sources for a run (called once per run; the run closes them). */
24
35
  eventSources?: () => EventSource[] | Promise<EventSource[]>;
36
+ /** How each business event name from `meta.events` is recognised; by default a CloudEvent whose `type` equals the name. */
25
37
  eventMatchers?: Record<string, EventMatcher>;
38
+ /** Extra privacy rules on top of the defaults. */
26
39
  privacy?: PrivacyRules;
27
40
  /** URLs the run will reach; checked against `privacy.allowHosts` (loopback by default). */
28
41
  targets?: string[];
42
+ /** Recorded in the manifest as the run's environment (`run.environment`), beside the driver name. */
29
43
  environment?: Record<string, unknown>;
44
+ /** How long to wait for a state to be recognised after an event, in milliseconds; 45 000 when omitted. */
30
45
  stepTimeoutMs?: number;
31
46
  /** Meta fields every state must carry (default: description). */
32
47
  requiredMeta?: string[];
33
48
  };
49
+ /**
50
+ * Declares an Atlas config with types, returning it unchanged. Put it as the default export of
51
+ * `atlas.config.ts`; the CLI loads the file with `tsx` and defaults to `atlas.config.ts` in the
52
+ * current directory.
53
+ *
54
+ * @see docs/statecharts.md
55
+ *
56
+ * @example
57
+ * export default defineConfig({
58
+ * specs: './specs',
59
+ * driver: () => functionDriver(() => new TodoModel()),
60
+ * implementation: {
61
+ * events: { 'Adds a todo': { kind: 'user', how: 'Calls add().', run: async (model) => model.add('x') } },
62
+ * states: { 'No todos': { recognize: async (model) => ({ matched: model.count === 0, signals: [] }) } }
63
+ * }
64
+ * });
65
+ */
34
66
  export declare function defineConfig<C>(config: AtlasConfig<C>): AtlasConfig<C>;
35
- /** Narrow what a config runs from the command line. */
67
+ /** Overrides of a config that the command line can give. */
36
68
  export type PrepareOptions = {
37
69
  /** Scope the run to this state instead of the config's. */
38
70
  state?: string;
39
71
  };
40
- /** Load, lint and plan a config without running anything. */
72
+ /**
73
+ * Loads, lints and plans a config without running anything (what `atlas lint` and `atlas plan` do).
74
+ *
75
+ * @param baseDirectory what a relative `config.specs` resolves against.
76
+ * @returns the loaded `bundle`; `lint` (findings, composition and graph, including `implemented`
77
+ * findings for what the implementation lacks); the run's `scope`; the `plan` (paths, journeys, seeds,
78
+ * `unreachable`); and the resolved `specs` directory.
79
+ * @throws Error when the specs cannot be loaded or composed, when a seed's `shows` is not active where
80
+ * it starts, or when a seed's `for` names an event no state handles. Lint findings are returned,
81
+ * not thrown.
82
+ */
41
83
  export declare function prepare<C>(config: AtlasConfig<C>, baseDirectory?: string, options?: PrepareOptions): {
42
84
  bundle: import('./index.js').SpecBundle;
43
85
  lint: {
@@ -82,22 +124,43 @@ export declare function prepare<C>(config: AtlasConfig<C>, baseDirectory?: strin
82
124
  };
83
125
  specs: string;
84
126
  };
127
+ /** The options of `atlas run` that `runConfig` accepts; each overrides the config's own setting. */
85
128
  export type RunCommandOptions = PrepareOptions & {
129
+ /** `fast` when omitted. */
86
130
  mode?: RunMode;
131
+ /** Override live reporting. Defaults to config.reporting or ATLAS_SERVER_URL. */
132
+ reporting?: LiveReporterOptions | false;
87
133
  /** Only these paths, by id. */
88
134
  paths?: string[];
89
135
  /** Only paths that start from these seeds ("start" for paths that `setup` starts). */
90
136
  seeds?: string[];
137
+ /** Whether a failed path runs again to tell flaky from broken; true unless `false`. */
91
138
  retry?: boolean;
139
+ /** Where the run is written; the config's `output`, else `atlas-runs`. */
92
140
  output?: string;
141
+ /** Path attempts at once; the config's `workers`, else one per CPU, always capped by the driver. */
93
142
  workers?: number;
94
143
  /** Run one shard of the plan; `atlas merge` composes the shards. */
95
144
  shard?: Shard;
96
145
  /** Keep the passed paths of this run (or the newest run, with "latest") and run the rest. */
97
146
  reuse?: string;
147
+ /** Receives progress lines; stdout when omitted. */
98
148
  log?: (line: string) => void;
99
149
  };
100
- /** Run a config end to end and write its manifest and reports. */
150
+ /**
151
+ * Runs a config end to end and writes the run (manifest, reports, media) under its output
152
+ * directory, like `atlas run`.
153
+ *
154
+ * Refuses to start (throws) when the spec has any structural lint finding (everything but missing
155
+ * implementations, which just block paths) or when a `targets` URL is not on the privacy allow-list.
156
+ * Then it calls `beforeRun`, creates the driver and runs the planned paths (filtered by
157
+ * `options.paths`/`seeds`/`shard`, reusing earlier passes when `options.reuse` is set).
158
+ *
159
+ * @returns what `runPaths` returns: the run directory, the manifest and `ok` (false if any path
160
+ * failed or the privacy scan found something).
161
+ * @throws Error also when `reuse` names a run with no outcomes or there is no earlier run for `latest`.
162
+ * @see docs/statecharts.md
163
+ */
101
164
  export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunCommandOptions, baseDirectory?: string): Promise<{
102
165
  runDir: string;
103
166
  manifest: {
@@ -202,6 +265,7 @@ export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunComman
202
265
  key: string;
203
266
  name: string;
204
267
  kind: import('./plan.js').PlannedPath["kind"];
268
+ progress?: "queued" | "running" | "complete";
205
269
  status: import('./index.js').Status;
206
270
  attempts: {
207
271
  status: "passed" | "failed";
@@ -285,7 +349,15 @@ export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunComman
285
349
  };
286
350
  ok: boolean;
287
351
  }>;
288
- /** Compose runs of a config (its shards, or a rerun and the run before it) into one run. */
352
+ /**
353
+ * Composes runs of a config (its shards, or a rerun and the run before it) into one new run
354
+ * under the output directory, like `atlas merge`. The plan is recomputed from the config, so the runs
355
+ * must come from the same specs, implementation and seeds.
356
+ *
357
+ * @param runDirs the run directories to compose; later ones win when two ran the same path.
358
+ * @returns what `mergeRuns` returns: the new run directory, its manifest and `ok`.
359
+ * @throws Error when a run directory has no `outcomes.json`.
360
+ */
289
361
  export declare function mergeConfigRuns<C>(config: AtlasConfig<C>, runDirs: string[], options?: PrepareOptions & {
290
362
  output?: string;
291
363
  }, baseDirectory?: string): {
@@ -392,6 +464,7 @@ export declare function mergeConfigRuns<C>(config: AtlasConfig<C>, runDirs: stri
392
464
  key: string;
393
465
  name: string;
394
466
  kind: import('./plan.js').PlannedPath["kind"];
467
+ progress?: "queued" | "running" | "complete";
395
468
  status: import('./index.js').Status;
396
469
  attempts: {
397
470
  status: "passed" | "failed";
@@ -1,14 +1,57 @@
1
+ /**
2
+ * @module Config and programmatic API
3
+ *
4
+ * The user-facing entry point: `defineConfig` types a project's `atlas.config.ts`, and `prepare`,
5
+ * `runConfig` and `mergeConfigRuns` are the programmatic equivalents of `atlas lint`/`plan`, `atlas
6
+ * run` and `atlas merge`. They wire the pieces together (load specs, lint, scope, plan, run) and add
7
+ * no behaviour of their own beyond validating the config against the spec. Relative paths in a config
8
+ * resolve against the `baseDirectory` argument (the config file's directory when called by the CLI).
9
+ *
10
+ * @see docs/statecharts.md
11
+ */
1
12
  import { availableParallelism } from 'node:os';
2
13
  import path from 'node:path';
14
+ import { createLiveReporter } from '../../reports/src/live-reporter.js';
15
+ import { httpStore } from '../../reports/src/http-store.js';
16
+ import { publishChecks } from '../../reports/src/publish-checks.js';
17
+ import { publishRunBundle } from '../../reports/src/run-bundle.js';
18
+ import { checksFromManifest } from '../../reports/src/ingest.js';
3
19
  import { lintBundle } from './lint.js';
4
20
  import { chartScope, planChart } from './plan.js';
5
21
  import { assertAllowedTarget, mergePrivacy } from './privacy.js';
6
22
  import { latestRun, mergeRuns, readOutcomes, runPaths, shardPaths } from './run/execute.js';
7
23
  import { loadSpecDirectory } from './spec/load.js';
24
+ /**
25
+ * Declares an Atlas config with types, returning it unchanged. Put it as the default export of
26
+ * `atlas.config.ts`; the CLI loads the file with `tsx` and defaults to `atlas.config.ts` in the
27
+ * current directory.
28
+ *
29
+ * @see docs/statecharts.md
30
+ *
31
+ * @example
32
+ * export default defineConfig({
33
+ * specs: './specs',
34
+ * driver: () => functionDriver(() => new TodoModel()),
35
+ * implementation: {
36
+ * events: { 'Adds a todo': { kind: 'user', how: 'Calls add().', run: async (model) => model.add('x') } },
37
+ * states: { 'No todos': { recognize: async (model) => ({ matched: model.count === 0, signals: [] }) } }
38
+ * }
39
+ * });
40
+ */
8
41
  export function defineConfig(config) {
9
42
  return config;
10
43
  }
11
- /** Load, lint and plan a config without running anything. */
44
+ /**
45
+ * Loads, lints and plans a config without running anything (what `atlas lint` and `atlas plan` do).
46
+ *
47
+ * @param baseDirectory what a relative `config.specs` resolves against.
48
+ * @returns the loaded `bundle`; `lint` (findings, composition and graph, including `implemented`
49
+ * findings for what the implementation lacks); the run's `scope`; the `plan` (paths, journeys, seeds,
50
+ * `unreachable`); and the resolved `specs` directory.
51
+ * @throws Error when the specs cannot be loaded or composed, when a seed's `shows` is not active where
52
+ * it starts, or when a seed's `for` names an event no state handles. Lint findings are returned,
53
+ * not thrown.
54
+ */
12
55
  export function prepare(config, baseDirectory = process.cwd(), options = {}) {
13
56
  const specs = path.resolve(baseDirectory, config.specs);
14
57
  const bundle = loadSpecDirectory(specs);
@@ -60,7 +103,20 @@ const contextOf = (config, prepared) => ({
60
103
  ...(config.privacy ? { privacy: config.privacy } : {}),
61
104
  ...(config.environment ? { environment: config.environment } : {})
62
105
  });
63
- /** Run a config end to end and write its manifest and reports. */
106
+ /**
107
+ * Runs a config end to end and writes the run (manifest, reports, media) under its output
108
+ * directory, like `atlas run`.
109
+ *
110
+ * Refuses to start (throws) when the spec has any structural lint finding (everything but missing
111
+ * implementations, which just block paths) or when a `targets` URL is not on the privacy allow-list.
112
+ * Then it calls `beforeRun`, creates the driver and runs the planned paths (filtered by
113
+ * `options.paths`/`seeds`/`shard`, reusing earlier passes when `options.reuse` is set).
114
+ *
115
+ * @returns what `runPaths` returns: the run directory, the manifest and `ok` (false if any path
116
+ * failed or the privacy scan found something).
117
+ * @throws Error also when `reuse` names a run with no outcomes or there is no earlier run for `latest`.
118
+ * @see docs/statecharts.md
119
+ */
64
120
  export async function runConfig(config, options = {}, baseDirectory = process.cwd()) {
65
121
  const prepared = prepare(config, baseDirectory, options);
66
122
  const structural = prepared.lint.findings.filter((f) => f.rule !== 'implemented');
@@ -78,22 +134,59 @@ export async function runConfig(config, options = {}, baseDirectory = process.cw
78
134
  const reused = reuseDir ? readOutcomes(reuseDir) : null;
79
135
  if (options.reuse && !reused)
80
136
  throw new Error(`There is no earlier run to reuse${reuseDir ? ` at ${reuseDir}` : ''}`);
81
- return runPaths({
82
- ...contextOf(config, prepared),
83
- paths,
84
- driver,
85
- mode: options.mode ?? 'fast',
86
- outputRoot,
87
- ...(options.retry === undefined ? {} : { retry: options.retry }),
88
- ...(config.stepTimeoutMs === undefined ? {} : { stepTimeoutMs: config.stepTimeoutMs }),
89
- eventSources: config.eventSources ? await config.eventSources() : [],
90
- workers: options.workers ?? config.workers ?? availableParallelism(),
91
- ...(options.shard ? { shard: options.shard } : {}),
92
- ...(reused && reuseDir ? { reuse: { runDir: reuseDir, outcomes: reused.outcomes } } : {}),
93
- ...(options.log ? { log: options.log } : {})
94
- });
137
+ const requestedReporting = options.reporting ?? config.reporting ?? (process.env.ATLAS_SERVER_URL ? { url: process.env.ATLAS_SERVER_URL, token: process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN } : undefined);
138
+ const reporting = requestedReporting ? { ...requestedReporting, project: requestedReporting.project ?? process.env.ATLAS_PROJECT, token: requestedReporting.token ?? process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN } : undefined;
139
+ let live;
140
+ const onProgress = reporting ? (manifest) => {
141
+ if (!manifest.privacy.passed)
142
+ return;
143
+ live ??= createLiveReporter({ producer: process.env.ATLAS_PRODUCER ?? 'atlas-statecharts', title: `${prepared.scope.chart} · ${options.mode ?? 'fast'}`,
144
+ plannedChecks: paths.length, environment: process.env.ATLAS_ENVIRONMENT ?? 'desktop-web', branch: manifest.run.branch ?? undefined, sha: manifest.run.commit ?? undefined }, reporting);
145
+ const ingested = checksFromManifest(manifest);
146
+ ingested.checks.forEach((check, index) => {
147
+ if (manifest.paths[index]?.progress === 'queued' && !manifest.run.finishedAt)
148
+ return;
149
+ live.check({ ...check, steps: check.steps?.slice(-20).map(step => ({ name: step.name, status: step.status })) });
150
+ });
151
+ } : undefined;
152
+ try {
153
+ const outcome = await runPaths({
154
+ ...contextOf(config, prepared),
155
+ paths,
156
+ driver,
157
+ mode: options.mode ?? 'fast',
158
+ outputRoot,
159
+ ...(options.retry === undefined ? {} : { retry: options.retry }),
160
+ ...(config.stepTimeoutMs === undefined ? {} : { stepTimeoutMs: config.stepTimeoutMs }),
161
+ eventSources: config.eventSources ? await config.eventSources() : [],
162
+ workers: options.workers ?? config.workers ?? availableParallelism(),
163
+ ...(options.shard ? { shard: options.shard } : {}),
164
+ ...(reused && reuseDir ? { reuse: { runDir: reuseDir, outcomes: reused.outcomes } } : {}),
165
+ ...(options.log ? { log: options.log } : {}), ...(onProgress ? { onProgress } : {})
166
+ });
167
+ await live?.finish(outcome.manifest.privacy.passed ? 'completed' : 'interrupted', outcome.manifest.privacy.passed ? undefined : 'Run failed its privacy scan; unsafe progress was withheld.');
168
+ if (reporting && outcome.manifest.privacy.passed) {
169
+ const store = httpStore({ url: reporting.url, project: reporting.project, token: reporting.token });
170
+ await publishChecks(store, { producer: process.env.ATLAS_PRODUCER ?? 'atlas-statecharts', environment: process.env.ATLAS_ENVIRONMENT ?? 'desktop-web',
171
+ branch: outcome.manifest.run.branch, sha: outcome.manifest.run.commit, recordedAtMs: Math.max(Date.now(), (live?.finishedAtMs ?? 0) + 1), checks: checksFromManifest(outcome.manifest).checks.map(check => ({ ...check, measurements: [...check.measurements] })) });
172
+ await publishRunBundle(store, outcome.runDir);
173
+ }
174
+ return outcome;
175
+ }
176
+ catch (error) {
177
+ await live?.finish('interrupted', 'The producer exited before completing the run.').catch(() => { });
178
+ throw error;
179
+ }
95
180
  }
96
- /** Compose runs of a config (its shards, or a rerun and the run before it) into one run. */
181
+ /**
182
+ * Composes runs of a config (its shards, or a rerun and the run before it) into one new run
183
+ * under the output directory, like `atlas merge`. The plan is recomputed from the config, so the runs
184
+ * must come from the same specs, implementation and seeds.
185
+ *
186
+ * @param runDirs the run directories to compose; later ones win when two ran the same path.
187
+ * @returns what `mergeRuns` returns: the new run directory, its manifest and `ok`.
188
+ * @throws Error when a run directory has no `outcomes.json`.
189
+ */
97
190
  export function mergeConfigRuns(config, runDirs, options = {}, baseDirectory = process.cwd()) {
98
191
  const prepared = prepare(config, baseDirectory, options);
99
192
  return mergeRuns(contextOf(config, prepared), prepared.plan.paths, runDirs.map((d) => path.resolve(d)), { outputRoot: path.resolve(baseDirectory, options.output ?? config.output ?? 'atlas-runs') });