basalt-ui 1.19.1 → 1.21.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.
- package/AGENTS.md +19 -1
- package/CHANGELOG.md +39 -0
- package/MIGRATING.md +326 -0
- package/README.md +87 -9
- package/agent/rules/basalt-app.md +84 -0
- package/agent/rules/basalt-charts.md +32 -17
- package/agent/rules/basalt-content.md +4 -0
- package/agent/rules/basalt-mantine.md +25 -10
- package/agent/rules/basalt-router.md +79 -15
- package/agent/rules/basalt-state.md +21 -3
- package/agent/rules/basalt-tokens.md +132 -6
- package/agent/skills/basalt-app/SKILL.md +45 -6
- package/agent/skills/basalt-charts/SKILL.md +5 -3
- package/agent/templates/CLAUDE-block.md.tpl +11 -5
- package/configs/check.yml +11 -4
- package/configs/lefthook.yml +59 -7
- package/configs/oxlint-plugin.js +633 -30
- package/configs/oxlint-plugin.test.ts +594 -15
- package/configs/oxlint.json +10 -1
- package/dist/agent/stick-to-bottom.js +1 -1
- package/dist/agent-chat/thread-detail-panel.js +1 -1
- package/dist/agent-chat/thread-message.js +2 -2
- package/dist/agent-chat/tool-chip.js +1 -1
- package/dist/charts/kinds/Bars.d.ts +1 -1
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.d.ts +1 -1
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +1 -1
- package/dist/charts/kinds/DualPanel.d.ts +1 -1
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.d.ts +1 -1
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.d.ts +1 -1
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.d.ts +1 -1
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.d.ts +1 -1
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +2 -2
- package/dist/charts/primitives/ChartTooltip.js +1 -1
- package/dist/cli/index.d.ts +146 -20
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +901 -101
- package/dist/cli/toolchain-wiring.test.d.ts +2 -0
- package/dist/cli/toolchain-wiring.test.d.ts.map +1 -0
- package/dist/cli/waiver-audit.test.d.ts +2 -0
- package/dist/cli/waiver-audit.test.d.ts.map +1 -0
- package/dist/dashboard/delta-badge.js +2 -2
- package/dist/dashboard/stat-card.js +1 -1
- package/dist/data/virtual-list.js +5 -5
- package/dist/guard/index.d.ts +101 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +474 -62
- package/dist/guard/types.d.ts +25 -5
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/register.d.ts +25 -0
- package/dist/register.d.ts.map +1 -1
- package/dist/router-tanstack/multi-search-param-store.d.ts +13 -0
- package/dist/router-tanstack/multi-search-param-store.d.ts.map +1 -1
- package/dist/router-tanstack/multi-search-param-store.js +4 -1
- package/dist/router-tanstack/search-param-store.d.ts +29 -5
- package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-param-store.js +31 -3
- package/dist/router-tanstack/search-param-store.test.d.ts +2 -0
- package/dist/router-tanstack/search-param-store.test.d.ts.map +1 -0
- package/dist/shell/app-mobile-nav.module.css +11 -3
- package/dist/shell/index.d.ts +12 -5
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +24 -6
- package/dist/surfaces.d.ts +1 -1
- package/dist/surfaces.js +1 -1
- package/dist/tokens/index.d.ts +5 -3
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +7 -1
- package/dist/tokens/palette.d.ts +35 -27
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +24 -18
- package/dist/tokens/text-scale.test.d.ts +2 -0
- package/dist/tokens/text-scale.test.d.ts.map +1 -0
- package/dist/tokens.css +21 -17
- package/dist/vite-color-mix.js +2 -2
- package/dist/vite.d.ts +24 -2
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +54 -13
- package/llms.txt +3 -3
- package/package.json +4 -3
- package/src/agent/stick-to-bottom.tsx +1 -1
- package/src/agent-chat/thread-detail-panel.tsx +1 -1
- package/src/agent-chat/thread-message.tsx +3 -3
- package/src/agent-chat/tool-chip.tsx +1 -1
- package/src/charts/kinds/Bars.tsx +1 -1
- package/src/charts/kinds/Donut.tsx +3 -2
- package/src/charts/kinds/DualPanel.tsx +2 -2
- package/src/charts/kinds/Heatmap.tsx +1 -1
- package/src/charts/kinds/MultiLine.tsx +1 -1
- package/src/charts/kinds/StackedArea.tsx +1 -1
- package/src/charts/kinds/ZonedLine.tsx +1 -1
- package/src/charts/primitives/ChartLegend.tsx +2 -2
- package/src/charts/primitives/ChartTooltip.tsx +1 -1
- package/src/cli/index.ts +1614 -164
- package/src/cli/init-sync.test.ts +21 -3
- package/src/cli/template-ledger.test.ts +1 -1
- package/src/cli/tokens-css.test.ts +27 -14
- package/src/cli/toolchain-wiring.test.ts +856 -0
- package/src/cli/waiver-audit.test.ts +131 -0
- package/src/dashboard/delta-badge.tsx +3 -3
- package/src/dashboard/stat-card.tsx +1 -1
- package/src/data/virtual-list.tsx +8 -8
- package/src/guard/check-source.test.ts +1104 -12
- package/src/guard/index.ts +1106 -103
- package/src/guard/types.ts +29 -4
- package/src/register.ts +32 -0
- package/src/router-tanstack/multi-search-param-store.ts +16 -1
- package/src/router-tanstack/search-param-store.test.ts +135 -0
- package/src/router-tanstack/search-param-store.ts +90 -8
- package/src/shell/app-mobile-nav.module.css +11 -3
- package/src/shell/app-mobile-nav.tsx +1 -1
- package/src/shell/index.test.tsx +52 -0
- package/src/shell/index.tsx +64 -13
- package/src/surfaces.ts +1 -1
- package/src/theme/density-relations.test.ts +8 -5
- package/src/theme/spacing.test.ts +2 -0
- package/src/theme-toggle/index.tsx +2 -2
- package/src/tokens/index.ts +28 -3
- package/src/tokens/palette.ts +24 -18
- package/src/tokens/text-scale.test.ts +51 -0
- package/src/vite-color-mix.ts +2 -2
- package/src/vite.test.ts +125 -6
- package/src/vite.ts +148 -20
|
@@ -53,6 +53,28 @@ own the files.
|
|
|
53
53
|
- `.basalt/manifest.json` — a sha256 per managed file + the basalt-ui version that wrote it, so
|
|
54
54
|
`sync` can three-way diff and `doctor` can spot a stale install.
|
|
55
55
|
|
|
56
|
+
It also patches `package.json`: **`basalt.roots`** inferred from the real layout (workspace packages
|
|
57
|
+
depending on basalt or Mantine, else every workspace `src/`, else `src`) and a **`lint:basalt`**
|
|
58
|
+
script (`oxlint . && basalt-ui check-theme`). Everything derives from `roots` — the guard's scan, the
|
|
59
|
+
seeded CI `oxfmt` globs, the default exemption — so a workspace repo without it scaffolds a guard
|
|
60
|
+
that scans zero files while every gate reports green. Correct it if your sources live elsewhere. A
|
|
61
|
+
Mantine-free consumer adds `"basalt": { "profile": "tokens-only" }` by hand; `check-theme` never
|
|
62
|
+
infers that, because inferring it from a missing `@mantine/core` would silence 17 kinds on a repo
|
|
63
|
+
that simply keeps Mantine in another workspace package.
|
|
64
|
+
|
|
65
|
+
**`init` on an EXISTING app is a lint-debt event, not a no-op.** Adopting the shipped preset turns
|
|
66
|
+
on whole oxlint plugins the repo was never linted against, so previously-clean code lands with real
|
|
67
|
+
findings on the first run. `init` names the plugins and every file it kept — plus what keeping it
|
|
68
|
+
costs (an existing `.oxlintrc.json` that does not `extends` the preset means the entire basalt lint
|
|
69
|
+
half is off, and nothing else says so; `--merge-lint` splices it in). Run `oxlint .` and triage
|
|
70
|
+
before the next commit; turn a rule off with a written reason rather than disabling a plugin.
|
|
71
|
+
|
|
72
|
+
Then `basalt-ui doctor`. `SKIPPED` is a third outcome beside pass/warn/fail and exits non-zero on
|
|
73
|
+
its own — a check that could not run is not a check that passed — and the hard checks now include
|
|
74
|
+
`basalt-resolves`, `guard-scan` (would `check-theme` cover more than zero files?) and
|
|
75
|
+
`oxlint-preset` (does `.oxlintrc.json` really extend the preset? JSONC is parsed, not rejected).
|
|
76
|
+
Expect doctor to go red where it was green on an older basalt; that is the point.
|
|
77
|
+
|
|
56
78
|
After `init`, do the runtime wiring (the CLI scaffolds files, not your app's composition):
|
|
57
79
|
|
|
58
80
|
```tsx
|
|
@@ -94,10 +116,18 @@ ordering (e.g. alongside `@content-collections/vite`) and the full head/PWA/mani
|
|
|
94
116
|
import 'basalt-ui/styles.css' // @layer basalt base styles, iOS input safety net, font stack
|
|
95
117
|
```
|
|
96
118
|
|
|
97
|
-
Lint wires as `oxlint . && basalt-ui check-theme`
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
119
|
+
Lint wires as `oxlint . && basalt-ui check-theme` (seeded as the `lint:basalt` script) — the theme
|
|
120
|
+
guard is the teeth behind the token doctrine. Before writing any composite, check whether basalt
|
|
121
|
+
already ships it: round 4 found ~15 forked copies of shipped components across seven repos, all
|
|
122
|
+
passing every gate, because a fork by a token-fluent author uses exactly the right tokens.
|
|
123
|
+
`basalt/shadow-basalt-export` reads all nine published barrels since 1.20.1 (the charts layer
|
|
124
|
+
included), but it warns only on an **exact** name collision — round 5 found the renamed forks
|
|
125
|
+
(`Cell`, `Box`, `Stat`) sail straight past it. It is a tripwire, not coverage; nothing catches the
|
|
126
|
+
rest. Ask before you build; do not wait to be told.
|
|
127
|
+
|
|
128
|
+
The consumer series file (`<first basalt.root>/lib/series.ts` by default — so `src/lib/series.ts` on
|
|
129
|
+
a plain app, `apps/web/src/lib/series.ts` on a monorepo; override via `basalt.seriesModulePath`) is
|
|
130
|
+
the single guard-exempt palette source — see `/basalt-charts`.
|
|
101
131
|
|
|
102
132
|
## Refresh: `bunx basalt-ui sync`
|
|
103
133
|
|
|
@@ -140,13 +170,22 @@ both.
|
|
|
140
170
|
- A thin `DESIGN.md` (deltas) + the thirteen `basalt-*` rules + the managed CLAUDE block are present.
|
|
141
171
|
- `<first basalt.root>/lib/series.ts` exists as the one guard-exempt series source (for any app metric colors).
|
|
142
172
|
- `basalt-ui sync --check` wired in CI (recommended) to catch drift on future upgrades.
|
|
173
|
+
- `basalt-ui doctor` run after `init` and read to the last line — a `SKIPPED` check exits non-zero
|
|
174
|
+
and is not a pass.
|
|
143
175
|
|
|
144
176
|
## Notes
|
|
145
177
|
|
|
146
178
|
- `init`, `sync`, and `check-theme` are all **real**. `sync` reconciles via a sha256 three-way diff
|
|
147
179
|
(`--check` is a CI drift gate, `--force` overwrites local edits); `check-theme` is the palette
|
|
148
|
-
guard; `doctor`
|
|
149
|
-
`bunx basalt-ui …`.
|
|
180
|
+
guard; `doctor` checks resolution, version, guard scan, oxlint preset, spacing-scale drift and
|
|
181
|
+
cross-package `ai` major parity. All via `bunx basalt-ui …`.
|
|
182
|
+
- **Not a React app?** `bunx basalt-ui tokens:css --out src/tokens.css` emits the `--vx-*` layer with
|
|
183
|
+
no package in your dependency tree, `--selector-class dark` for the Tailwind `<html class="dark">`
|
|
184
|
+
convention, and `fonts:css` emits the shipped `--basalt-font-*` stacks. Both carry the two-line
|
|
185
|
+
`@generated basalt-ui` header the guard skips on — that header verbatim, and then only the LINES
|
|
186
|
+
that are basalt custom properties, selectors, `}` or self-closing comments, so the marker pasted
|
|
187
|
+
into a `.tsx` suppresses nothing and a declaration added to such a file is still reported — and
|
|
188
|
+
both take `--check` as a CI drift gate. See `docs/FRAMEWORK-FREE.md` in the basalt-ui repo.
|
|
150
189
|
- The framework ships **no** icon or notification dep — pass icons as `ReactNode` and wire toasts
|
|
151
190
|
yourself (e.g. `ThemeLabControls`' `copyIcon` / `onCopy`).
|
|
152
191
|
- The framework DOES ship `motion` (motion.dev, formerly framer-motion) as a bundled dependency —
|
|
@@ -210,9 +210,11 @@ import { ChartCursorScope } from 'basalt-ui/charts'
|
|
|
210
210
|
`AxisLeftNumeric` / `AxisRightNumeric` / `AxisBottomDate` (escape via `theme-allow`).
|
|
211
211
|
- **No hand-rolled plot assembly.** `basalt/hand-rolled-plot` fails the build on a chart-assembly
|
|
212
212
|
primitive (`AxisLeftNumeric`, `AxisRightNumeric`, `AxisBottomDate`, `HoverOverlay`, `Crosshair`)
|
|
213
|
-
rendered in a file that doesn't compose `CartesianChart
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
rendered in a file that doesn't compose `CartesianChart`, per NODE. Escape:
|
|
214
|
+
`theme-allow hand-rolled-plot — <why>` on the one node, or `theme-allow-file hand-rolled-plot —
|
|
215
|
+
<why>` anywhere in the file — how a genuinely non-single-plot shape (`DualPanel`, `Heatmap`,
|
|
216
|
+
`Donut`) declares itself. `-file` is the 1.20.1 spelling and it is required. The file that defines
|
|
217
|
+
`CartesianChart` is exempt definitionally.
|
|
216
218
|
- **No hand-authored legends.** `basalt/chart-legend-literal` fails the build on a hand-written
|
|
217
219
|
array literal passed to `ChartLegend`'s `items` — derive it from the same `series` the chart draws
|
|
218
220
|
(`deriveLegend`, or let `ChartFrame`/`CartesianChart` do it) so it can't name a series the plot no
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## basalt-ui (managed — do not hand-edit)
|
|
4
4
|
|
|
5
|
-
Scaffolded by `bunx basalt-ui init`
|
|
6
|
-
|
|
5
|
+
Scaffolded by `bunx basalt-ui init` (the one command that legitimately predates the install) and
|
|
6
|
+
refreshed by the locally installed `basalt-ui sync` after every upgrade; `basalt-ui sync --check`
|
|
7
|
+
gates drift in CI. This block is framework-owned — edit `DESIGN.md`
|
|
7
8
|
or the `basalt-*` rules instead; manual changes here are overwritten on the next sync.
|
|
8
9
|
|
|
9
10
|
**Stack:** React 19 + Mantine v9, themed by `basalt-ui` (`BasaltProvider` + `createBasaltTheme`).
|
|
@@ -18,9 +19,14 @@ code must follow) — never import `@visx/*` outside a `charts/` directory (oxli
|
|
|
18
19
|
Toolchain is oxlint + oxfmt (no ESLint/Biome/Prettier) and `basalt-ui check-theme` guards the
|
|
19
20
|
palette. Runtime is Bun.
|
|
20
21
|
|
|
21
|
-
**Before guessing an import,
|
|
22
|
-
`
|
|
23
|
-
|
|
22
|
+
**Before guessing an import, read the installed package's machine docs — `llms.txt` (per-subpath
|
|
23
|
+
import map) and `AGENTS.md`, at the install directory.** That is `./node_modules/basalt-ui` only on
|
|
24
|
+
a single-package app. In a workspace, basalt resolves under the package that depends on it
|
|
25
|
+
(`packages/<name>/node_modules/basalt-ui`), and the repo root may have no copy at all. Run
|
|
26
|
+
`basalt-ui doctor` — its `basalt-resolves` line prints the resolved install dir and version; read
|
|
27
|
+
the two files there. Invoke the CLI through the **locally installed** bin (the `lint:basalt` script
|
|
28
|
+
seeded by `init` shows the path); `bunx basalt-ui` fetches a second copy from npm and can answer
|
|
29
|
+
for a different version than the one you are building against.
|
|
24
30
|
|
|
25
31
|
**DESIGN.md is law.** `./DESIGN.md` (imported below) records this app's palette identity and series
|
|
26
32
|
dictionary. Precedence: **DESIGN.md > `basalt-*` rules > skills.** When building or restyling any
|
package/configs/check.yml
CHANGED
|
@@ -5,8 +5,14 @@
|
|
|
5
5
|
# color literals / off-identity accents that bypass the --vx-* token system).
|
|
6
6
|
# `basalt-ui sync --check` fails when the basalt-managed files (rules, skills, the
|
|
7
7
|
# CLAUDE block) have drifted from the installed basalt-ui version.
|
|
8
|
-
# The oxfmt globs below are rendered from `basalt.roots` at init time —
|
|
9
|
-
#
|
|
8
|
+
# The oxfmt globs below are rendered from `basalt.roots` at init time — `init` writes that
|
|
9
|
+
# key from the repo's real layout (workspace packages included), so a monorepo does not
|
|
10
|
+
# seed a `src/**` that matches nothing.
|
|
11
|
+
# The basalt-ui command below is the LOCAL bin, rendered from where basalt actually
|
|
12
|
+
# installed. `bunx basalt-ui` is deliberately not used: when the package is not resolvable
|
|
13
|
+
# from the working directory (bun's isolated linker puts it beside the package that depends
|
|
14
|
+
# on it, not at the root) bunx silently downloads a DIFFERENT copy from npm and the gate
|
|
15
|
+
# runs a version nobody pinned.
|
|
10
16
|
name: check
|
|
11
17
|
on:
|
|
12
18
|
pull_request:
|
|
@@ -23,8 +29,9 @@ jobs:
|
|
|
23
29
|
bun-version: latest
|
|
24
30
|
- run: bun install --frozen-lockfile
|
|
25
31
|
- run: bunx oxlint .
|
|
26
|
-
- run:
|
|
27
|
-
- run:
|
|
32
|
+
- run: '{{BASALT_BIN}} doctor'
|
|
33
|
+
- run: '{{BASALT_BIN}} check-theme'
|
|
34
|
+
- run: '{{BASALT_BIN}} sync --check'
|
|
28
35
|
- run: bunx oxfmt {{ROOTS_GLOBS}} '!**/dist/**' --check
|
|
29
36
|
# Enable once your app defines these package.json scripts:
|
|
30
37
|
# - run: bun run typecheck
|
package/configs/lefthook.yml
CHANGED
|
@@ -2,10 +2,32 @@
|
|
|
2
2
|
# `basalt-ui init` seeds a lefthook.yml that references this file:
|
|
3
3
|
# extends:
|
|
4
4
|
# - node_modules/basalt-ui/configs/lefthook.yml
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
5
|
+
# so this preset auto-updates with the package. Runs oxlint + oxfmt on staged files and the theme
|
|
6
|
+
# guard on the whole tree, pre-commit. Assumes oxlint/oxfmt are installed.
|
|
7
|
+
#
|
|
8
|
+
# ── HOW OVERRIDING ACTUALLY WORKS (read before trying) ───────────────────────────────────────────
|
|
9
|
+
# An `extends` target WINS over your own lefthook.yml on a colliding key. Verified with
|
|
10
|
+
# `lefthook dump`: declare `pre-commit.commands.oxfmt.run` (or `glob:`) in your file and the
|
|
11
|
+
# preset's value is what runs — yours is discarded silently, with no warning. Only keys this preset
|
|
12
|
+
# does NOT define merge in from yours. So:
|
|
13
|
+
# • `env:`, `exclude:`, `skip:` and any command name not used here — yours, they merge.
|
|
14
|
+
# • `run:` and `glob:` on a command below — NOT overridable. Do not try.
|
|
15
|
+
# The sanctioned seams are therefore:
|
|
16
|
+
# • `BASALT_BIN` (below) — set it via `env:` to point the guard at a specific CLI.
|
|
17
|
+
# • `exclude:` — carve files out of a glob you cannot narrow.
|
|
18
|
+
# • a differently-named command of your own, plus `skip: true` on the one here you are replacing.
|
|
19
|
+
#
|
|
20
|
+
# It does NOT assume your `.oxlintrc.json` extends the shipped preset — that assumption was
|
|
21
|
+
# false for exactly the repos this seed exists for, since `init` KEEPS an existing oxlint
|
|
22
|
+
# config. `basalt-ui doctor` now checks the extends and hard-fails when it is missing OR when it
|
|
23
|
+
# points at a path that does not resolve; run it in CI (the seeded check.yml does) rather than
|
|
24
|
+
# trusting a comment nobody reads.
|
|
25
|
+
#
|
|
26
|
+
# `init` seeds the path RESOLVED from where basalt actually installed. Under bun's isolated
|
|
27
|
+
# linker basalt lives beside the package that depends on it, not at the repo root, and a
|
|
28
|
+
# root-relative `extends` there resolves to nothing — silently, because lefthook merges a missing
|
|
29
|
+
# file into ZERO commands and exits 0. `basalt-ui doctor`'s `lefthook-preset` check is the only
|
|
30
|
+
# thing that can see that state; nothing else errors.
|
|
9
31
|
pre-commit:
|
|
10
32
|
parallel: true
|
|
11
33
|
commands:
|
|
@@ -15,9 +37,20 @@ pre-commit:
|
|
|
15
37
|
# `css` is load-bearing, not tidiness: oxfmt formats stylesheets, so without it a CSS-only
|
|
16
38
|
# commit passes the hook and then fails the same check in CI. `oxlint` above deliberately
|
|
17
39
|
# stops at JS — it has nothing to say about CSS.
|
|
40
|
+
#
|
|
41
|
+
# SOURCE EXTENSIONS ONLY, deliberately. This glob used to include `json,md,yml,yaml`, which
|
|
42
|
+
# reached every staged file at the repo ROOT — and oxfmt pads markdown table separators, so it
|
|
43
|
+
# blocked commits on a consumer's CLAUDE.md and docs/ over a house style basalt has no opinion
|
|
44
|
+
# about, in files their own `format` script does not own. Since you cannot narrow this glob
|
|
45
|
+
# (see the override note above), the preset has to be the one that is narrow. Markdown, YAML
|
|
46
|
+
# and JSON stay yours: add them to your own `format` script if you want them formatted.
|
|
47
|
+
#
|
|
48
|
+
# `--no-error-on-unmatched-pattern` covers the case where every staged file is excluded by an
|
|
49
|
+
# ignore file: oxfmt exits 2 on "Expected at least one target file", which failed a docs-only
|
|
50
|
+
# commit for any consumer carrying a .prettierignore — and, again, they could not add the flag.
|
|
18
51
|
oxfmt:
|
|
19
|
-
glob: '*.{ts,tsx,js,jsx,css
|
|
20
|
-
run: bunx oxfmt --check {staged_files}
|
|
52
|
+
glob: '*.{ts,tsx,js,jsx,css}'
|
|
53
|
+
run: bunx oxfmt --check --no-error-on-unmatched-pattern {staged_files}
|
|
21
54
|
|
|
22
55
|
# NO glob, deliberately. This command scans the configured `basalt.roots` — it never reads
|
|
23
56
|
# {staged_files} — so any glob here is a gate on WHETHER the guard runs, decided by the file
|
|
@@ -28,5 +61,24 @@ pre-commit:
|
|
|
28
61
|
# was written against: a guard that only runs when someone remembers to run it is not a guard.
|
|
29
62
|
# Without this, a consumer accumulates violations indefinitely while `check-theme` is never
|
|
30
63
|
# invoked, and the kinds it never ran are indistinguishable from the kinds that found nothing.
|
|
64
|
+
#
|
|
65
|
+
# `$BASALT_BIN` is the one sanctioned override seam here, because `run:` itself is not
|
|
66
|
+
# overridable (see the note at the top). It defaults to `bunx --no-install basalt-ui`:
|
|
67
|
+
# • `--no-install` because a plain `bunx basalt-ui` in a repo where basalt is not resolvable
|
|
68
|
+
# from the ROOT (bun's isolated linker puts it beside the package that depends on it)
|
|
69
|
+
# silently downloads a DIFFERENT copy from npm and gates the commit with a version nobody
|
|
70
|
+
# pinned. With the flag it fails loudly instead, which is the answer you can act on.
|
|
71
|
+
# • point it at the local bin to fix that, exactly as the seeded check.yml does:
|
|
72
|
+
# pre-commit:
|
|
73
|
+
# commands:
|
|
74
|
+
# check-theme:
|
|
75
|
+
# env: { BASALT_BIN: ./packages/web/node_modules/.bin/basalt-ui }
|
|
76
|
+
#
|
|
77
|
+
# Lefthook runs commands at the REPO ROOT, while in a monorepo the `basalt` config and the
|
|
78
|
+
# manifest live in a package below it — verified to produce `0 files scanned`, i.e. following
|
|
79
|
+
# this preset installed a gate that never gated. `check-theme` now relocates to the single
|
|
80
|
+
# workspace package carrying a basalt config and says so; with more than one, set BASALT_CWD
|
|
81
|
+
# in the same `env:` block to name the package:
|
|
82
|
+
# env: { BASALT_CWD: apps/web }
|
|
31
83
|
check-theme:
|
|
32
|
-
run: bunx basalt-ui check-theme
|
|
84
|
+
run: ${BASALT_BIN:-bunx --no-install basalt-ui} check-theme
|