@crvouga/atlas 0.10.2 → 0.12.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 (114) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +7 -0
  3. package/dist/reports/src/catalog-health.d.ts +142 -0
  4. package/dist/reports/src/catalog-health.js +257 -0
  5. package/dist/reports/src/test-catalog.d.ts +8 -0
  6. package/dist/reports/src/test-catalog.js +5 -1
  7. package/dist/schema/src/api.d.ts +79 -0
  8. package/dist/schema/src/api.js +50 -0
  9. package/dist/server/src/app.js +9 -0
  10. package/dist/server/src/llms.js +1 -0
  11. package/dist/server/src/openapi.js +18 -2
  12. package/dist/server/src/settings-page.d.ts +4 -4
  13. package/dist/server/src/settings-page.js +17 -78
  14. package/docs/reference/http-api.md +34 -0
  15. package/docs/reference/reports.md +224 -0
  16. package/docs/reference/schema.md +10 -0
  17. package/docs/reference/server.md +4 -4
  18. package/docs/server.md +10 -0
  19. package/docs/ui.md +142 -0
  20. package/docs/workspaces.md +130 -0
  21. package/llms-full.txt +322 -0
  22. package/llms.txt +2 -0
  23. package/package.json +17 -10
  24. package/packages/schema/schemas/catalog-health.schema.json +400 -0
  25. package/packages/server/openapi.json +596 -0
  26. package/packages/visualizer/src/admin/SettingsPage.tsx +456 -0
  27. package/packages/visualizer/src/admin/main.tsx +11 -0
  28. package/packages/visualizer/src/app/AppShell.tsx +62 -38
  29. package/packages/visualizer/src/app/gazetteer.tsx +90 -83
  30. package/packages/visualizer/src/app/router.tsx +33 -15
  31. package/packages/visualizer/src/components/ActivityIndicator.tsx +4 -5
  32. package/packages/visualizer/src/components/DataIssues.tsx +36 -54
  33. package/packages/visualizer/src/components/Header.tsx +197 -125
  34. package/packages/visualizer/src/components/Legend.tsx +13 -41
  35. package/packages/visualizer/src/components/ProjectPicker.tsx +61 -26
  36. package/packages/visualizer/src/components/Screen.tsx +80 -71
  37. package/packages/visualizer/src/components/SpecLogo.tsx +15 -0
  38. package/packages/visualizer/src/components/Status.tsx +20 -34
  39. package/packages/visualizer/src/components/labels.tsx +8 -3
  40. package/packages/visualizer/src/components/spec-logos/APACHE-2.0.txt +206 -0
  41. package/packages/visualizer/src/components/spec-logos/CAMUNDA-MIT.txt +21 -0
  42. package/packages/visualizer/src/components/spec-logos/FILE-ICONS-ISC.txt +13 -0
  43. package/packages/visualizer/src/components/spec-logos/README.md +23 -0
  44. package/packages/visualizer/src/components/spec-logos/SIMPLE-ICONS-CC0.txt +30 -0
  45. package/packages/visualizer/src/components/spec-logos/alloy.svg +1 -0
  46. package/packages/visualizer/src/components/spec-logos/dmn.svg +3 -0
  47. package/packages/visualizer/src/components/spec-logos/gherkin.svg +1 -0
  48. package/packages/visualizer/src/components/spec-logos/openslo.svg +63 -0
  49. package/packages/visualizer/src/components/spec-logos/quint.svg +1 -0
  50. package/packages/visualizer/src/evidence/artifacts.tsx +263 -110
  51. package/packages/visualizer/src/evidence/chart-source.tsx +18 -0
  52. package/packages/visualizer/src/evidence/check-detail.tsx +283 -139
  53. package/packages/visualizer/src/evidence/decision-table.tsx +35 -26
  54. package/packages/visualizer/src/evidence/document-page.tsx +51 -29
  55. package/packages/visualizer/src/evidence/feature-page.tsx +121 -53
  56. package/packages/visualizer/src/evidence/marks.tsx +112 -79
  57. package/packages/visualizer/src/evidence/model-page.tsx +77 -46
  58. package/packages/visualizer/src/evidence/model-trace.tsx +55 -35
  59. package/packages/visualizer/src/evidence/overview.tsx +137 -69
  60. package/packages/visualizer/src/evidence/recording-page.tsx +70 -31
  61. package/packages/visualizer/src/evidence/recording.tsx +135 -68
  62. package/packages/visualizer/src/evidence/snapshot.tsx +99 -43
  63. package/packages/visualizer/src/evidence/source-text.tsx +33 -0
  64. package/packages/visualizer/src/evidence/sources-panel.tsx +138 -144
  65. package/packages/visualizer/src/evidence/spec-header.tsx +52 -36
  66. package/packages/visualizer/src/evidence/spec-index.tsx +61 -32
  67. package/packages/visualizer/src/evidence/spec-page.tsx +56 -25
  68. package/packages/visualizer/src/evidence/test-filter.tsx +38 -14
  69. package/packages/visualizer/src/explorer/Explorer.tsx +688 -261
  70. package/packages/visualizer/src/explorer/ExplorerIndex.tsx +136 -68
  71. package/packages/visualizer/src/explorer/RunsView.tsx +307 -94
  72. package/packages/visualizer/src/explorer/TestDetail.tsx +393 -118
  73. package/packages/visualizer/src/explorer/parts.tsx +35 -13
  74. package/packages/visualizer/src/find/Finder.tsx +106 -90
  75. package/packages/visualizer/src/find/open.ts +17 -20
  76. package/packages/visualizer/src/live/test-progress.tsx +60 -22
  77. package/packages/visualizer/src/looks/Stage.tsx +223 -110
  78. package/packages/visualizer/src/main.tsx +9 -11
  79. package/packages/visualizer/src/map/ChartMap.tsx +125 -69
  80. package/packages/visualizer/src/map/EventEdge.tsx +59 -37
  81. package/packages/visualizer/src/map/map.module.css +12 -546
  82. package/packages/visualizer/src/map/nodes.tsx +124 -70
  83. package/packages/visualizer/src/reachable.test.ts +3 -2
  84. package/packages/visualizer/src/spec-kind.ts +2 -2
  85. package/packages/visualizer/src/ui/grammars/ALLOY-MIT.txt +21 -0
  86. package/packages/visualizer/src/ui/grammars/QUINT-APACHE-2.0.txt +206 -0
  87. package/packages/visualizer/src/ui/grammars/README.md +14 -0
  88. package/packages/visualizer/src/ui/grammars/alloy.json +71 -0
  89. package/packages/visualizer/src/ui/grammars/quint.json +152 -0
  90. package/packages/visualizer/src/ui/highlight.ts +50 -0
  91. package/packages/visualizer/src/ui/theme.tsx +109 -0
  92. package/packages/visualizer/src/views/ChartPage.tsx +46 -26
  93. package/packages/visualizer/src/views/ChartTests.tsx +59 -22
  94. package/packages/visualizer/src/views/ProductPage.tsx +16 -15
  95. package/packages/visualizer/src/views/SidePanel.tsx +241 -131
  96. package/packages/visualizer/src/app/gazetteer.module.css +0 -107
  97. package/packages/visualizer/src/components/ActivityIndicator.module.css +0 -4
  98. package/packages/visualizer/src/components/DataIssues.module.css +0 -136
  99. package/packages/visualizer/src/components/Header.module.css +0 -114
  100. package/packages/visualizer/src/components/Legend.module.css +0 -84
  101. package/packages/visualizer/src/components/Screen.module.css +0 -312
  102. package/packages/visualizer/src/components/Status.module.css +0 -116
  103. package/packages/visualizer/src/components/icons.tsx +0 -156
  104. package/packages/visualizer/src/evidence/artifacts.module.css +0 -213
  105. package/packages/visualizer/src/evidence/evidence.module.css +0 -907
  106. package/packages/visualizer/src/evidence/recording.module.css +0 -460
  107. package/packages/visualizer/src/evidence/sources.module.css +0 -168
  108. package/packages/visualizer/src/evidence/spec-snapshot.tsx +0 -26
  109. package/packages/visualizer/src/explorer/explorer.module.css +0 -1238
  110. package/packages/visualizer/src/find/Finder.module.css +0 -168
  111. package/packages/visualizer/src/looks/stage.module.css +0 -300
  112. package/packages/visualizer/src/styles/global.css +0 -105
  113. package/packages/visualizer/src/styles/tokens.css +0 -80
  114. package/packages/visualizer/src/views/views.module.css +0 -546
package/llms-full.txt CHANGED
@@ -1435,6 +1435,7 @@ with `format=markdown` (or `Accept: text/markdown`), and takes the project prefi
1435
1435
  | Every test, a summary (by status, environment, producer, domain), insights (failing, flaky, slowest) and facets | `GET /api/reports/tests` |
1436
1436
  | Only some: `q` (all words), `status` (or `flaky`), `environment`, `producer`, `domain`, `spec`, `tag`, `run`; `sort`, `offset`, `limit` | `GET /api/reports/tests?status=failed&environment=ios` |
1437
1437
  | One test: every recorded result (status, duration, environment, branch, commit, CI run), newest first | `GET /api/reports/tests/history?key=<key>` |
1438
+ | Why Specs, domains and counts disagree: ambiguous spec paths, shared domains, gaps, a reconciliation of the totals | `GET /api/reports/tests/health` |
1438
1439
  | The runs that recorded the report (by CI run URL, else branch and commit) | `GET /api/reports/runs` |
1439
1440
  | Every test one run recorded | `GET /api/reports/runs/detail?key=<run key>` |
1440
1441
 
@@ -1447,6 +1448,13 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
1447
1448
  `stats` describes its recorded history: pass rate, flips, whether it is flaky and why (it passed and failed on the
1448
1449
  same commit, passed only after a retry, or its producer said so), durations (avg, p50, p95, min, max, last), runs
1449
1450
  and branches.
1451
+ - The **health** document explains the numbers instead of adding one. It keeps spec files, defined specs, specs with an
1452
+ executed test, tests, outlines, examples and per-environment observations apart, and walks from the Specs total to
1453
+ the Tests total. Two spec paths are one logical spec only when a mapping says so
1454
+ (`?root=<from>><to>`, for example `?root=%3Especs/` to put `checkout/cart.feature` under `specs/`); similar paths
1455
+ are reported as ambiguous and never merged, and a similar title is never an identity. Give a check the label
1456
+ `outline` to say which scenario outline an example belongs to. A domain shared by nearly every spec is flagged, but
1457
+ explicit domain metadata always stays authoritative. The document only reads: it changes no status.
1450
1458
  - The server keeps the newest 100 results of every test (progress reported as `running` is not history) and every run's last result per test, in memory, as layers
1451
1459
  arrive; it is rebuilt from the layers on restart. History never changes a result.
1452
1460
  - Without a published spec set, tests are grouped under the specs their layers recorded (`specs[]`: path, domain,
@@ -1498,6 +1506,8 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
1498
1506
  | `DELETE /api/projects/{project}/store/{key}` | publish | Remove a scratch object. |
1499
1507
  | `GET /api/reports/tests` | read | Every test, with insights, facets and history statistics. |
1500
1508
  | `GET /api/projects/{project}/reports/tests` | read | Every test, with insights, facets and history statistics. |
1509
+ | `GET /api/reports/tests/health` | read | Why specs, domains and counts disagree. |
1510
+ | `GET /api/projects/{project}/reports/tests/health` | read | Why specs, domains and counts disagree. |
1501
1511
  | `GET /api/reports/tests/history` | read | One test and every result recorded for it. |
1502
1512
  | `GET /api/projects/{project}/reports/tests/history` | read | One test and every result recorded for it. |
1503
1513
  | `GET /api/reports/runs` | read | The runs that recorded the report. |
@@ -3524,6 +3534,284 @@ document shows the combined result of its checks per environment, with the layer
3524
3534
  the client at your stores with `reportsHost` ([integrating Atlas](integrating.md#6-browse-it)).
3525
3535
  </doc>
3526
3536
 
3537
+ <doc path="docs/workspaces.md">
3538
+ # Atlas in agent IDEs
3539
+
3540
+ This guide is for developing **this repository** in Superset, super.engineering or Orca. A consumer
3541
+ project should install Atlas from npm and follow [integrating](integrating.md) instead.
3542
+
3543
+ ## Start from any terminal
3544
+
3545
+ Install the Bun version named by `packageManager` in [package.json](../package.json), then run these
3546
+ commands from the repository root. Setup requires no tokens, copied `.env`, Docker or external services.
3547
+
3548
+ ```sh
3549
+ bun run workspace:setup
3550
+ bun run workspace:run
3551
+ ```
3552
+
3553
+ Open the `Atlas server ready:` URL printed in the Run terminal. It serves the real API and hot-reloading
3554
+ viewer together; `/admin` opens settings. A fresh node starts empty. Publish real results to the printed
3555
+ `ATLAS_STORE` address using the existing [report commands](reference/reports.md).
3556
+
3557
+ For UI work with populated specs, statecharts, failures and recordings, run the separate examples target:
3558
+
3559
+ ```sh
3560
+ bun run workspace:preview
3561
+ ```
3562
+
3563
+ This viewer uses `examples/todo/specs` and the existing example-evidence adapter. It does not seed or
3564
+ alter the real server's data. It has no server administration interface. Existing example run files are
3565
+ shown when present; setup does not run browsers, model checkers or generate recordings. To create fresh
3566
+ example recordings, use the existing `example:run` command and [statechart guide](statecharts.md).
3567
+
3568
+ ## Shared commands
3569
+
3570
+ | Command | Behavior |
3571
+ | --- | --- |
3572
+ | `bun run workspace:setup` | Check the pinned Bun and install with `--frozen-lockfile`; safe to repeat. |
3573
+ | `bun run workspace:run` | Run the real node and viewer; repeat the frozen install before starting. |
3574
+ | `bun run workspace:preview` | Run the populated examples viewer; repeat the same setup first. |
3575
+ | `bun run workspace:status` | Print live URLs, mode and readiness as JSON; omit private control credentials. |
3576
+ | `bun run workspace:stop` | Stop both targets owned by this checkout; retain all reports. |
3577
+ | `bun run workspace:stop server` | Stop only the API/viewer target. `preview` selects only examples. |
3578
+ | `bun run workspace:check` | Run documentation, types, tests, package/client builds and consumer smoke. |
3579
+
3580
+ `run` and `preview` stay in the foreground so the IDE owns their lifetime and displays their output.
3581
+ Ctrl+C or an IDE Stop closes the owned server and its child process. Teardown uses a random private
3582
+ control capability stored in `.atlas-workspace/`; it never kills a PID from a file or uses `pkill`.
3583
+ If the owned development child does not finish after five seconds, only that child is terminated.
3584
+ Stopping an unrelated IDE, agent, checkout or application is outside these scripts' scope.
3585
+
3586
+ ## Workspace isolation and ports
3587
+
3588
+ The API/viewer tries port 5180, and examples try 5181. If that default is busy, the OS supplies a free
3589
+ port. Read `workspace:status` instead of assuming a URL. An explicit `--port`, `ATLAS_PORT`, or `PORT`
3590
+ (in that priority order) is strict: conflicts fail and never connect publishers to a different node.
3591
+ `--port 0` requests a free port explicitly.
3592
+
3593
+ ```sh
3594
+ bun run workspace:run --port 5280
3595
+ bun run workspace:status
3596
+ ```
3597
+
3598
+ Everything binds to `127.0.0.1`. For remote workspaces, use the IDE's port forwarding. Reports and server
3599
+ settings stay in this checkout's `.atlas-data/`; live runtime leases stay in `.atlas-workspace/`.
3600
+ Keep both directories private to each worktree. Do not share `node_modules`, `.atlas-data/`,
3601
+ `.atlas-workspace/` or caches across checkouts with different dependencies. Frozen installs use Bun's
3602
+ download cache without linking one worktree's dependency tree to another.
3603
+
3604
+ Two simultaneous starts cannot claim the same target's runtime lease. A hard kill may leave metadata:
3605
+ run `workspace:stop` before restarting. It removes a stale lease only when its owner PID is gone; if the
3606
+ PID is still alive but the control endpoint cannot authenticate, investigate that owner rather than
3607
+ assuming it is safe to stop. No reports or settings are deleted by teardown.
3608
+
3609
+ ## Superset
3610
+
3611
+ [`.superset/config.json`](https://github.com/crvouga/atlas/blob/main/.superset/config.json) wires workspace creation to setup, the Run button
3612
+ to the real node/viewer, and teardown to stop. Superset discovers listening ports; the conventional
3613
+ ports are labelled in [ports.json](https://github.com/crvouga/atlas/blob/main/.superset/ports.json). Automatically chosen ports still appear
3614
+ in its port panel. Use the examples command in a second terminal when needed. Personal lifecycle
3615
+ overrides belong in ignored `.superset/config.local.json`.
3616
+
3617
+ Superset's Run command resolves from the main repository's configuration. Commit the configuration
3618
+ and scripts together before expecting another workspace's Run button to discover them. See the
3619
+ [official lifecycle guide](https://docs.superset.sh/setup-teardown-scripts) and
3620
+ [port management](https://docs.superset.sh/ports).
3621
+
3622
+ ## super.engineering
3623
+
3624
+ [`.super.engineering/config.json`](https://github.com/crvouga/atlas/blob/main/.super.engineering/config.json) defines **Atlas** (default),
3625
+ **Viewer examples** and **Checks** in the Run controls. Each server target's Stop command affects only
3626
+ that target; deletion stops both. Shared commands expose **Atlas URLs**, **Check Atlas** and a
3627
+ **Review Atlas UI** prompt. The prompt uses the current agent's configured provider and does not
3628
+ launch a team or change model settings.
3629
+
3630
+ Use the documented CLI to inspect or invoke the same definitions:
3631
+
3632
+ ```sh
3633
+ sc project scripts check --json
3634
+ sc project scripts run Atlas --json
3635
+ sc project scripts status --json
3636
+ sc project scripts stop Atlas --json
3637
+ ```
3638
+
3639
+ Edit shared script configuration with `sc project scripts set ... --scope repo`, and shared commands
3640
+ with `sc commands ... --scope shared`. Preserve other entries and unknown configuration keys. See
3641
+ [project config and scripts](https://super.engineering/docs/project-config-and-scripts/).
3642
+
3643
+ ## Orca
3644
+
3645
+ [`orca.yaml`](https://github.com/crvouga/atlas/blob/main/orca.yaml) uses the supported `scripts.setup` and `scripts.archive` hooks. Agents
3646
+ wait for setup. The first default tab is reserved for the agent; the second starts Atlas. Tab commands
3647
+ may start alongside setup, so Run repeats the frozen install before importing application dependencies.
3648
+ Orca's normal shared-script trust and setup-policy settings still apply. No `scripts.run` key is
3649
+ invented: Orca starts the app through the terminal template.
3650
+
3651
+ Keep **Shared + Local** or **Shared only** enabled for repository hooks, and approve the shared config
3652
+ in Orca when it offers its trust prompt. These are user-owned controls. For existing workspaces,
3653
+ run the shared Bun commands in a terminal; default tabs are created for new workspaces. See the
3654
+ [official `orca.yaml` reference](https://www.onorca.dev/docs/model/orca-yaml).
3655
+
3656
+ ## Agent workflow
3657
+
3658
+ Read `AGENTS.md`, then use `workspace:status` to discover this checkout's live app. Run the server for
3659
+ API, settings, upload and streaming changes; use examples for populated UI review. Read [UI conventions](ui.md)
3660
+ before changing screens. Keep report/schema/permission contracts intact, and report what the browser and
3661
+ checks actually verified. Do not launch other agents, change IDE permissions or install global IDE tooling
3662
+ as a side effect of setup. `workspace:check` is an on-demand verification target, never a creation hook.
3663
+
3664
+ The lifecycle regression suite (`bun test scripts/workspace.test.ts`) checks fresh directories with spaces,
3665
+ repeatable setup, strict ports, separate stores, authenticated ownership and independent shutdown.
3666
+ Real IDE boot verification additionally needs that IDE installed and available; a passing configuration
3667
+ test alone does not prove the IDE started a new workspace.
3668
+ </doc>
3669
+
3670
+ <doc path="docs/ui.md">
3671
+ # Viewer UI conventions
3672
+
3673
+ Read this before changing the Atlas viewer or settings UI. React and Mantine are the design system.
3674
+ Use the installed version in `package.json` (currently 9.7.3) and its [official documentation](https://mantine.dev/).
3675
+ Look up unfamiliar interactions before writing them; component props and compound components usually solve them.
3676
+
3677
+ ## One setup
3678
+
3679
+ - `packages/visualizer/src/ui/theme.tsx` owns the only theme and `AtlasThemeProvider`.
3680
+ - Both `src/main.tsx` (reports) and `src/admin/main.tsx` (settings) use that provider and Mantine's styles.
3681
+ - Keep Atlas's blue navigation, neutral surfaces, system typography, and light color scheme. Outcome colors
3682
+ come from `statusColor`: green passed, red failed, orange flaky, blue running, gray unknown/unrun.
3683
+ Always accompany color with text or a named status mark. Unknown evidence must never look passed.
3684
+ - The theme darkens the existing Mantine outcome scales and muted text to meet small-text contrast requirements. Use the default sizes, radii, font sizes, shadows and variants. Defaults belong in the theme, not in features.
3685
+ The spacing vocabulary is Mantine's `xs`, `sm`, `md`, `lg`, `xl`.
3686
+
3687
+ ## Compose directly
3688
+
3689
+ Use `AppShell` for persistent navigation, `Container size="xl"` for report pages (`md` for settings),
3690
+ `Stack` for vertical flow, `Group` for horizontal flow, and `SimpleGrid` for responsive metrics/forms.
3691
+ Page headers contain a `Title order={1}`, descriptive `Text c="dimmed"`, then the page's controls.
3692
+ Use `Title order={2}` for sections and `order={3}` for subsections; do not choose heading sizes per page.
3693
+
3694
+ Use Mantine components directly. Do not add wrappers for ordinary buttons, inputs, cards, menus, or dialogs.
3695
+ Shared product compositions include `SpecHeader`, `ResultRow`, `StatusMark`, `Origin`, `Stage`, and `TestDetail`:
3696
+ they preserve evidence semantics, provenance, URL selection, or playback behavior.
3697
+
3698
+ - Primary action: `Button variant="filled"`. Secondary: default `Button` (light). Quiet: `variant="subtle"`.
3699
+ Destructive action: `color="red"`. Icon-only action: `ActionIcon` with an `aria-label`, usually a `Tooltip`.
3700
+ - Inputs: Mantine inputs with a visible `label`, `description` when needed, and `error` for validation.
3701
+ Use `NativeSelect` for small native option lists; keep form values controlled. Settings validation and
3702
+ authorization stay on the server; its optional JSON editor also validates with the shared schema.
3703
+ - Use `Menu` for navigation menus, `Popover` for view options, `Drawer` for sources/test details,
3704
+ `Modal` for modal content, and `Spotlight` for search. Let Mantine own dismissal, focus and keyboard behavior.
3705
+ When an action opens a drawer from a popover, close and disable the parent popover during the drawer's lifetime;
3706
+ return focus to its persistent trigger. Do not fix overlapping focus traps by raising z-index values.
3707
+ - Use `Tabs` for view modes and `Accordion` for disclosure. URL-backed selections stay in the existing router.
3708
+ - Render typed router links with Mantine's `renderRoot={props => <Link {...props} ... />}`.
3709
+ This keeps route/search type inference and native navigation semantics.
3710
+ - Use `Table` in `Table.ScrollContainer` for wide evidence, with column headers. Long lists must retain
3711
+ `Bounded`/show-more controls. Do not fetch unopened results' recordings eagerly.
3712
+ - Loading: named `Loader`/`Skeleton` or explicit text with `role="status"`. Error: `Alert color="red"` and
3713
+ a retry when possible. Empty: descriptive `Text` and a relevant action. Use built-in loading/disabled states.
3714
+ - Spec overview links use a centered `Group`: status, flexible title/folder, then outcome and time. Keep gaps
3715
+ explicit with theme spacing; stack metadata on narrow screens instead of crowding the title.
3716
+
3717
+ ## Executable spec source
3718
+
3719
+ `SourceText` is the common source reader for Gherkin, Quint, DMN/XML, Alloy, OpenSLO/YAML and statechart
3720
+ XML/JSON/YAML. Show it expanded near the top of document pages; preserve indentation, comments and the
3721
+ complete file. Do not replace source with a trimmed snapshot. Mantine `CodeHighlightTabs` supplies file
3722
+ labels, line numbers, horizontal scrolling and copying. The full file is expanded by default. Native
3723
+ collapse/expand controls can limit long files to 70vh; the Recorded results action jumps to the existing
3724
+ results section and moves keyboard focus there. Keep scenario selection,
3725
+ filters, traces, decision tables and model declaration links working alongside the source.
3726
+
3727
+ `ui/highlight.ts` owns the one lazy Shiki adapter. It imports only the supported grammars and caches the
3728
+ engine. The shared source composition installs that adapter when source is displayed; the Mantine theme
3729
+ and component defaults still live only in `ui/theme.tsx`. Quint/Alloy grammar sources and licenses live in
3730
+ [`ui/grammars/README.md`](../packages/visualizer/src/ui/grammars/README.md). Unknown formats remain plain
3731
+ text, and parse failures must leave the source visible. Syntax highlighting never means a spec passed.
3732
+
3733
+ ## Icons and notation marks
3734
+
3735
+ Use named imports from `@tabler/icons-react` for all UI glyphs. The icon package supplies SVG paths;
3736
+ Mantine still supplies every control and interaction. Use size 16 for compact inline glyphs and size 20
3737
+ for standalone actions, with `aria-hidden="true"` when the adjacent text or control names the action.
3738
+ Do not draw SVG icons, use Unicode glyphs as buttons, or add another icon library. Mantine's built-in
3739
+ icons are fine. Keep textual keyboard shortcuts and path separators as text.
3740
+
3741
+ `SpecLogo` maps every `SpecKind` to a bundled SVG mark, used in navigation and page headers. Keep the
3742
+ visible notation label; marks are decorative. Sources, licenses and the DMN notation-mark choice are in
3743
+ [`spec-logos/README.md`](../packages/visualizer/src/components/spec-logos/README.md). Add a sourced SVG
3744
+ and update this mapping when adding a format. Brand artwork preserves upstream colors independently of
3745
+ Atlas's theme. SVG data plots and statechart arrow markers are geometry, not handcrafted UI icons.
3746
+
3747
+ ## Accessibility and responsive behavior
3748
+
3749
+ The shell collapses its index below Mantine's `md` breakpoint; its named Burger toggles mobile navigation.
3750
+ Navigation closes after choosing a destination. Use responsive props and the theme's breakpoints; no custom
3751
+ media-query system. Let controls wrap, use one form column on mobile, and keep dialogs inside the viewport.
3752
+ Wide tables scroll inside their container. Native video/audio controls remain available.
3753
+
3754
+ Preserve labels, status announcements, keyboard shortcuts, selected states, meaningful headings and focus
3755
+ restoration. Mantine respects reduced motion through the central theme. Avoid nested interactive controls.
3756
+ Never rely on color alone, remove focus outlines, or hide an important action only to make a layout fit.
3757
+
3758
+ ## Styling policy and exceptions
3759
+
3760
+ Default custom CSS: zero. First try Mantine defaults, central defaults, variants, props, layout components,
3761
+ and theme tokens. Do not add Tailwind, Radix, another design system, CSS modules, custom token scales,
3762
+ inline styles, or `styles` objects for ordinary UI. Document a concrete functional limitation here before
3763
+ adding an exception; `scripts/ui-architecture.test.ts` checks these boundaries in the normal test suite.
3764
+
3765
+ The central List Styles API adjustment makes item labels fill the available width, including Mantine's column wrappers;
3766
+ List has no full-width label prop. This keeps all report rows usable without feature styles.
3767
+
3768
+ The narrowly scoped exceptions are:
3769
+
3770
+ 1. **Interactive statechart graph:** React Flow and ELK provide graph layout, pan/zoom, edges and minimap,
3771
+ which Mantine does not supply. Graph nodes and controls use Mantine. `src/map/map.module.css` only covers
3772
+ SVG strokes, graph handles, edge-label geometry and graph selection/dimming. The two edge-label transforms
3773
+ and node dimensions are computed by the layout engine, not visual design tokens.
3774
+ 2. **Captured evidence:** native video/audio and sandboxed iframes render recorded bytes. HTML snapshots use
3775
+ the existing isolated shadow tree and intrinsic phone coordinates; their captured styles never style Atlas.
3776
+ Recorded click markers and intrinsic image/video dimensions are evidence coordinates, not UI spacing.
3777
+ 3. **Public compatibility APIs:** `solid-js` and `@tanstack/solid-query` remain dependencies of existing
3778
+ report-library entry points. They render no Atlas screen. Do not import them into the viewer or add Solid UI.
3779
+ 4. **Syntax rendering:** Shiki is the syntax engine behind Mantine's official code-highlight adapter,
3780
+ not a second component system. Its token styles and escaped HTML are generated by the highlighter.
3781
+ The supported Shiki line transformer supplies the existing Quint `line-N` navigation anchors.
3782
+ No feature CSS, handcrafted code controls or custom syntax color theme is introduced.
3783
+ 5. **Consumer test fixture:** `examples/todo/app` is the app Atlas tests and records, not an Atlas screen.
3784
+ Its intentionally separate implementation and selectors are test inputs; the overhaul does not restyle it.
3785
+
3786
+ ## Inventory and migration boundary
3787
+
3788
+ | Area | Screens/interactions | Mantine composition |
3789
+ | --- | --- | --- |
3790
+ | Shared shell | Project switching, spec navigation, run selection, connection status, diagnostics, mobile index | AppShell, Burger, NavLink, Menu, Popover, NativeSelect, Drawer |
3791
+ | Project home | Tests/runs tabs, metrics, search, status/environment/domain filters, grouping, sorting, show more | Container, Tabs, SimpleGrid, Paper, TextInput, Button, Accordion |
3792
+ | Test detail | Current outcomes, statistics, duration graph, history, artifacts, recording | Drawer, Table, Badge, Alert, Stage |
3793
+ | Specs | All six existing kinds, overview/index, Gherkin rules/scenarios/examples, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Table, CodeHighlightTabs, ResultRow |
3794
+ | Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
3795
+ | Evidence | Steps, retries, annotations, facts, unknown extensions, safe downloads and previews | List, Badge, Accordion, Code, Image, native media |
3796
+ | Recordings | Pictures/video/timeline, actor selection, moments, failure jumps, timing, model-state differences | Tabs, Slider, Button, ScrollArea, Table, Progress |
3797
+ | Search/help | Ranked and semantic search, shortcut help, recording shortcuts | Spotlight, Modal, Kbd |
3798
+ | Administration | Token access, storage backends/write destination, live timeouts, report rules, limits, raw JSON, conflicts | Same provider/theme, Fieldset, Mantine inputs, Accordion, Alert |
3799
+
3800
+ The hash routes (`/`, `/chart/$chartId`, `/specs/$kind`), query contracts, project scoping, streaming,
3801
+ report APIs and data adapters remain the migration boundary. `/admin` still serves an independent document:
3802
+ it lazily bundles the shared React settings entry once, so API-only servers do not need a prebuilt viewer.
3803
+
3804
+ ## Checks
3805
+
3806
+ Run `bunx tsc --noEmit -p packages/visualizer`,
3807
+ `bun test --cwd packages/visualizer --preload ./tests/preload.ts tests`,
3808
+ `bun test scripts/ui-architecture.test.ts`, `bun run client:build`, then `bun run docs` and `bun run docs:check`.
3809
+ Before pushing, run the full repository checks from `AGENTS.md`, including package build and consumer smoke
3810
+ when dependencies change. DOM tests use the same `AtlasThemeProvider` with Mantine's supported `env="test"`.
3811
+ Use semantic/product selectors, not Mantine's private class names. Inspect real desktop and narrow layouts,
3812
+ menus, dialogs, complex evidence and settings in the browser; do not describe a DOM test as a visual audit.
3813
+ </doc>
3814
+
3527
3815
  <doc path="docs/dogfooding.md">
3528
3816
  # Dogfooding Atlas from another project
3529
3817
 
@@ -4527,6 +4815,40 @@ Scoped to one project. The same project may be selected on the unprefixed API us
4527
4815
 
4528
4816
  Responses: `200` The catalog.; `304` Unchanged since the `If-None-Match` ETag.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
4529
4817
 
4818
+ ### Why specs, domains and counts disagree
4819
+
4820
+ `GET /api/reports/tests/health` · role: read
4821
+
4822
+ Diagnoses the report's metadata, so a domain filter or a coverage percentage can be trusted or fixed at its source. It reads; it never changes a status, a slot or a winner.
4823
+
4824
+ `counts` keeps the denominators apart: spec files, defined specs, specs with an executed test (and those without: the defined coverage gaps), tests, outlines, examples and per-environment observations. `reconciliation` walks from the Specs count to the Tests count. `findings` name ambiguous and unmatched spec paths, identical or same-titled specs, a domain shared by nearly every spec, tests with no spec, checks that fall back to their title as identity and root mappings that matched nothing.
4825
+
4826
+ Two paths are one logical spec only when a `root` mapping relates them (`from>to`: paths under `from` are the same specs as paths under `to`; an empty `from` matches every path). Without one, similar paths are reported as ambiguous and never merged. A check's label `outline` names the outline its example belongs to. Send `format=markdown` for Markdown.
4827
+
4828
+ - `root` (query): A root mapping `from>to`, URL-encoded. Repeatable or comma-separated.
4829
+ - `format` (query): `markdown` for a Markdown report instead of JSON.
4830
+ - `project` (query): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
4831
+
4832
+ Responses: `200` The diagnostics.; `304` Unchanged since the `If-None-Match` ETag.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
4833
+
4834
+ ### Why specs, domains and counts disagree
4835
+
4836
+ `GET /api/projects/{project}/reports/tests/health` · role: read
4837
+
4838
+ Diagnoses the report's metadata, so a domain filter or a coverage percentage can be trusted or fixed at its source. It reads; it never changes a status, a slot or a winner.
4839
+
4840
+ `counts` keeps the denominators apart: spec files, defined specs, specs with an executed test (and those without: the defined coverage gaps), tests, outlines, examples and per-environment observations. `reconciliation` walks from the Specs count to the Tests count. `findings` name ambiguous and unmatched spec paths, identical or same-titled specs, a domain shared by nearly every spec, tests with no spec, checks that fall back to their title as identity and root mappings that matched nothing.
4841
+
4842
+ Two paths are one logical spec only when a `root` mapping relates them (`from>to`: paths under `from` are the same specs as paths under `to`; an empty `from` matches every path). Without one, similar paths are reported as ambiguous and never merged. A check's label `outline` names the outline its example belongs to. Send `format=markdown` for Markdown.
4843
+
4844
+ Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
4845
+
4846
+ - `project` (path, required): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
4847
+ - `root` (query): A root mapping `from>to`, URL-encoded. Repeatable or comma-separated.
4848
+ - `format` (query): `markdown` for a Markdown report instead of JSON.
4849
+
4850
+ Responses: `200` The diagnostics.; `304` Unchanged since the `If-None-Match` ETag.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
4851
+
4530
4852
  ### One test and every result recorded for it
4531
4853
 
4532
4854
  `GET /api/reports/tests/history` · role: read
package/llms.txt CHANGED
@@ -26,6 +26,8 @@ Given only the repository link, start at docs/agents.md: install `@crvouga/atlas
26
26
 
27
27
  ## Working with this project
28
28
 
29
+ - [Atlas in agent IDEs](https://raw.githubusercontent.com/crvouga/atlas/main/docs/workspaces.md): This guide is for developing this repository in Superset, super.engineering or Orca.
30
+ - [Viewer UI conventions](https://raw.githubusercontent.com/crvouga/atlas/main/docs/ui.md): Read this before changing the Atlas viewer or settings UI.
29
31
  - [Dogfooding Atlas from another project](https://raw.githubusercontent.com/crvouga/atlas/main/docs/dogfooding.md): Atlas is developed by using it in real projects.
30
32
  - [Reporting issues](https://raw.githubusercontent.com/crvouga/atlas/main/docs/reporting-issues.md): How people and coding agents in a project that uses Atlas report a bug or a missing feature.
31
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvouga/atlas",
3
- "version": "0.10.2",
3
+ "version": "0.12.0",
4
4
  "description": "Atlas: specs of any kind, reported as layered evidence. Publish checks from any runner (JUnit, CTRF, a script), combine them across nodes, branches, environments and backends, gate CI on the result, and run statecharts against the real app.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -153,7 +153,9 @@
153
153
  "docs/reporting-issues.md",
154
154
  "CHANGELOG.md",
155
155
  "docs/runners.md",
156
- "packages/runners/compat"
156
+ "packages/runners/compat",
157
+ "docs/ui.md",
158
+ "docs/workspaces.md"
157
159
  ],
158
160
  "scripts": {
159
161
  "build": "bun scripts/build-package.ts",
@@ -182,29 +184,34 @@
182
184
  "health": "bun scripts/health/cli.ts",
183
185
  "prepare": "husky",
184
186
  "example:publish": "bun examples/todo/publish.ts",
185
- "atlas": "bun scripts/atlas.mjs"
187
+ "atlas": "bun scripts/atlas.mjs",
188
+ "workspace:setup": "bun scripts/workspace.ts setup",
189
+ "workspace:run": "bun scripts/workspace.ts run",
190
+ "workspace:preview": "bun scripts/workspace.ts preview",
191
+ "workspace:status": "bun scripts/workspace.ts status",
192
+ "workspace:stop": "bun scripts/workspace.ts stop",
193
+ "workspace:check": "bun run docs:check && bun run type-check && bun run test && bun run build && bun run client:build --out .atlas-workspace/site && bun run release:smoke"
186
194
  },
187
195
  "dependencies": {
188
196
  "@cucumber/gherkin": "^42.0.1",
189
197
  "@cucumber/messages": "^34.2.1",
190
- "@radix-ui/react-collapsible": "^1.1.21",
191
- "@radix-ui/react-dialog": "^1.2.0",
192
- "@radix-ui/react-dropdown-menu": "^2.1.25",
193
- "@radix-ui/react-popover": "^1.2.0",
194
- "@radix-ui/react-tabs": "^1.1.22",
195
- "@radix-ui/react-tooltip": "^1.3.0",
198
+ "@mantine/code-highlight": "9.7.3",
199
+ "@mantine/core": "9.7.3",
200
+ "@mantine/hooks": "9.7.3",
201
+ "@mantine/spotlight": "9.7.3",
202
+ "@tabler/icons-react": "3.49.0",
196
203
  "@tanstack/query-persist-client-core": "^5.104.0",
197
204
  "@tanstack/react-query": "^5.101.4",
198
205
  "@tanstack/react-router": "^1.170.41",
199
206
  "@tanstack/solid-query": "^5.104.0",
200
207
  "@vitejs/plugin-react": "5.2.0",
201
208
  "@xyflow/react": "^12.11.5",
202
- "cmdk": "^1.1.1",
203
209
  "elkjs": "0.12.0",
204
210
  "fast-xml-parser": "5.11.0",
205
211
  "hono": "^4.13.9",
206
212
  "react": "^19.3.0",
207
213
  "react-dom": "^19.3.0",
214
+ "shiki": "4.5.0",
208
215
  "solid-js": "^1.9.15",
209
216
  "tsx": "4.23.13",
210
217
  "vite": "7.3.7",