Repository navigation
Migrate 20 MUI X implementations to MUI X 9 and the adaptable-code convention #12267
Description
Goal
Migrate 20 MUI X implementations of the catalogue from the MUI X 7 API to MUI X 9.16 (React 19, Material 9.5) and restructure each to the adaptable-code convention, on a gemini/* branch. The pipeline then takes every file through its own render, review and merge (impl-generate's adopt mode, in progress), so this batch measures whether a Gemini migration plus an Opus review is cheaper than a full Opus regeneration for the remaining 300 files. Nothing from this branch is merged directly.
Context
- The render stack moved to MUI X 9.16 in deps(js): bump MUI X Charts to 9.16 with React 19 and Material 9.5 #12243. Of 323
muix.tsxfiles, 164 no longer bundle (the@mui/x-charts/ChartContainerpath is gone), 157 render differently (legendhiddenprop, v7 legend position and styling, v7 axis and font-size props, removed CSS classes; 67 with a blank axis), 2 render unchanged. - The current rules for MUI X code are
prompts/library/muix.md; its section "MUI X v9 API — the pinned version" lists every API change that matters, and "The harness contract" says how a.tsxfile connects to the render harness. The adaptable-code convention isprompts/adaptable-code.md(the JavaScript form: one record array as the data block, role constants, plot code that reads only the constants); the "Data block" section ofprompts/library/muix.mdhas the MUI X example. The general rules ofprompts/plot-generator.mdandprompts/default-style-guide.mdapply (canvas, palette, imprint, sizing in CSS px, animation off). - Each spec lives in
plots/<spec>/specification.md; its current implementation isplots/<spec>/implementations/javascript/muix.tsx. The per-spec measurement of the 20 files is in the table below (which v7 feature each file uses;blank_axis: yesmeans the file renders on 9 with an empty axis today). - The harness renders a file locally without credentials:
ANYPLOT_THEME=light node automation/js-render/render.mjs plots/<spec>/implementations/javascript/muix.tsxand the same withANYPLOT_THEME=dark, run from the repository root; it writesplot-light.png/plot-dark.png(3200×1800) next to the file. Node 24 and the rootpackage.jsondependencies are needed; install them the way.github/actions/setup-nodedoes:npm ciat the repository root (the root usespackage-lock.json, not yarn;app/is the yarn project) andnpx playwright install chromium. - The pipeline's render check:
PYTHON_DOTENV_DISABLED=1 uv run python -c "from core.canvas import check_png; print(check_png('plots/<spec>/implementations/javascript/plot-light.png', 'muix'))"must report ok for both themes.
| spec | result on MUI X 9 | blank axis | removed CSS classes | legend hidden prop | v7 legend position | v7 legend styling | v7 axis props | v7 font-size props |
|---|---|---|---|---|---|---|---|---|
| alluvial-basic | fails to bundle | n/a | no | no | no | no | no | no |
| calibration-beer-lambert | fails to bundle | n/a | no | no | yes | yes | no | no |
| datamatrix-basic | fails to bundle | n/a | no | no | no | no | no | no |
| genome-track-multi | fails to bundle | n/a | no | no | no | no | no | no |
| horizon-basic | fails to bundle | n/a | no | no | no | no | no | no |
| map-marker-clustered | fails to bundle | n/a | no | no | no | no | no | no |
| phase-diagram | fails to bundle | n/a | no | no | yes | yes | no | no |
| recurrence-basic | fails to bundle | n/a | no | no | no | no | no | no |
| sequence-logo-basic | fails to bundle | n/a | no | no | no | no | no | no |
| ternary-density | fails to bundle | n/a | no | no | no | no | no | no |
| area-basic | changed | yes | yes | yes | no | no | no | yes |
| confusion-matrix | changed | yes | no | yes | yes | no | yes | yes |
| hexbin-basic | changed | yes | no | yes | yes | no | no | yes |
| line-stepwise | changed | yes | yes | yes | no | no | no | no |
| scatter-color-mapped | changed | yes | no | yes | yes | no | no | no |
| acf-pacf | changed | no | no | yes | no | no | no | no |
| calibration-curve | changed | no | yes | yes | no | no | no | yes |
| gauge-basic | changed | no | no | no | no | no | no | no |
| line-loss-training | changed | no | yes | no | yes | no | no | no |
| scatter-annotated | changed | no | no | no | yes | no | no | yes |
Steps
- Set up the harness once and render one of the two unchanged files (for example
gauge-basic) in both themes to confirm the local setup works. - For each of the 20 specs, in the table's order, one commit per spec (
feat(muix): migrate <spec> to MUI X 9): read the specification and the current file, port the API to MUI X 9 asprompts/library/muix.mddescribes, restructure the file to the convention (# Datablock as one record array, role constants, no hard-coded categories, counts or palette slices in the plot code; the header comment and the imprint stay), keep the existing data scenario and visual design unless the spec or the convention forces a change, render both themes, run the canvas check, and look at both PNGs: axes, ticks, legend, labels and the imprint must be visible and inside the canvas, with no blank axis and no cropped bottom. - Open the draft PR with a table: spec, what changed (API, convention, data), render result, anything you could not solve.
Constraints
- Change only the 20 files
plots/<spec>/implementations/javascript/muix.tsxnamed in the table. No metadata files, no PNGs or HTML committed (delete the render outputs before committing;git statusmust show only the 20.tsxfiles), no other plots, no prompts, no workflows, no changelog fragment (catalogue-only changes are exempt). - Keep the header comment's
Quality:andUpdated:lines as they are; the pipeline rewrites them. - Keep each file self-contained the way the harness contract requires: a default-exported React component, no manual mount, no network, no animation, sizes from
window.ANYPLOT_SIZE, colours fromwindow.ANYPLOT_TOKENS. - The scenario and the visual variant of the old file stay (same chart type, same story, same data unless it violates the convention or the spec). This is a migration, not a redesign. Where MUI X 9 cannot express something the old file did (read "When MUI X can't express the spec" in the library prompt), choose the documented fallback and say so in the PR table.
- Branch
gemini/<issue number>-muix-9-batch1fromorigin/main; a draft PR only. The draft is reviewed by Claude and then fed to the pipeline file by file; it is closed afterwards without a merge, so do not expect CI on it to be the acceptance.
Acceptance
For every one of the 20 files, from the repository root:
ANYPLOT_THEME=light node automation/js-render/render.mjs plots/<spec>/implementations/javascript/muix.tsx
ANYPLOT_THEME=dark node automation/js-render/render.mjs plots/<spec>/implementations/javascript/muix.tsx
PYTHON_DOTENV_DISABLED=1 uv run python -c "from core.canvas import check_png; print(check_png('plots/<spec>/implementations/javascript/plot-light.png', 'muix'), check_png('plots/<spec>/implementations/javascript/plot-dark.png', 'muix'))"
Both renders exit 0 and both canvas checks are ok; the PNGs show every axis, tick label, legend and the imprint; none of the v7 names from prompts/library/muix.md (ChartContainer, ResponsiveChartContainer, DefaultChartsLegend, slotProps.legend.hidden, labelFontSize, tickFontSize, topAxis/leftAxis/bottomAxis/rightAxis, .MuiAreaElement-root, .MuiLineElement-series-*, .MuiBarElement-root, lineElementClasses, itemMarkWidth, markGap, itemGap) remains in the file (grep -nE over the 20 files finds nothing). The existing rules still win where they conflict with a mechanical port: the eight-hue palette order and "never recycle colours", the 3200×1800 canvas with sizes in CSS px, the imprint text, a legend outside the SVG that reserves its own height.
Decide yourself / report back
Decide yourself: how to express a v7 construct in v9 when the library prompt gives the mapping; small data edits the convention needs (for example moving inline arrays into the record array); whether a hidden legend becomes hideLegend or an explicit in-chart legend when the spec asks for one. Report back in the PR table instead of guessing: a spec whose chart type MUI X 9 cannot render at all, a file where keeping the old scenario would violate the spec, a render that passes the canvas check but still looks wrong to you, and any harness or dependency problem on your machine.
Activity
fix(muix): area-basic keeps its average reference line
fix(muix): recurrence-basic keeps its i = j identity line
fix(muix): acf-pacf derives its panel y limits from the data
fix(muix): gauge-basic stores its thresholds as two scalar columns
fix(muix): confusion-matrix takes its classes from both label columns
fix(muix): line-stepwise peak label claims only what the rule guarantees
fix(muix): calibration-beer-lambert labels series by their rows and d…
fix(muix): phase-diagram orders trajectories by time, no recycled col…
fix(muix): map-marker-clustered pads its extent and stops recycling c…
fix(muix): sequence-logo-basic gives unmapped letters unused palette …
fix(muix): genome-track-multi picks each track's renderer by rule
fix(muix): hexbin-basic derives its bin size from the data extent
MarkusNeusinger commentedon Oct 23, 2026
Done. Gemini migrated the 20 files on
gemini/12267-muix-9-batch1(draft #12275); Claude's review added 12 fixes; the pipeline adopted all 20 (PRs #12276–#12295, all merged 2026-10-23 20:41–21:58 UTC). Result: first-review scores 77–89 (mean 83), final 81–89 (mean 85.7), 19 of 20 needed one repair round; Claude cost $2.33 per pair against $3.15 for the Opus pilot.chore(muix): name gemini-4-argon as author of 20 adopted files (#12298)