shadcn-maestro
v0.7.0
Published
CLI and Claude Code/Codex plugins that change one page of an existing web app with shadcn, checked by an independent reviewer and a browser.
Readme
[!NOTE] Existing applications only. shadcn-maestro never creates a project, and it never changes an application source file before your explicit "yes".
Why it exists
Coding agents are quick to redesign a screen, but they misread pages, touch screens nobody asked about and stop at "it compiles". shadcn-maestro puts a map, a second opinion, an explicit approval and a browser check between the request and the commit.
| Without shadcn-maestro | With shadcn-maestro | | --- | --- | | The agent guesses what the page does | Each region is annotated with evidence and reviewed by another session | | Changes spill into screens nobody asked about | The proposal lists the files, the other screens affected and the global effects | | Edits start as soon as the prompt ends | No application source file changes before your "yes" | | "It compiles" is the finish line | The page is opened in a browser and the app's own checks run | | Commits and pushes happen on their own | It asks before committing and never pushes |
Built with: TypeScript on Node 24, the TypeScript compiler API for code extraction, Ajv for JSON Schema validation, shadcn and agent-browser as global prerequisites, and plugin packaging for Claude Code and Codex.
How it works
Everything in the box
Prerequisites
| Tool | Version | Why |
| --- | --- | --- |
| Node.js | >=24.2 | Runs the shadcn-maestro CLI |
| npm | bundled with Node | Installs the package and the prerequisites |
| agent-browser | latest | Browser observation and verification |
| shadcn | latest | Adds the components to your app |
| Chrome | optional | Browser review; without it, the review is reported as not done |
| Claude Code or Codex | current | Hosts for the plugins |
shadcn-maestro reviewer checks agent-browser and shadcn against npm and stops until they are up to date. Install them first:
npm i -g agent-browser@latest shadcn@latestRecent npm versions may skip the postinstall script of agent-browser. That is fine: the native binaries ship in the agent-browser package.
If npm fails with EEXIST: file already exists on /opt/homebrew/bin/agent-browser, another install (for example Homebrew) already owns that binary. Remove the other install, or the stale link, and run the command again.
Install
npm i -g shadcn-maestroThis puts shadcn-maestro on your PATH. Chrome is never downloaded. Without Chrome, the browser review is reported as not done.
From a clone:
git clone https://github.com/Brennoaltair/shadcn-maestro.git && cd shadcn-maestro
npm ci
npm run build
npm install -g .Plugins
The plugins need the shadcn-maestro CLI from Install on your PATH, at the same version. Then add this repository as a plugin marketplace and install the shadcn-maestro plugin in your host.
Claude Code
claude plugin marketplace add Brennoaltair/shadcn-maestro
claude plugin install shadcn-maestro@shadcn-maestroOpen a session in your app's directory and run /shadcn-maestro:design-apply.
Codex
codex plugin marketplace add Brennoaltair/shadcn-maestro
codex plugin add shadcn-maestro@shadcn-maestroOpen a session in your app's directory and run $design-apply (it also appears in the /skills menu). Before the first review, add the Codex sandbox rules.
Update the plugins
After a new release, update the global package with npm i -g shadcn-maestro, then the marketplace and the plugin:
claude plugin marketplace update shadcn-maestro
claude plugin update shadcn-maestro@shadcn-maestro
codex plugin marketplace upgrade shadcn-maestroWhen the plugin version did not change, plugin update keeps the installed copy. To get the latest skill anyway, reinstall: claude plugin uninstall and claude plugin install shadcn-maestro@shadcn-maestro, or codex plugin remove and codex plugin add shadcn-maestro@shadcn-maestro. Open a new session afterwards.
How the plugins run
Both plugins are named shadcn-maestro and come from the marketplace shadcn-maestro, this repository. They carry no copy of the CLI: their binaries run the global shadcn-maestro package, and stop with exit 127 and the install command when it is missing or is another version than the plugin's.
| Plugin binary | What it does |
| --- | --- |
| shadcn-maestro | Runs the global shadcn-maestro CLI, checking that its version matches the plugin |
| shadcn-maestro review | Opens the independent reviewer session (claude -p or codex exec), optionally with --url <app-url> for browser evidence |
Codex sandbox rules
The independent reviewer in Codex runs in a sandbox without network. Add these lines to ~/.codex/rules/shadcn-maestro.rules so its commands can run outside it (shadcn-maestro review prints the lines that are missing, with the paths filled in, and exits 3). The agent-browser rules are pinned to the absolute path of the agent-browser on your PATH (command -v agent-browser), so no other agent-browser matches.
prefix_rule(pattern=["shadcn-maestro", "reviewer", "review", "--input"], decision="allow")
prefix_rule(pattern=["<agent-browser path>", "open"], decision="allow")
prefix_rule(pattern=["<agent-browser path>", "snapshot"], decision="allow")
prefix_rule(pattern=["<agent-browser path>", "screenshot"], decision="allow")
prefix_rule(pattern=["<agent-browser path>", "close"], decision="allow")[!WARNING] Any Codex session can call that absolute binary with those subcommands outside the sandbox, so
opencan reach any URL andscreenshotcan write any path. Remove the rules when not reviewing.
Use
Open your app's directory in the host and invoke the skill, then describe the change you want:
/shadcn-maestro:design-apply turn the settings page into tabs with a card per section| Step | What happens | Who acts |
| --- | --- | --- |
| 1 | Maps the app and shows the stack and its pages | Agent, shadcn-maestro reviewer |
| 2 | Asks which page to work on, an existing one or a new one, and which mode: redesign (recommended) or conservative | You |
| 3 | Analyzes the page and has an independent reviewer session confirm its reading | Agent, shadcn-maestro review |
| 4 | Reads the 20 UX laws and shows a proposal: layout, shadcn components, files to change, other screens affected, global effects and how each law applies | Agent |
| 5 | Waits for your "yes". No application source file changes before it | You |
| 6 | Applies the change with your shadcn | Agent, shadcn |
| 7 | Checks the page in the browser and measures the UX items that have a numeric limit | Agent, agent-browser |
| 8 | Checks the UX report of all 145 checklist items, asking you about each failure, then runs the app's typecheck, lint, test and build scripts that exist | Agent, shadcn-maestro ux-check, you |
| 9 | Reports what changed, what passed and what was not done, then asks before committing | Agent, you |
It never pushes.
CLI
shadcn-maestro <command> [--cwd <path>] [--json]| Command | What it does |
| --- | --- |
| shadcn-maestro help | Show usage |
| shadcn-maestro reviewer [--screen <id>] | Map the whole application; print a summary or one screen |
| shadcn-maestro reviewer annotate --input <file\|-> | Submit a semantic annotation (JSON); it is saved as pending review |
| shadcn-maestro reviewer review --input <file\|-> | Record an independent verdict (JSON) for an exact annotation revision |
| shadcn-maestro verify --screen <id> --input <file\|-> | Verify official component files, dependencies and their JSX use without modifying the app |
| shadcn-maestro ux-check --screen <id> --input <file\|-> | Check a UX laws report against the 145 checklist items and the browser measurement |
| Flag | Meaning |
| --- | --- |
| --cwd <path> | Application directory (default: the current one) |
| --json | Print one envelope: {schemaVersion, command, status, data, issues, nextAction} |
| --screen <id> | Print one screen instead of the summary |
| --input <file\|-> | Read the annotation or review JSON from a file or stdin |
| Exit code | Status | Meaning |
| --- | --- | --- |
| 0 | ok | Completed |
| 2 | error | Invalid input or failed operation |
| 3 | pending | Blocked pending a condition |
cd my-app
shadcn-maestro reviewer # summary of stack and screens
shadcn-maestro reviewer --screen <id> --json # one screen, as a JSON envelopeThe map is written to .shadcn-maestro/ in the application.
Verify applied components
After applying the approved proposal, run:
shadcn-maestro verify --cwd ./my-app --screen screen:app/page.tsx --input ./my-app/.shadcn-maestro/verification.json --jsonManifest: { "components": ["button", "card"], "mode": "conservative" }. Use redesign to check the real nova tokens and Geist font setup too. The plugin includes this manifest in the proposal and requires verification before declaring completion.
The verifier checks configuration and aliases, the configured stylesheet's import, official files after shadcn's transformations, installed dependencies and resolved JSX use in the selected screen. Missing, changed or unused components fail with exit 2. Unavailable evidence, an unsupported tool API, ambiguous usage or changing sources return pending (exit 3). A pass returns exit 0 with hashes and evidence. It never installs, repairs or overwrites the app.
The preview adapter supports shadcn 4.22.0 and 4.22.1; other versions remain pending until their API is checked. Static verification does not replace browser observation or the app's own checks. See verify documentation.
Check the UX laws
The plugin follows the 20 UX laws in ux-laws/ (Fitts, Hick, Jakob, Miller, Doherty and others) on every page it changes. After the browser check, the agent measures the page with ux-measure.js and writes a report with all 145 checklist items, then runs:
shadcn-maestro ux-check --cwd ./my-app --screen screen:app/page.tsx --input ./my-app/.shadcn-maestro/ux-report.json --jsonA missing item, an item without evidence, a failed item or a status that differs from the measurement fails with exit 2. A missing, stale or incomplete measurement returns pending (exit 3). The agent asks you about each failed item, one at a time: fix it or accept it. The delivery is complete only when ux-check is ok. Format and measured rules: ux-laws.md.
Dependency check
Before mapping, shadcn-maestro reviewer compares agent-browser --version and shadcn --version with the latest version on npm.
| Issue | Status | When |
| --- | --- | --- |
| dependency_missing | pending (exit 3) | agent-browser or shadcn is not on PATH |
| dependency_outdated | pending (exit 3) | Either is older than the npm latest |
| dependency_check_skipped | mapping continues | npm cannot be reached |
When blocked, it maps nothing and prints npm i -g agent-browser@latest shadcn@latest.
Issue codes
| Code | Meaning |
| --- | --- |
| astro_not_supported | The app is an Astro project |
| invalid_package_json | package.json cannot be read |
| manager_conflict | Evidence for more than one package manager |
| unknown_screen | --screen names a screen that is not in the map |
| map_update_failed | The map could not be written |
| disputed | The reviewer disputed an annotation |
| insufficient_evidence | The reviewer could not confirm an annotation |
Supported stacks
| Stack | Routing | Supported |
| --- | --- | --- |
| Next.js | App Router and Pages Router | ✅ |
| Vite | With or without React Router | ✅ |
| React Router | Framework mode | ✅ |
| TanStack Start | File routes | ✅ |
| Laravel | Inertia (React) | ✅ |
| React | Manual setup | ✅ |
| Astro | | ❌ (astro_not_supported) |
When the app has no components.json, the proposal includes the shadcn "Existing Project" setup for its stack.
Development
npm ci
npm ci --prefix site
npm run checkThis runs typecheck, lint, the plugin build, all CLI tests, and the site's typecheck and tests. Narrower scripts:
| Script | What it runs |
| --- | --- |
| npm run build | Compiles src/ to dist/ |
| npm run build:plugin | Builds and assembles both plugins |
| npm run typecheck | tsc without output |
| npm run lint | ESLint |
| npm run test:unit | Tests named unit: |
| npm run test:integration | Tests named integration: |
| npm run check:site | Site typecheck and tests, including a consumer compilation test |
The procedure for trying both plugins in real hosts is in test/hosts/acceptance.md.
Docs site
The docs site lives in site/, its own npm package outside the root lint. It documents the CLI, the agent, every shadcn component (Base UI and Radix demos), the AI Elements, Forms, Utilities, @shadcn/react and @shadcn/helpers. Each page is also served as Markdown for agents (<page>.md, llms.txt, llms-full.txt).
cd site
npm ci
npm run dev # local site
npm test # sync and Markdown plugin tests
npm run build # Markdown audit and production build
npm run sync # pull the components from the shadcn registry and report what changed upstreamThe weekly update is the shadcn-docs-update skill (.claude/skills/shadcn-docs-update/), run on demand by a Claude Code agent. It brings new, changed and removed upstream pages into the site, writes a report to shadcn-updates/ and never commits.
Architecture overview
One npm package, shadcn-maestro, ships the CLI. Two plugins, both named shadcn-maestro, carry no copy of it: their binaries run the global package, and expose the design-apply skill and the shadcn-maestro review launcher. The CLI only reads the application and writes .shadcn-maestro/map/. The agent writes to the application, with shadcn and its own edits, after your approval. Before choosing components, it reads the docs site (site/), which a weekly agent keeps in line with shadcn.
graph TD
H[Human in a terminal] --> CLI[shadcn-maestro CLI]
S[Skill design-apply<br/>/shadcn-maestro:design-apply · $design-apply] --> CLI
S --> SH[shadcn on PATH]
S --> AB[agent-browser on PATH]
S --> RV[shadcn-maestro review]
S -.reads components.-> DOCS[shadcn-maestro docs<br/>shadcn-maestro-docs.vercel.app]
RV --> HS[Separate host session<br/>claude -p · codex exec]
HS --> CLI
HS -.observation.-> AB
CLI --> DEP[dependencies.ts<br/>npm version check]
CLI --> DET[project.ts<br/>stack detection]
CLI --> MAP[map/*<br/>extraction, routes, store, refresh]
CLI --> ANN[annotate · review · identity]
MAP --> STORE[(.shadcn-maestro/map/)]
ANN --> STORE
SH --> APP[(User application)]
S --> APPAgent flow: map → page choice → --screen → annotations → shadcn-maestro review → proposal → "yes" → shadcn and edits → app running + agent-browser → checks → report → commit question.
| Path | Role |
| --- | --- |
| src/cli.ts | Command routing, JSON envelope, exit codes |
| src/dependencies.ts | Compares agent-browser and shadcn with npm |
| src/project.ts | Stack and package manager detection |
| src/reviewer.ts | The shadcn-maestro reviewer command and its summaries |
| src/map/extract.ts | Source extraction with the TypeScript compiler API |
| src/map/routes-*.ts | Route adapters per stack |
| src/map/store.ts, refresh.ts | Atomic store under .shadcn-maestro/map/ and hash-based refresh |
| src/map/annotate.ts, review.ts, identity.ts | Annotations, independent verdicts, session identity |
| schemas/ | JSON Schemas for the map, annotations and reviews |
| plugins/claude, plugins/codex, plugins/shared | Plugin binaries, host adapters, the design-apply skill |
| site/ | The docs site (Vocs), its own npm package, published to https://shadcn-maestro-docs.vercel.app on every merge to main |
| .claude/skills/shadcn-docs-update | The weekly agent's skill that brings the docs site in line with shadcn |
Contributing
This project follows a spec-driven harness. Read CLAUDE.md and .harness/rules.md before any change.
| Rule | What it means |
| --- | --- |
| Gitflow | main is protected by convention: never push to it. Branch from main with a typed prefix (feat/, fix/, docs/, chore/), open a pull request and wait for review. Merge, release and deploy need the maintainer's approval. |
| Spec first | Features start as a spec in .specs/features/<feature>/spec.md, then design.md and tasks.md. No implementation before the spec and the plan are approved. |
| Commits | Conventional Commits, in English, imperative, with a scope: feat(cli): ..., fix(plugins): ..., docs(spec): ..., chore(release): .... One atomic commit per task. |
| Records | In the same commit: a log in .harness/logs/YYYY-MM-DD-<topic>.md (O que mudou, Por quê, Como verificar) and an entry in .harness/changelog.json. Infra, contract and eval choices go to .harness/decisions/. |
| Checks | npm run check passes before a pull request. Tests and approved requirements are never weakened to make code pass. |
Maintainers
| | Role | | --- | --- | | Brenno A (@Brennoaltair) | Author and maintainer |
Issues and pull requests are welcome.
License
MIT © 2026 Brenno A
