@crvouga/atlas 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +649 -2
  4. package/dist/bun/src/driver.d.ts +67 -0
  5. package/dist/bun/src/driver.js +90 -0
  6. package/dist/bun/src/index.d.ts +2 -0
  7. package/dist/bun/src/index.js +2 -0
  8. package/dist/core/src/cli.d.ts +1 -0
  9. package/dist/core/src/cli.js +177 -0
  10. package/dist/core/src/config.d.ts +477 -0
  11. package/dist/core/src/config.js +100 -0
  12. package/dist/core/src/events/cloudevents.d.ts +56 -0
  13. package/dist/core/src/events/cloudevents.js +152 -0
  14. package/dist/core/src/graph.d.ts +113 -0
  15. package/dist/core/src/graph.js +221 -0
  16. package/dist/core/src/index.d.ts +17 -0
  17. package/dist/core/src/index.js +17 -0
  18. package/dist/core/src/lint.d.ts +53 -0
  19. package/dist/core/src/lint.js +138 -0
  20. package/dist/core/src/plan.d.ts +109 -0
  21. package/dist/core/src/plan.js +324 -0
  22. package/dist/core/src/privacy.d.ts +8 -0
  23. package/dist/core/src/privacy.js +42 -0
  24. package/dist/core/src/report/formats.d.ts +69 -0
  25. package/dist/core/src/report/formats.js +109 -0
  26. package/dist/core/src/report/markdown.d.ts +8 -0
  27. package/dist/core/src/report/markdown.js +140 -0
  28. package/dist/core/src/run/clients.d.ts +42 -0
  29. package/dist/core/src/run/clients.js +250 -0
  30. package/dist/core/src/run/execute.d.ts +854 -0
  31. package/dist/core/src/run/execute.js +877 -0
  32. package/dist/core/src/run/frames.d.ts +16 -0
  33. package/dist/core/src/run/frames.js +52 -0
  34. package/dist/core/src/run/http.d.ts +41 -0
  35. package/dist/core/src/run/http.js +71 -0
  36. package/dist/core/src/run/types.d.ts +248 -0
  37. package/dist/core/src/run/types.js +39 -0
  38. package/dist/core/src/signals.d.ts +110 -0
  39. package/dist/core/src/signals.js +121 -0
  40. package/dist/core/src/spec/compose.d.ts +28 -0
  41. package/dist/core/src/spec/compose.js +71 -0
  42. package/dist/core/src/spec/index.d.ts +5 -0
  43. package/dist/core/src/spec/index.js +5 -0
  44. package/dist/core/src/spec/load.d.ts +8 -0
  45. package/dist/core/src/spec/load.js +46 -0
  46. package/dist/core/src/spec/parse.d.ts +5 -0
  47. package/dist/core/src/spec/parse.js +32 -0
  48. package/dist/core/src/spec/scxml.d.ts +19 -0
  49. package/dist/core/src/spec/scxml.js +239 -0
  50. package/dist/core/src/spec/types.d.ts +96 -0
  51. package/dist/core/src/spec/types.js +25 -0
  52. package/dist/detox/src/index.d.ts +75 -0
  53. package/dist/detox/src/index.js +110 -0
  54. package/dist/playwright/src/driver.d.ts +44 -0
  55. package/dist/playwright/src/driver.js +82 -0
  56. package/dist/playwright/src/index.d.ts +3 -0
  57. package/dist/playwright/src/index.js +3 -0
  58. package/dist/playwright/src/media.d.ts +68 -0
  59. package/dist/playwright/src/media.js +283 -0
  60. package/dist/playwright/src/signals.d.ts +34 -0
  61. package/dist/playwright/src/signals.js +56 -0
  62. package/dist/reports/src/browser-navigation.d.ts +2 -0
  63. package/dist/reports/src/browser-navigation.js +28 -0
  64. package/dist/reports/src/bundle.d.ts +24 -0
  65. package/dist/reports/src/bundle.js +114 -0
  66. package/dist/reports/src/catalog.d.ts +37 -0
  67. package/dist/reports/src/catalog.js +127 -0
  68. package/dist/reports/src/clock.d.ts +14 -0
  69. package/dist/reports/src/clock.js +4 -0
  70. package/dist/reports/src/completion-order.d.ts +10 -0
  71. package/dist/reports/src/completion-order.js +76 -0
  72. package/dist/reports/src/evidence-live.d.ts +40 -0
  73. package/dist/reports/src/evidence-live.js +118 -0
  74. package/dist/reports/src/evidence-types.d.ts +90 -0
  75. package/dist/reports/src/evidence-types.js +15 -0
  76. package/dist/reports/src/evidence-view.d.ts +68 -0
  77. package/dist/reports/src/evidence-view.js +113 -0
  78. package/dist/reports/src/explorer-types.d.ts +56 -0
  79. package/dist/reports/src/explorer-types.js +0 -0
  80. package/dist/reports/src/explorer-versions.d.ts +4 -0
  81. package/dist/reports/src/explorer-versions.js +21 -0
  82. package/dist/reports/src/export-evidence.d.ts +11 -0
  83. package/dist/reports/src/export-evidence.js +94 -0
  84. package/dist/reports/src/fetcher.d.ts +50 -0
  85. package/dist/reports/src/fetcher.js +205 -0
  86. package/dist/reports/src/format-date.d.ts +1 -0
  87. package/dist/reports/src/format-date.js +10 -0
  88. package/dist/reports/src/format.d.ts +16 -0
  89. package/dist/reports/src/format.js +71 -0
  90. package/dist/reports/src/frames.d.ts +46 -0
  91. package/dist/reports/src/frames.js +245 -0
  92. package/dist/reports/src/hash.d.ts +17 -0
  93. package/dist/reports/src/hash.js +43 -0
  94. package/dist/reports/src/html-frame.d.ts +13 -0
  95. package/dist/reports/src/html-frame.js +63 -0
  96. package/dist/reports/src/http.d.ts +3 -0
  97. package/dist/reports/src/http.js +0 -0
  98. package/dist/reports/src/junit.d.ts +23 -0
  99. package/dist/reports/src/junit.js +119 -0
  100. package/dist/reports/src/keyboard.d.ts +16 -0
  101. package/dist/reports/src/keyboard.js +135 -0
  102. package/dist/reports/src/keys.d.ts +53 -0
  103. package/dist/reports/src/keys.js +122 -0
  104. package/dist/reports/src/layer-catalog.d.ts +5 -0
  105. package/dist/reports/src/layer-catalog.js +39 -0
  106. package/dist/reports/src/layer-merge.d.ts +43 -0
  107. package/dist/reports/src/layer-merge.js +154 -0
  108. package/dist/reports/src/layer-source.d.ts +6 -0
  109. package/dist/reports/src/layer-source.js +32 -0
  110. package/dist/reports/src/layer-store.d.ts +10 -0
  111. package/dist/reports/src/layer-store.js +36 -0
  112. package/dist/reports/src/layer-types.d.ts +32 -0
  113. package/dist/reports/src/layer-types.js +0 -0
  114. package/dist/reports/src/layers-route.d.ts +20 -0
  115. package/dist/reports/src/layers-route.js +259 -0
  116. package/dist/reports/src/namespace-guard.d.ts +11 -0
  117. package/dist/reports/src/namespace-guard.js +40 -0
  118. package/dist/reports/src/navigation.d.ts +8 -0
  119. package/dist/reports/src/navigation.js +0 -0
  120. package/dist/reports/src/object-io.d.ts +9 -0
  121. package/dist/reports/src/object-io.js +41 -0
  122. package/dist/reports/src/object-store.d.ts +67 -0
  123. package/dist/reports/src/object-store.js +32 -0
  124. package/dist/reports/src/performance-part.d.ts +9 -0
  125. package/dist/reports/src/performance-part.js +42 -0
  126. package/dist/reports/src/performance.d.ts +13 -0
  127. package/dist/reports/src/performance.js +45 -0
  128. package/dist/reports/src/persist.d.ts +10 -0
  129. package/dist/reports/src/persist.js +38 -0
  130. package/dist/reports/src/phone.d.ts +5 -0
  131. package/dist/reports/src/phone.js +18 -0
  132. package/dist/reports/src/protocol.d.ts +78 -0
  133. package/dist/reports/src/protocol.js +36 -0
  134. package/dist/reports/src/publication.d.ts +4 -0
  135. package/dist/reports/src/publication.js +35 -0
  136. package/dist/reports/src/publish.d.ts +52 -0
  137. package/dist/reports/src/publish.js +189 -0
  138. package/dist/reports/src/read.d.ts +62 -0
  139. package/dist/reports/src/read.js +214 -0
  140. package/dist/reports/src/recording-bundle.d.ts +22 -0
  141. package/dist/reports/src/recording-bundle.js +4 -0
  142. package/dist/reports/src/recording-keys.d.ts +9 -0
  143. package/dist/reports/src/recording-keys.js +50 -0
  144. package/dist/reports/src/remote-report.d.ts +39 -0
  145. package/dist/reports/src/remote-report.js +304 -0
  146. package/dist/reports/src/report-loader.d.ts +22 -0
  147. package/dist/reports/src/report-loader.js +0 -0
  148. package/dist/reports/src/report-parts.d.ts +10 -0
  149. package/dist/reports/src/report-parts.js +112 -0
  150. package/dist/reports/src/report-types.d.ts +194 -0
  151. package/dist/reports/src/report-types.js +29 -0
  152. package/dist/reports/src/reports-explorer-route.d.ts +90 -0
  153. package/dist/reports/src/reports-explorer-route.js +65 -0
  154. package/dist/reports/src/reports-list-route.d.ts +23 -0
  155. package/dist/reports/src/reports-list-route.js +55 -0
  156. package/dist/reports/src/reports-route.d.ts +267 -0
  157. package/dist/reports/src/reports-route.js +204 -0
  158. package/dist/reports/src/reports-store.d.ts +11 -0
  159. package/dist/reports/src/reports-store.js +28 -0
  160. package/dist/reports/src/resilient-cache.d.ts +3 -0
  161. package/dist/reports/src/resilient-cache.js +33 -0
  162. package/dist/reports/src/retention.d.ts +9 -0
  163. package/dist/reports/src/retention.js +16 -0
  164. package/dist/reports/src/scenario.d.ts +15 -0
  165. package/dist/reports/src/scenario.js +35 -0
  166. package/dist/reports/src/snapshot-bundle.d.ts +18 -0
  167. package/dist/reports/src/snapshot-bundle.js +94 -0
  168. package/dist/reports/src/snapshot-surface.d.ts +29 -0
  169. package/dist/reports/src/snapshot-surface.js +339 -0
  170. package/dist/reports/src/source-content.d.ts +30 -0
  171. package/dist/reports/src/source-content.js +63 -0
  172. package/dist/reports/src/source-entries.d.ts +4 -0
  173. package/dist/reports/src/source-entries.js +34 -0
  174. package/dist/reports/src/source-part.d.ts +4 -0
  175. package/dist/reports/src/source-part.js +66 -0
  176. package/dist/reports/src/source-reader.d.ts +6 -0
  177. package/dist/reports/src/source-reader.js +17 -0
  178. package/dist/reports/src/spec-evidence.d.ts +6 -0
  179. package/dist/reports/src/spec-evidence.js +20 -0
  180. package/dist/reports/src/spec-inventory.d.ts +14 -0
  181. package/dist/reports/src/spec-inventory.js +75 -0
  182. package/dist/reports/src/status.d.ts +4 -0
  183. package/dist/reports/src/status.js +8 -0
  184. package/dist/reports/src/store-prefix.d.ts +21 -0
  185. package/dist/reports/src/store-prefix.js +53 -0
  186. package/dist/reports/src/test-catalog-entity.d.ts +3 -0
  187. package/dist/reports/src/test-catalog-entity.js +34 -0
  188. package/dist/reports/src/types.d.ts +5 -0
  189. package/dist/reports/src/types.js +0 -0
  190. package/dist/reports/src/use-report-nav.d.ts +25 -0
  191. package/dist/reports/src/use-report-nav.js +181 -0
  192. package/dist/schema/src/common.d.ts +57 -0
  193. package/dist/schema/src/common.js +32 -0
  194. package/dist/schema/src/index.d.ts +5 -0
  195. package/dist/schema/src/index.js +5 -0
  196. package/dist/schema/src/manifest.d.ts +457 -0
  197. package/dist/schema/src/manifest.js +247 -0
  198. package/dist/schema/src/report-sources.d.ts +68 -0
  199. package/dist/schema/src/report-sources.js +53 -0
  200. package/dist/schema/src/runs-index.d.ts +52 -0
  201. package/dist/schema/src/runs-index.js +24 -0
  202. package/dist/schema/src/spec.d.ts +245 -0
  203. package/dist/schema/src/spec.js +133 -0
  204. package/dist/vitest/src/index.d.ts +22 -0
  205. package/dist/vitest/src/index.js +33 -0
  206. package/dist/webdriver/src/driver.d.ts +69 -0
  207. package/dist/webdriver/src/driver.js +230 -0
  208. package/dist/webdriver/src/index.d.ts +11 -0
  209. package/dist/webdriver/src/index.js +10 -0
  210. package/dist/webdriver/src/protocol.d.ts +60 -0
  211. package/dist/webdriver/src/protocol.js +146 -0
  212. package/package.json +181 -4
  213. package/packages/bun/README.md +69 -0
  214. package/packages/core/README.md +78 -0
  215. package/packages/core/bin/atlas.mjs +8 -0
  216. package/packages/detox/README.md +73 -0
  217. package/packages/playwright/README.md +77 -0
  218. package/packages/reports/README.md +47 -0
  219. package/packages/reports/STORAGE.md +73 -0
  220. package/packages/schema/README.md +23 -0
  221. package/packages/schema/schemas/atlas-change.schema.json +34 -0
  222. package/packages/schema/schemas/atlas.schema.json +32 -0
  223. package/packages/schema/schemas/cloud-event.schema.json +40 -0
  224. package/packages/schema/schemas/journeys.schema.json +17 -0
  225. package/packages/schema/schemas/manifest.schema.json +160 -0
  226. package/packages/schema/schemas/path-record.schema.json +151 -0
  227. package/packages/schema/schemas/report-sources.schema.json +95 -0
  228. package/packages/schema/schemas/run-info.schema.json +176 -0
  229. package/packages/schema/schemas/run-summary.schema.json +206 -0
  230. package/packages/schema/schemas/runs-index.schema.json +23 -0
  231. package/packages/schema/schemas/state-node.schema.json +238 -0
  232. package/packages/schema/schemas/state-record.schema.json +354 -0
  233. package/packages/schema/schemas/timeline-entry.schema.json +124 -0
  234. package/packages/schema/schemas/transition-record.schema.json +125 -0
  235. package/packages/visualizer/README.md +154 -0
  236. package/packages/visualizer/bin/atlas-visualizer.mjs +176 -0
  237. package/packages/visualizer/example/specs/coffee/ordering/checkout.scxml +82 -0
  238. package/packages/visualizer/example/specs/coffee/ordering/journeys.yaml +129 -0
  239. package/packages/visualizer/example/specs/coffee/ordering/known-issues.md +14 -0
  240. package/packages/visualizer/example/specs/coffee/ordering/machine.yaml +158 -0
  241. package/packages/visualizer/example/specs/coffee/ordering/open-questions.md +25 -0
  242. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  243. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +245 -0
  244. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +12 -0
  245. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +2003 -0
  246. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  247. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  248. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  249. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  250. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +17 -0
  251. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +9 -0
  252. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +17 -0
  253. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +17 -0
  254. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +13 -0
  255. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
  256. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +9 -0
  257. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
  258. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
  259. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  260. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  261. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  262. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  263. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  264. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  265. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
  266. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
  267. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  268. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  269. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  270. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  271. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  272. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  273. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  274. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  275. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  276. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  277. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  278. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  279. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.png +0 -0
  280. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.webp +0 -0
  281. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
  282. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
  283. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
  284. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
  285. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/checkout.scxml +82 -0
  286. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/journeys.yaml +129 -0
  287. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/known-issues.md +14 -0
  288. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/machine.yaml +158 -0
  289. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/open-questions.md +25 -0
  290. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/chart.mmd +67 -0
  291. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/ctrf.json +247 -0
  292. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/junit.xml +12 -0
  293. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/manifest.json +1875 -0
  294. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/chart.mmd +67 -0
  295. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/ctrf.json +244 -0
  296. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/junit.xml +12 -0
  297. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/manifest.json +1977 -0
  298. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/001.vtt +9 -0
  299. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/002.vtt +9 -0
  300. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/003.vtt +9 -0
  301. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/004.vtt +9 -0
  302. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/005.vtt +17 -0
  303. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/006.vtt +9 -0
  304. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  305. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  306. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  307. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  308. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  309. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  310. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  311. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  312. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  313. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  314. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  315. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  316. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  317. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +472 -0
  318. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +16 -0
  319. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +3701 -0
  320. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  321. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  322. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  323. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  324. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
  325. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +13 -0
  326. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +9 -0
  327. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +13 -0
  328. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +17 -0
  329. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
  330. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +13 -0
  331. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
  332. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
  333. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/014.vtt +9 -0
  334. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/015.vtt +9 -0
  335. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/016.vtt +9 -0
  336. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/017.vtt +9 -0
  337. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/018.vtt +17 -0
  338. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/019.vtt +9 -0
  339. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/020.vtt +9 -0
  340. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/021.vtt +9 -0
  341. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/022.vtt +17 -0
  342. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/023.vtt +17 -0
  343. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/024.vtt +13 -0
  344. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/025.vtt +9 -0
  345. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/026.vtt +9 -0
  346. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/027.vtt +9 -0
  347. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/028.vtt +9 -0
  348. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  349. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  350. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  351. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  352. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  353. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  354. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
  355. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
  356. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  357. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  358. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  359. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  360. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  361. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  362. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  363. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  364. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  365. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  366. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.png +0 -0
  367. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.webp +0 -0
  368. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.png +0 -0
  369. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.webp +0 -0
  370. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.png +0 -0
  371. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.webp +0 -0
  372. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.png +0 -0
  373. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.webp +0 -0
  374. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.png +0 -0
  375. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.webp +0 -0
  376. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.png +0 -0
  377. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.webp +0 -0
  378. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.png +0 -0
  379. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.webp +0 -0
  380. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.png +0 -0
  381. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.webp +0 -0
  382. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.png +0 -0
  383. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.webp +0 -0
  384. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  385. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  386. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
  387. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
  388. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
  389. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
  390. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
  391. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
  392. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.png +0 -0
  393. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.webp +0 -0
  394. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.png +0 -0
  395. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.webp +0 -0
  396. package/packages/visualizer/fixtures/full/specs/coffee/ordering/checkout.scxml +82 -0
  397. package/packages/visualizer/fixtures/full/specs/coffee/ordering/journeys.yaml +129 -0
  398. package/packages/visualizer/fixtures/full/specs/coffee/ordering/known-issues.md +14 -0
  399. package/packages/visualizer/fixtures/full/specs/coffee/ordering/machine.yaml +158 -0
  400. package/packages/visualizer/fixtures/full/specs/coffee/ordering/open-questions.md +25 -0
  401. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/ctrf.json +1280 -0
  402. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/junit.xml +26 -0
  403. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/manifest.json +28393 -0
  404. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/identity-check.machine.yaml +397 -0
  405. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/journeys.yaml +129 -0
  406. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/machine.yaml +830 -0
  407. package/packages/visualizer/fixtures/large/specs/atlas.yaml +65 -0
  408. package/packages/visualizer/fixtures/large/specs/billing/invoices/journeys.yaml +132 -0
  409. package/packages/visualizer/fixtures/large/specs/billing/invoices/machine.yaml +830 -0
  410. package/packages/visualizer/fixtures/large/specs/billing/invoices/refund-handling.scxml +288 -0
  411. package/packages/visualizer/fixtures/large/specs/catalog/browsing/journeys.yaml +126 -0
  412. package/packages/visualizer/fixtures/large/specs/catalog/browsing/machine.yaml +831 -0
  413. package/packages/visualizer/fixtures/large/specs/catalog/browsing/product-comparison.machine.yaml +395 -0
  414. package/packages/visualizer/fixtures/large/specs/orders/checkout/journeys.yaml +120 -0
  415. package/packages/visualizer/fixtures/large/specs/orders/checkout/machine.yaml +724 -0
  416. package/packages/visualizer/fixtures/large/specs/orders/checkout/open-questions.md +16 -0
  417. package/packages/visualizer/fixtures/large/specs/orders/checkout/payment.scxml +288 -0
  418. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/delivery-scheduling.machine.yaml +397 -0
  419. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/journeys.yaml +132 -0
  420. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/known-issues.md +13 -0
  421. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/machine.yaml +830 -0
  422. package/packages/visualizer/fixtures/large/specs/support/tickets/escalation.machine.yaml +395 -0
  423. package/packages/visualizer/fixtures/large/specs/support/tickets/journeys.yaml +123 -0
  424. package/packages/visualizer/fixtures/large/specs/support/tickets/machine.yaml +720 -0
  425. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T10-00-00-000Z-showcase/manifest.json +68 -0
  426. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/ctrf.json +50 -0
  427. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/junit.xml +6 -0
  428. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/manifest.json +1281 -0
  429. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/ctrf.json +50 -0
  430. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/junit.xml +6 -0
  431. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/manifest.json +1232 -0
  432. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T13-00-00-000Z-showcase/manifest.json +1244 -0
  433. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/checkout.scxml +82 -0
  434. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/journeys.yaml +134 -0
  435. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/known-issues.md +14 -0
  436. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/loyalty.scxml +4 -0
  437. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/machine.yaml +156 -0
  438. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/open-questions.md +25 -0
  439. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  440. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +149 -0
  441. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +9 -0
  442. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1718 -0
  443. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  444. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +17 -0
  445. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +17 -0
  446. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  447. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
  448. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  449. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  450. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  451. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  452. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  453. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  454. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  455. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  456. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  457. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  458. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  459. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  460. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  461. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  462. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
  463. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
  464. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.png +0 -0
  465. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.webp +0 -0
  466. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  467. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  468. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/checkout.scxml +82 -0
  469. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/journeys.yaml +129 -0
  470. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/known-issues.md +14 -0
  471. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/machine.yaml +158 -0
  472. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/open-questions.md +25 -0
  473. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +79 -0
  474. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +7 -0
  475. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1504 -0
  476. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  477. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  478. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  479. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +17 -0
  480. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  481. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  482. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  483. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  484. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  485. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  486. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  487. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  488. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  489. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  490. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  491. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  492. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  493. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  494. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/checkout.scxml +82 -0
  495. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/journeys.yaml +129 -0
  496. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/known-issues.md +14 -0
  497. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/machine.yaml +158 -0
  498. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/open-questions.md +25 -0
  499. package/packages/visualizer/fixtures/spec-only/runs/.gitkeep +0 -0
  500. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/checkout.scxml +82 -0
  501. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/journeys.yaml +129 -0
  502. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/known-issues.md +14 -0
  503. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/machine.yaml +158 -0
  504. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/open-questions.md +25 -0
  505. package/packages/visualizer/index.html +13 -0
  506. package/packages/visualizer/scripts/make-fixtures.ts +1490 -0
  507. package/packages/visualizer/scripts/publish-data.ts +22 -0
  508. package/packages/visualizer/src/app/AppShell.tsx +56 -0
  509. package/packages/visualizer/src/app/atlas-context.tsx +23 -0
  510. package/packages/visualizer/src/app/gazetteer.module.css +97 -0
  511. package/packages/visualizer/src/app/gazetteer.tsx +105 -0
  512. package/packages/visualizer/src/app/report-sources.tsx +122 -0
  513. package/packages/visualizer/src/app/router.tsx +69 -0
  514. package/packages/visualizer/src/app/search-query.tsx +14 -0
  515. package/packages/visualizer/src/components/DataIssues.module.css +136 -0
  516. package/packages/visualizer/src/components/DataIssues.tsx +70 -0
  517. package/packages/visualizer/src/components/Header.module.css +189 -0
  518. package/packages/visualizer/src/components/Header.tsx +127 -0
  519. package/packages/visualizer/src/components/Legend.module.css +84 -0
  520. package/packages/visualizer/src/components/Legend.tsx +50 -0
  521. package/packages/visualizer/src/components/Screen.module.css +312 -0
  522. package/packages/visualizer/src/components/Screen.tsx +141 -0
  523. package/packages/visualizer/src/components/Status.module.css +116 -0
  524. package/packages/visualizer/src/components/Status.tsx +60 -0
  525. package/packages/visualizer/src/components/icons.tsx +156 -0
  526. package/packages/visualizer/src/components/labels.tsx +22 -0
  527. package/packages/visualizer/src/data/adapters/adapter.ts +112 -0
  528. package/packages/visualizer/src/data/adapters/context.tsx +11 -0
  529. package/packages/visualizer/src/data/adapters/index.ts +29 -0
  530. package/packages/visualizer/src/data/adapters/report-backend.test.ts +96 -0
  531. package/packages/visualizer/src/data/adapters/report-backend.ts +42 -0
  532. package/packages/visualizer/src/data/fixtures.test.ts +407 -0
  533. package/packages/visualizer/src/data/model/build.ts +418 -0
  534. package/packages/visualizer/src/data/model/event-kind.test.ts +59 -0
  535. package/packages/visualizer/src/data/model/event-kind.ts +54 -0
  536. package/packages/visualizer/src/data/model/index.ts +3 -0
  537. package/packages/visualizer/src/data/model/journeys.test.ts +159 -0
  538. package/packages/visualizer/src/data/model/journeys.ts +29 -0
  539. package/packages/visualizer/src/data/model/simulation.test.ts +115 -0
  540. package/packages/visualizer/src/data/model/simulation.ts +187 -0
  541. package/packages/visualizer/src/data/model/status.test.ts +34 -0
  542. package/packages/visualizer/src/data/model/status.ts +43 -0
  543. package/packages/visualizer/src/data/model/types.ts +280 -0
  544. package/packages/visualizer/src/data/parse/issues.test.ts +82 -0
  545. package/packages/visualizer/src/data/parse/issues.ts +114 -0
  546. package/packages/visualizer/src/data/parse/manifest.ts +173 -0
  547. package/packages/visualizer/src/data/parse/markdown.test.ts +119 -0
  548. package/packages/visualizer/src/data/parse/markdown.ts +133 -0
  549. package/packages/visualizer/src/data/parse/spec.test.ts +106 -0
  550. package/packages/visualizer/src/data/parse/spec.ts +557 -0
  551. package/packages/visualizer/src/data/parse/structured.ts +44 -0
  552. package/packages/visualizer/src/data/queries.ts +369 -0
  553. package/packages/visualizer/src/data/testing/load-fixture.ts +63 -0
  554. package/packages/visualizer/src/evidence/api.ts +41 -0
  555. package/packages/visualizer/src/evidence/check-detail.tsx +257 -0
  556. package/packages/visualizer/src/evidence/decision-table.tsx +68 -0
  557. package/packages/visualizer/src/evidence/document-page.tsx +40 -0
  558. package/packages/visualizer/src/evidence/evidence-context.tsx +159 -0
  559. package/packages/visualizer/src/evidence/evidence.module.css +877 -0
  560. package/packages/visualizer/src/evidence/feature-page.tsx +88 -0
  561. package/packages/visualizer/src/evidence/format.ts +56 -0
  562. package/packages/visualizer/src/evidence/gherkin.ts +98 -0
  563. package/packages/visualizer/src/evidence/marks.tsx +118 -0
  564. package/packages/visualizer/src/evidence/model-page.tsx +60 -0
  565. package/packages/visualizer/src/evidence/model-trace.tsx +57 -0
  566. package/packages/visualizer/src/evidence/overview.tsx +134 -0
  567. package/packages/visualizer/src/evidence/quint.ts +45 -0
  568. package/packages/visualizer/src/evidence/recording-page.tsx +69 -0
  569. package/packages/visualizer/src/evidence/recording.module.css +464 -0
  570. package/packages/visualizer/src/evidence/recording.tsx +197 -0
  571. package/packages/visualizer/src/evidence/snapshot.tsx +108 -0
  572. package/packages/visualizer/src/evidence/sources-panel.tsx +134 -0
  573. package/packages/visualizer/src/evidence/sources.module.css +168 -0
  574. package/packages/visualizer/src/evidence/spec-header.tsx +64 -0
  575. package/packages/visualizer/src/evidence/spec-index.tsx +82 -0
  576. package/packages/visualizer/src/evidence/spec-page.tsx +92 -0
  577. package/packages/visualizer/src/evidence/spec-snapshot.tsx +26 -0
  578. package/packages/visualizer/src/layout/graph.test.ts +113 -0
  579. package/packages/visualizer/src/layout/graph.ts +324 -0
  580. package/packages/visualizer/src/layout/layout.ts +237 -0
  581. package/packages/visualizer/src/layout/use-chart-layout.ts +18 -0
  582. package/packages/visualizer/src/main.tsx +31 -0
  583. package/packages/visualizer/src/map/ChartMap.tsx +252 -0
  584. package/packages/visualizer/src/map/EventEdge.tsx +138 -0
  585. package/packages/visualizer/src/map/map.module.css +546 -0
  586. package/packages/visualizer/src/map/nodes.tsx +145 -0
  587. package/packages/visualizer/src/map/path.ts +24 -0
  588. package/packages/visualizer/src/reachable.test.ts +54 -0
  589. package/packages/visualizer/src/spec-kind.test.ts +27 -0
  590. package/packages/visualizer/src/spec-kind.ts +56 -0
  591. package/packages/visualizer/src/state/ui-store.ts +44 -0
  592. package/packages/visualizer/src/styles/global.css +105 -0
  593. package/packages/visualizer/src/styles/tokens.css +80 -0
  594. package/packages/visualizer/src/views/ChartPage.tsx +52 -0
  595. package/packages/visualizer/src/views/ProductPage.tsx +35 -0
  596. package/packages/visualizer/src/views/SidePanel.tsx +339 -0
  597. package/packages/visualizer/src/views/views.module.css +546 -0
  598. package/packages/visualizer/vite/atlas-dev-plugin.ts +169 -0
  599. package/packages/visualizer/vite/atlas-files.test.ts +119 -0
  600. package/packages/visualizer/vite/atlas-files.ts +199 -0
  601. package/packages/visualizer/vite/publish.test.ts +52 -0
  602. package/packages/visualizer/vite/publish.ts +99 -0
  603. package/packages/visualizer/vite/reports-dev-plugin.ts +82 -0
  604. package/packages/visualizer/vite.config.ts +13 -0
  605. package/packages/vitest/README.md +58 -0
  606. package/packages/webdriver/README.md +77 -0
@@ -0,0 +1,154 @@
1
+ # Atlas visualizer
2
+
3
+ A map of how a product behaves: every screen a user can see, every event that moves them on, the
4
+ named journeys through them, and whether the latest run of the app did what the spec says. It
5
+ reads two independent sources and works with whatever exists:
6
+
7
+ 1. **Spec only.** Charts render from the specs directory alone, with designed placeholders where
8
+ screenshots will go.
9
+ 2. **Partial runs.** Real screenshots and clips replace each placeholder as a run writes them.
10
+ 3. **Full runs.** Everything is populated, with history across runs.
11
+
12
+ The explorer is one header, an open index and one plate. The index lists every place and journey of
13
+ the product; each kind of spec (Gherkin, Quint, DMN, Alloy, OpenSLO) has its own tab, with the
14
+ recorded result of every spec in its index. Local directories, published HTTP files and HTTP APIs
15
+ can supply reports simultaneously. Reports update through file watching, polling or server events.
16
+ Latest includes running reports; one unavailable backend leaves the others usable.
17
+
18
+ See [report backends and live snapshots](../../docs/report-backends.md) for configuration,
19
+ the API contract, streaming notifications and adding another transport.
20
+
21
+ ## Point it at your project
22
+
23
+ ```sh
24
+ atlas-visualizer dev --specs ./specs --runs ./atlas-runs
25
+ ```
26
+
27
+ | Flag | Meaning |
28
+ | ----------------- | -------------------------------------------------------------------------------------------------------- |
29
+ | `--specs <dir>` | Statecharts, journeys and notes. Default `./specs`. |
30
+ | `--runs <dir>` | One directory per run, each with a `manifest.json` (what `atlas run` writes). Default `./atlas-runs`. |
31
+ | `--sources <file>` | JSON configuration for additional directories, HTTP files or HTTP API sources. |
32
+ | `--fixture <name>`| Show a bundled example instead: `spec-only`, `partial`, `full`, `failures`, `removed`, `malformed`, `large`. |
33
+ | `--out <dir>` | `build`: the static site (default `./atlas-site`). `publish-data`: the data only (default `./atlas-data`). |
34
+ | `--keep <n>` | How many of the newest runs to publish (default 30). |
35
+ | `--no-data` | `build`: leave the data out, to host it elsewhere. |
36
+ | `--port <n>`, `--host <host>` | `dev`: where to listen (default `localhost:5180`, or the next free port). |
37
+
38
+ Relative paths resolve against the directory the command was run from. Without flags the
39
+ environment is read: `ATLAS_SPECS_ROOT`, `ATLAS_RUNS_ROOT` (relative to `INIT_CWD` when your package
40
+ manager sets it to where you ran the command, or the current directory) and `ATLAS_FIXTURE`. With nothing configured and no
41
+ `specs/` directory, the `full` example is shown.
42
+
43
+ Editing a spec file or a run publishing a snapshot updates the open page in about a second, without a reload,
44
+ keeping selection, zoom and pan.
45
+
46
+ ### Commands
47
+
48
+ ```sh
49
+ atlas-visualizer dev --specs <dir> --runs <dir> # live, from disk
50
+ atlas-visualizer build --specs <dir> --runs <dir> --out site # static site + its data
51
+ atlas-visualizer publish-data --specs <dir> --runs <dir> --out data # data only
52
+ ```
53
+
54
+ `build` writes a static site that any file server can host, with the spec and the newest privacy-checked snapshots
55
+ under `<out>/data`. URLs use the hash, so deep links work without server rewrites. A run whose
56
+ privacy check failed or is missing is never published. With `--no-data`, set
57
+ `VITE_ATLAS_BASE_URL` at build time to where `publish-data` output is hosted; `VITE_ATLAS_POLL_MS`
58
+ sets how often the site checks for new runs (default 60 s, plus when the tab regains focus).
59
+
60
+ ### Inside this repository
61
+
62
+ ```sh
63
+ bun run viz:dev # ATLAS_SPECS_ROOT / ATLAS_RUNS_ROOT, or the example
64
+ ATLAS_FIXTURE=partial bun run viz:dev # one of the fixtures
65
+ bun test packages/visualizer/src packages/visualizer/vite # parsing, composition, statuses, every fixture
66
+ bun run viz:fixtures # regenerate the fixtures (needs ImageMagick, cwebp, ffmpeg)
67
+ ```
68
+
69
+ `bun run viz:publish-data` and `bun run viz:build` do the same as the CLI, writing to `public/data` (or
70
+ `ATLAS_OUT`) and `dist`. `ATLAS_SOURCES_FILE` supplies additional sources, and
71
+ `VITE_ATLAS_SOURCES_URL` can point a hosted viewer at a separate source descriptor file.
72
+
73
+ ## What it reads
74
+
75
+ Open formats first, so specs are not tied to this tool:
76
+
77
+ - **W3C SCXML** (`*.scxml`): `<state>`, `<parallel>`, `<final>`, `initial`, `<transition event target>`
78
+ and `<invoke>`. Readable names and business metadata travel in the Atlas namespace
79
+ (`atlas:name`, `<atlas:meta>`, a final state's `atlas:done-event`), as SCXML allows.
80
+ - **XState v5 machine config** (`*.machine.yaml`, `*.machine.yml`, `*.machine.json`), the JSON
81
+ form Stately Studio imports and exports. A `machine.json` beside a `machine.yaml` is taken as
82
+ the same chart.
83
+ - **Child charts** compose with the standard `invoke: { src, id, onDone }` (SCXML `<invoke>` plus a
84
+ `done.invoke.<id>` transition), or the older `meta.childMachine` with `meta.childFinalEvents`.
85
+ Each final state at the top of a child hands an event to the state that runs it: its
86
+ `childFinalEvents` entry, its own `meta.doneEvent`, or `done.invoke.<id>`, handled by a
87
+ transition of that name or the invoke's `onDone`. This is how the Atlas runner composes charts,
88
+ so transition ids match the run manifests.
89
+ - **Journeys** (`journeys.yaml` beside a chart): named event lists, replayed through the composed
90
+ chart with hand-off events inserted.
91
+ - **Notes** beside a chart: `open-questions.md`, `known-issues.md`; a `<chart>.layout.json` pins
92
+ node positions; an optional `atlas.yaml` at the specs root declares contexts and hand-offs
93
+ between them (without it, each top-level folder holding a chart is a context).
94
+ - **Run manifests** (`<runs>/<run-id>/manifest.json`, the `@crvouga/atlas/schema` contract):
95
+ screenshots, clips with WebVTT captions (shown as the video's caption track), timelines,
96
+ business events with the CloudEvents a source observed, paths, coverage, and links to the
97
+ JUnit, CTRF and Mermaid reports the run wrote. Unknown fields and newer formats are read as far
98
+ as they go.
99
+
100
+ The spec parsing is `@crvouga/atlas/spec`, the browser-safe part of the Atlas core.
101
+
102
+ ## How it fits together
103
+
104
+ ```
105
+ bin/atlas-visualizer.mjs CLI: dev, build and publish-data through Vite's JS API
106
+ vite/atlas-files.ts node: resolve the roots, find spec files, summarize run directories, safe paths
107
+ vite/atlas-dev-plugin.ts dev adapter: serves /__atlas/{specs,runs}, range requests, change events over HMR
108
+ vite/publish.ts lays out specs/ and runs/ (with index.json files) for a static host
109
+ src/data/adapters static adapter (HTTP from a base URL) and dev adapter (same + HMR)
110
+ src/data/parse tolerant parsing: each chart, state, transition, journey and run record on its own
111
+ src/data/model the view model: spec + selected run → one status per state, event, journey
112
+ src/data/queries.ts TanStack Query: per-file caching, live invalidation, polling
113
+ src/layout chart → ELK graph → positions in ELK's worker, cached by structure
114
+ src/map React Flow map: phone-frame screens, regions, child-chart boxes, event chips
115
+ src/components, src/views header, legend, placeholders, panels, product map
116
+ src/evidence spec tabs: index, result pages, recordings, sources
117
+ example/specs the example spec every fixture is generated from
118
+ ```
119
+
120
+ Components read only the view model (`AtlasView`), never raw files.
121
+
122
+ - **Statuses.** States and events resolve to working (`passed`), unreliable (`flaky`), broken
123
+ (`failed`), not reached, not run yet (a run exists but didn't cover it), or spec only (no runs).
124
+ Groups take the worst of themselves and what they contain. Run records the spec no longer has
125
+ are listed as removed from the spec, never dropped.
126
+ - **Event kinds.** Who sends an event (`user`, `system`, `time`, `hand-off`; the older `member` is
127
+ read as `user`) comes from, in order: chart `meta.eventKinds`; the structure (hand-offs); chart
128
+ `meta.timeEvents`; the run record; a guess from the wording. The developer section says which.
129
+ - **Data issues.** Every skipped or guessed piece becomes a plain-language issue with its file and
130
+ path, listed behind a quiet count in the header.
131
+ - **Layout.** ELK lays out each chart (nested states as regions, parallel states side by side) in
132
+ its own worker. Positions are cached under a hash of the chart's structure only, so new results
133
+ never move anything.
134
+
135
+ ## Fixtures
136
+
137
+ `fixtures/` holds seven scenarios generated by `scripts/make-fixtures.ts` from `example/specs`, a
138
+ coffee-ordering app: an XState root chart with a parallel region that invokes a checkout chart
139
+ written in SCXML. Every screenshot and clip is synthetic. `large` is a generated six-context atlas
140
+ of about 500 states that mixes `invoke`, SCXML children and the legacy composition.
141
+
142
+ ## License
143
+
144
+ MIT
145
+
146
+ ## Specs and their results
147
+
148
+ Beside the statechart map, every other kind of spec has its own tab: Gherkin features, Quint models, DMN decision tables, Alloy structures and OpenSLO objectives. A tab appears when the specs folder has files of its kind. The index lists every spec with what was recorded for it, and filters to those with results, those failing, or those with none. A spec page shows each scenario, trace or check with its outcome; opening one shows the recorded steps, the error, the timings, every other run of the same check, and its recording.
149
+
150
+ Results come from the Atlas reports API (`/api/reports` in dev, `VITE_ATLAS_REPORTS_URL` when hosted elsewhere) or from a static `data/evidence` export. They combine across backends, branches and runs; **Sources** in the header switches any of them off. While a spec suite is running, the header says so and each finished test appears within a couple of seconds. See [Atlas reports](../reports/README.md) for the API and host configuration.
151
+
152
+ The header title is the product's name, taken from `atlas.yaml`'s `title` up to its first dash or colon, or "Atlas".
153
+
154
+ `src/evidence/` holds this part of the viewer: `evidence-context.tsx` reads and combines the layers, `spec-index.tsx` is the index, `feature-page.tsx`, `model-page.tsx` and `document-page.tsx` are the three kinds of spec page, `check-detail.tsx` is one check's results, and `recording.tsx` is the recorded timeline. `tests/reports.test.tsx` drives the whole viewer against an in-memory reports API.
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readdirSync, statSync } from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { parseArgs } from 'node:util';
7
+
8
+ const APP_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
9
+ const CONFIG_FILE = path.join(APP_ROOT, 'vite.config.ts');
10
+
11
+ const USAGE = `atlas-visualizer: browse statechart specs and the runs that execute them
12
+
13
+ Usage
14
+ atlas-visualizer dev [--specs <dir>] [--runs <dir>] [--port <n>] [--host <host>]
15
+ atlas-visualizer build [--specs <dir>] [--runs <dir>] [--out <dir>] [--keep <n>] [--no-data]
16
+ atlas-visualizer publish-data [--specs <dir>] [--runs <dir>] [--out <dir>] [--keep <n>]
17
+
18
+ Options
19
+ --specs <dir> all specs: statecharts, Gherkin, Quint, DMN, Alloy, notes (default: ./specs)
20
+ --runs <dir> run directories, each with a manifest.json (default: ./atlas-runs)
21
+ --sources <file> additional directory, HTTP and streaming API report sources (JSON)
22
+ --fixture <name> show a bundled example instead (spec-only, partial, full, failures, removed, malformed, large)
23
+ --out <dir> build: the static site (default ./atlas-site); publish-data: the data (default ./atlas-data)
24
+ --keep <n> how many of the newest runs to publish (default 30)
25
+ --no-data build: leave the data out; point the site at it with VITE_ATLAS_BASE_URL
26
+ --port <n> dev: port to listen on (default 5180, or the next free one)
27
+ --host <host> dev: address to listen on (default localhost)
28
+
29
+ Relative paths resolve against the directory the command was run from. ATLAS_SPECS_ROOT and
30
+ ATLAS_RUNS_ROOT are read when the flags are absent.
31
+ `;
32
+
33
+ class UsageError extends Error {}
34
+
35
+ function parse(argv) {
36
+ const { values, positionals } = parseArgs({
37
+ args: argv,
38
+ allowPositionals: true,
39
+ strict: true,
40
+ options: {
41
+ specs: { type: 'string' },
42
+ runs: { type: 'string' },
43
+ sources: { type: 'string' },
44
+ fixture: { type: 'string' },
45
+ out: { type: 'string' },
46
+ keep: { type: 'string' },
47
+ port: { type: 'string' },
48
+ host: { type: 'string' },
49
+ 'no-data': { type: 'boolean', default: false },
50
+ help: { type: 'boolean', short: 'h', default: false }
51
+ }
52
+ });
53
+ return { command: positionals[0], extra: positionals.slice(1), values };
54
+ }
55
+
56
+ function integer(name, value, min, max) {
57
+ if (value === undefined) return undefined;
58
+ const n = Number(value);
59
+ if (!Number.isInteger(n) || n < min || n > max) throw new UsageError(`--${name} must be a whole number from ${min} to ${max}, got "${value}"`);
60
+ return n;
61
+ }
62
+
63
+ /** Point the shared root resolution (vite/atlas-files.ts) at the flags, as absolute paths. */
64
+ function applyRoots(values, base) {
65
+ if (values.sources) process.env.ATLAS_SOURCES_FILE = path.resolve(base, values.sources);
66
+ if (values.fixture) {
67
+ if (values.specs || values.runs) throw new UsageError('--fixture cannot be combined with --specs or --runs');
68
+ process.env.ATLAS_FIXTURE = values.fixture;
69
+ return;
70
+ }
71
+ if (values.specs || values.runs) delete process.env.ATLAS_FIXTURE;
72
+ if (values.specs) {
73
+ const specs = path.resolve(base, values.specs);
74
+ if (!existsSync(specs) || !statSync(specs).isDirectory()) throw new UsageError(`No specs directory at ${specs}`);
75
+ process.env.ATLAS_SPECS_ROOT = specs;
76
+ } else if (process.env.ATLAS_SPECS_ROOT) {
77
+ process.env.ATLAS_SPECS_ROOT = path.resolve(base, process.env.ATLAS_SPECS_ROOT);
78
+ }
79
+ if (values.runs) process.env.ATLAS_RUNS_ROOT = path.resolve(base, values.runs);
80
+ else if (process.env.ATLAS_RUNS_ROOT) process.env.ATLAS_RUNS_ROOT = path.resolve(base, process.env.ATLAS_RUNS_ROOT);
81
+ process.env.INIT_CWD = base;
82
+ }
83
+
84
+ /** Refuse to empty a directory that is not a previous build: the base, its ancestors, home, or anything else with files. */
85
+ function assertSafeOut(out, base) {
86
+ const rel = path.relative(out, base);
87
+ if (out === path.parse(out).root || out === os.homedir() || rel === '' || !rel.startsWith('..')) {
88
+ throw new UsageError(`Refusing to build into ${out}: it holds the directory you ran from. Pass --out <new dir>.`);
89
+ }
90
+ if (existsSync(out)) {
91
+ const entries = readdirSync(out).filter((n) => n !== '.DS_Store');
92
+ if (entries.length && !entries.includes('index.html')) {
93
+ throw new UsageError(`Refusing to replace ${out}: it is not empty and is not a previous build. Pass --out <new dir>.`);
94
+ }
95
+ }
96
+ }
97
+
98
+ async function loadNodeSide() {
99
+ const { runnerImport } = await import('vite');
100
+ const files = await runnerImport(path.join(APP_ROOT, 'vite/atlas-files.ts'));
101
+ const publish = await runnerImport(path.join(APP_ROOT, 'vite/publish.ts'));
102
+ return { resolveRoots: files.module.resolveRoots, publishData: publish.module.publishData };
103
+ }
104
+
105
+ function publish(publishData, roots, out, keep) {
106
+ const result = publishData({ roots, out, keep: keep ?? 30 });
107
+ process.stdout.write(`Published ${result.files.length} spec file(s) and ${result.published.length} run(s) to ${out}\n`);
108
+ if (result.skipped.length) process.stdout.write(`Not published, privacy check missing or failed: ${result.skipped.join(', ')}\n`);
109
+ }
110
+
111
+ async function main(argv) {
112
+ const { command, extra, values } = parse(argv);
113
+ if (values.help || !command) {
114
+ process.stdout.write(USAGE);
115
+ return command || values.help ? 0 : 1;
116
+ }
117
+ if (extra.length) throw new UsageError(`Unexpected argument: ${extra.join(' ')}`);
118
+ const base = process.env.INIT_CWD || process.cwd();
119
+ const port = integer('port', values.port, 0, 65_535);
120
+ const keep = integer('keep', values.keep, 0, 10_000);
121
+ applyRoots(values, base);
122
+
123
+ if (command === 'dev') {
124
+ const { createServer } = await import('vite');
125
+ const server = await createServer({
126
+ configFile: CONFIG_FILE,
127
+ configLoader: 'runner',
128
+ root: APP_ROOT,
129
+ server: { ...(port !== undefined ? { port } : {}), ...(values.host ? { host: values.host } : {}), strictPort: false }
130
+ });
131
+ await server.listen();
132
+ server.printUrls();
133
+ server.bindCLIShortcuts({ print: true });
134
+ return null;
135
+ }
136
+
137
+ if (command === 'build') {
138
+ const out = path.resolve(base, values.out ?? 'atlas-site');
139
+ assertSafeOut(out, base);
140
+ const { build } = await import('vite');
141
+ await build({
142
+ configFile: CONFIG_FILE,
143
+ configLoader: 'runner',
144
+ root: APP_ROOT,
145
+ publicDir: false,
146
+ build: { outDir: out, emptyOutDir: true }
147
+ });
148
+ if (!values['no-data']) {
149
+ const { resolveRoots, publishData } = await loadNodeSide();
150
+ publish(publishData, resolveRoots(), path.join(out, 'data'), keep);
151
+ }
152
+ process.stdout.write(`Built the site in ${out}; serve it with any static file server.\n`);
153
+ return 0;
154
+ }
155
+
156
+ if (command === 'publish-data') {
157
+ const out = path.resolve(base, values.out ?? 'atlas-data');
158
+ const { resolveRoots, publishData } = await loadNodeSide();
159
+ publish(publishData, resolveRoots(), out, keep);
160
+ return 0;
161
+ }
162
+
163
+ throw new UsageError(`Unknown command "${command}"`);
164
+ }
165
+
166
+ main(process.argv.slice(2)).then(
167
+ (code) => {
168
+ if (typeof code === 'number') process.exitCode = code;
169
+ },
170
+ (error) => {
171
+ const usage = error instanceof UsageError || error?.code === 'ERR_PARSE_ARGS_UNKNOWN_OPTION' || error?.code === 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE';
172
+ process.stderr.write(`atlas-visualizer: ${error instanceof Error ? error.message : String(error)}\n`);
173
+ if (usage) process.stderr.write(`\n${USAGE}`);
174
+ process.exitCode = 1;
175
+ }
176
+ );
@@ -0,0 +1,82 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- The child chart: W3C SCXML. Readable names travel in atlas:name; a final state's
3
+ atlas:done-event names the event the parent chart receives when checkout ends there. -->
4
+ <scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:atlas="https://github.com/crvouga/atlas/ns/1" version="1.0" name="Checkout" initial="choosing-how-to-pay" datamodel="null">
5
+ <atlas:meta>
6
+ <atlas:description>Paying for the order, by card or with a wallet.</atlas:description>
7
+ <atlas:timeEvents>{"Payment takes longer than a minute": "1 minute"}</atlas:timeEvents>
8
+ </atlas:meta>
9
+ <state id="choosing-how-to-pay" atlas:name="Choosing how to pay">
10
+ <atlas:meta>
11
+ <atlas:description>Card and wallet buttons, and the order total.</atlas:description>
12
+ <atlas:snapshot>pay-options</atlas:snapshot>
13
+ <atlas:confidence>confirmed</atlas:confidence>
14
+ <atlas:hints>["A card button", "A wallet button", "The order total"]</atlas:hints>
15
+ </atlas:meta>
16
+ <transition event="picks-card" atlas:name="Picks card" target="entering-card-details"/>
17
+ <transition event="picks-wallet" atlas:name="Picks wallet" target="confirming-with-the-wallet"/>
18
+ <transition event="closes-checkout" atlas:name="Closes checkout" target="checkout-abandoned"/>
19
+ </state>
20
+ <state id="entering-card-details" atlas:name="Entering card details">
21
+ <atlas:meta>
22
+ <atlas:description>A form for the card number, expiry and code.</atlas:description>
23
+ <atlas:snapshot>card-form</atlas:snapshot>
24
+ <atlas:confidence>confirmed</atlas:confidence>
25
+ <atlas:check>The pay button stays off until the card is complete</atlas:check>
26
+ </atlas:meta>
27
+ <transition event="submits-the-card" atlas:name="Submits the card" target="waiting-for-the-payment"/>
28
+ <transition event="goes-back-to-the-payment-options" atlas:name="Goes back to the payment options" target="choosing-how-to-pay"/>
29
+ </state>
30
+ <state id="confirming-with-the-wallet" atlas:name="Confirming with the wallet">
31
+ <atlas:meta>
32
+ <atlas:description>The wallet sheet asks the customer to confirm the payment.</atlas:description>
33
+ <atlas:snapshot>wallet-sheet</atlas:snapshot>
34
+ <atlas:confidence>confirmed</atlas:confidence>
35
+ </atlas:meta>
36
+ <transition event="confirms-with-the-wallet" atlas:name="Confirms with the wallet" target="waiting-for-the-payment"/>
37
+ <transition event="cancels-the-wallet" atlas:name="Cancels the wallet" target="choosing-how-to-pay"/>
38
+ </state>
39
+ <state id="waiting-for-the-payment" atlas:name="Waiting for the payment">
40
+ <atlas:meta>
41
+ <atlas:description>A spinner while the payment provider answers.</atlas:description>
42
+ <atlas:snapshot>paying</atlas:snapshot>
43
+ <atlas:confidence>confirmed</atlas:confidence>
44
+ <atlas:event>Payment requested</atlas:event>
45
+ </atlas:meta>
46
+ <transition event="payment-provider-approves-the-payment" atlas:name="Payment provider approves the payment" target="paid"/>
47
+ <transition event="payment-provider-declines-the-payment" atlas:name="Payment provider declines the payment" target="told-the-payment-was-declined"/>
48
+ <transition event="payment-takes-longer-than-a-minute" atlas:name="Payment takes longer than a minute" target="told-the-payment-is-slow"/>
49
+ </state>
50
+ <state id="told-the-payment-is-slow" atlas:name="Told the payment is slow">
51
+ <atlas:meta>
52
+ <atlas:description>A message says the payment is taking longer than usual, with "Check again".</atlas:description>
53
+ <atlas:snapshot>paying-slow</atlas:snapshot>
54
+ <atlas:confidence>assumed</atlas:confidence>
55
+ </atlas:meta>
56
+ <transition event="checks-the-payment-again" atlas:name="Checks the payment again" target="waiting-for-the-payment"/>
57
+ </state>
58
+ <state id="told-the-payment-was-declined" atlas:name="Told the payment was declined">
59
+ <atlas:meta>
60
+ <atlas:description>A message says the payment was declined, with "Try another way".</atlas:description>
61
+ <atlas:snapshot>payment-declined</atlas:snapshot>
62
+ <atlas:confidence>confirmed</atlas:confidence>
63
+ <atlas:event>Payment declined</atlas:event>
64
+ </atlas:meta>
65
+ <transition event="tries-another-way-to-pay" atlas:name="Tries another way to pay" target="choosing-how-to-pay"/>
66
+ </state>
67
+ <final id="paid" atlas:name="Paid" atlas:done-event="Payment goes through">
68
+ <atlas:meta>
69
+ <atlas:description>A check mark confirms the payment.</atlas:description>
70
+ <atlas:snapshot>paid</atlas:snapshot>
71
+ <atlas:confidence>confirmed</atlas:confidence>
72
+ <atlas:event>Payment captured</atlas:event>
73
+ </atlas:meta>
74
+ </final>
75
+ <final id="checkout-abandoned" atlas:name="Checkout abandoned" atlas:done-event="Leaves checkout">
76
+ <atlas:meta>
77
+ <atlas:description>Checkout closes and the cart is kept.</atlas:description>
78
+ <atlas:snapshot>checkout-closed</atlas:snapshot>
79
+ <atlas:confidence>confirmed</atlas:confidence>
80
+ </atlas:meta>
81
+ </final>
82
+ </scxml>
@@ -0,0 +1,129 @@
1
+ # Named paths through the composed chart. Hand-off events from Checkout are inserted automatically.
2
+ journeys:
3
+ Orders a drink and pays by card:
4
+ description: The everyday order, from the menu to picking the drink up.
5
+ tour: true
6
+ events:
7
+ - Picks a drink
8
+ - Picks a size
9
+ - Picks a milk
10
+ - Adds the drink to the cart
11
+ - Starts checkout
12
+ - Picks card
13
+ - Submits the card
14
+ - Payment provider approves the payment
15
+ - Barista starts the drink
16
+ - Barista finishes the drink
17
+ - Picks up the drink
18
+ endsIn:
19
+ - Order complete
20
+ Pays with a wallet:
21
+ description: The wallet confirms the payment instead of a card.
22
+ events:
23
+ - Picks a drink
24
+ - Picks a size
25
+ - Picks a milk
26
+ - Adds the drink to the cart
27
+ - Starts checkout
28
+ - Picks wallet
29
+ - Confirms with the wallet
30
+ - Payment provider approves the payment
31
+ endsIn:
32
+ - Paid, waiting for the barista
33
+ - Updates on
34
+ Card declined, then a wallet works:
35
+ description: The card is declined and the wallet goes through.
36
+ events:
37
+ - Picks a drink
38
+ - Picks a size
39
+ - Picks a milk
40
+ - Adds the drink to the cart
41
+ - Starts checkout
42
+ - Picks card
43
+ - Submits the card
44
+ - Payment provider declines the payment
45
+ - Tries another way to pay
46
+ - Picks wallet
47
+ - Confirms with the wallet
48
+ - Payment provider approves the payment
49
+ endsIn:
50
+ - Paid, waiting for the barista
51
+ Slow payment:
52
+ description: The payment provider takes more than a minute to answer.
53
+ events:
54
+ - Picks a drink
55
+ - Picks a size
56
+ - Picks a milk
57
+ - Adds the drink to the cart
58
+ - Starts checkout
59
+ - Picks card
60
+ - Submits the card
61
+ - Payment takes longer than a minute
62
+ - Checks the payment again
63
+ - Payment provider approves the payment
64
+ endsIn:
65
+ - Paid, waiting for the barista
66
+ Leaves checkout and comes back:
67
+ description: The customer closes checkout, then starts it again.
68
+ events:
69
+ - Picks a drink
70
+ - Picks a size
71
+ - Picks a milk
72
+ - Adds the drink to the cart
73
+ - Starts checkout
74
+ - Closes checkout
75
+ - Starts checkout
76
+ endsIn:
77
+ - Checking out
78
+ - Choosing how to pay
79
+ Drink left too long:
80
+ description: Nobody picks the drink up, so it is thrown away and refunded.
81
+ events:
82
+ - Picks a drink
83
+ - Picks a size
84
+ - Picks a milk
85
+ - Adds the drink to the cart
86
+ - Starts checkout
87
+ - Picks card
88
+ - Submits the card
89
+ - Payment provider approves the payment
90
+ - Barista starts the drink
91
+ - Barista finishes the drink
92
+ - Drink sits ready for ten minutes
93
+ - Orders again
94
+ endsIn:
95
+ - Browsing the menu
96
+ Turns off updates while waiting:
97
+ description: Updates go off while the drink is in the queue; the drink is still made.
98
+ events:
99
+ - Picks a drink
100
+ - Picks a size
101
+ - Picks a milk
102
+ - Adds the drink to the cart
103
+ - Starts checkout
104
+ - Picks wallet
105
+ - Confirms with the wallet
106
+ - Payment provider approves the payment
107
+ - Turns off updates
108
+ - Barista starts the drink
109
+ endsIn:
110
+ - Updates off
111
+ - Drink being made
112
+ Changes their mind about the drink:
113
+ description: The customer backs out while choosing the drink.
114
+ events:
115
+ - Picks a drink
116
+ - Picks a size
117
+ - Goes back to the menu
118
+ endsIn:
119
+ - Browsing the menu
120
+ Empties the cart:
121
+ description: The only drink is removed from the cart.
122
+ events:
123
+ - Picks a drink
124
+ - Picks a size
125
+ - Picks a milk
126
+ - Adds the drink to the cart
127
+ - Removes the last drink
128
+ endsIn:
129
+ - Browsing the menu
@@ -0,0 +1,14 @@
1
+ # Known issues
2
+
3
+ ## Drink being made
4
+
5
+ - The progress bar jumps back once. It settles after a second.
6
+
7
+ ## Drink ready for pickup → Picks up the drink
8
+
9
+ - The pickup button needs two taps on small screens.
10
+
11
+ ## Other
12
+
13
+ - `Updates off` shows the wrong icon.
14
+ - Nothing named here.