Repository navigation
fix(create-bestax): bring the vite-ts tsconfigs up to create-vite 9 - #1076
Conversation
The vite-ts template still had the tsconfigs of an older create-vite: an ES2020 target and lib, and a src/vite-env.d.ts for the Vite client types. tsconfig.app.json and tsconfig.node.json are now create-vite 9.2.1's react-ts files as written: ES2023, `types: ["vite/client"]` in place of vite-env.d.ts, verbatimModuleSyntax, erasableSyntaxOnly, moduleDetection force and allowArbitraryExtensions. tsconfig.json was already the same. `strict` goes because TypeScript 6, which the template installs, turns it on by default, and DOM.Iterable because TypeScript 6 folds it into DOM. tsconfig.node.json now names `types: ["node"]`, so the template declares @types/node at create-vite's range; without it `tsc -b` stops on TS2688. That is the one devDependency change. ESLint stays as the linter, and the App, its assets and the README are untouched. No template source needed `import type` or an enum rewrite, and nothing create-bestax writes into main.tsx or App.tsx did either: every flavor and icon library scaffolds, builds and lints, and the built output matches what the old tsconfigs produce byte for byte. The docs sandbox builders copy the template's files by name, so they stop copying vite-env.d.ts in the same change, or the docs build would fail to find it. Refs #1049
…roject skips The sandbox test already failed when a file the StackBlitz builder copies left the template. A file the template gained went unnoticed: the builder copies only what TEMPLATE_FILES names, so a new tsconfig or .d.ts from a create-vite catch-up would leave the sandbox a step behind the scaffold. Every template file is now either in TEMPLATE_FILES or in a LEFT_OUT map with the reason the sandbox does without it, and a LEFT_OUT entry for a file the template no longer has fails too. Refs #1049
The docs fence gate checked every live example against a literal of create-vite's react-ts options, while the template the sandbox buttons build from and `npm create bestax` scaffolds had options of its own. The two drifted apart: a fence using `.at()` passed the gate under ES2023 and was a type error in a scaffold on ES2020. The gate now reads the options the template compiles `src/` with, through the reader the skill examples gate already used. That reader moves to scripts/lib/template-tsconfig.mjs, with its tests, so both gates hold code to the same file. The fence gate overrides only what its harness needs: `types`, since vite/client resolves from a scaffold's install and not from the template here, and `allowJs` for the docs-only ProfileCard. Every live fence passes under the template's options, with no fence changed. The new reader gets a coverage floor row and a test for a template with no tsconfig.json, the one path the moved tests did not reach. Refs #1049
Nothing said when to compare the template with what create-vite writes, so its tsconfigs fell a major behind before anyone looked. The create-bestax CLAUDE.md now says to compare the tsconfigs, devDependencies, vite.config.ts and src/main.tsx at each Vite or create-vite major, names what differs on purpose (the App, its assets, the README, and ESLint as the linter), and points at the sandbox test that fails when a catch-up adds or removes a file. Refs #1049
|
deep-review: fresh This brings create-bestax's vite-ts template up to create-vite 9.2.1's tsconfigs. The docs fence gate now reads its compiler options from the template's Review it in full:
Post every finding, advisory included, as its own thread. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 3 minutes. View limit details
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughThe Vite TypeScript template’s compiler settings and files changed. Sandbox generation and validation now track the template file set, and compiler-option checks read options from the template through a shared helper. ChangesVite TypeScript template alignment
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to
|
Preview DeploymentPreview URL: https://1e5619cd.bestax.pages.dev |
There was a problem hiding this comment.
Deep review — 0 blocking · 3 advisory
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Coverage | The new guard closes template dir ↔ TEMPLATE_FILES, but nothing reads the TEMPLATE map in open.js, so a file a future catch-up adds can break the sandbox button at click time |
docs/scripts/sandbox.test.mjs:412 |
| 2 | 🔵 Advisory | Robustness | templateFiles() walks the working tree, so a lockfile or dist/ left by an in-place install fails the gate with the wrong instruction |
docs/scripts/sandbox.test.mjs:396 |
| 3 | 🔵 Advisory | Coverage | Fixes #1049 closes the issue while its first proposal — a check that builds the generated StackBlitz project — stays a one-time manual check |
create-bestax/CLAUDE.md:82 (no line of its own) |
Overall: Sound, and unusually well evidenced. I checked both tsconfigs and @types/node: ^24.13.3 byte-for-byte against vitejs/vite at the SHA the PR names, and every removal against the installed typescript@6.0.3 rather than against a changelog: getStrictOptionValue reads strict !== false, so unset is on; isolatedModules is implied by verbatimModuleSyntax; resolveJsonModule defaults true under bundler resolution; useDefineForClassFields defaults true at ES2022+; allowSyntheticDefaultImports defaults true; and lib.dom.iterable.d.ts is now a stub saying its contents are included in the main types file. The riskiest part is the one the focus names — the fence gate no longer spells strict out, so it inherits it from whatever TypeScript the repo has — and that turns out to be self-guarding: fixture/untyped-state.md asserts a TS2322 that exists only under strictNullChecks, so losing strict mode reds the gate rather than quietly widening it. Human attention is best spent on finding 1: the file-list chain is now airtight on the half a test can see, and untested on the half the shipped site actually uses.
Residual risk:
- The gate checking options no app has — closed. Both gates read one
appCompilerOptions, andtemplate-tsconfig.test.mjspins theconfigFilePathit lands on to inside the template, so a reader that silently picked the wrong project fails.Build and Testis green on this commit, which exercisestest:scriptsincluding the newbranches: 82floor row. - The two overrides hiding a difference — refuted; both are needed and neither relaxes checking.
types: []becausevite/clientcannot resolve from a template with no install (TS2688), andallowJsfor the docs-only.jsxProfileCard. Both make the gate stricter than the scaffold, so they can only produce loud false failures, never a false pass. The inheritedtsBuildInfoFileis not neutralized the way the skill-examples gate neutralizes it, but TypeScript writes build info only whenincrementalorcompositeis set, neither is, and the gate never emits — so nothing is written. - A flavor or icon path tripping the new options — refuted. The scaffolder writes only CSS imports,
IconTextandConfigProvider, all value imports, with no enum, namespace or parameter property anywhere in it or in the template source. Fivevite-tsscenarios invisual-regression.ymlinstall standalone and runtsc -b && vite build; all pass on this commit, as do the two skill examples that useimport type. LEFT_OUTdrifting — refuted today. The 9 copied plus 7 left-out entries are exactly the 16 files in the template, each reason matches what the builder does (the lint packages really are stripped;App.css,App.tsx,react.svgandvite.svgreally are starter-only), and a staleLEFT_OUTkey now fails too.- Open: the
TEMPLATE_FILEStoopen.jsleg (finding 1), the one path left where the sandbox can fall a step behind the scaffold with every gate green. - Open, low: the shared reader compares the forward-slash
fileNamesTypeScript reports againstjoin(template, "src") + path.sep, so on Windows both gates wouldassert.fail("no project … compiles src/"). Moved verbatim rather than introduced, it fails loudly rather than silently, and nothing in the repo claims Windows as a dev platform — so recorded here, not raised. - Not a risk: a template that compiled
src/through two projects would get the first in reference order. Onlytsconfig.app.jsonincludessrc, and the create-bestax jest walk independently assertsnoEmiton every project that has files.
🏄 Total cleanup set, dude — paddled the template out of ES2020, pointed the fence gate at the real board instead of a photo of one, and brought upstream receipts for every line. Only thing still bobbing out back is that
open.jsfile list nobody is watching. Ship it.
The guard over the sandbox's file list walked whatever sat under templates/vite-ts, so an npm install or build run inside the template left a lockfile or dist/ behind that failed it, with a message asking for a TEMPLATE_FILES or LEFT_OUT entry when the fix was to delete them. It now lists the template's files with `git ls-files`, keeping those still on disk. Refs #1049
The guard held the template to TEMPLATE_FILES, but the site's buttons copy from the TEMPLATE map in open.js, which no test read. A file added to TEMPLATE_FILES and left out of open.js passed the docs build and every test, and the StackBlitz button then threw on the reader's click. open.js only runs under webpack, so the test reads it as text: its TEMPLATE must have a key for exactly the files in TEMPLATE_FILES, each bound to the raw-loader import of the file of that name. Refs #1049
|
deep-review: verify Every open thread has a reply: fixed, with the commit, or refuted with a reason. This settles them on 0cac0ca. |
Preview DeploymentPreview URL: https://d5f98b6e.bestax.pages.dev |
There was a problem hiding this comment.
Deep review (verify) — 3 resolved · 0 open
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Coverage | The TEMPLATE map in open.js was unguarded — fixed in 58a1b3c1, resolved |
docs/scripts/sandbox.test.mjs:445 |
| 2 | 🔵 Advisory | Robustness | templateFiles() walked the working tree — fixed in dc4fbe0b, resolved |
docs/scripts/sandbox.test.mjs |
| 3 | 🔵 Advisory | Coverage | Fixes #1049 with the build check unimplemented — accepted, the decision is now recorded in the PR body, resolved |
create-bestax/CLAUDE.md:82 |
Overall: This pass settled the three threads the earlier deep review left open, and reviewed no commits. Two were code findings and both are genuinely fixed rather than papered over: openJsTemplate() parses open.js as text and holds its TEMPLATE to TEMPLATE_FILES in both directions, and templateFiles() reads git ls-files, so a local lockfile or dist/ no longer fails the gate. The third was a reasoned decline from the maintainer, with the decision written into the PR body, which is what the finding asked for. Nothing here is left for a human to rule on.
What I checked, per thread
Thread 1 — the TEMPLATE map in open.js (58a1b3c). I re-ran the new guard against mutations of the real open.js:
| Mutation | keys match | misbound |
|---|---|---|
| baseline | true | [] |
drop the src/main.tsx key |
false | ["src/main.tsx"] |
bind tsconfig.app.json to tsconfigNode |
true | ["tsconfig.app.json"] |
add a stray src/App.css key |
false | [] |
repoint the main.tsx import path |
true | ["src/main.tsx"] |
Every mutation trips at least one of the two assertions, and the baseline is clean. The wrong-file binding is the case a plain includes check would have let through, so this is stricter than the fix I had suggested.
Thread 2 — templateFiles() (dc4fbe0). I dropped package-lock.json, pnpm-lock.yaml and dist/assets/index.js into create-bestax/templates/vite-ts and ran the same git ls-files -z plus existsSync call: 16 tracked files came out (9 TEMPLATE_FILES and 7 LEFT_OUT), with the lockfiles visible only as untracked in git status --porcelain. I removed them again, and the tree is clean. The existsSync filter covers the other direction, a tracked file deleted but not staged.
Thread 3 — the issue reference. The PR body now carries a "What #1049 proposed" section marking the docs-test build of the assembled StackBlitz project as declined, with the cost it would add and the compensating gates. The reply is from allxsmith, live role_name: admin.
Test run. pnpm --filter @allxsmith/bestax-docs run test — 121 pass, 0 fail, including both of the the template files tests. One run covers every thread.
Residual risk: none newly identified, a verify pass raising no findings by design. On the failure class the settled threads named: the TEMPLATE_FILES-to-open.js half of the copied-file chain is now closed both ways, with each key bound to the import of the file of that name (mutation-tested above), and the template-directory half no longer mistakes untracked build output for a file the template gained (reproduced, then refuted, above). The gap the maintainer accepted on the record stands: no gate installs and builds the project stackblitzProject assembles, so a break reachable only through the rewritten package.json or the edited main.tsx still surfaces on a reader click.
🏄 Three advisories paddled out, three came back in clean — two with real code behind them and one with a straight answer on the record. The author even out-hardened my own suggestion on the
open.jsguard, which is the good kind of getting dropped in on. Good to go.
📸 Story screenshots at handoff —
|
…nfigs # Conflicts: # scripts/docs-fence-types.test.mjs
Preview DeploymentPreview URL: https://c08c1181.bestax.pages.dev |
|
deep-review: fresh Main is merged in, with what landed since the last review, and the generated files are regenerated. The last review covered the PR before that merge, so this one reviews the head in full. Post every finding, advisory included, as its own thread. |
There was a problem hiding this comment.
Deep review — 0 blocking · 1 advisory
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Coverage | The new file-list guard closes template ↔ StackBlitz in both directions; the CodeSandbox project's set is hand-rolled and still unguarded, and the new create-bestax/CLAUDE.md bullet reads as covering both |
docs/scripts/sandbox.test.mjs:390 |
Overall: Sound, and verified this pass by the thing that matters rather than by reading: the six Test vite-ts-* visual-regression jobs on 200b790 are green, and each one scaffolds the template, runs a real pnpm install --ignore-workspace and then pnpm run build — tsc -b && vite build — so @types/node@^24.13.3 resolves from npm and the two new tsconfigs type-check a real app. Locally pnpm run test:scripts exits 0 with every coverage floor met, and pnpm --filter @allxsmith/bestax-docs run test passes, including the two new the template files tests. The riskiest part is the one the focus names — the merge, whose single conflict was in scripts/docs-fence-types.test.mjs — and it is resolved correctly: it keeps main's docsOnlyModule: DOCS_ONLY_MODULE over the branch's profileCard: PROFILE_CARD while keeping fenceCompilerOptions(), and both scope-binding tests that would catch a wrong resolution pass. Human attention is best spent on the advisory, which is a scope question rather than a defect.
Residual risk:
- The gate checking options no app has — closed. Both gates read one
appCompilerOptions(), andtemplate-tsconfig.test.mjspins theconfigFilePathit lands on to inside the template. The new floor row is not a loose one either:template-tsconfig.mjsmeasures 100 / 94.12 / 100, and the row 100 / 82 / 100 is exactly the documented rule — two covered branches of slack, (16-2)/17 = 82.35 — so it was derived, not picked. - Dropping
strictfrom the fence gate's options — refuted. The roottypescriptis^6.0.3, where an unsetstrictreads as on, andfixture/untyped-state.mdasserts a TS2322 that exists only understrictNullChecks, so losing strict mode reds the gate rather than quietly widening it. typesnamingvite/clientmoving into the app project — new in this diff, since it used to sit intsconfig.node.json, which no gate reads, soappCompilerOptions()now hands it to both gates. Refuted: each overrides it to an empty list, and the raises nothing outside the examples themselves test inskill-examples-typecheck.test.mjskeys on a diagnostic with no file, which is exactly where the TS2688 would land if that override ever went away.- The two fence-gate overrides hiding a difference — refuted; both make the gate stricter than the scaffold (an empty
typesagainst the app'svite/client,allowJsonly for the docs-only.jsx), so they can produce loud false failures, never a false pass. The inheritedtsBuildInfoFileis not neutralized the way the skill gate neutralizes it, but TypeScript writes build info only underincrementalorcomposite, neither is set, and the gate never emits. - The deleted
src/vite-env.d.tsleaving a dangling reference — refuted;vite-envappears nowhere else in the tree (skills,bestax-mcp/data, the workflows, the docs andcreate-bestax/srcare all clean), andcodesandboxFileswrites its ownsrc/css.d.tsrather than reading it. - An
open.js-only edit skipping the new guard under turbo — refuted. The docs test task carries the turbo default input set alongside the template input, so a change underdocs/src/invalidates its cache. - Open: which project
appCompilerOptions()lands on is decided by reference order, and its test pins only that the config sits inside the template. A future template with a second project oversrc/listed ahead oftsconfig.app.jsonwould swap the options both gates hold code to, with every test green. Not reachable today, since the template has one project oversrc/. - Open: the CodeSandbox half of the sandbox file list, posted as finding 1.
🏄 Dude, this one caught the wave it was paddling for — the template is back in step with create-vite, the fence gate finally reads the same file the app does, and six real scaffolds built clean in CI. Clean ride, green light, go surf.
|
deep-review: verify Every open thread has a reply: fixed, with the commit, or refuted with a reason. This settles them on 92f54f9. |
Preview DeploymentPreview URL: https://0365c5d7.bestax.pages.dev |
There was a problem hiding this comment.
Deep review (verify) — 1 resolved · 0 open
| No. | Severity | Area | Thread | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Coverage | CodeSandbox project unguarded by the new file-list check — accepted as deliberate, prose narrowed in bf1fa9a4 |
docs/scripts/sandbox.test.mjs:392 |
Overall: This pass settled threads and reviewed no commits. One advisory thread was open; the maintainer answered it as deliberate and applied the finding's own suggested remedy — the LEFT_OUT comment now carries the clause, and the create-bestax/CLAUDE.md bullet scopes the guard to the StackBlitz project while stating that no test holds the CodeSandbox builder to the template. I confirmed that narrowed prose is true against projects.mjs (codesandboxFiles reads three template entries; public/index.html and tsconfig.json are written from literals) and that the docs suite is green at 125/125. Every thread of mine on this PR is now resolved.
Residual risk:
- The CodeSandbox project still has no file-list guard — refuted as a blocker rather than as a risk: a CRA layout has no file-for-file mapping to the Vite template, five of the nine
TEMPLATE_FILESentries already go unused there, and the limitation is now stated in both the test andcreate-bestax/CLAUDE.mdinstead of being implied away. - No new findings were hunted for: a verify pass settles open threads only. A reader who wants the current code reviewed asks for a fresh one.
🏄 Last wave of the set, and it came in clean — one advisory, answered with a reason that actually holds, and the docs even got honest about what the check does and does not cover. Board is on the rack, 125 for 125, this one is good to paddle in.
## [4.2.17](https://github.com/allxsmith/bestax/compare/create-bestax@4.2.16...create-bestax@4.2.17) (2026-10-17) ### Bug Fixes * **bestax-mcp:** leave the query behind when a component's own rows answered it ([ec8a2f1](ec8a2f1)) * **bestax-mcp:** release with every bulma-ui release so the published index keeps up ([#1027](#1027)) ([618e483](618e483)) * **bestax-mcp:** say "matching" in the pointer answer only when there is a query ([2d28530](2d28530)) * **bestax-mcp:** say Button's variables style it for the colors and modifiers it accepts ([2b94042](2b94042)) * **bestax-migrate:** carry size to Buttons, Tags and Message ([#1038](#1038)) ([7549264](7549264)) * **bestax-migrate:** keep a title's heading level when its size carries over ([#1071](#1071)) ([7549699](7549699)) * **bulma-ui:** announce Autocomplete's empty content, and keep its listbox to options ([98cfaac](98cfaac)), closes [#1066](#1066) * **bulma-ui:** deprecate Autocomplete's unread selected and dropdown props ([#1091](#1091)) ([5a90eba](5a90eba)), closes [#1080](#1080) * **bulma-ui:** describe a Tooltip's trigger with its text for screen readers ([5a7eb99](5a7eb99)), closes [#1031](#1031) * **bulma-ui:** drop a Field label's for when nothing it holds takes it ([#1020](#1020)) ([3604c14](3604c14)) * **bulma-ui:** drop a key's fill in forced colors, so only its border draws it ([466ad38](466ad38)), closes [#1063](#1063) * **bulma-ui:** give TimeInput's AM/PM column a real name for screen readers ([2b1122f](2b1122f)) * **bulma-ui:** hide a Tooltip with its stylesheet alone, without aria-hidden ([d4cbee4](d4cbee4)) * **bulma-ui:** hold Autocomplete's empty announcement while results load ([75d8fdf](75d8fdf)) * **bulma-ui:** keep a loading ToggleButton from toggling ([cf9f6e8](cf9f6e8)) * **bulma-ui:** keep a Notification's text clear of its close button ([#1017](#1017)) ([91ebb63](91ebb63)) * **bulma-ui:** keep a picker label's default when its override is undefined ([aa88e50](aa88e50)) * **bulma-ui:** keep EmptyState's left room only for an indicator, and follow py ([9a615d6](9a615d6)), closes [#1065](#1065) * **bulma-ui:** keep SegmentedControl's fallback tab stop on the first segment after a reorder ([b32df32](b32df32)) * **bulma-ui:** keep Theme's component-variable check out of production ([537d90d](537d90d)) * **bulma-ui:** key each key in Kbd.Group by its own React key ([b51c5c8](b51c5c8)), closes [#1063](#1063) * **bulma-ui:** leave the keys alone on a SegmentedControl segment outside its row ([f477666](f477666)) * **bulma-ui:** let Autocomplete's Enter submit, keep focus on a click, and open on a highlight ([#1090](#1090)) ([81f5982](81f5982)), closes [#1078](#1078) [#1089](#1089) [#1079](#1079) [#1081](#1081) [#1081](#1081) * **bulma-ui:** mark a loading ToggleButton aria-disabled as well as aria-busy ([f87425f](f87425f)) * **bulma-ui:** name a composed DateRangeInputBase's group from a Field label ([75aa6cb](75aa6cb)) * **bulma-ui:** name a range Slider's thumbs from a hand-wired Field label's id ([355065b](355065b)) * **bulma-ui:** name Autocomplete's list from a hand-wired Field label's id ([ad46c06](ad46c06)) * **bulma-ui:** name Autocomplete's suggestion list from a surrounding Field's label ([190183f](190183f)), closes [#998](#998) * **bulma-ui:** one Escape closes one layer inside a Modal or Sidebar ([#1086](#1086)) ([3ea7ac8](3ea7ac8)), closes [#1077](#1077) [#1077](#1077) * **bulma-ui:** open Fragments in Kbd.Group before placing its separators ([c595de2](c595de2)), closes [#1063](#1063) * **bulma-ui:** say a label placed in Field.Label reaches no thumbs or list ([07c2a99](07c2a99)) * **bulma-ui:** say the label prop needs wiring to reach thumbs or list in an inner Field ([9b33d8d](9b33d8d)) * **bulma-ui:** say which controls a hand-wired Field label's id reaches ([514127f](514127f)) * **bulma-ui:** stop the keys a SegmentedControl takes from reaching listeners above it ([6b9e797](6b9e797)) * **bulma-ui:** warn when Tab can't reach a Tooltip trigger that carries the link ([cfd21c7](cfd21c7)) * **bulma-ui:** warn when Theme is given a variable Bulma sets on the component ([bb8f9b8](bb8f9b8)), closes [#1021](#1021) * **bulma-ui:** wire Taginput's suggestions as a combobox ([#1084](#1084)) ([e30c33a](e30c33a)), closes [#942](#942) [#998](#998) [#1082](#1082) * **create-bestax:** bring the vite-ts tsconfigs up to create-vite 9 ([#1076](#1076)) ([dc6995c](dc6995c)), closes [#1049](#1049) * **docs:** address the deep review of the sandbox builders ([b7338d9](b7338d9)) * **docs:** close the CodeSandbox tab when its launch fails ([d1e6d1d](d1e6d1d)) * **docs:** compare the icon link as a string in the sandbox test ([9ac4737](9ac4737)) * **docs:** darken the live preview surface and follow the library stylesheet import ([363badf](363badf)) * **docs:** draw the CodeSandbox button icon as the cube mark ([8389e18](8389e18)) * **docs:** give both sandboxes the example window's dark page and padding ([33dfb4a](33dfb4a)) * **docs:** give the mixin note the modifier caveat its lead carries ([1427f08](1427f08)) * **docs:** keep the live preview's spacing outside its dark surface ([7a158e1](7a158e1)) * **docs:** keep the live-preview margin off the homepage previews ([f18eed3](f18eed3)) * **docs:** keep the modifier caveat for mixin variables in the MCP index ([e227663](e227663)) * **docs:** load the CodeSandbox stylesheet from the CDN and darken example windows ([253f057](253f057)) * **docs:** match the preview's color scheme and keep the copy button on narrow screens ([c4d6d25](c4d6d25)) * **docs:** name the one edge of the rule for which variables Theme reaches ([b33ebfa](b33ebfa)) * **docs:** open CodeSandbox through its JSON define API ([6a65276](6a65276)) * **docs:** open the CodeSandbox tab on the click, and skip the sandbox when popups are blocked ([bcc0634](bcc0634)) * **docs:** pin react-scripts in CodeSandbox sandboxes and keep the sandbox notes in step ([#1074](#1074)) ([3ac8a65](3ac8a65)) * **docs:** qualify the guide and the theming skill on what Theme reaches ([9c2347b](9c2347b)) * **docs:** read only a component's own mixin as its home ([f40cd2c](f40cd2c)) * **docs:** refuse a CSS-variable scope the page cannot fully word ([c815602](c815602)) * **docs:** restore the homepage preview margin, and reject a CodeSandbox reply without an id ([9e0991f](9e0991f)) * **docs:** say where component-scoped Bulma variables have to be set ([771d5bd](771d5bd)), closes [#1021](#1021) * **docs:** send the copy and sandbox buttons the code the reader typed ([019edf0](019edf0)) ### Features * **bestax-mcp:** name the other component's call in get_component's theming hint ([cbedd5f](cbedd5f)) * **bestax-mcp:** point get_css_variables at the component whose element a component renders ([d4be1a8](d4be1a8)) * **bulma-ui:** add Buttons.ToggleButton ([0c8fb10](0c8fb10)) * **bulma-ui:** add ContextMenu, a menu that opens on right-click or long press ([#1036](#1036)) ([85a3e77](85a3e77)) * **bulma-ui:** add EmptyState, the block a list shows when it has nothing in it ([c5929d2](c5929d2)), closes [#1065](#1065) * **bulma-ui:** add HoverCard, a card that opens on hover or keyboard focus ([#1030](#1030)) ([0eb41df](0eb41df)) * **bulma-ui:** add Kbd, a key drawn as a keycap, and Kbd.Group for combinations ([98d1578](98d1578)), closes [#1063](#1063) * **bulma-ui:** add SegmentedControl, a row of buttons where only one can be on ([b1be0e8](b1be0e8)), closes [#1040](#1040) * **bulma-ui:** add ToggleButton, a button that stays pressed ([#1041](#1041)) ([582aff0](582aff0)) * **bulma-ui:** give Dropdown typeahead ([1bb35bf](1bb35bf)), closes [#1035](#1035) * **bulma-ui:** let a Tooltip be hovered, dismissed with Escape, and opened by a tap ([#1033](#1033)) ([52aeeda](52aeeda)) * **bulma-ui:** let ConfigProvider set where portaled content goes ([#1032](#1032)) ([5e928ae](5e928ae)) * **docs:** open live examples in StackBlitz and CodeSandbox ([654b16c](654b16c)) * **docs:** open live examples in StackBlitz and CodeSandbox ([#1073](#1073)) ([730db1e](730db1e))
|
🎉 This PR is included in version 4.2.17 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [5.35.0](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.34.3...@allxsmith/bestax-bulma@5.35.0) (2026-10-17) ### Bug Fixes * **bestax-migrate:** convert an active menu link only beside its own aria-current ([c3f68f4](c3f68f4)) * **bulma-ui:** clear a Checkbox's mixed state when indeterminate goes unset ([979730f](979730f)), closes [#1092](#1092) * **bulma-ui:** close Taginput's suggestion list at the tag limit ([1ea3d42](1ea3d42)), closes [#1087](#1087) * **bulma-ui:** dismiss Taginput's list at the tag limit, not just hide it ([6d6f43a](6d6f43a)) * **bulma-ui:** draw a custom completed icon in the check mark's color in forced colors ([47792ef](47792ef)), closes [#1106](#1106) * **bulma-ui:** give Steps' list role="list", so Safari keeps it a list ([9063bc7](9063bc7)), closes [#1108](#1108) * **bulma-ui:** keep a checked Checkbox's mark readable in forced colors ([42b1b6b](42b1b6b)), closes [#1092](#1092) * **bulma-ui:** keep a clickable Steps.Step a list item, with a button inside it ([a4cfbd7](a4cfbd7)), closes [#1107](#1107) * **bulma-ui:** keep a mixed Checkbox's dash in forced colors ([016eb9b](016eb9b)), closes [#1092](#1092) * **bulma-ui:** keep a Toast's timer and outside-click listener while onClose changes ([5263454](5263454)), closes [#1113](#1113) * **bulma-ui:** keep Bulma's loader rings open in forced colors ([5fae568](5fae568)), closes [#1109](#1109) * **bulma-ui:** keep each overlay's Escape listener while its callback changes ([9750c67](9750c67)), closes [#1088](#1088) * **bulma-ui:** keep React 18's useLayoutEffect warning out of server renders ([737cf13](737cf13)), closes [#1099](#1099) * **bulma-ui:** keep Steps' lines and completed fill visible in forced colors ([424f555](424f555)), closes [#1106](#1106) * **bulma-ui:** keep Steps' lines and label gaps on the right side in a right-to-left page ([9b90f1b](9b90f1b)), closes [#1105](#1105) * **bulma-ui:** keep the Escape a date picker in a Dropdown menu closes on ([255b69c](255b69c)), closes [#1085](#1085) * **bulma-ui:** leave the overlay stack alone when a cleanup finds its place gone ([fc189bb](fc189bb)), closes [#1085](#1085) * **bulma-ui:** let a clickable step's whole box take the click and the pointer ([9082bf4](9082bf4)), closes [#1107](#1107) * **bulma-ui:** mark the active Menu.Item as the current page ([1791660](1791660)), closes [#1093](#1093) * **bulma-ui:** one Escape closes only the topmost overlay ([07cbf16](07cbf16)), closes [#1085](#1085) * **bulma-ui:** show how a menu marks one page when more than one item is active ([c9d66d2](c9d66d2)) * **create-bestax:** bring the vite-ts tsconfigs up to create-vite 9 ([#1076](#1076)) ([dc6995c](dc6995c)), closes [#1049](#1049) ### Features * **bulma-ui:** add an indeterminate prop to Checkbox ([21091e8](21091e8)), closes [#1092](#1092)
|
🎉 This PR is included in version 5.35.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## [2.25.5](https://github.com/allxsmith/bestax/compare/bestax-migrate@2.25.4...bestax-migrate@2.25.5) (2026-10-17) ### Bug Fixes * **bestax-migrate:** convert an active menu link only beside its own aria-current ([c3f68f4](c3f68f4)) * **bulma-ui:** clear a Checkbox's mixed state when indeterminate goes unset ([979730f](979730f)), closes [#1092](#1092) * **bulma-ui:** close Taginput's suggestion list at the tag limit ([1ea3d42](1ea3d42)), closes [#1087](#1087) * **bulma-ui:** deprecate Autocomplete's unread selected and dropdown props ([#1091](#1091)) ([5a90eba](5a90eba)), closes [#1080](#1080) * **bulma-ui:** dismiss Taginput's list at the tag limit, not just hide it ([6d6f43a](6d6f43a)) * **bulma-ui:** draw a custom completed icon in the check mark's color in forced colors ([47792ef](47792ef)), closes [#1106](#1106) * **bulma-ui:** give Steps' list role="list", so Safari keeps it a list ([9063bc7](9063bc7)), closes [#1108](#1108) * **bulma-ui:** keep a checked Checkbox's mark readable in forced colors ([42b1b6b](42b1b6b)), closes [#1092](#1092) * **bulma-ui:** keep a clickable Steps.Step a list item, with a button inside it ([a4cfbd7](a4cfbd7)), closes [#1107](#1107) * **bulma-ui:** keep a mixed Checkbox's dash in forced colors ([016eb9b](016eb9b)), closes [#1092](#1092) * **bulma-ui:** keep a Toast's timer and outside-click listener while onClose changes ([5263454](5263454)), closes [#1113](#1113) * **bulma-ui:** keep Bulma's loader rings open in forced colors ([5fae568](5fae568)), closes [#1109](#1109) * **bulma-ui:** keep each overlay's Escape listener while its callback changes ([9750c67](9750c67)), closes [#1088](#1088) * **bulma-ui:** keep React 18's useLayoutEffect warning out of server renders ([737cf13](737cf13)), closes [#1099](#1099) * **bulma-ui:** keep Steps' lines and completed fill visible in forced colors ([424f555](424f555)), closes [#1106](#1106) * **bulma-ui:** keep Steps' lines and label gaps on the right side in a right-to-left page ([9b90f1b](9b90f1b)), closes [#1105](#1105) * **bulma-ui:** keep the Escape a date picker in a Dropdown menu closes on ([255b69c](255b69c)), closes [#1085](#1085) * **bulma-ui:** leave the overlay stack alone when a cleanup finds its place gone ([fc189bb](fc189bb)), closes [#1085](#1085) * **bulma-ui:** let a clickable step's whole box take the click and the pointer ([9082bf4](9082bf4)), closes [#1107](#1107) * **bulma-ui:** let Autocomplete's Enter submit, keep focus on a click, and open on a highlight ([#1090](#1090)) ([81f5982](81f5982)), closes [#1078](#1078) [#1089](#1089) [#1079](#1079) [#1081](#1081) [#1081](#1081) * **bulma-ui:** mark the active Menu.Item as the current page ([1791660](1791660)), closes [#1093](#1093) * **bulma-ui:** one Escape closes one layer inside a Modal or Sidebar ([#1086](#1086)) ([3ea7ac8](3ea7ac8)), closes [#1077](#1077) [#1077](#1077) * **bulma-ui:** one Escape closes only the topmost overlay ([07cbf16](07cbf16)), closes [#1085](#1085) * **bulma-ui:** show how a menu marks one page when more than one item is active ([c9d66d2](c9d66d2)) * **create-bestax:** bring the vite-ts tsconfigs up to create-vite 9 ([#1076](#1076)) ([dc6995c](dc6995c)), closes [#1049](#1049) ### Features * **bulma-ui:** add an indeterminate prop to Checkbox ([21091e8](21091e8)), closes [#1092](#1092)
|
🎉 This PR is included in version 2.25.5 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## [1.15.7](https://github.com/allxsmith/bestax/compare/bestax-mcp@1.15.6...bestax-mcp@1.15.7) (2026-10-17) ### Bug Fixes * **bestax-migrate:** convert an active menu link only beside its own aria-current ([c3f68f4](c3f68f4)) * **bulma-ui:** clear a Checkbox's mixed state when indeterminate goes unset ([979730f](979730f)), closes [#1092](#1092) * **bulma-ui:** close Taginput's suggestion list at the tag limit ([1ea3d42](1ea3d42)), closes [#1087](#1087) * **bulma-ui:** dismiss Taginput's list at the tag limit, not just hide it ([6d6f43a](6d6f43a)) * **bulma-ui:** draw a custom completed icon in the check mark's color in forced colors ([47792ef](47792ef)), closes [#1106](#1106) * **bulma-ui:** give Steps' list role="list", so Safari keeps it a list ([9063bc7](9063bc7)), closes [#1108](#1108) * **bulma-ui:** keep a checked Checkbox's mark readable in forced colors ([42b1b6b](42b1b6b)), closes [#1092](#1092) * **bulma-ui:** keep a clickable Steps.Step a list item, with a button inside it ([a4cfbd7](a4cfbd7)), closes [#1107](#1107) * **bulma-ui:** keep a mixed Checkbox's dash in forced colors ([016eb9b](016eb9b)), closes [#1092](#1092) * **bulma-ui:** keep a Toast's timer and outside-click listener while onClose changes ([5263454](5263454)), closes [#1113](#1113) * **bulma-ui:** keep Bulma's loader rings open in forced colors ([5fae568](5fae568)), closes [#1109](#1109) * **bulma-ui:** keep each overlay's Escape listener while its callback changes ([9750c67](9750c67)), closes [#1088](#1088) * **bulma-ui:** keep React 18's useLayoutEffect warning out of server renders ([737cf13](737cf13)), closes [#1099](#1099) * **bulma-ui:** keep Steps' lines and completed fill visible in forced colors ([424f555](424f555)), closes [#1106](#1106) * **bulma-ui:** keep Steps' lines and label gaps on the right side in a right-to-left page ([9b90f1b](9b90f1b)), closes [#1105](#1105) * **bulma-ui:** keep the Escape a date picker in a Dropdown menu closes on ([255b69c](255b69c)), closes [#1085](#1085) * **bulma-ui:** leave the overlay stack alone when a cleanup finds its place gone ([fc189bb](fc189bb)), closes [#1085](#1085) * **bulma-ui:** let a clickable step's whole box take the click and the pointer ([9082bf4](9082bf4)), closes [#1107](#1107) * **bulma-ui:** mark the active Menu.Item as the current page ([1791660](1791660)), closes [#1093](#1093) * **bulma-ui:** one Escape closes only the topmost overlay ([07cbf16](07cbf16)), closes [#1085](#1085) * **bulma-ui:** show how a menu marks one page when more than one item is active ([c9d66d2](c9d66d2)) * **create-bestax:** bring the vite-ts tsconfigs up to create-vite 9 ([#1076](#1076)) ([dc6995c](dc6995c)), closes [#1049](#1049) ### Features * **bulma-ui:** add an indeterminate prop to Checkbox ([21091e8](21091e8)), closes [#1092](#1092)
|
🎉 This PR is included in version 1.15.7 🎉 The release is available on: Your semantic-release bot 📦🚀 |
The create-bestax
vite-tstemplate had fallen a create-vite major behind on its tsconfigs: an ES2020 target and lib, and asrc/vite-env.d.tsfor the Vite client types. The docs fence gate, meanwhile, checked every live example against a literal copy of create-vite's newer options, not the template's. So a fence using.at()passed the gate and was a type error in the appnpm create bestaxactually makes.This brings the template's tsconfigs up to create-vite's, points the fence gate at the template itself, keeps the StackBlitz project in step, and writes down when to catch up next time.
The template
The tsconfigs are create-vite 9.2.1's
react-tsfiles, byte for byte (same git blobs):packages/create-vite/template-react-tsatcreate-vite@9.2.1. The tsconfigs at that tag are still the ones on vite'smain.tsconfig.jsonwas already the same, so it doesn't change.And
src/vite-env.d.tsis gone, sincetypes: ["vite/client"]does its job.A few of the removals look scarier than they are:
strictisn't off. TypeScript 6, which the template installs, turns it on by default, which is why create-vite dropped the line. The fence gate's untyped-state fixture only fails understrictNullChecks, so it would catch the gate losing strict mode.DOM.Iterableis folded intoDOMin TypeScript 6.isolatedModulescomes withverbatimModuleSyntax, andresolveJsonModuleis the default under bundler resolution. A JSON import insrc/still compiles.One devDependency joins:
@types/nodeat create-vite's range (^24.13.3).tsconfig.node.jsonnamestypes: ["node"], and without the packagetsc -bstops on TS2688. Vite lists it only as an optional peer, so nothing else brings it in. If you'd rather not add it, the alternative istypes: []intsconfig.node.json, which leavesvite.config.tswithout Node's types, the way it is today.Everything else stays put: ESLint with typescript-eslint is still the linter (create-vite now ships oxlint), and the App, its assets, the README,
vite.config.tsandmain.tsxare untouched.What
verbatimModuleSyntaxanderasableSyntaxOnlyforced: nothing. The template's own source has no type-only value import and no enum, and neither does anything create-bestax writes into it. The flavor step writes CSS imports, the icon step writes CSS imports andIconText, andConfigProvideris a value import.The fence gate
scripts/docs-fence-types.test.mjsno longer carries its own options. It reads the options of the template project that compilessrc/, through the readerskill-examples-typecheck.test.mjsalready used, which moves toscripts/lib/template-tsconfig.mjs(with its tests, inscripts/template-tsconfig.test.mjs). That reader parses withgetParsedCommandLineOfConfigFile, so the comments in the template's JSON are fine, and it fails on any option it can't read rather than dropping it. Both gates now hold code to the same file.The fence gate overrides two options, each with a comment:
types: [], sincevite/clientresolves from a scaffold's install, not from the template in this repo (left as is, it's a TS2688), and only declares asset imports, which no fence keeps.allowJs: true, for the docs-onlyProfileCard, a.jsxfile.It needs nothing for
noEmitorpaths: the template already setsnoEmit, and the fence modules sit inbulma-ui/so the library resolves without paths.Every live fence passes under the template's options. No fence changed.
The new reader has a coverage floor row, and one new test (a template with no
tsconfig.json) for the one path the moved tests didn't reach.The docs sandboxes
The StackBlitz builder copies the template's files by name, so
TEMPLATE_FILESand the raw-loader imports inopen.jsdropvite-env.d.tsin the template commit, or the docs build would fail looking for it. The project now gets the new tsconfigs and@types/nodealong with them. CodeSandbox has its own tsconfig for its older editor, so it doesn't change.sandbox.test.mjsalready failed when a copied file left the template, but a file the template gained went unnoticed. Now every file the template tracks has to be inTEMPLATE_FILESor in aLEFT_OUTmap with the reason the sandbox does without it (the gitignore, README, lint config, the starter App with its CSS and images). The list comes fromgit ls-files, so a lockfile ordist/from an install inside the template doesn't count.The buttons copy from the
TEMPLATEmap inopen.js, not fromTEMPLATE_FILES, and before this no test read it. A file listed in one and left out of the other passed every check, and the button threw on the reader's click.open.jsonly runs under webpack, so the test reads it as text. Its keys have to be exactlyTEMPLATE_FILES, each bound to the raw-loader import of the file with that name.These fail it: dropping a key from
open.js, binding a key to the wrong file's import, and takingREADME.mdout ofLEFT_OUT. A lockfile anddist/left in the template don't.turbo.jsonneeded nothing.docs#testalready listscreate-bestax/templates/vite-ts/**as an input, and the fence gate runs intest:scripts, outside turbo.When to catch up next time
create-bestax/CLAUDE.mdnow says that at each Vite or create-vite major you scaffoldnpm create vite@latest'sreact-ts, compare its tsconfigs, devDependencies,vite.config.tsandsrc/main.tsx, and catch up. It names what differs on purpose: the App, its assets, the README, and ESLint as the linter. It doesn't include a version number, so it won't go stale.What #1049 proposed
visual-regression.ymlalready installs and buildsvite-tsscaffolds on every PR that touchescreate-bestax/**and on a daily schedule. The fence gate type-checks each sandboxApp.tsxunder the template's options, and the sandbox test holds the copied file list to the template. A build in the docs tests would add an install of the assembled project (the template'spackage.jsonwithout its lint packages) on every run.create-bestax/CLAUDE.md.@types/node, is create-vite's range, published well before the cooldown, and nothing islatest.Checked
vite-tsoutside the repo in all 30 combinations of the five Bulma flavors (complete, prefixed, no-helpers, no-helpers-prefixed, no-dark-mode) and the six icon choices (none, fontawesome, mdi, ionicons, material-icons, material-symbols), and rantsc -b,vite buildandeslint .in each. They shared one real npm install of the template's dependencies plus the icon packages. One app went through a freshnpm install && npm run build && npm run lint. Another went throughpnpm install --ignore-workspaceandpnpm run buildandlint, the way the visual-regression workflow does it.import type) and TS1294 (an enum), and.at()andimport.meta.envcompiled.dist/came out byte-identical.stackblitzProjectmakes for an example using.at()and an MDI icon, from the real template, and it passedtsc -b && vite build.pnpm --filter create-bestax test:coverage, the docs tests,pnpm test:scripts(coverage floors included),pnpm check:conformance,pnpm typecheck,pnpm lint,pnpm format:check, and the threegen:*:checkstaleness checks all pass. I didn't runpnpm all.Releasing and listings
Squashed under this title, it's a patch release of
create-bestax, which is how the new template reachesnpm create bestax. Thetest,test(docs)anddocscommits release nothing.Nothing in "What goes stale" in the distribution guide applies. No skill, MCP tool, install command, package folder or Node floor changes.
Fixes #1049