@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
@@ -0,0 +1,825 @@
1
+ # Reference: server
2
+
3
+ The Atlas server: the API results are uploaded to, the live report, and the viewer on one host. Import path `@crvouga/atlas/server`.
4
+
5
+ > Generated from the doc comments of `packages/server/src` by `bun run docs`. Do not edit: change the comment next to the code.
6
+
7
+ ### The Atlas server application
8
+
9
+ Source: `packages/server/src/app.ts`
10
+
11
+ `createAtlasServer` is the whole of a project's Atlas as one `fetch` handler: the API results are uploaded to, the live
12
+ report every viewer is shown, the gate, the server-sent event stream, the specs and runs the viewer reads, the viewer
13
+ itself, and the server's own description (`/api/openapi.json`, `/llms.txt`). What it knows lives in its backends (by
14
+ default a folder on its own disk), so replacing it loses nothing. Every error leaves as an RFC 9457 problem document; every
15
+ route is described in `openapi.ts` (a test holds the two together).
16
+
17
+ See docs/server.md
18
+
19
+ #### `AtlasServerOptions`
20
+
21
+ ```ts
22
+ export type AtlasServerOptions = {
23
+ /** Every backend, read together. */
24
+ readonly backends: readonly BackendInput[];
25
+ /** The id of the backend uploads go to. */
26
+ readonly write: string;
27
+ /** Operational lease storage. Defaults to the write backend; HTTP relays use their own local store. */
28
+ readonly liveStore?: ObjectStore;
29
+ readonly tokens?: readonly ResolvedToken[];
30
+ readonly anonymousRead?: boolean;
31
+ /** The built viewer. Without it, only the API is served. */
32
+ readonly site?: string;
33
+ readonly outlineBranch?: string;
34
+ readonly include?: (layer: LayerHeader) => boolean;
35
+ readonly refreshMs?: number;
36
+ readonly limits?: { readonly maxObjectMiB?: number; readonly maxJsonMiB?: number; readonly maxStreams?: number };
37
+ readonly heartbeatMs?: number;
38
+ /** Producer lease timeout; default 30 seconds. */
39
+ readonly runTimeoutMs?: number;
40
+ /** Maximum time without progress; default 15 minutes, 0 disables. */
41
+ readonly runStallMs?: number;
42
+ readonly log?: (line: Record<string, unknown>) => void;
43
+ readonly now?: () => number;
44
+ readonly version?: string;
45
+ /** Admin configuration persistence, supplied by atlas serve. Changes apply on restart. */
46
+ readonly settings?: ServerSettings;
47
+ /** Extra runtime configuration written into the page. */
48
+ readonly page?: Record<string, unknown>;
49
+ };
50
+ ```
51
+
52
+ What the server is built from: its `backends` (read together) and which one takes uploads (`write`), `tokens`, the built `site`, the report's filters (`include`, `outlineBranch`), `limits`, timings, `log`, and `now` for tests.
53
+
54
+ #### `AtlasServer`
55
+
56
+ ```ts
57
+ export type AtlasServer = {
58
+ readonly fetch: (request: Request) => Promise<Response>;
59
+ readonly index: ReportIndex;
60
+ readonly events: EventHub;
61
+ /** The routes the server answers, as registered: what the OpenAPI document must describe (a test holds the two together). */
62
+ readonly routes: readonly { readonly method: string; readonly path: string }[];
63
+ /** Resolves when the first pass over the backends is done. */
64
+ readonly ready: Promise<void>;
65
+ /** Stop refreshing and end every live connection. */
66
+ close(): void;
67
+ };
68
+ ```
69
+
70
+ A running server application: `fetch` (serve requests), `index` (the live report), `events` (the viewers), `routes` (what it answers), `ready` (the first pass over the backends is done) and `close`.
71
+
72
+ #### `createAtlasServer`
73
+
74
+ ```ts
75
+ export function createAtlasServer(options: AtlasServerOptions): AtlasServer
76
+ ```
77
+
78
+ The whole of a project's Atlas on one process: the API that results are uploaded to, the live report every
79
+ viewer is shown, and the viewer itself. All of it is under one host, `/api` for the API and `/` for the page.
80
+ What it knows lives in its backends (by default a folder on its own disk), so replacing it loses nothing.
81
+
82
+ ### Authentication and roles
83
+
84
+ Source: `packages/server/src/auth.ts`
85
+
86
+ Who is asking, and may they. Tokens have a role (`read` < `publish` < `admin`) and are compared in constant time. Reading
87
+ accepts a Bearer token or the browser's sign-in box (any user name, the token as the password); changing anything needs
88
+ the Bearer header, because a browser sends the sign-in box's credentials to any page that asks, which would let another
89
+ site upload with them. A server with no tokens is open, and refuses to listen beyond this machine unless told it may.
90
+
91
+ #### `Identity`
92
+
93
+ ```ts
94
+ export type Identity = {
95
+ readonly name: string;
96
+ readonly role: ServerRole;
97
+ /** `bearer` for a token in a header, `basic` for the browser's sign-in box, `none` for a server with no tokens. */
98
+ readonly via: 'bearer' | 'basic' | 'none';
99
+ };
100
+ ```
101
+
102
+ Who a request is: the token's `name` (never the token), its `role`, and how it was presented (`bearer`, `basic`, or `none` for an open server or an anonymous reader).
103
+
104
+ #### `Verdict`
105
+
106
+ ```ts
107
+ export type Verdict =
108
+ | { readonly ok: true; readonly identity: Identity }
109
+ | { readonly ok: false; readonly status: 401 | 403; readonly message: string };
110
+ ```
111
+
112
+ The answer to "may this request do that": allowed with the identity, or refused with the status to answer (`401` no or unknown token, `403` a known token that may not) and a message that says what to do.
113
+
114
+ #### `createAuth`
115
+
116
+ ```ts
117
+ export function createAuth(tokens: readonly ResolvedToken[], anonymousRead: boolean)
118
+ ```
119
+
120
+ Who is asking, and may they. A server with no tokens is open (and refuses to listen beyond this machine
121
+ unless told it may). With tokens, every request must carry one, except where `anonymousRead` lets anyone look.
122
+
123
+ Changing anything needs a token in an `Authorization: Bearer` header, never the browser's sign-in box: the
124
+ browser sends that box's credentials on its own to any page that asks, which would let another site upload
125
+ with them.
126
+
127
+ #### `Auth`
128
+
129
+ ```ts
130
+ export type Auth = ReturnType<typeof createAuth>;
131
+ ```
132
+
133
+ The authentication of one server: `identify` (who is this), `check` (may they, for a needed role) and `open` (the server has no tokens).
134
+
135
+ ### Server configuration
136
+
137
+ Source: `packages/server/src/config.ts`
138
+
139
+ Loads how the server runs: `atlas.server.json`, then environment variables, then flags, each overriding the last, checked
140
+ against `ServerConfigSchema` and resolved (paths made absolute, backends named, tokens read). Every mistake is a
141
+ `ConfigError` that says what to change, and a server that would listen beyond this machine with no tokens refuses to
142
+ start. `SERVER_SETTINGS` documents every setting once; the table in docs/server.md is generated from it and a test proves
143
+ each row.
144
+
145
+ See docs/server.md#configuration
146
+
147
+ #### `ResolvedToken`
148
+
149
+ ```ts
150
+ export type ResolvedToken = { readonly name: string; readonly role: ServerRole; readonly token: string };
151
+ ```
152
+
153
+ A token as the server holds it: the `name` it is shown under in logs, its `role`, and the secret `token`.
154
+
155
+ #### `BackendSpec`
156
+
157
+ ```ts
158
+ export type BackendSpec = { readonly id: string; readonly label: string; readonly url: string };
159
+ ```
160
+
161
+ A backend as configured: its `id`, the `label` people see, and the `url` (a folder, `s3://…`, or another server) to open.
162
+
163
+ #### `ResolvedServerConfig`
164
+
165
+ ```ts
166
+ export type ResolvedServerConfig = Omit<ServerConfig, 'backends' | 'auth' | 'write'> & {
167
+ /** The folder that is the default backend, absolute. */
168
+ readonly data: string;
169
+ /** Every backend, the data folder first. All are read; uploads go to `writeId`. */
170
+ readonly backends: readonly BackendSpec[];
171
+ readonly writeId: string;
172
+ readonly tokens: readonly ResolvedToken[];
173
+ readonly anonymousRead: boolean;
174
+ readonly insecure: boolean;
175
+ /** Where the config came from, for the first line of the log. */
176
+ readonly configFile: string | null;
177
+ };
178
+ ```
179
+
180
+ The configuration the server runs with: the file, then the environment, then the flags, checked and resolved.
181
+
182
+ #### `ConfigError`
183
+
184
+ ```ts
185
+ export class ConfigError extends Error {}
186
+ ```
187
+
188
+ A configuration that cannot be used. The message says what to change; `atlas serve` prints it and exits 2.
189
+
190
+ #### `SERVER_FLAGS`
191
+
192
+ ```ts
193
+ export const SERVER_FLAGS: readonly string[]
194
+ ```
195
+
196
+ Every flag `atlas serve` accepts, with its `--`.
197
+
198
+ #### `ServerSetting`
199
+
200
+ ```ts
201
+ export type ServerSetting = {
202
+ /** What it sets, in words. */
203
+ readonly summary: string;
204
+ /** The key in `atlas.server.json` (dotted for nested keys). */
205
+ readonly key: string;
206
+ /** The command-line flag, with its value placeholder, or null when there is none. */
207
+ readonly flag: string | null;
208
+ /** The environment variables, the first that is set wins; empty when there are none. */
209
+ readonly env: readonly string[];
210
+ /** What it is when nothing sets it. */
211
+ readonly default: string;
212
+ /**
213
+ * How the documentation is held to the code: giving `value` through the environment variable (or the flag) must make
214
+ * `read` of the resolved configuration equal `expected`. A test runs every setting's example both ways.
215
+ */
216
+ readonly example: { readonly value: string; readonly read: (config: ResolvedServerConfig) => unknown; readonly expected: unknown };
217
+ };
218
+ ```
219
+
220
+ One setting of the server as an operator meets it: the config key, the flag, the environment variables, and what it does.
221
+
222
+ #### `SERVER_SETTINGS`
223
+
224
+ ```ts
225
+ export const SERVER_SETTINGS: readonly ServerSetting[]
226
+ ```
227
+
228
+ Every setting that can be given by flag or environment, documented once. `docs/server.md` renders its table from
229
+ this list, and a test proves each row: its example, through the flag and through the environment, changes the
230
+ configuration as the row says. A setting added to the loader without a row here is therefore not documented in the
231
+ table; one documented here that the loader ignores fails the test.
232
+
233
+ #### `SERVER_USAGE`
234
+
235
+ ```ts
236
+ export const SERVER_USAGE = …
237
+ ```
238
+
239
+ The text `atlas serve --help` prints. Also the source of the `atlas serve` section of `docs/reference/cli.md`.
240
+
241
+ #### `loadServerConfig`
242
+
243
+ ```ts
244
+ export function loadServerConfig(argv: readonly string[], env: Env, cwd: string, read: (file: string) => string = file => readFileSync(file, 'utf8')): ResolvedServerConfig
245
+ ```
246
+
247
+ Read the file named by `--config`/`ATLAS_CONFIG`, or `atlas.server.json` in the folder if there is one, lay the
248
+ environment and then the flags over it, and check the result. Every problem is a {@link ConfigError} that says
249
+ what to change.
250
+
251
+ #### `assertSafeToListen`
252
+
253
+ ```ts
254
+ export function assertSafeToListen(config: Pick<ResolvedServerConfig, 'host' | 'tokens' | 'insecure'>): void
255
+ ```
256
+
257
+ A server that anyone on the network can upload to must say who may.
258
+
259
+ ### `atlas dev`
260
+
261
+ Source: `packages/server/src/dev.ts`
262
+
263
+ Runs the same server as `atlas serve` on a port of its own, with the client's Vite dev server in front of it. Vite proxies
264
+ `/api` (server-sent events included) to the server and writes the same address book into the page, so the browser, the
265
+ uploaders and the client all use one host, exactly as in production, and a change to the client shows at once.
266
+
267
+ #### `DEV_USAGE`
268
+
269
+ ```ts
270
+ export const DEV_USAGE = …
271
+ ```
272
+
273
+ The text `atlas dev --help` prints. Also the source of the `atlas dev` section of `docs/reference/cli.md`.
274
+
275
+ #### `devMain`
276
+
277
+ ```ts
278
+ export async function devMain(argv: readonly string[], io: ServeIo): Promise<number>
279
+ ```
280
+
281
+ `atlas dev`.
282
+
283
+ ### Server-sent events
284
+
285
+ Source: `packages/server/src/events.ts`
286
+
287
+ What the server tells every connected viewer the moment it happens. A viewer that misses some (a dropped connection, a
288
+ laptop that slept) loses nothing: report events announce changes, run events carry bounded progress snapshots, and a viewer reads authoritative state again
289
+ when it reconnects. `EventHub` encodes each event once for all viewers, sends a named `ping` every heartbeat so proxies
290
+ keep the connection and a quiet server is told apart from a dead one, refuses past a maximum number of viewers (they poll
291
+ instead), and lets go of a viewer that has stopped reading rather than hold its backlog.
292
+
293
+ See docs/server.md#streaming
294
+
295
+ #### `EventName`
296
+
297
+ ```ts
298
+ export type EventName = 'hello' | 'report' | 'atlas:change' | 'run' | 'projects';
299
+ ```
300
+
301
+ The events the server publishes: `hello` (sent first to a new viewer), `report` (layers arrived) `atlas:change` (specs or runs changed), `run` (a bounded live lease snapshot), and `projects` (project discovery changed). `ping` is the heartbeat, sent by the hub itself.
302
+
303
+ #### `EventHub`
304
+
305
+ ```ts
306
+ export class EventHub
307
+ ```
308
+
309
+ The viewers connected to `/api/events` and how to reach them all. One hub per server.
310
+
311
+ - `get count(): number { return this.#subscribers.size; }` — How many viewers are connected right now.
312
+ - `publish(name: EventName, data: unknown): void` — Tell every viewer. `data` is JSON.
313
+ - `stream(request: Request, greeting: () => unknown): Response` — A stream for one viewer, starting with `hello` (what `greeting` returns). It ends when the viewer goes.
314
+ - `close(): void` — End every stream, for shutting down.
315
+
316
+ ### HTTP host for a fetch handler
317
+
318
+ Source: `packages/server/src/host.ts`
319
+
320
+ `listen` serves any `(Request) => Promise<Response>` over HTTP: with `Bun.serve` when running on Bun, with a `node:http`
321
+ bridge (streaming bodies in and out, so server-sent events work) everywhere else. The server's behaviour is the same on
322
+ both; `bun run release:smoke` proves it under each. Bodies over `maxBodyBytes` are refused by the runtime before the
323
+ handler sees them.
324
+
325
+ #### `RunningServer`
326
+
327
+ ```ts
328
+ export type RunningServer = {
329
+ readonly port: number;
330
+ readonly url: string;
331
+ /** Stop accepting, let requests in flight finish for up to `graceMs`, then end what is left. */
332
+ close(graceMs?: number): Promise<void>;
333
+ };
334
+ ```
335
+
336
+ A server that is listening: the `port` it got (useful when asked for `0`), its `url`, and `close`.
337
+
338
+ #### `ListenOptions`
339
+
340
+ ```ts
341
+ export type ListenOptions = {
342
+ readonly port: number;
343
+ readonly host: string;
344
+ /** The largest request body to read, in bytes. */
345
+ readonly maxBodyBytes: number;
346
+ };
347
+ ```
348
+
349
+ Where to listen (`port`, `host`) and the largest request body the runtime will accept.
350
+
351
+ #### `listen`
352
+
353
+ ```ts
354
+ export async function listen(handler: Handler, options: ListenOptions): Promise<RunningServer>
355
+ ```
356
+
357
+ Serve a fetch handler. On Bun, which is what Atlas is made for, that is `Bun.serve`: one native server for the
358
+ API, the live streams and the page. On Node it is the same handler behind `node:http`, so the package still runs
359
+ where Bun is not installed.
360
+
361
+ ### Server package entry point (`@crvouga/atlas/server`)
362
+
363
+ Source: `packages/server/src/index.ts`. Import: `@crvouga/atlas/server`
364
+
365
+ Everything needed to run the Atlas server from code: `createAtlasServer` (a `fetch` handler with the live report, uploads
366
+ and the viewer), `listen` (serve it over HTTP on Bun or Node), `loadServerConfig` (the file, the environment and the flags
367
+ as one checked configuration), `serveMain` (what `atlas serve` runs), `EventHub`, `createAuth`, and the upload checks.
368
+
369
+ See docs/server.md
370
+
371
+ ### live-runs.ts
372
+
373
+ Source: `packages/server/src/live-runs.ts`
374
+
375
+ @module Live run leases
376
+ Tracks producer heartbeats independently of progress, publishes completed checks incrementally, and persists
377
+ bounded run summaries. A server restart interrupts outstanding leases rather than inventing continued progress.
378
+
379
+ #### `LiveRunError`
380
+
381
+ ```ts
382
+ export class LiveRunError extends Error
383
+ ```
384
+
385
+ A refused run update: 403 another publisher, 404 unknown run, 409 stale/terminal run, or 429 capacity.
386
+
387
+ #### `LiveRuns`
388
+
389
+ ```ts
390
+ export class LiveRuns
391
+ ```
392
+
393
+ One server's live feed. Heartbeats never create result layers. Persisted summaries contain at most 20 recent
394
+ checks and 10 active checks; completed results live in ordinary immutable layers. Leases expire by server time.
395
+
396
+ **Example**
397
+
398
+ ```ts
399
+ const live = new LiveRuns({ store, timeoutMs: 30_000, stalledMs: 900_000, onChange: () => {}, onLayer: async () => {} });
400
+ ```
401
+
402
+ - `readonly ready: Promise<void>;` — Resolves after restoring summaries and interrupting leases left by a previous server process.
403
+ - `async list(): Promise<LiveRun[]>` — Read the most recent 50 summaries. Progress detail and counters are already bounded and cached.
404
+ - `async start(input: Start, owner: string): Promise<LiveRun>` — Register one producer lease. Retrying an identical start is idempotent.
405
+ - `async heartbeat(id: string, owner: string): Promise<void>` — Renew liveness by server receipt time, independently of whether a test made progress.
406
+ - `async update(id: string, input: Update, owner: string): Promise<LiveRun>` — Apply one ordered progress batch and publish its completed checks before acknowledging it.
407
+ - `async sweep(): Promise<void>` — Expire silent producers and optional progress stalls. Heartbeats cannot revive an expired run.
408
+
409
+ ### llms.txt of a running server
410
+
411
+ Source: `packages/server/src/llms.ts`
412
+
413
+ The plain-text guide ([llms.txt](https://llmstxt.org)) a server serves about itself at `GET /llms.txt`, for an AI
414
+ agent that was handed nothing but the server's address. It is written from this server's own settings (its
415
+ address, whether it needs a token), so what it says is true of the server that says it, and it points at the
416
+ machine-readable description (`/api/openapi.json`) rather than repeating it.
417
+
418
+ #### `LlmsContext`
419
+
420
+ ```ts
421
+ export type LlmsContext = {
422
+ /** The address clients use, such as `https://atlas.example.com`, no trailing slash. */
423
+ readonly url: string;
424
+ /** True when the server has no tokens: anyone who can reach it may upload. */
425
+ readonly open: boolean;
426
+ /** The id of the backend uploads go to. */
427
+ readonly write: string;
428
+ };
429
+ ```
430
+
431
+ What the guide says about the server that serves it.
432
+
433
+ #### `llmsTxt`
434
+
435
+ ```ts
436
+ export function llmsTxt(context: LlmsContext): string
437
+ ```
438
+
439
+ The guide for one server, Markdown. Stable in structure: an agent may read it by its headings.
440
+
441
+ ### `atlas serve`
442
+
443
+ Source: `packages/server/src/main.ts`
444
+
445
+ Starts the Atlas server from its configuration: opens every backend (creating the data folder), proves the upload
446
+ backend can be written to before listening, finds or builds the client, listens at once (so a liveness probe finds the
447
+ process while a large backend is still being read), and stops cleanly on SIGTERM or SIGINT. `serverOptionsOf` is shared
448
+ with `atlas dev`, so the two run the same server.
449
+
450
+ See docs/server.md#run-it
451
+
452
+ #### `ServeIo`
453
+
454
+ ```ts
455
+ export type ServeIo = { readonly out: (text: string) => void; readonly env?: Env; readonly cwd?: string; readonly signal?: AbortSignal };
456
+ ```
457
+
458
+ What `serveMain` and `devMain` are given besides arguments: where output goes, and, for tests and embedding, the environment, working directory and an `AbortSignal` that stops the server (otherwise SIGTERM and SIGINT do).
459
+
460
+ #### `openConfiguredBackends`
461
+
462
+ ```ts
463
+ export function openConfiguredBackends(config: ResolvedServerConfig, env: Env, cwd: string): (BackendInput & { readonly writable: boolean })[]
464
+ ```
465
+
466
+ Open every backend of a configuration. The data folder is made if it is not there.
467
+
468
+ #### `serverOptionsOf`
469
+
470
+ ```ts
471
+ export function serverOptionsOf(config: ResolvedServerConfig, backends: ReturnType<typeof openConfiguredBackends>, log?: (line: Record<string, unknown>) => void): AtlasServerOptions
472
+ ```
473
+
474
+ What `createAtlasServer` is given for a configuration: `atlas serve` and `atlas dev` run the same server.
475
+
476
+ #### `serveMain`
477
+
478
+ ```ts
479
+ export async function serveMain(argv: readonly string[], io: ServeIo): Promise<number>
480
+ ```
481
+
482
+ `atlas serve`. Runs until it is told to stop; returns the exit code.
483
+
484
+ ### OpenAPI document of the Atlas server
485
+
486
+ Source: `packages/server/src/openapi.ts`
487
+
488
+ The server's HTTP API described as an OpenAPI 3.1 document (JSON Schema 2020-12 inside), generated from the
489
+ operation table below and the Zod schemas of `packages/schema/src/api.ts`. It is served at `GET /api/openapi.json`,
490
+ shipped as `@crvouga/atlas/openapi.json`, and committed as `packages/server/openapi.json` (`bun run docs` rewrites
491
+ it; a test fails when it differs). Any OpenAPI tool can generate a client, a mock or a test suite from it.
492
+
493
+ The table is held to the code by a test: every route the server registers must have an operation here and every
494
+ operation here must be a route the server registers. Adding a route without describing it fails the build.
495
+
496
+ Stability: this API only grows within `API_VERSION`: optional parameters, optional response fields, new
497
+ operations and new events. See AGENTS.md ("The server is a living application").
498
+
499
+ #### `API_VERSION`
500
+
501
+ ```ts
502
+ export const API_VERSION = …
503
+ ```
504
+
505
+ The version of the API described, `major.minor.patch`: the minor grows when an operation or field is added, the major never within `/api`.
506
+
507
+ #### `Role`
508
+
509
+ ```ts
510
+ export type Role = 'none' | 'read' | 'publish' | 'admin';
511
+ ```
512
+
513
+ Who may call an operation: `none` (anyone), or the least role that may (`read` < `publish` < `admin`).
514
+
515
+ #### `Operation`
516
+
517
+ ```ts
518
+ export type Operation = {
519
+ /** The route as Hono registers it, `METHOD /path` (`:name` for a parameter, `*` for the rest of the path). */
520
+ readonly route: string;
521
+ /** The same route as OpenAPI writes it, `/path/{name}`. */
522
+ readonly path: string;
523
+ readonly operationId: string;
524
+ readonly tag: string;
525
+ readonly summary: string;
526
+ /** What it does and how to use it, written for a client that has read nothing else (Markdown). */
527
+ readonly description: string;
528
+ readonly role: Role;
529
+ readonly parameters?: readonly Param[];
530
+ readonly body?: Body;
531
+ readonly responses: Readonly<Record<string, Response>>;
532
+ };
533
+ ```
534
+
535
+ One operation of the API, and the route the server registers for it.
536
+
537
+ #### `OPERATIONS`
538
+
539
+ ```ts
540
+ export const OPERATIONS: readonly Operation[]
541
+ ```
542
+
543
+ Every node operation and the same stable report protocol inside each project namespace.
544
+
545
+ #### `NOT_OPERATIONS`
546
+
547
+ ```ts
548
+ export const NOT_OPERATIONS: ReadonlyMap<string, string>
549
+ ```
550
+
551
+ Routes the server registers that are not operations of this API, each with the reason. The coverage test skips
552
+ these and only these.
553
+
554
+ #### `openApiDocument`
555
+
556
+ ```ts
557
+ export function openApiDocument(options: { readonly serverUrl?: string } = {}): Record<string, unknown>
558
+ ```
559
+
560
+ The OpenAPI 3.1 document of the API. `serverUrl` (such as `https://atlas.example.com`) is written into `servers` when given.
561
+
562
+ ### Problem documents
563
+
564
+ Source: `packages/server/src/problem.ts`
565
+
566
+ Every error the server answers is an [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem document
567
+ (`application/problem+json`): `type`, `title`, `status`, `detail`, and `error`, a copy of `detail` for clients
568
+ written before the standard was adopted. Handlers answer however is natural (`{ error }`); one place,
569
+ {@link asProblem}, makes every error response a problem document, so none can differ.
570
+
571
+ #### `problemResponse`
572
+
573
+ ```ts
574
+ export function problemResponse(status: number, detail: string, headers: Record<string, string> = {}): Response
575
+ ```
576
+
577
+ A response for a problem, built directly (used where no handler is involved, such as authentication).
578
+
579
+ #### `asProblem`
580
+
581
+ ```ts
582
+ export async function asProblem(response: Response): Promise<Response>
583
+ ```
584
+
585
+ The response made into a problem document when it is an error (status 400 or more) with a JSON body naming an
586
+ `error`. Headers (`WWW-Authenticate`, `Retry-After`, `Allow`) and any other body fields are kept. Anything else,
587
+ including every success, is returned as it is.
588
+
589
+ ### projects.ts
590
+
591
+ Source: `packages/server/src/projects.ts`
592
+
593
+ @module Project routing
594
+ One node serves isolated project stores through the same authenticated API. Legacy unqualified requests address
595
+ the default project; named projects use scoped stores without rewriting uploaded report documents.
596
+
597
+ #### `projectServer`
598
+
599
+ ```ts
600
+ export function projectServer(options: AtlasServerOptions, create: (options: AtlasServerOptions) => AtlasServer): AtlasServer
601
+ ```
602
+
603
+ Wrap the single-project protocol in project selection. Auth, upload validation and composition stay identical.
604
+
605
+ ### settings-page.ts
606
+
607
+ Source: `packages/server/src/settings-page.ts`
608
+
609
+ @module Settings page
610
+ A standalone administrator form, styled with the Atlas client's shared design tokens.
611
+ Credentials remain in page memory; the settings API owns authorization and validation.
612
+
613
+ #### `SETTINGS_PAGE`
614
+
615
+ ```ts
616
+ export const SETTINGS_PAGE = …
617
+ ```
618
+
619
+ The settings form and its browser controller, also usable without a built client.
620
+
621
+ #### `renderSettingsPage`
622
+
623
+ ```ts
624
+ export function renderSettingsPage(): Promise<string>
625
+ ```
626
+
627
+ Render Settings using the exact design tokens shipped with the Atlas client. Loads and caches the stylesheet
628
+ on first request, never at import time. Minimal neutral tokens keep embedded API-only servers usable too.
629
+
630
+ **Example**
631
+
632
+ ```ts
633
+ const html = await renderSettingsPage();
634
+ ```
635
+
636
+ ### settings.ts
637
+
638
+ Source: `packages/server/src/settings.ts`
639
+
640
+ @module Persisted server settings
641
+ The admin UI edits storage and report configuration in atlas.server.json. Changes take effect on restart;
642
+ environment variables and flags keep their documented precedence. Authentication is managed outside this UI.
643
+
644
+ #### `SettingsSnapshot`
645
+
646
+ ```ts
647
+ export type SettingsSnapshot = { readonly revision: string; readonly settings: Record<string, unknown>; readonly active: Record<string, unknown>; readonly restartRequired: boolean; readonly precedence: string };
648
+ ```
649
+
650
+ The persisted editable settings, active settings and a revision for optimistic concurrency. Authentication token settings are excluded.
651
+
652
+ #### `ServerSettings`
653
+
654
+ ```ts
655
+ export type ServerSettings = { read(): Promise<SettingsSnapshot>; save(settings: unknown, revision: string): Promise<SettingsSnapshot> };
656
+ ```
657
+
658
+ Storage for the admin API; saving is serialized and refuses a stale revision.
659
+
660
+ #### `fileServerSettings`
661
+
662
+ ```ts
663
+ export function fileServerSettings(config: ResolvedServerConfig, argv: readonly string[], env: Readonly<Record<string, string | undefined>>, cwd: string): ServerSettings
664
+ ```
665
+
666
+ Manage the server's configuration file with atomic replacement, preserving authentication and unrelated fields.
667
+ Validates both the file alone and the effective configuration before saving. Never migrates or deletes report data.
668
+ Changes need a server restart; deployment environment variables and flags override the file.
669
+
670
+ **Example**
671
+
672
+ ```ts
673
+ const settings = fileServerSettings(config, argv, process.env, process.cwd());
674
+ ```
675
+
676
+ ### Finding the client
677
+
678
+ Source: `packages/server/src/site.ts`
679
+
680
+ Locates the built client a server serves: the folder named by `--site`, `./atlas-site`, or one built once into the user's
681
+ cache from the client source shipped in the package (`atlas client build --no-data`). The build is the same for every
682
+ project because the server writes its own address book into the page, so it is built at most once per installed version.
683
+
684
+ #### `clientMain`
685
+
686
+ ```ts
687
+ export async function clientMain(argv: readonly string[]): Promise<number>
688
+ ```
689
+
690
+ Run the Atlas client build tools. Returns the child's exit code; throws when the client is missing.
691
+
692
+ #### `visualizerRoot`
693
+
694
+ ```ts
695
+ export function visualizerRoot(): string | null
696
+ ```
697
+
698
+ Where the client's source is, in this repository and in an installed package.
699
+
700
+ #### `buildSite`
701
+
702
+ ```ts
703
+ export async function buildSite(out: string, log: (text: string) => void): Promise<boolean>
704
+ ```
705
+
706
+ Build the client once into a folder, for a server that was not given a prebuilt one.
707
+
708
+ #### `findSite`
709
+
710
+ ```ts
711
+ export async function findSite(named: string | undefined, cwd: string, log: (text: string) => void): Promise<string | null>
712
+ ```
713
+
714
+ The client to serve: the one named, a build beside the project, or one built into the user's cache.
715
+
716
+ ### Store protocol routes
717
+
718
+ Source: `packages/server/src/store-api.ts`
719
+
720
+ The `ObjectStore` interface over HTTP at `/api/store`: list keys under `layers/`, read and probe an object, upload one
721
+ (checked by `validateUpload`, immutable once stored) and remove a scratch object. This is what `httpStore` talks to. An
722
+ upload is told to the report only after it is stored, and a layer's manifest, parsed while it was checked, is handed on so
723
+ it is not read again. Everything read is served as untrusted bytes (never sniffed, never run).
724
+
725
+ See docs/server.md#the-store-protocol
726
+
727
+ #### `StoreApiOptions`
728
+
729
+ ```ts
730
+ export type StoreApiOptions = {
731
+ readonly store: ObjectStore;
732
+ readonly auth: Auth;
733
+ readonly maxObjectBytes: number;
734
+ /** Told after something was uploaded: its key, and what kind of thing it is. */
735
+ readonly onStored: (key: string, kind: string, layer?: ReportLayer) => void | Promise<void>;
736
+ };
737
+ ```
738
+
739
+ What the store routes need: the `store` they read and write, the `auth` that decides who may, the largest object accepted, and `onStored`, told after each upload with its key, its kind and (for a layer catalog entry) the layer already parsed.
740
+
741
+ #### `readLimited`
742
+
743
+ ```ts
744
+ export async function readLimited(request: Request, limit: number): Promise<Uint8Array>
745
+ ```
746
+
747
+ Read a request body, refusing as soon as it is over the limit rather than after holding it all.
748
+
749
+ #### `storeApi`
750
+
751
+ ```ts
752
+ export function storeApi(options: StoreApiOptions)
753
+ ```
754
+
755
+ The Hono app of the store protocol, to be mounted at `/api/store`. Reads need role `read`; writes need `publish` through a Bearer token.
756
+
757
+ ### Upload validation
758
+
759
+ Source: `packages/server/src/validate.ts`
760
+
761
+ What the server checks before it stores an object, so one bad upload cannot corrupt the report for everyone: the key is
762
+ one Atlas writes (`classify`), a layer's content hashes to its id, blobs and spec files are what their names say, a
763
+ document's files and a catalog entry's document are already there (so nothing half-uploaded is visible), and a run
764
+ passed its privacy scan. Refusals are `Refusal`s carrying the HTTP status to answer. Layers are immutable: the same
765
+ bytes again are fine, other bytes under the same key are not.
766
+
767
+ See docs/server.md#what-the-server-refuses
768
+
769
+ #### `Refusal`
770
+
771
+ ```ts
772
+ export class Refusal extends Error
773
+ ```
774
+
775
+ Why an upload was not accepted. The status is what to answer.
776
+
777
+ #### `UploadKind`
778
+
779
+ ```ts
780
+ export type UploadKind = (typeof KINDS)[number]['kind'];
781
+ ```
782
+
783
+ What a key names: `layer`, `layer-catalog`, `blob`, `spec-body`, `spec-set`, `spec-catalog`, `run-manifest`, `run-catalog`, `run-file` or `scratch` (what `doctor` writes to try the store).
784
+
785
+ #### `validKey`
786
+
787
+ ```ts
788
+ export function validKey(key: string): boolean
789
+ ```
790
+
791
+ Is this a key a client may name? No traversal, no odd characters, and under `layers/`.
792
+
793
+ #### `classify`
794
+
795
+ ```ts
796
+ export function classify(key: string): { kind: UploadKind; id: string | null } | null
797
+ ```
798
+
799
+ What kind of object a key names and the id inside it (the layer id, the digest…), or null when it is not a key Atlas writes.
800
+
801
+ #### `isCatalog`
802
+
803
+ ```ts
804
+ export const isCatalog = …
805
+ ```
806
+
807
+ Catalog entries are what makes something visible, so they are the last thing a client writes.
808
+
809
+ #### `validateUpload`
810
+
811
+ ```ts
812
+ export async function validateUpload(key: string, bytes: Uint8Array, store: ObjectStore, parsedLayer?: (layer: ReportLayer) => void): Promise<UploadKind>
813
+ ```
814
+
815
+ Check an object before it is stored. What is checked is what would otherwise corrupt the report for everyone:
816
+ a layer whose content is not its name, a catalog entry for something not there yet, a run that failed its
817
+ privacy scan. Everything that is checked is checked cheaply, from the bytes in hand.
818
+
819
+ #### `sameBytes`
820
+
821
+ ```ts
822
+ export async function sameBytes(store: ObjectStore, key: string, bytes: Uint8Array): Promise<'absent' | 'same' | 'different'>
823
+ ```
824
+
825
+ Is this the same object already? Layers are immutable: the same bytes again is fine, other bytes under the same key is not.