Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
263e74a
refactor(bestax-migrate): hoist source-agnostic helpers to _shared
allxsmith Aug 30, 2026
8cf2f4a
refactor(bestax-migrate): share the structural-handler building blocks
allxsmith Aug 30, 2026
ef95b94
feat(bestax-migrate): add rbx as a migration source
allxsmith Aug 30, 2026
1b12845
test(bestax-migrate): add rbx transform fixtures
allxsmith Aug 30, 2026
c749a44
feat(bestax-migrate): validate rbx against its own documentation corpus
allxsmith Aug 30, 2026
6f5dd68
test(bestax-migrate): add the rbx kitchen-sink e2e
allxsmith Aug 30, 2026
a2bdffe
docs(bestax-migrate): document the rbx source and split the skill per…
allxsmith Aug 30, 2026
c2147d9
fix(bestax-migrate): close seven defects found reviewing the rbx source
allxsmith Aug 30, 2026
7faf2d8
fix(bestax-migrate): address the PR #613 review round
allxsmith Aug 30, 2026
443829f
fix(bestax-migrate): refresh the MCP index after the reference edits
allxsmith Aug 30, 2026
df222c3
fix(bestax-migrate): address the second review round on PR #613
allxsmith Aug 30, 2026
2feca47
fix(bestax-migrate): keep a namespace import referenced as a value
allxsmith Aug 30, 2026
92fc2a0
fix(bestax-migrate): address the third review round on PR #613
allxsmith Aug 30, 2026
dee9f08
fix(bestax-migrate): correct the Navbar dropdown target and doc drift
allxsmith Aug 30, 2026
9dd22df
fix(bestax-migrate): preserve shorthand object keys, and read deps si…
allxsmith Aug 30, 2026
f12c3a3
fix(bestax-migrate): strip `responsive` from plain elements, cover th…
allxsmith Aug 30, 2026
9d8219b
fix(bestax-migrate): fix the alias collision in react-bulma-component…
allxsmith Aug 30, 2026
e659ed8
fix(bestax-migrate): stop collapsing containers onto children they do…
allxsmith Aug 30, 2026
fcf11dc
fix(create-bestax): name rbx in the scaffolded CLAUDE.md skill roster
allxsmith Aug 30, 2026
90d01e0
docs(bestax-migrate): say what rbx's Loader actually becomes
allxsmith Aug 30, 2026
bd7f47e
test(bestax-migrate): hold the shipped `as` guidance to actual behaviour
allxsmith Aug 30, 2026
aaef103
fix(bestax-migrate): migrate component references through a namespace…
allxsmith Aug 30, 2026
0b5a77c
test(bestax-migrate): cover how the specifier retention rules interact
allxsmith Aug 31, 2026
1c35319
fix(bestax-migrate): port namespace-import retention to react-bulma-c…
allxsmith Aug 31, 2026
58b14cf
fix(bestax-migrate): resolve destructured aliases and protect aliased…
allxsmith Aug 31, 2026
9c0dea8
fix(bestax-migrate): resolve shorthand and destructured aliases corre…
allxsmith Aug 31, 2026
3f53bea
fix(bestax-migrate): resolve dotted targets for bare alias references
allxsmith Aug 31, 2026
4c1629c
test(bestax-migrate): pin the rbx value unions against bestax's own
allxsmith Aug 31, 2026
34b75ad
fix(bestax-migrate): drain the Copilot backlog — 9 findings
allxsmith Aug 31, 2026
5ec0008
docs(bestax-migrate): close the last backlog items, two as declines
allxsmith Aug 31, 2026
d637083
fix(bestax-migrate): four more findings that arrived mid-pass
allxsmith Aug 31, 2026
5f37135
fix(bestax-migrate): flag the Modal behaviours bestax does not implement
allxsmith Sep 1, 2026
bc0096a
fix(bestax-migrate): port four value-reference fixes to the RBC source
allxsmith Sep 1, 2026
0722674
fix(bestax-migrate): resolve component references by binding, not by …
allxsmith Sep 1, 2026
a208436
fix(bestax-migrate): report what actually happened to bulma, not a fi…
allxsmith Sep 1, 2026
402a950
fix(bestax-migrate): key aliases by scope and reserve retained partia…
allxsmith Sep 1, 2026
82bc4b3
Merge remote-tracking branch 'origin/main' into feat/409-rbx-migratio…
allxsmith Sep 2, 2026
794e0a7
fix(bestax-migrate): flag labelled dividers, parse pre-1.0 ranges, ma…
allxsmith Sep 2, 2026
ea287b6
fix(bestax-migrate): read spaced comparators and stop calling non-sem…
allxsmith Sep 2, 2026
1f02e12
fix(bestax-migrate): resolve aliases by location, reserve value-retai…
allxsmith Sep 2, 2026
0c45ff3
fix(bestax-migrate): let a nearer binding win over a shadowed alias
allxsmith Sep 2, 2026
382f267
docs(bestax-migrate): match the license wording to bestax-bulma
allxsmith Sep 2, 2026
b317e08
docs: match the root license wording to bestax-bulma
allxsmith Sep 2, 2026
889c225
docs(bestax-mcp): match the license wording to bestax-bulma
allxsmith Sep 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,4 @@ Bulma framework!_

## License

MIT © [Alex Smith](https://github.com/allxsmith)
Source code licensed MIT
2 changes: 1 addition & 1 deletion bestax-mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ One per skill, so a task can start from the library's own guidance:
- [Documentation](https://bestax.io)
- [GitHub](https://github.com/allxsmith/bestax)

MIT © Alex Smith
Source code licensed MIT
37 changes: 28 additions & 9 deletions bestax-mcp/data/skills.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,43 @@
},
{
"name": "bestax-migrate",
"description": "Migrate an existing app from react-bulma-components (v4) to @allxsmith/bestax-bulma on Bulma v1 — run the bestax-migrate codemod, then resolve every TODO(bestax-migrate) comment it leaves using the mapping references. Use when a repo imports react-bulma-components and wants to move to bestax-bulma, when TODO(bestax-migrate) comments are present in a codebase, or when asked to migrate off an unmaintained React Bulma library.",
"description": "Migrate an existing app from an unmaintained React Bulma library — react-bulma-components (v4) or rbx (v2) — to @allxsmith/bestax-bulma on Bulma v1. Run the bestax-migrate codemod, then resolve every TODO(bestax-migrate) comment it leaves using the per-source mapping references. Use when a repo imports react-bulma-components or rbx and wants to move to bestax-bulma, when TODO(bestax-migrate) comments are present in a codebase, or when asked to migrate off an unmaintained React Bulma library.",
"promptName": "migrate",
"dir": "bestax-migrate",
"references": [
{
"id": "component-map",
"file": "references/component-map.md",
"id": "css-migration",
"file": "references/css-migration.md",
"bytes": 8555
},
{
"id": "rbx-component-map",
"file": "references/rbx/component-map.md",
"bytes": 12252
},
{
"id": "rbx-prop-map",
"file": "references/rbx/prop-map.md",
"bytes": 7973
},
{
"id": "rbx-unmappables",
"file": "references/rbx/unmappables.md",
"bytes": 11237
},
{
"id": "react-bulma-components-component-map",
"file": "references/react-bulma-components/component-map.md",
"bytes": 13190
},
{
"id": "css-migration",
"file": "references/css-migration.md",
"bytes": 7999
"id": "react-bulma-components-prop-map",
"file": "references/react-bulma-components/prop-map.md",
"bytes": 6363
},
{ "id": "prop-map", "file": "references/prop-map.md", "bytes": 6363 },
{
"id": "unmappables",
"file": "references/unmappables.md",
"id": "react-bulma-components-unmappables",
"file": "references/react-bulma-components/unmappables.md",
"bytes": 4861
}
],
Comment thread
allxsmith marked this conversation as resolved.
Expand Down
58 changes: 42 additions & 16 deletions bestax-migrate/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,37 @@

jscodeshift-based CLI (`pnpm dlx bestax-migrate <source> <paths…>`) that migrates existing
apps from other React Bulma libraries to `@allxsmith/bestax-bulma`. Multi-source by design:
each source library registers in `src/sources/registry.ts`; the first is
`react-bulma-components` (v4 only).
each source library registers in `src/sources/registry.ts`. Two are shipped —
`react-bulma-components` (v4 only) and `rbx` (v2 only).

## Hard rules

- **react-bulma-components is NEVER installed anywhere in this repo** (supply-chain
policy). Fixtures are read as _text_ (`__testfixtures__`, `fixtures/kitchen-sink`); the
migration _input_ is never typechecked or executed. Validation typechecks the migrated
_output_ against the workspace `@allxsmith/bestax-bulma`.
- Mapping-table first: `src/sources/react-bulma-components/mapping.ts` is the single source
of truth. Every RBC v4 export must have an entry (`mapped`/`partial`/`todo`) — the
`mapping-coverage` test walks the vendored `RBC_EXPORTS` list against it. New coverage is
a table edit (plus a `special` handler in `specials.ts` when structure changes).
- **No source library is EVER installed anywhere in this repo** (supply-chain policy) —
not react-bulma-components, not rbx. Fixtures are read as _text_ (`__testfixtures__`,
`fixtures/kitchen-sink`, `fixtures/rbx-kitchen-sink`); the migration _input_ is never
typechecked or executed. Validation typechecks the migrated _output_ against the
workspace `@allxsmith/bestax-bulma`.
- Mapping-table first: each source's `mapping.ts` is its single source of truth. Every
export of that library must have an entry (`mapped`/`partial`/`todo`) — the
`mapping-coverage` test walks the vendored `RBC_EXPORTS` / `RBX_EXPORTS` list against it,
in both directions, so the table cannot grow an entry for something the library never
exported either. New coverage is a table edit (plus a `special` handler in `specials.ts`
when structure changes).
- **A new source is a directory plus one registry line.** `src/sources/_shared/` holds
everything library-agnostic: `jsx-utils.ts` (AST helpers + `TransformContext`),
`props.ts` (the `PropAction` interpreter — its universal table is a parameter, not an
import), `imports.ts` (binding collection and import aliasing), `specials-utils.ts`
(`alignTarget`, `mergeClassName`, `parseIconClasses`, and the `stripModifierProps`
factory), and `make-styles-transform.ts` (the whole Bulma 0.9→v1 stylesheet transform,
parameterised by the source package's own specifiers). What stays per-source is the data
— `mapping.ts`, `specials.ts`, `responsive.ts`, `deps.ts` — plus a `transform.ts` that
orchestrates them.
- `'<source>'` must be added to `MIGRATE_SOURCE_VALUES` in `telemetry-worker/src/schema.ts`
or its events are dropped at ingest; `check:conformance --only=telemetry-allowlists`
fails until it is. That worker deploys to production on merge, so the two land together.
The same check regex-scrapes each source's `index.ts` for
`: MigrationSource = { … name: '…' }` — a declaration that doesn't match that shape is a
hard violation, not a skip.
- Anything unsafe gets a `// TODO(bestax-migrate): <hint>` comment on the enclosing
statement + a report entry — never a silent skip, never a best-guess rewrite of dynamic
values.
Expand Down Expand Up @@ -58,12 +76,20 @@ each source library registers in `src/sources/registry.ts`; the first is
supported ones go in the other fixture files, which must stay TODO-free.
- Fixtures and `.e2e-tmp` are excluded from tsc/eslint/prettier at both root and package
level (root `eslint.config.js` + both `.prettierignore`s) — keep them that way.
- Real-world corpus: `pnpm --filter bestax-migrate validate:corpus` fetches the
react-bulma-components repo's own MIT-licensed Storybook stories (pinned SHA, text only,
into `.e2e-tmp/`) and scores the transform over them — fails on any crash or
unknown-component TODO. Deliberately NOT in CI (no third-party fetches in the pipeline);
run it before releases and after mapping changes, and eyeball the before/after diffs it
writes to `.e2e-tmp/corpus-out/`.
- Real-world corpus, one script per source, both fetching a pinned SHA as text only into
`.e2e-tmp/` and failing on any crash or unknown-component TODO. Deliberately NOT in CI
(no third-party fetches in the pipeline); run them before releases and after mapping
changes, and eyeball the before/after diffs they write:
- `validate:corpus` — react-bulma-components' own MIT Storybook stories →
`.e2e-tmp/corpus-out/`.
- `validate:corpus:rbx` — rbx's own MIT docs. rbx used **docz**, not Storybook, so the
script extracts the `<Playground>` blocks out of its 43 `*.docs.mdx` pages (254 blocks)
and rebuilds each page as one synthetic module written the way a consumer writes rbx.
Output lands in `.e2e-tmp/corpus-out-rbx/`.

The corpus is the only check that sees breadth; the kitchen-sink e2e is the only one that
sees bestax's _real_ prop names. Both are needed — the rbx e2e's typecheck caught six
mapping errors that 254 clean Playgrounds had not.

## Releases

Expand Down
21 changes: 13 additions & 8 deletions bestax-migrate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ Codemods that migrate existing React apps to [`@allxsmith/bestax-bulma`](https:/

Currently supported source libraries:

| Source | Status |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |
| Source | Status |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |
| [`rbx`](https://github.com/dfee/rbx) (v2) | ✅ Full export surface mapped (a few patterns are flagged as TODOs) |

Pass the source library as the first argument: `bestax-migrate <source> <paths…>`.

## Requirements

Expand All @@ -30,6 +33,8 @@ the app being migrated — the source is read as text and is never executed.
```bash
# Preview what would change (no writes)
pnpm dlx bestax-migrate react-bulma-components src/ --dry
# …or, for an rbx app
pnpm dlx bestax-migrate rbx src/ --dry

# Apply the migration
pnpm dlx bestax-migrate react-bulma-components src/
Expand All @@ -39,15 +44,15 @@ npm and yarn work too: `npx bestax-migrate …` / `yarn dlx bestax-migrate …`.

The codemod uses [jscodeshift](https://github.com/facebook/jscodeshift) to:

- rewrite `react-bulma-components` imports to `@allxsmith/bestax-bulma` (including `const { Input } = Form` destructuring and namespace imports)
- rewrite the source library's imports to `@allxsmith/bestax-bulma` (including destructuring and namespace imports)
- rename components and compound sub-components (`Form.Textarea` → `TextArea`, `Card.Footer.Item` → `Card.FooterItem`, `Hero.Footer` → `Hero.Foot`, …)
- convert props (`renderAs` → `as`, `loading` → `isLoading`, numeric spacing/text sizes → string unions, `textAlign="center"` → `textAlign="centered"`, …)
- flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`)
- restructure patterns bestax models differently (`Table.Container`, Navbar dropdowns, `Form.Help`, icon-font children → `<Icon name=…>`)
- migrate stylesheets: CSS imports converge on `@allxsmith/bestax-bulma/bestax.css`, and SCSS files move from Bulma 0.9's `@import` + `$var !default` overrides to `@use 'bulma/sass' with (…)` plus `@use '@allxsmith/bestax-bulma/scss/extras'`
- update `package.json`: remove `react-bulma-components`, add `@allxsmith/bestax-bulma`, bump `bulma` to `^1`, and swap the dead `node-sass` for dart `sass` (no install is ever run)
- update `package.json`: remove the source library, add `@allxsmith/bestax-bulma`, raise a declared pre-1.0 `bulma` to `^1` (adding it only when your sources import `bulma/…` directly — otherwise it arrives transitively), and swap the dead `node-sass` for dart `sass` (no install is ever run). Migrating **rbx** is what frees an app from Bulma 0.7.5: rbx pinned it as a _direct_ dependency, so the app could not choose its own Bulma version at all. The four Bulma extensions rbx also pulled in (`bulma-badge`, `bulma-divider`, `bulma-pageloader`, `bulma-tooltip`) are **reported rather than removed** — bestax replaces all four, but a manifest entry is a deliberate declaration and your own Sass may import them

Anything without a safe automatic conversion is left in place with a `// TODO(bestax-migrate): …` comment, and the run ends with a report of every TODO by file and line. TODOs are expected output, not errors — resolve them with the [migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:
Anything without a safe automatic conversion is left in place with a `// TODO(bestax-migrate): …` comment, and the run ends with a report of every TODO by file and line. TODOs are expected output, not errors — resolve them with the migration guide ([react-bulma-components](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components), [rbx](https://bestax.io/docs/guides/getting-started/migration/rbx)), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:

```bash
npx skills add https://github.com/allxsmith/bestax --skill bestax-migrate
Expand All @@ -69,7 +74,7 @@ npx skills add https://github.com/allxsmith/bestax --skill bestax-migrate
2. Search for `TODO(bestax-migrate)` and resolve each comment
3. Typecheck/build and review the rendered app

Full walkthrough: [react-bulma-components migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components).
Full walkthrough: [react-bulma-components migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components) · [rbx migration guide](https://bestax.io/docs/guides/getting-started/migration/rbx).

## Hardened by default

Expand Down Expand Up @@ -100,4 +105,4 @@ Full disclosure of every field and control: [Telemetry guide](https://bestax.io/

## License

MIT © Alex Smith
Source code licensed MIT
Loading
Loading