basalt-ui 2.0.1 → 2.0.2
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.
- package/CHANGELOG.md +9 -0
- package/MIGRATING.md +23 -12
- package/dist/cli/config.d.ts +10 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +28 -3
- package/dist/cli/index.d.ts +20 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +43 -5
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +7 -1
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +5 -0
- package/dist/tokens/core.d.ts +12 -11
- package/dist/tokens/core.d.ts.map +1 -1
- package/dist/tokens/core.js +9 -1
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/cli/config.ts +11 -1
- package/src/cli/doctor.ts +37 -3
- package/src/cli/index.ts +62 -3
- package/src/cli/init.ts +10 -1
- package/src/cli/sync.ts +6 -0
- package/src/tokens/core.ts +25 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [2.0.2](https://github.com/jkrumm/basalt-ui/compare/v2.0.1...v2.0.2) (2026-10-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* keep the brand symbol out of keyof a groupTokens result ([27f44d3](https://github.com/jkrumm/basalt-ui/commit/27f44d3da50f07f9adb5b850edc86e8e388d0550))
|
|
7
|
+
* make doctor and sync monorepo-aware ([eafb701](https://github.com/jkrumm/basalt-ui/commit/eafb7013d07a7935b393c70553e11d2a57f01c71))
|
|
8
|
+
* throw a clear error for a group not built by groupTokens ([7c0dc44](https://github.com/jkrumm/basalt-ui/commit/7c0dc447e2faff22561166f66d6e449be511981c))
|
|
9
|
+
|
|
1
10
|
## [2.0.1](https://github.com/jkrumm/basalt-ui/compare/v2.0.0...v2.0.1) (2026-10-14)
|
|
2
11
|
|
|
3
12
|
|
package/MIGRATING.md
CHANGED
|
@@ -66,18 +66,18 @@ There is one row per SURFACE, not per export, and a surface earns a row once any
|
|
|
66
66
|
shipped lefthook preset both changed in 1.30.0 with no row that owned them — which is how a
|
|
67
67
|
consumer read this index, found nothing, and diffed a KPI row that had silently gone 4-up → 2-up.
|
|
68
68
|
|
|
69
|
-
| Surface | 1.27.0 | 1.28.0 | 1.29.0 | 1.30.0 | 1.30.1 | 1.30.2 | 1.31.0 | 1.32.0 | 1.32.1 | 1.33.0 | 1.34.0 | 1.34.1 | 1.35.0 | 1.36.0 | 1.36.1 | 1.37.0 | 1.37.1 | 1.38.0 | 1.38.1 | 1.39.0 | 1.40.0 | 1.40.1 | 1.40.2 | 1.40.3 | 1.41.0 | 2.0.0 | 2.0.1 | Unreleased |
|
|
70
|
-
| ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------- | ------ | ------ | -------------------------------------------------------------------------------------------- | ------ | ------ | ------ | ------ | ------ | ----------------------------------------------- | ------ | ------ | ------ | ------ | ------------------------------------------------------------ | ---------- | --- | --- | --- |
|
|
71
|
-
| **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | `--vx-hit` replaces the touch vars; `SIZE_CLASSES` (§ 1.31.0) | — | `SIZE_CLASSES`/`CONTAINER_CLASSES` actually exported (§ Fixes) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | `CONTAINER_KEYS` (§ 1.34.0) | — | — | — | — | — | — | — | | `appShellInset` 20 → 16 (§ 1.38.1) | — | — | — | — | — | — | — | — | — |
|
|
72
|
-
| **charts** (`./charts`) | — | phone tier, `curve`, formatters, `state`, log axis (§ preamble) | `ChartState.empty: string`, `AxisBottomNumeric` (§ Additions) | responsive `height`, `legend.maxRows` (§ Charts) | `height` reaches the kinds; `maxRows` beats the `fill` fit (§ Charts) | — | container-class tier + `height` keys (§ 1.31.0) | — | `ResponsiveChartHeight` `sm` → key (§ Container recipes) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
73
|
-
| **shell** (`.`) | — | scrollport, region seams, **the brand left the sidebar** (§§ scrollport, brand, Shell) | `PageTitle`, `BasaltDevDock`, `useBreakpoint` (§ Additions) | More popover, aside pill, the responsive gutter, `useBasaltSpacing` (§ Chrome) | — | — | `theme.breakpoints` derived, `useSizeClass`, `data-basalt-host`, `useBreakpoint` on notice (§ 1.31.0) | `useBreakpoint` removal → 1.33.0; `useSizeClass` is shell-only (§ 1.32.0) | shell-less `shell/` gutter, `AppShell` breakpoints, `useSizeClass` for overlays (§§ Shell-less, `useSizeClass`) | — | `useBreakpoint` removed (§ 1.34.0) | — | — | `useCoarsePointer()` (§ `useCoarsePointer()`) | — | — | — | — | | content gutter 16, block 8 from `sm` (§ 1.38.1) | — | — | — | — | — | — | — | — | — |
|
|
74
|
-
| **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — | — | `NumberFilter clearable`; `createSearchStore` `resets` (§ State and controls) | — | — | — | `FormSection`/`FormRow`/`FormGroup`/`FormActions` move here (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
75
|
-
| **forms** (`./forms`) | — | `field` → `inputProps`, **`inputProps` drops `key`**, the layout tier (§ `inputProps`) | `field` DELETED — and the `--fix` recipe no longer works (§ Consolidation) | — | — | — | — | — | `FormGroup` row no longer stretches (§ Fixes) | — | — | — | — | the layout + `useForm`/`schemaResolver` deprecated, removed 1.37.0 (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
76
|
-
| **data** (`./data/table`) | — | root is a `<div>`, row selection, `getItemKey` required (§ `basalt-ui/data`) | `./data` + `./query` + `./connectivity` dropped (§ Consolidation) | — | — | — | — | — | `renderCard` documented (§ `renderCard`) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
77
|
-
| **dashboard** (`.`) | `StatCard`: `unit`, `breakdown`, delta format (§ `StatCard`) | `StatGroup`, `WidgetGrid`, query-aware `StatCard` — additive | — | **the column law keys on the CONTAINER; `cols={4}` is 2-up at `sm`** (§ Dashboard) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
78
|
-
| **toolchain** (`./configs/*`) | — | — | the shipped lefthook preset's `check-theme` BROKE — the CLI resolver stopped ascending (§ CLI) | the preset's default bin, and the `root:` recipe (§ Toolchain) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
79
|
-
| **CLI** (`basalt-ui`) | — | — | **resolver stops relocating; `doctor` loses 6 of 10 checks** (§ CLI) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | the managed block moves `CLAUDE.md` → `AGENTS.md` (§ 1.41.0) | — | — | — |
|
|
80
|
-
| **guards** | five rules → `error` (§ Guards) | six new ids at `warn` (§ preamble) | `query-dual-import` retired in 1.29.1 (§ Guards) | four rules → `error` (§ Guards) | — | — | — | `raw-breakpoint`: the container-grid answer, `error` at 1.33.0 (§ 1.32.0) | `FormRow`/`FormGroup` homes in both lanes; `basalt-main` dropped (§ Fixes) | C1 + breakpoint pairs → `error`; `unknown-vx-token` `warn` (§ Guards) | — | — | — | `unknown-vx-token` → `error`; the token factories throw (§ Guards) | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
69
|
+
| Surface | 1.27.0 | 1.28.0 | 1.29.0 | 1.30.0 | 1.30.1 | 1.30.2 | 1.31.0 | 1.32.0 | 1.32.1 | 1.33.0 | 1.34.0 | 1.34.1 | 1.35.0 | 1.36.0 | 1.36.1 | 1.37.0 | 1.37.1 | 1.38.0 | 1.38.1 | 1.39.0 | 1.40.0 | 1.40.1 | 1.40.2 | 1.40.3 | 1.41.0 | 2.0.0 | 2.0.1 | 2.0.2 | Unreleased |
|
|
70
|
+
| ----------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------- | ------ | ------ | -------------------------------------------------------------------------------------------- | ------ | ------ | ------ | ------ | ------ | ----------------------------------------------- | ------ | ------ | ------ | ------ | ------------------------------------------------------------ | ---------- | --- | --- | --- | --- |
|
|
71
|
+
| **tokens** (`./tokens`) | — | `--vx-divider` → `rgba()` on both schemes (§ Shell) | `--vx-space-touch-target` added (§ Additions) | eight spacing numbers (§ Chrome) | — | — | `--vx-hit` replaces the touch vars; `SIZE_CLASSES` (§ 1.31.0) | — | `SIZE_CLASSES`/`CONTAINER_CLASSES` actually exported (§ Fixes) | `CONTAINER_GRID_BREAKPOINTS`; `raw-breakpoint` trusts it (§ 1.33.0) | `CONTAINER_KEYS` (§ 1.34.0) | — | — | — | — | — | — | — | | `appShellInset` 20 → 16 (§ 1.38.1) | — | — | — | — | — | — | — | — | — | — |
|
|
72
|
+
| **charts** (`./charts`) | — | phone tier, `curve`, formatters, `state`, log axis (§ preamble) | `ChartState.empty: string`, `AxisBottomNumeric` (§ Additions) | responsive `height`, `legend.maxRows` (§ Charts) | `height` reaches the kinds; `maxRows` beats the `fill` fit (§ Charts) | — | container-class tier + `height` keys (§ 1.31.0) | — | `ResponsiveChartHeight` `sm` → key (§ Container recipes) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
73
|
+
| **shell** (`.`) | — | scrollport, region seams, **the brand left the sidebar** (§§ scrollport, brand, Shell) | `PageTitle`, `BasaltDevDock`, `useBreakpoint` (§ Additions) | More popover, aside pill, the responsive gutter, `useBasaltSpacing` (§ Chrome) | — | — | `theme.breakpoints` derived, `useSizeClass`, `data-basalt-host`, `useBreakpoint` on notice (§ 1.31.0) | `useBreakpoint` removal → 1.33.0; `useSizeClass` is shell-only (§ 1.32.0) | shell-less `shell/` gutter, `AppShell` breakpoints, `useSizeClass` for overlays (§§ Shell-less, `useSizeClass`) | — | `useBreakpoint` removed (§ 1.34.0) | — | — | `useCoarsePointer()` (§ `useCoarsePointer()`) | — | — | — | — | | content gutter 16, block 8 from `sm` (§ 1.38.1) | — | — | — | — | — | — | — | — | — | — |
|
|
74
|
+
| **controls** (`./controls`) | `NumberFilter`, `field.number` (§ Controls) | sheet renders panel rows; `PanelRow`, `SliderControl` (§ `basalt-ui/controls`) | — | — | — | — | — | — | — | `NumberFilter clearable`; `createSearchStore` `resets` (§ State and controls) | — | — | — | `FormSection`/`FormRow`/`FormGroup`/`FormActions` move here (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
75
|
+
| **forms** (`./forms`) | — | `field` → `inputProps`, **`inputProps` drops `key`**, the layout tier (§ `inputProps`) | `field` DELETED — and the `--fix` recipe no longer works (§ Consolidation) | — | — | — | — | — | `FormGroup` row no longer stretches (§ Fixes) | — | — | — | — | the layout + `useForm`/`schemaResolver` deprecated, removed 1.37.0 (§ The form layout moves) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
76
|
+
| **data** (`./data/table`) | — | root is a `<div>`, row selection, `getItemKey` required (§ `basalt-ui/data`) | `./data` + `./query` + `./connectivity` dropped (§ Consolidation) | — | — | — | — | — | `renderCard` documented (§ `renderCard`) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
77
|
+
| **dashboard** (`.`) | `StatCard`: `unit`, `breakdown`, delta format (§ `StatCard`) | `StatGroup`, `WidgetGrid`, query-aware `StatCard` — additive | — | **the column law keys on the CONTAINER; `cols={4}` is 2-up at `sm`** (§ Dashboard) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
78
|
+
| **toolchain** (`./configs/*`) | — | — | the shipped lefthook preset's `check-theme` BROKE — the CLI resolver stopped ascending (§ CLI) | the preset's default bin, and the `root:` recipe (§ Toolchain) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
79
|
+
| **CLI** (`basalt-ui`) | — | — | **resolver stops relocating; `doctor` loses 6 of 10 checks** (§ CLI) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — | the managed block moves `CLAUDE.md` → `AGENTS.md` (§ 1.41.0) | — | — | — | — |
|
|
80
|
+
| **guards** | five rules → `error` (§ Guards) | six new ids at `warn` (§ preamble) | `query-dual-import` retired in 1.29.1 (§ Guards) | four rules → `error` (§ Guards) | — | — | — | `raw-breakpoint`: the container-grid answer, `error` at 1.33.0 (§ 1.32.0) | `FormRow`/`FormGroup` homes in both lanes; `basalt-main` dropped (§ Fixes) | C1 + breakpoint pairs → `error`; `unknown-vx-token` `warn` (§ Guards) | — | — | — | `unknown-vx-token` → `error`; the token factories throw (§ Guards) | — | — | — | — | — | — | — | — | — | — | — | — | — | — | — |
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
@@ -992,6 +992,10 @@ optional, subpath-required peers.
|
|
|
992
992
|
_Nothing yet. Author the next section under this heading as `## Unreleased — <title>`; the
|
|
993
993
|
release renames it and opens a new one here._
|
|
994
994
|
|
|
995
|
+
## 2.0.2
|
|
996
|
+
|
|
997
|
+
_Nothing to migrate in this release._
|
|
998
|
+
|
|
995
999
|
## 2.0.1
|
|
996
1000
|
|
|
997
1001
|
_Nothing to migrate in this release._
|
|
@@ -1008,6 +1012,13 @@ _Nothing to migrate in this release._
|
|
|
1008
1012
|
- Corrected the § 2.0 "Upgrading from 1.x" step 2: delete only the core, notifications and
|
|
1009
1013
|
spotlight layer imports; extension packages (`@mantine/dates`, `@mantine/schedule`) stay, after
|
|
1010
1014
|
`basalt-ui/styles.css`.
|
|
1015
|
+
- `doctor` and `sync` are monorepo-aware. The manifest, `.claude/` and the AGENTS block stay at the
|
|
1016
|
+
install root; the app-scoped half (`tsconfig-base`, `app-wiring`, the `src/main.tsx`,
|
|
1017
|
+
`src/lib/nav.tsx` and `src/routes/__root.tsx` seeds) targets the app package: `basalt.app`
|
|
1018
|
+
(relative path, e.g. `"apps/dashboard"`) in the root package.json, else the one workspace package
|
|
1019
|
+
that depends on basalt-ui and has `src/main.tsx` or `index.html`, else the cwd. Two candidates
|
|
1020
|
+
fail with a message naming `basalt.app`. `doctor` run inside the app package finds the root
|
|
1021
|
+
manifest, and warns about a router seed an earlier `sync` left at the root — delete it.
|
|
1011
1022
|
|
|
1012
1023
|
## 2.0.0
|
|
1013
1024
|
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { GuardKind, GuardSeverity } from '../guard/index.js';
|
|
2
2
|
/** Shape of the optional `"basalt"` key in a consumer's package.json. */
|
|
3
3
|
export type BasaltConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* The Vite app's directory relative to the install root, for a workspace monorepo whose manifest,
|
|
6
|
+
* `.claude/` and AGENTS block live at the root. App-scoped checks (`tsconfig-base`, `app-wiring`)
|
|
7
|
+
* and the router seeds target it. Default: the single workspace package that depends on basalt-ui
|
|
8
|
+
* and has a Vite entry, else the root itself.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* { app: 'apps/dashboard' }
|
|
12
|
+
*/
|
|
13
|
+
app?: string;
|
|
4
14
|
/** Source roots to scan. Default: `['src']`. Set explicitly for a monorepo layout. */
|
|
5
15
|
roots?: string[];
|
|
6
16
|
/** Files exempt from the scan (they ARE the palette source). Default: argo's exempt set. */
|
package/dist/cli/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExD,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG;IACzB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;IACnC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;wFACoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;IACpD,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAA;IACzD;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5E,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,EAAE,CAG5E;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGlF;AAED,eAAO,MAAM,YAAY,QAAQ,CAAA;AACjC,eAAO,MAAM,aAAa,UAAiB,CAAA;AAE3C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAExD;AAED,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,EAIf,CAAC,MAAM,YAAY,CAAC,EAAE,CAAA;AAEtC,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEhE,CAAA"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExD,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;IACnC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;wFACoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;IACpD,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAA;IACzD;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5E,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,EAAE,CAG5E;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGlF;AAED,eAAO,MAAM,YAAY,QAAQ,CAAA;AACjC,eAAO,MAAM,aAAa,UAAiB,CAAA;AAE3C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAExD;AAED,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,EAIf,CAAC,MAAM,YAAY,CAAC,EAAE,CAAA;AAEtC,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEhE,CAAA"}
|
package/dist/cli/config.js
CHANGED
|
@@ -11,7 +11,7 @@ const DEFAULT_ROOTS = [DEFAULT_ROOT];
|
|
|
11
11
|
function resolveRoots(cfg) {
|
|
12
12
|
return cfg.roots?.length ? cfg.roots : DEFAULT_ROOTS;
|
|
13
13
|
}
|
|
14
|
-
const BASALT_CONFIG_KEYS = "roots exempt profile include spacingSteps severity forbiddenAccents accentHue rawRadius rawSurface cardWithBorder offSystemSurfaceVar mantineShadeIndex rawHtmlLayout inlineSpacing inlineDisplay rawMotionValue rawFormControl sub16InputFont seriesModulePath exemptRules aiMajorSkewReason".split(" ");
|
|
14
|
+
const BASALT_CONFIG_KEYS = "app roots exempt profile include spacingSteps severity forbiddenAccents accentHue rawRadius rawSurface cardWithBorder offSystemSurfaceVar mantineShadeIndex rawHtmlLayout inlineSpacing inlineDisplay rawMotionValue rawFormControl sub16InputFont seriesModulePath exemptRules aiMajorSkewReason".split(" ");
|
|
15
15
|
const RETIRED_CONFIG_KEYS = {
|
|
16
16
|
chartMissingAriaLabel: "its guard kind is gone in 2.0 (`ariaLabel` is required on a chart now)"
|
|
17
17
|
};
|
package/dist/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAyDA,MAAM,MAAM,YAAY,GAAG;IACzB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAA;IACpB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AA8CD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,aAAa,GAAE,MAAsB,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,MAAM,CAsU1F"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -19,7 +19,9 @@ import {
|
|
|
19
19
|
readBasaltConfig,
|
|
20
20
|
readIfExists,
|
|
21
21
|
readManifest,
|
|
22
|
+
resolveAppDir,
|
|
22
23
|
resolveProjectDir,
|
|
24
|
+
ROUTER_SEED_DESTS,
|
|
23
25
|
sameFile,
|
|
24
26
|
scannableFiles,
|
|
25
27
|
scanBlock,
|
|
@@ -74,7 +76,12 @@ function resolveAiMajorSkewReason(cfg) {
|
|
|
74
76
|
function doctor(invocationCwd = process.cwd(), flags = []) {
|
|
75
77
|
if (conflictingProfileFlags("doctor", flags)) return 1;
|
|
76
78
|
const project = resolveProjectDir(invocationCwd);
|
|
77
|
-
const
|
|
79
|
+
const aboveRoot = project.relocatedFrom === null && !existsSync(resolve(project.dir, MANIFEST_PATH)) ? findManifestAbove(project.dir) : null;
|
|
80
|
+
const insideApp = aboveRoot !== null && (() => {
|
|
81
|
+
const app2 = resolveAppDir(aboveRoot);
|
|
82
|
+
return !("error" in app2) && app2.dir === project.dir;
|
|
83
|
+
})();
|
|
84
|
+
const cwd = insideApp && aboveRoot !== null ? aboveRoot : project.dir;
|
|
78
85
|
const cfg = readBasaltConfig(cwd);
|
|
79
86
|
const result = { hardFailures: 0, warnings: 0, skipped: 0 };
|
|
80
87
|
const lines = [`
|
|
@@ -99,6 +106,11 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
99
106
|
lines.push(` \u2192 BASALT_CWD relocated from ${project.relocatedFrom} to ${cwd}.
|
|
100
107
|
`);
|
|
101
108
|
}
|
|
109
|
+
if (insideApp)
|
|
110
|
+
lines.push(` \u2192 ${project.dir} is the app package; checking the install root ${cwd}.
|
|
111
|
+
`);
|
|
112
|
+
const app = resolveAppDir(cwd);
|
|
113
|
+
const appDir = "error" in app ? cwd : app.dir;
|
|
102
114
|
const profile = declaredProfile(cfg, flags);
|
|
103
115
|
if (profile === "tokens-only") {
|
|
104
116
|
lines.push(
|
|
@@ -120,6 +132,19 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
120
132
|
fail(`${MANIFEST_PATH} missing \u2014 run \`basalt-ui init\` to scaffold the consumer repo`);
|
|
121
133
|
}
|
|
122
134
|
const install = findBasaltInstall(cwd);
|
|
135
|
+
if ("error" in app) {
|
|
136
|
+
fail(`app-dir: ${app.error}`);
|
|
137
|
+
} else if (app.rel !== "") {
|
|
138
|
+
pass(`app-dir: the app is ${app.rel} (agent layer and manifest stay at the install root)`);
|
|
139
|
+
const ledger = readManifest(cwd).files;
|
|
140
|
+
for (const seed of Object.values(ROUTER_SEED_DESTS)) {
|
|
141
|
+
if (ledger[seed] !== void 0 && existsSync(resolve(cwd, seed))) {
|
|
142
|
+
warn(
|
|
143
|
+
`app-dir: ${seed} was seeded at the install root by an earlier \`sync\`, but the app is ${app.rel} \u2014 it is dead code there. Delete it (\`sync\` seeds ${app.rel}/${seed} instead).`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
123
148
|
const manifestVersion = profile === "tokens-only" ? void 0 : readManifest(cwd).basaltVersion;
|
|
124
149
|
const at = install.dir === null ? "" : `${relative(cwd, install.dir)} (${install.version})`;
|
|
125
150
|
if (install.dir === null) {
|
|
@@ -255,7 +280,7 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
255
280
|
);
|
|
256
281
|
} else {
|
|
257
282
|
const upgrade = [
|
|
258
|
-
["tsconfig-base: tsconfig.json extends the shipped preset", tsconfigBaseCheck(
|
|
283
|
+
["tsconfig-base: tsconfig.json extends the shipped preset", tsconfigBaseCheck(appDir)],
|
|
259
284
|
[
|
|
260
285
|
"retired-lint-rules: .oxlintrc.json sets no retired basalt/* rule",
|
|
261
286
|
retiredLintRulesCheck(cwd, install)
|
|
@@ -266,7 +291,7 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
266
291
|
],
|
|
267
292
|
[
|
|
268
293
|
"app-wiring: the entry mounts BasaltProvider and the router tree is generated",
|
|
269
|
-
appWiringCheck(
|
|
294
|
+
appWiringCheck(appDir)
|
|
270
295
|
],
|
|
271
296
|
["exact-peers: installed exact-pinned peers match basalt-ui", exactPeersCheck(cwd, install)],
|
|
272
297
|
[
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -199,6 +199,22 @@ export declare const ROUTER_SEED_DESTS: {
|
|
|
199
199
|
readonly root: "src/routes/__root.tsx";
|
|
200
200
|
readonly main: "src/main.tsx";
|
|
201
201
|
};
|
|
202
|
+
/** A router seed's dest, relative to the install root: under the app dir when it is not the root. */
|
|
203
|
+
export declare function routerSeedDest(appRel: string, seed: keyof typeof ROUTER_SEED_DESTS): string;
|
|
204
|
+
/** The app directory a command's app-scoped half targets: `rel` is '' when it is the install root. */
|
|
205
|
+
export type AppResolution = {
|
|
206
|
+
dir: string;
|
|
207
|
+
rel: string;
|
|
208
|
+
} | {
|
|
209
|
+
error: string;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Where the Vite app lives relative to the install root `root` (manifest, `.claude/`, AGENTS block).
|
|
213
|
+
* ONE resolution for `doctor`, `sync` and `init`, in order: `basalt.app` in the root package.json;
|
|
214
|
+
* else the single workspace package that depends on basalt-ui AND has a Vite entry; else `root`
|
|
215
|
+
* itself (a single-package app). Two such packages is an error — the choice is not inferable.
|
|
216
|
+
*/
|
|
217
|
+
export declare function resolveAppDir(root: string): AppResolution;
|
|
202
218
|
/**
|
|
203
219
|
* Where the seed engine is running relative to the consumer's git repo — decides which
|
|
204
220
|
* repo-root-shaped seeds are safe to write. `init`/`sync` compute it once per run via
|
|
@@ -214,6 +230,10 @@ export type PlacementFlags = {
|
|
|
214
230
|
/** Absolute path of the detected repo root. Meaningful only when `isPackageRepoRoot` is false —
|
|
215
231
|
* otherwise it equals the package dir and is never read. */
|
|
216
232
|
repoRoot: string;
|
|
233
|
+
/** The app directory relative to the install root ('' = the root itself); see {@link resolveAppDir}. */
|
|
234
|
+
appRel: string;
|
|
235
|
+
/** Non-null when the app directory is ambiguous or invalid: commands refuse rather than guess. */
|
|
236
|
+
appError: string | null;
|
|
217
237
|
};
|
|
218
238
|
/** The default placement — today's single-package-at-repo-root behaviour, unconditionally. */
|
|
219
239
|
export declare const ROOT_PLACEMENT: PlacementFlags;
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -351,6 +351,37 @@ const ROUTER_SEED_DESTS = {
|
|
|
351
351
|
root: "src/routes/__root.tsx",
|
|
352
352
|
main: "src/main.tsx"
|
|
353
353
|
};
|
|
354
|
+
function routerSeedDest(appRel, seed) {
|
|
355
|
+
return appRel === "" ? ROUTER_SEED_DESTS[seed] : `${appRel}/${ROUTER_SEED_DESTS[seed]}`;
|
|
356
|
+
}
|
|
357
|
+
const appRelative = (root, dir) => relativePosix(root, dir).replace(/^\.\/?/, "");
|
|
358
|
+
const hasViteEntry = (dir) => existsSync(resolve(dir, "src/main.tsx")) || existsSync(resolve(dir, "index.html"));
|
|
359
|
+
function resolveAppDir(root) {
|
|
360
|
+
const self = { dir: root, rel: "" };
|
|
361
|
+
const explicit = readBasaltConfig(root).app;
|
|
362
|
+
if (explicit !== void 0) {
|
|
363
|
+
const dir = resolve(root, explicit);
|
|
364
|
+
const rel = appRelative(root, dir);
|
|
365
|
+
if (rel.startsWith("..") || !existsSync(resolve(dir, "package.json"))) {
|
|
366
|
+
return {
|
|
367
|
+
error: `basalt.app "${explicit}" must be a directory with a package.json inside ${root}.`
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
return dir === root ? self : { dir, rel };
|
|
371
|
+
}
|
|
372
|
+
const candidates = collectWorkspacePackages(root).packages.filter(
|
|
373
|
+
(pkg) => pkg.dir !== root && hasDependency(pkg.dir, "basalt-ui") && hasViteEntry(pkg.dir)
|
|
374
|
+
);
|
|
375
|
+
if (candidates.length === 0) return self;
|
|
376
|
+
const [only] = candidates;
|
|
377
|
+
if (candidates.length === 1 && only !== void 0) {
|
|
378
|
+
return { dir: only.dir, rel: appRelative(root, only.dir) };
|
|
379
|
+
}
|
|
380
|
+
const names = candidates.map((pkg) => appRelative(root, pkg.dir)).join(", ");
|
|
381
|
+
return {
|
|
382
|
+
error: `${candidates.length} workspace packages depend on basalt-ui and have a Vite entry (${names}) \u2014 cannot tell which is the app. Set \`basalt.app\` (e.g. \`"basalt": { "app": "apps/web" }\`) in the root package.json.`
|
|
383
|
+
};
|
|
384
|
+
}
|
|
354
385
|
function hasDependency(cwd, pkgName) {
|
|
355
386
|
try {
|
|
356
387
|
const pkg = JSON.parse(readFileSync(resolve(cwd, "package.json"), "utf8"));
|
|
@@ -363,7 +394,9 @@ function hasDependency(cwd, pkgName) {
|
|
|
363
394
|
}
|
|
364
395
|
const ROOT_PLACEMENT = {
|
|
365
396
|
isPackageRepoRoot: true,
|
|
366
|
-
repoRoot: ""
|
|
397
|
+
repoRoot: "",
|
|
398
|
+
appRel: "",
|
|
399
|
+
appError: null
|
|
367
400
|
};
|
|
368
401
|
function findRepoRoot(dir) {
|
|
369
402
|
let current = dir;
|
|
@@ -384,9 +417,12 @@ function oxlintBinResolves(dir) {
|
|
|
384
417
|
}
|
|
385
418
|
function resolvePlacement(cwd) {
|
|
386
419
|
const repoRoot = findRepoRoot(cwd);
|
|
420
|
+
const app = resolveAppDir(cwd);
|
|
387
421
|
return {
|
|
388
422
|
isPackageRepoRoot: repoRoot === cwd,
|
|
389
|
-
repoRoot
|
|
423
|
+
repoRoot,
|
|
424
|
+
appRel: "error" in app ? "" : app.rel,
|
|
425
|
+
appError: "error" in app ? app.error : null
|
|
390
426
|
};
|
|
391
427
|
}
|
|
392
428
|
function managedFiles(placement = ROOT_PLACEMENT) {
|
|
@@ -480,7 +516,7 @@ pre-commit:
|
|
|
480
516
|
`
|
|
481
517
|
};
|
|
482
518
|
const rootRoute = {
|
|
483
|
-
dest:
|
|
519
|
+
dest: routerSeedDest(placement.appRel, "root"),
|
|
484
520
|
mode: "seed",
|
|
485
521
|
source: "agent/templates/__root.tpl",
|
|
486
522
|
render: (ctx) => {
|
|
@@ -490,13 +526,13 @@ pre-commit:
|
|
|
490
526
|
}
|
|
491
527
|
};
|
|
492
528
|
const navModule = {
|
|
493
|
-
dest:
|
|
529
|
+
dest: routerSeedDest(placement.appRel, "nav"),
|
|
494
530
|
mode: "seed",
|
|
495
531
|
source: "agent/templates/nav.tpl",
|
|
496
532
|
render: (ctx) => readSource(ctx.pkgRoot, "agent/templates/nav.tpl")
|
|
497
533
|
};
|
|
498
534
|
const mainEntry = {
|
|
499
|
-
dest:
|
|
535
|
+
dest: routerSeedDest(placement.appRel, "main"),
|
|
500
536
|
mode: "seed",
|
|
501
537
|
source: "agent/templates/main.tpl",
|
|
502
538
|
render: (ctx) => readSource(ctx.pkgRoot, "agent/templates/main.tpl")
|
|
@@ -1002,11 +1038,13 @@ export {
|
|
|
1002
1038
|
relativePosix,
|
|
1003
1039
|
renderContext,
|
|
1004
1040
|
reportPrune,
|
|
1041
|
+
resolveAppDir,
|
|
1005
1042
|
resolveGuardConfig,
|
|
1006
1043
|
resolvePlacement,
|
|
1007
1044
|
resolveProjectDir,
|
|
1008
1045
|
retiredManagedDests,
|
|
1009
1046
|
rootsNotices,
|
|
1047
|
+
routerSeedDest,
|
|
1010
1048
|
run,
|
|
1011
1049
|
sameFile,
|
|
1012
1050
|
scanBlock,
|
package/dist/cli/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,SAAS,CAAA;AA6D7D,yGAAyG;AACzG,wBAAgB,IAAI,CAAC,GAAG,GAAE,MAAsB,EAAE,aAAa,GAAE,aAAkB,GAAG,MAAM,CA0L3F"}
|
package/dist/cli/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
declaredProfile,
|
|
7
7
|
readBasaltConfig,
|
|
8
8
|
ROUTER_SEED_DESTS,
|
|
9
|
+
routerSeedDest,
|
|
9
10
|
findBasaltInstall,
|
|
10
11
|
managedFiles,
|
|
11
12
|
mergeOxlintExtends,
|
|
@@ -47,6 +48,11 @@ function init(cwd = process.cwd(), scaffoldFlags = {}) {
|
|
|
47
48
|
`\u26A0 basalt-ui init: basalt-ui does not resolve from ${cwd} or any directory above it \u2014 the seeded \`extends\` paths and CI steps are being written against the repo root by assumption. Install basalt-ui here (or at the repo root) and re-run \`basalt-ui init\` so they resolve.`
|
|
48
49
|
);
|
|
49
50
|
}
|
|
51
|
+
const appError = resolvePlacement(cwd).appError;
|
|
52
|
+
if (appError !== null) {
|
|
53
|
+
console.error(`\u2716 basalt-ui init: ${appError}`);
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
50
56
|
const rootsState = reconcileRoots(cwd, { write: true });
|
|
51
57
|
const ctx = renderContext(cwd);
|
|
52
58
|
const lintScript = `oxlint . && ${ctx.vars.BASALT_BIN} check-theme`;
|
|
@@ -74,7 +80,7 @@ function init(cwd = process.cwd(), scaffoldFlags = {}) {
|
|
|
74
80
|
const manifest = readManifest(cwd);
|
|
75
81
|
const placement = resolvePlacement(cwd);
|
|
76
82
|
const tokensOnly = declaredProfile(readBasaltConfig(cwd), []) === "tokens-only";
|
|
77
|
-
const routerSeeds = Object.
|
|
83
|
+
const routerSeeds = Object.keys(ROUTER_SEED_DESTS).map((seed) => routerSeedDest(placement.appRel, seed));
|
|
78
84
|
const files = managedFiles(placement).filter((f) => !(tokensOnly && routerSeeds.includes(f.dest)));
|
|
79
85
|
const writtenFiles = [];
|
|
80
86
|
const keptFiles = [];
|
package/dist/cli/sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"AAwCA,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjE;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mGAAmG;IACnG,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrF;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,WAAgB,EAAE,aAAa,GAAE,MAAsB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"AAwCA,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjE;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mGAAmG;IACnG,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrF;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,WAAgB,EAAE,aAAa,GAAE,MAAsB,GAAG,MAAM,CAgM1F"}
|
package/dist/cli/sync.js
CHANGED
|
@@ -63,6 +63,11 @@ function sync(opts = {}, invocationCwd = process.cwd()) {
|
|
|
63
63
|
);
|
|
64
64
|
return 0;
|
|
65
65
|
}
|
|
66
|
+
const appError = resolvePlacement(cwd).appError;
|
|
67
|
+
if (appError !== null) {
|
|
68
|
+
console.error(`\u2716 basalt-ui sync: ${appError}`);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
66
71
|
if (!existsSync(resolve(cwd, MANIFEST_PATH))) {
|
|
67
72
|
const elsewhere = findManifestAbove(cwd);
|
|
68
73
|
const wouldWrite = managedFiles(resolvePlacement(cwd)).length;
|
package/dist/tokens/core.d.ts
CHANGED
|
@@ -190,18 +190,19 @@ export declare function seriesTokens<const T extends SeriesMap>(map: T, prefix?:
|
|
|
190
190
|
* not the widened SeriesMap, enabling downstream exact-key checks in groupTokens / seriesTokens).
|
|
191
191
|
*/
|
|
192
192
|
export declare function defineSeries<const T extends SeriesMap>(map: T): T;
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
declare const GROUP_REF: unique symbol;
|
|
194
|
+
/** A `var(--vx-<name>-<key>)` ref minted by `groupTokens`. The brand lives on the VALUES, so it never shows up in `keyof` the group. */
|
|
195
|
+
export type GroupRef = string & {
|
|
196
|
+
readonly [GROUP_REF]: true;
|
|
197
|
+
};
|
|
195
198
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
+
* What `groupTokens` returns. `BuildPaletteOpts.groups` takes these, so the `${name}-` key that
|
|
200
|
+
* emits the variables and the one that references them come from one call and cannot be spelled
|
|
201
|
+
* two ways. A bare series map (object values) and a plain string record (unbranded values) are
|
|
202
|
+
* both rejected; the runtime payload sits under the non-enumerable {@link SERIES_GROUP} symbol.
|
|
199
203
|
*/
|
|
200
204
|
export type SeriesGroup = {
|
|
201
|
-
readonly [
|
|
202
|
-
readonly prefix: string;
|
|
203
|
-
readonly map: SeriesMap;
|
|
204
|
-
};
|
|
205
|
+
readonly [key: string]: GroupRef;
|
|
205
206
|
};
|
|
206
207
|
/**
|
|
207
208
|
* Build a single namespaced group's token refs (`var(--vx-<name>-<key>)`).
|
|
@@ -210,8 +211,8 @@ export type SeriesGroup = {
|
|
|
210
211
|
* error at the call site rather than a silent `Record<string, string>` widening.
|
|
211
212
|
*/
|
|
212
213
|
export declare function groupTokens<const T extends SeriesMap>(name: string, map: T): {
|
|
213
|
-
[K in keyof T]:
|
|
214
|
-
}
|
|
214
|
+
readonly [K in keyof T]: GroupRef;
|
|
215
|
+
};
|
|
215
216
|
/**
|
|
216
217
|
* The attribute + values the per-scheme blocks key off. Defaults reproduce Mantine's own toggle
|
|
217
218
|
* (`data-mantine-color-scheme` = `dark` / `light`), so a consumer only names the axis it differs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/tokens/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAUvE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,WAAW,CAAA;AAMjC,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnF,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAM5D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAO7C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,YAAY,GACb,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,wFAAwF;AACxF,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,8FAA8F;AAC9F,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,GAAG,MAAM,KAAG,MACoB,CAAA;AA6DrE,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4Jb;;;;;OAKG;;IAEH;;wDAEoD;;CAE5C,CAAA;AAEV;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW;IACtB;;;;;OAKG;;CAEK,CAAA;AAOV;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAExC;AAwbD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,EACpD,GAAG,EAAE,CAAC,EACN,MAAM,SAAK,GACV;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAAE,CAQ5B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAEjE;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/tokens/core.ts"],"names":[],"mappings":"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"}
|
package/dist/tokens/core.js
CHANGED
|
@@ -596,7 +596,15 @@ function buildPaletteCss(opts = {}, data = buildPaletteData()) {
|
|
|
596
596
|
const derived = extraDerived ? `${derivedBlock}
|
|
597
597
|
${extraDerived}` : derivedBlock;
|
|
598
598
|
const side = (s) => {
|
|
599
|
-
const extra = groups.map((group) =>
|
|
599
|
+
const extra = groups.map((group) => {
|
|
600
|
+
const payload = group[SERIES_GROUP];
|
|
601
|
+
if (!payload) {
|
|
602
|
+
throw new Error(
|
|
603
|
+
"BuildPaletteOpts.groups: every group must come from groupTokens(name, map)"
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
return groupSide(payload.prefix, payload.map, s);
|
|
607
|
+
}).join("\n");
|
|
600
608
|
const framework = frameworkPrimitives(s, data, legacyAliases);
|
|
601
609
|
return extra ? `${framework}
|
|
602
610
|
${extra}` : framework;
|
package/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# basalt-ui v2.0.
|
|
1
|
+
# basalt-ui v2.0.2
|
|
2
2
|
# Opinionated framework for Mantine-based React apps — theme, app shell, TanStack Charts, toolchain presets
|
|
3
3
|
#
|
|
4
4
|
# Entry points: use the exact import specifier below; do not guess.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# A subpath's `Install:` line is its required peers; `OptionalPeers:` are import()-only, install on use.
|
|
14
14
|
|
|
15
15
|
Package: basalt-ui
|
|
16
|
-
Version: 2.0.
|
|
16
|
+
Version: 2.0.2
|
|
17
17
|
|
|
18
18
|
## basalt-ui
|
|
19
19
|
Import: import { ... } from 'basalt-ui'
|
package/package.json
CHANGED
package/src/cli/config.ts
CHANGED
|
@@ -4,6 +4,16 @@ import type { GuardKind, GuardSeverity } from '../guard'
|
|
|
4
4
|
|
|
5
5
|
/** Shape of the optional `"basalt"` key in a consumer's package.json. */
|
|
6
6
|
export type BasaltConfig = {
|
|
7
|
+
/**
|
|
8
|
+
* The Vite app's directory relative to the install root, for a workspace monorepo whose manifest,
|
|
9
|
+
* `.claude/` and AGENTS block live at the root. App-scoped checks (`tsconfig-base`, `app-wiring`)
|
|
10
|
+
* and the router seeds target it. Default: the single workspace package that depends on basalt-ui
|
|
11
|
+
* and has a Vite entry, else the root itself.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* { app: 'apps/dashboard' }
|
|
15
|
+
*/
|
|
16
|
+
app?: string
|
|
7
17
|
/** Source roots to scan. Default: `['src']`. Set explicitly for a monorepo layout. */
|
|
8
18
|
roots?: string[]
|
|
9
19
|
/** Files exempt from the scan (they ARE the palette source). Default: argo's exempt set. */
|
|
@@ -181,7 +191,7 @@ export function resolveRoots(cfg: BasaltConfig): string[] {
|
|
|
181
191
|
|
|
182
192
|
/** Every `BasaltConfig` key, as data for `doctor`'s `config-keys` (a test pins it to the type). */
|
|
183
193
|
export const BASALT_CONFIG_KEYS = (
|
|
184
|
-
'roots exempt profile include spacingSteps severity forbiddenAccents accentHue rawRadius rawSurface ' +
|
|
194
|
+
'app roots exempt profile include spacingSteps severity forbiddenAccents accentHue rawRadius rawSurface ' +
|
|
185
195
|
'cardWithBorder offSystemSurfaceVar mantineShadeIndex rawHtmlLayout inlineSpacing inlineDisplay ' +
|
|
186
196
|
'rawMotionValue rawFormControl sub16InputFont seriesModulePath exemptRules aiMajorSkewReason'
|
|
187
197
|
).split(' ') as (keyof BasaltConfig)[]
|
package/src/cli/doctor.ts
CHANGED
|
@@ -26,7 +26,9 @@ import {
|
|
|
26
26
|
readBasaltConfig,
|
|
27
27
|
readIfExists,
|
|
28
28
|
readManifest,
|
|
29
|
+
resolveAppDir,
|
|
29
30
|
resolveProjectDir,
|
|
31
|
+
ROUTER_SEED_DESTS,
|
|
30
32
|
sameFile,
|
|
31
33
|
scannableFiles,
|
|
32
34
|
scanBlock,
|
|
@@ -135,7 +137,18 @@ function resolveAiMajorSkewReason(cfg: BasaltConfig): {
|
|
|
135
137
|
export function doctor(invocationCwd: string = process.cwd(), flags: string[] = []): number {
|
|
136
138
|
if (conflictingProfileFlags('doctor', flags)) return 1
|
|
137
139
|
const project = resolveProjectDir(invocationCwd)
|
|
138
|
-
|
|
140
|
+
// Inside the app package of a monorepo the manifest is above: read the install root instead.
|
|
141
|
+
const aboveRoot =
|
|
142
|
+
project.relocatedFrom === null && !existsSync(resolve(project.dir, MANIFEST_PATH))
|
|
143
|
+
? findManifestAbove(project.dir)
|
|
144
|
+
: null
|
|
145
|
+
const insideApp =
|
|
146
|
+
aboveRoot !== null &&
|
|
147
|
+
(() => {
|
|
148
|
+
const app = resolveAppDir(aboveRoot)
|
|
149
|
+
return !('error' in app) && app.dir === project.dir
|
|
150
|
+
})()
|
|
151
|
+
const cwd = insideApp && aboveRoot !== null ? aboveRoot : project.dir
|
|
139
152
|
const cfg = readBasaltConfig(cwd)
|
|
140
153
|
const result: DoctorResult = { hardFailures: 0, warnings: 0, skipped: 0 }
|
|
141
154
|
const lines: string[] = [`\nbasalt-ui doctor — ${cwd}\n`]
|
|
@@ -160,6 +173,11 @@ export function doctor(invocationCwd: string = process.cwd(), flags: string[] =
|
|
|
160
173
|
lines.push(` → BASALT_CWD relocated from ${project.relocatedFrom} to ${cwd}.\n`)
|
|
161
174
|
}
|
|
162
175
|
|
|
176
|
+
if (insideApp)
|
|
177
|
+
lines.push(` → ${project.dir} is the app package; checking the install root ${cwd}.\n`)
|
|
178
|
+
|
|
179
|
+
const app = resolveAppDir(cwd)
|
|
180
|
+
const appDir = 'error' in app ? cwd : app.dir
|
|
163
181
|
const profile = declaredProfile(cfg, flags)
|
|
164
182
|
if (profile === 'tokens-only') {
|
|
165
183
|
lines.push(
|
|
@@ -192,6 +210,22 @@ export function doctor(invocationCwd: string = process.cwd(), flags: string[] =
|
|
|
192
210
|
|
|
193
211
|
const install = findBasaltInstall(cwd)
|
|
194
212
|
|
|
213
|
+
// ── App placement: the agent layer is at the root, the app is where `resolveAppDir` says ────
|
|
214
|
+
if ('error' in app) {
|
|
215
|
+
fail(`app-dir: ${app.error}`)
|
|
216
|
+
} else if (app.rel !== '') {
|
|
217
|
+
pass(`app-dir: the app is ${app.rel} (agent layer and manifest stay at the install root)`)
|
|
218
|
+
const ledger = readManifest(cwd).files
|
|
219
|
+
for (const seed of Object.values(ROUTER_SEED_DESTS)) {
|
|
220
|
+
if (ledger[seed] !== undefined && existsSync(resolve(cwd, seed))) {
|
|
221
|
+
warn(
|
|
222
|
+
`app-dir: ${seed} was seeded at the install root by an earlier \`sync\`, but the app is ` +
|
|
223
|
+
`${app.rel} — it is dead code there. Delete it (\`sync\` seeds ${app.rel}/${seed} instead).`,
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
195
229
|
// ── Hard check 2: install matches the manifest, and doctor says WHERE (the AGENTS-block's claim)
|
|
196
230
|
const manifestVersion = profile === 'tokens-only' ? undefined : readManifest(cwd).basaltVersion
|
|
197
231
|
const at = install.dir === null ? '' : `${relative(cwd, install.dir)} (${install.version})`
|
|
@@ -380,7 +414,7 @@ export function doctor(invocationCwd: string = process.cwd(), flags: string[] =
|
|
|
380
414
|
)
|
|
381
415
|
} else {
|
|
382
416
|
const upgrade: [string, Check][] = [
|
|
383
|
-
['tsconfig-base: tsconfig.json extends the shipped preset', tsconfigBaseCheck(
|
|
417
|
+
['tsconfig-base: tsconfig.json extends the shipped preset', tsconfigBaseCheck(appDir)],
|
|
384
418
|
[
|
|
385
419
|
'retired-lint-rules: .oxlintrc.json sets no retired basalt/* rule',
|
|
386
420
|
retiredLintRulesCheck(cwd, install),
|
|
@@ -391,7 +425,7 @@ export function doctor(invocationCwd: string = process.cwd(), flags: string[] =
|
|
|
391
425
|
],
|
|
392
426
|
[
|
|
393
427
|
'app-wiring: the entry mounts BasaltProvider and the router tree is generated',
|
|
394
|
-
appWiringCheck(
|
|
428
|
+
appWiringCheck(appDir),
|
|
395
429
|
],
|
|
396
430
|
['exact-peers: installed exact-pinned peers match basalt-ui', exactPeersCheck(cwd, install)],
|
|
397
431
|
[
|
package/src/cli/index.ts
CHANGED
|
@@ -654,6 +654,56 @@ export const ROUTER_SEED_DESTS = {
|
|
|
654
654
|
main: 'src/main.tsx',
|
|
655
655
|
} as const
|
|
656
656
|
|
|
657
|
+
/** A router seed's dest, relative to the install root: under the app dir when it is not the root. */
|
|
658
|
+
export function routerSeedDest(appRel: string, seed: keyof typeof ROUTER_SEED_DESTS): string {
|
|
659
|
+
return appRel === '' ? ROUTER_SEED_DESTS[seed] : `${appRel}/${ROUTER_SEED_DESTS[seed]}`
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/** The app directory a command's app-scoped half targets: `rel` is '' when it is the install root. */
|
|
663
|
+
export type AppResolution = { dir: string; rel: string } | { error: string }
|
|
664
|
+
|
|
665
|
+
/** `dir` relative to `root` without relativePosix's leading `./` ('' for the root itself). */
|
|
666
|
+
const appRelative = (root: string, dir: string): string =>
|
|
667
|
+
relativePosix(root, dir).replace(/^\.\/?/, '')
|
|
668
|
+
|
|
669
|
+
const hasViteEntry = (dir: string): boolean =>
|
|
670
|
+
existsSync(resolve(dir, 'src/main.tsx')) || existsSync(resolve(dir, 'index.html'))
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Where the Vite app lives relative to the install root `root` (manifest, `.claude/`, AGENTS block).
|
|
674
|
+
* ONE resolution for `doctor`, `sync` and `init`, in order: `basalt.app` in the root package.json;
|
|
675
|
+
* else the single workspace package that depends on basalt-ui AND has a Vite entry; else `root`
|
|
676
|
+
* itself (a single-package app). Two such packages is an error — the choice is not inferable.
|
|
677
|
+
*/
|
|
678
|
+
export function resolveAppDir(root: string): AppResolution {
|
|
679
|
+
const self = { dir: root, rel: '' }
|
|
680
|
+
const explicit = readBasaltConfig(root).app
|
|
681
|
+
if (explicit !== undefined) {
|
|
682
|
+
const dir = resolve(root, explicit)
|
|
683
|
+
const rel = appRelative(root, dir)
|
|
684
|
+
if (rel.startsWith('..') || !existsSync(resolve(dir, 'package.json'))) {
|
|
685
|
+
return {
|
|
686
|
+
error: `basalt.app "${explicit}" must be a directory with a package.json inside ${root}.`,
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return dir === root ? self : { dir, rel }
|
|
690
|
+
}
|
|
691
|
+
const candidates = collectWorkspacePackages(root).packages.filter(
|
|
692
|
+
(pkg) => pkg.dir !== root && hasDependency(pkg.dir, 'basalt-ui') && hasViteEntry(pkg.dir),
|
|
693
|
+
)
|
|
694
|
+
if (candidates.length === 0) return self
|
|
695
|
+
const [only] = candidates
|
|
696
|
+
if (candidates.length === 1 && only !== undefined) {
|
|
697
|
+
return { dir: only.dir, rel: appRelative(root, only.dir) }
|
|
698
|
+
}
|
|
699
|
+
const names = candidates.map((pkg) => appRelative(root, pkg.dir)).join(', ')
|
|
700
|
+
return {
|
|
701
|
+
error:
|
|
702
|
+
`${candidates.length} workspace packages depend on basalt-ui and have a Vite entry (${names}) — ` +
|
|
703
|
+
'cannot tell which is the app. Set `basalt.app` (e.g. `"basalt": { "app": "apps/web" }`) in the root package.json.',
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
657
707
|
/** True when `pkgName` appears in the consumer's dependencies, devDependencies, or peerDependencies. */
|
|
658
708
|
function hasDependency(cwd: string, pkgName: string): boolean {
|
|
659
709
|
try {
|
|
@@ -687,12 +737,18 @@ export type PlacementFlags = {
|
|
|
687
737
|
/** Absolute path of the detected repo root. Meaningful only when `isPackageRepoRoot` is false —
|
|
688
738
|
* otherwise it equals the package dir and is never read. */
|
|
689
739
|
repoRoot: string
|
|
740
|
+
/** The app directory relative to the install root ('' = the root itself); see {@link resolveAppDir}. */
|
|
741
|
+
appRel: string
|
|
742
|
+
/** Non-null when the app directory is ambiguous or invalid: commands refuse rather than guess. */
|
|
743
|
+
appError: string | null
|
|
690
744
|
}
|
|
691
745
|
|
|
692
746
|
/** The default placement — today's single-package-at-repo-root behaviour, unconditionally. */
|
|
693
747
|
export const ROOT_PLACEMENT: PlacementFlags = {
|
|
694
748
|
isPackageRepoRoot: true,
|
|
695
749
|
repoRoot: '',
|
|
750
|
+
appRel: '',
|
|
751
|
+
appError: null,
|
|
696
752
|
}
|
|
697
753
|
|
|
698
754
|
/**
|
|
@@ -725,9 +781,12 @@ export function oxlintBinResolves(dir: string): boolean {
|
|
|
725
781
|
/** Resolve a run's placement flags once, from the consumer cwd. */
|
|
726
782
|
export function resolvePlacement(cwd: string): PlacementFlags {
|
|
727
783
|
const repoRoot = findRepoRoot(cwd)
|
|
784
|
+
const app = resolveAppDir(cwd)
|
|
728
785
|
return {
|
|
729
786
|
isPackageRepoRoot: repoRoot === cwd,
|
|
730
787
|
repoRoot,
|
|
788
|
+
appRel: 'error' in app ? '' : app.rel,
|
|
789
|
+
appError: 'error' in app ? app.error : null,
|
|
731
790
|
}
|
|
732
791
|
}
|
|
733
792
|
|
|
@@ -854,7 +913,7 @@ export function managedFiles(placement: PlacementFlags = ROOT_PLACEMENT): Manage
|
|
|
854
913
|
|
|
855
914
|
/** TanStack Router root route with QueryClient context wiring (seed — consumer-owned after init). */
|
|
856
915
|
const rootRoute: ManagedFile = {
|
|
857
|
-
dest:
|
|
916
|
+
dest: routerSeedDest(placement.appRel, 'root'),
|
|
858
917
|
mode: 'seed',
|
|
859
918
|
source: 'agent/templates/__root.tpl',
|
|
860
919
|
render: (ctx) => {
|
|
@@ -866,7 +925,7 @@ export function managedFiles(placement: PlacementFlags = ROOT_PLACEMENT): Manage
|
|
|
866
925
|
|
|
867
926
|
/** The leaf `NAV` module `__root.tsx` imports (seed — consumer-owned after init). */
|
|
868
927
|
const navModule: ManagedFile = {
|
|
869
|
-
dest:
|
|
928
|
+
dest: routerSeedDest(placement.appRel, 'nav'),
|
|
870
929
|
mode: 'seed',
|
|
871
930
|
source: 'agent/templates/nav.tpl',
|
|
872
931
|
render: (ctx) => readSource(ctx.pkgRoot, 'agent/templates/nav.tpl'),
|
|
@@ -874,7 +933,7 @@ export function managedFiles(placement: PlacementFlags = ROOT_PLACEMENT): Manage
|
|
|
874
933
|
|
|
875
934
|
/** The 2.0 entry: mounts the router and declares the `Register` augmentation `defineNav` needs. */
|
|
876
935
|
const mainEntry: ManagedFile = {
|
|
877
|
-
dest:
|
|
936
|
+
dest: routerSeedDest(placement.appRel, 'main'),
|
|
878
937
|
mode: 'seed',
|
|
879
938
|
source: 'agent/templates/main.tpl',
|
|
880
939
|
render: (ctx) => readSource(ctx.pkgRoot, 'agent/templates/main.tpl'),
|
package/src/cli/init.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
declaredProfile,
|
|
14
14
|
readBasaltConfig,
|
|
15
15
|
ROUTER_SEED_DESTS,
|
|
16
|
+
routerSeedDest,
|
|
16
17
|
findBasaltInstall,
|
|
17
18
|
managedFiles,
|
|
18
19
|
mergeOxlintExtends,
|
|
@@ -82,6 +83,12 @@ export function init(cwd: string = process.cwd(), scaffoldFlags: ScaffoldFlags =
|
|
|
82
83
|
)
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
const appError = resolvePlacement(cwd).appError
|
|
87
|
+
if (appError !== null) {
|
|
88
|
+
console.error(`✖ basalt-ui init: ${appError}`)
|
|
89
|
+
return 1
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
const rootsState = reconcileRoots(cwd, { write: true })
|
|
86
93
|
|
|
87
94
|
// Built AFTER the roots patch — every roots-derived template variable reads the key just written.
|
|
@@ -120,7 +127,9 @@ export function init(cwd: string = process.cwd(), scaffoldFlags: ScaffoldFlags =
|
|
|
120
127
|
const placement = resolvePlacement(cwd)
|
|
121
128
|
// A tokens-only consumer has no use for the Mantine/React scaffolds (doctor skips them there too).
|
|
122
129
|
const tokensOnly = declaredProfile(readBasaltConfig(cwd), []) === 'tokens-only'
|
|
123
|
-
const routerSeeds: string[] =
|
|
130
|
+
const routerSeeds: string[] = (
|
|
131
|
+
Object.keys(ROUTER_SEED_DESTS) as (keyof typeof ROUTER_SEED_DESTS)[]
|
|
132
|
+
).map((seed) => routerSeedDest(placement.appRel, seed))
|
|
124
133
|
const files = managedFiles(placement).filter((f) => !(tokensOnly && routerSeeds.includes(f.dest)))
|
|
125
134
|
|
|
126
135
|
const writtenFiles: string[] = []
|
package/src/cli/sync.ts
CHANGED
|
@@ -101,6 +101,12 @@ export function sync(opts: SyncOptions = {}, invocationCwd: string = process.cwd
|
|
|
101
101
|
return 0
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
const appError = resolvePlacement(cwd).appError
|
|
105
|
+
if (appError !== null) {
|
|
106
|
+
console.error(`✖ basalt-ui sync: ${appError}`)
|
|
107
|
+
return 1
|
|
108
|
+
}
|
|
109
|
+
|
|
104
110
|
// Refuse BEFORE reconcileRoots, which writes `basalt.roots` into package.json.
|
|
105
111
|
if (!existsSync(resolve(cwd, MANIFEST_PATH))) {
|
|
106
112
|
const elsewhere = findManifestAbove(cwd)
|
package/src/tokens/core.ts
CHANGED
|
@@ -820,15 +820,23 @@ export function defineSeries<const T extends SeriesMap>(map: T): T {
|
|
|
820
820
|
/** Runtime key of the {@link SeriesGroup} brand. */
|
|
821
821
|
const SERIES_GROUP: unique symbol = Symbol('basalt.series-group')
|
|
822
822
|
|
|
823
|
-
|
|
824
|
-
* The brand `groupTokens` puts on its return value. `BuildPaletteOpts.groups` takes these, so the
|
|
825
|
-
* `${name}-` key that emits the variables and the one that references them come from one call and
|
|
826
|
-
* cannot be spelled two ways.
|
|
827
|
-
*/
|
|
828
|
-
export type SeriesGroup = {
|
|
823
|
+
type GroupPayload = {
|
|
829
824
|
readonly [SERIES_GROUP]: { readonly prefix: string; readonly map: SeriesMap }
|
|
830
825
|
}
|
|
831
826
|
|
|
827
|
+
declare const GROUP_REF: unique symbol
|
|
828
|
+
|
|
829
|
+
/** A `var(--vx-<name>-<key>)` ref minted by `groupTokens`. The brand lives on the VALUES, so it never shows up in `keyof` the group. */
|
|
830
|
+
export type GroupRef = string & { readonly [GROUP_REF]: true }
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* What `groupTokens` returns. `BuildPaletteOpts.groups` takes these, so the `${name}-` key that
|
|
834
|
+
* emits the variables and the one that references them come from one call and cannot be spelled
|
|
835
|
+
* two ways. A bare series map (object values) and a plain string record (unbranded values) are
|
|
836
|
+
* both rejected; the runtime payload sits under the non-enumerable {@link SERIES_GROUP} symbol.
|
|
837
|
+
*/
|
|
838
|
+
export type SeriesGroup = { readonly [key: string]: GroupRef }
|
|
839
|
+
|
|
832
840
|
/**
|
|
833
841
|
* Build a single namespaced group's token refs (`var(--vx-<name>-<key>)`).
|
|
834
842
|
*
|
|
@@ -838,12 +846,12 @@ export type SeriesGroup = {
|
|
|
838
846
|
export function groupTokens<const T extends SeriesMap>(
|
|
839
847
|
name: string,
|
|
840
848
|
map: T,
|
|
841
|
-
): { [K in keyof T]:
|
|
849
|
+
): { readonly [K in keyof T]: GroupRef } {
|
|
842
850
|
const refs = seriesTokens(map, `${name}-`)
|
|
843
851
|
// Non-enumerable, symbol-keyed: a series key can never collide with the brand, and
|
|
844
852
|
// `Object.keys(refs)` still lists exactly the series.
|
|
845
853
|
Object.defineProperty(refs, SERIES_GROUP, { value: { prefix: `${name}-`, map } })
|
|
846
|
-
return refs as { [K in keyof T]:
|
|
854
|
+
return refs as { readonly [K in keyof T]: GroupRef }
|
|
847
855
|
}
|
|
848
856
|
|
|
849
857
|
/**
|
|
@@ -1024,7 +1032,15 @@ export function buildPaletteCss(
|
|
|
1024
1032
|
const derived = extraDerived ? `${derivedBlock}\n${extraDerived}` : derivedBlock
|
|
1025
1033
|
const side = (s: Side): string => {
|
|
1026
1034
|
const extra = groups
|
|
1027
|
-
.map((group) =>
|
|
1035
|
+
.map((group) => {
|
|
1036
|
+
const payload = (group as unknown as Partial<GroupPayload>)[SERIES_GROUP]
|
|
1037
|
+
if (!payload) {
|
|
1038
|
+
throw new Error(
|
|
1039
|
+
'BuildPaletteOpts.groups: every group must come from groupTokens(name, map)',
|
|
1040
|
+
)
|
|
1041
|
+
}
|
|
1042
|
+
return groupSide(payload.prefix, payload.map, s)
|
|
1043
|
+
})
|
|
1028
1044
|
.join('\n')
|
|
1029
1045
|
const framework = frameworkPrimitives(s, data, legacyAliases)
|
|
1030
1046
|
return extra ? `${framework}\n${extra}` : framework
|