From apps-generation
Generates self-contained React applications for interactive output. Triggered when the user asks to "create a dashboard", "build an interactive report", "make a comparison view", "generate a timeline", "create a web app", "interactive dashboard", "KPI dashboard", "side-by-side comparison", "milestone timeline", or requests any interactive/visual output format.
How this skill is triggered — by the user, by Claude, or both
Slash command
/apps-generation:jsx-generatorThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate self-contained React applications using Vite + TypeScript + Tailwind CSS + shadcn/ui (https://ui.shadcn.com). Apps must work as `file://` — no server required, no internet required, shareable as a folder. **Every app MUST be built via `scripts/build.sh`** — there is no alternative method. Do not create CDN-based HTML files as a substitute.
Generate self-contained React applications using Vite + TypeScript + Tailwind CSS + shadcn/ui (https://ui.shadcn.com). Apps must work as file:// — no server required, no internet required, shareable as a folder. Every app MUST be built via scripts/build.sh — there is no alternative method. Do not create CDN-based HTML files as a substitute.
apps-generation/.mcp.json — use it to look up component APIs, props, and examples during buildsSee references/components.md for the full component reference with chart examples, sidebar patterns, and layout diagrams.
Before generating output, check that {WORKING_DIR}/.reporting-resolved/brand-config.json exists. If it does not, tell the user: "The branding plugin is required but has not run. Please install the branding plugin and run /reporting-plugins:brand first." Do not produce unbranded output.
If a JSON data file was generated earlier in this session (in output/text/), read it as the canonical data source to ensure cross-format parity. If no prior JSON exists, use data from the conversation context directly.
Read .reporting-resolved/brand-config.json for brand values. Read logo from .reporting-resolved/logo.png (if exists).
Node.js 20+ is required. If not available, report error with install instructions.
output/app/{app-name}/output/app/q1-dashboard/build.sh — do not create manually):
dist/ — built app, ready to open via file:// ← this is the deliverabledist/index.html — entry point the user opens in their browserdist/assets/*.js — bundled JavaScriptsrc/ — source code for rebuildspackage.json — dependencies for npm install && npm run buildvite.config.ts — Vite configurationtsconfig.json, tsconfig.app.json — TypeScript configcomponents.json — shadcn/ui configdata.json — the data used to generate the appAn output directory without dist/index.html is not a valid deliverable. Raw .jsx or .tsx files alone cannot be opened in a browser.
Select template based on intent keywords in the user's request:
| Template | Trigger keywords | Layout |
|---|---|---|
| dashboard | "dashboard", "KPIs", "metrics", "monitor", "overview" | Header + KPI cards grid + chart sections + data table |
| report | "report", "memo", "analysis", "brief", "summary" | Sidebar TOC + scrollable sections + figures |
| comparison | "compare", "benchmark", "vs", "side-by-side", "tier" | Split panes + delta highlights + radar/bar charts |
| timeline | "timeline", "milestones", "audit trail", "history", "roadmap" | Vertical timeline + expandable detail cards |
If ambiguous, default to dashboard for data-heavy requests or report for narrative-heavy requests.
CRITICAL: Every invocation of this skill MUST produce a fully built Vite application by running scripts/build.sh. There is NO alternative build method. Specifically:
.jsx, .tsx, or .js files directly to output/app/ as the deliverable.build.sh. CDN-based HTML files require internet access and violate the self-containment requirement.<script type="text/babel">) as a build substitute.dist/index.html — it must be produced by npm run build inside build.sh.The ONLY valid build method is: run scripts/build.sh, which uses Vite to bundle everything into a self-contained dist/ with no external dependencies.
Why: The output must work offline via file:// with zero network requests. CDN-based approaches fail without internet and violate the self-containment contract.
The plugin ships with a pre-initialized template base (_base/base.tar.gz) — a fully scaffolded Vite + React + shadcn project. This avoids the 2-5 minute cold-start of npm create vite + npx shadcn init.
Follow these steps in exact order. Do not skip any step.
Write the app's data to a JSON file (e.g., data.json) in the working directory. This file will be injected into the app by the build script.
Write any custom React components (App.tsx, pages, etc.) to a temporary staging directory (e.g., _staging/src/). Do NOT write them to output/app/ — that directory is populated by build.sh. The build script copies the selected template first, then custom source files from the staging directory override the template.
IMPORTANT: Do not write source files directly to output/app/ and consider the job done. Source files alone are not a deliverable. Continue to step 3.
Execute the build script. This is the mandatory step that produces the final app:
bash ${CLAUDE_PLUGIN_ROOT}/skills/jsx-generator/scripts/build.sh \
--template dashboard \
--data $(pwd)/data.json \
--brand $(pwd)/.reporting-resolved/brand-config.json \
--logo $(pwd)/.reporting-resolved/logo.png \
--output $(pwd)/output/app/my-dashboard \
--plugin-dir ${CLAUDE_PLUGIN_ROOT}/skills/jsx-generator
IMPORTANT: Use absolute paths ($(pwd)/...) for --output, --data, --brand, and --logo. Relative paths will resolve incorrectly because the script changes directories internally.
The build script performs these steps automatically:
_base/base.tar.gz into a temp working directorysrc/data.json into public/public/base: './' in vite.config.ts (critical for file:// access)npm run build → produces dist/scripts/verify-self-contained.sh on dist/dist/, src/, package.json, vite.config.ts, tsconfig.json to the output pathTypical build time with pre-initialized base: ~20 seconds.
After build.sh completes, verify the output directory contains the required structure:
# All of these must exist — if any is missing, the build failed
test -f output/app/my-dashboard/dist/index.html || echo "FAIL: no dist/index.html"
test -d output/app/my-dashboard/dist/assets || echo "FAIL: no dist/assets/"
ls output/app/my-dashboard/dist/assets/*.js >/dev/null 2>&1 || echo "FAIL: no JS bundle"
test -f output/app/my-dashboard/package.json || echo "FAIL: no package.json"
test -d output/app/my-dashboard/src || echo "FAIL: no src/"
# Self-containment: MUST NOT have CDN/external script tags
! grep -q 'unpkg.com\|cdn.tailwindcss\|esm.sh\|cdnjs.com\|jsdelivr.net\|babel.*standalone' \
output/app/my-dashboard/dist/index.html || echo "FAIL: dist/index.html contains CDN references"
If validation fails, diagnose the build error and retry. Do not deliver an output directory that lacks dist/index.html or that contains CDN references.
Confirm the output path and list the key files:
dist/index.html — open this in a browser (works via file://)src/ — source code for future modificationdata.json — the data powering the appEnforced by scripts/verify-self-contained.sh. ALL must pass:
data.json — fetched with relative ./data.json, no API calls./ relative. Vite base: './' is critical.#section-name)index.html, assets/ directoryMap brand tokens to Tailwind CSS custom properties:
/* In tailwind config or global CSS */
:root {
--brand-primary: {colors.primary};
--brand-accent: {colors.accent};
--brand-text: {colors.text};
--brand-surface: {colors.surface};
--brand-heading: {semantic.heading_color};
--brand-positive: {colors.positive};
--brand-negative: {colors.negative};
--brand-border: {semantic.border_color};
--brand-card-radius: {components.card_radius};
--brand-card-shadow: {components.card_shadow};
}
.reporting-resolved/logo.png)<title>) and footerEach template defines a JSON schema in references/data-shapes.md. Prepare data.json matching the chosen template's schema.
Include meta.sources in data.json for provenance tracking:
{
"meta": {
"title": "Dashboard Title",
"generated_at": "2026-04-04T14:30:00Z",
"confidential": true,
"sources": ["source-1", "source-2"]
},
"data": { ... }
}
When dependencies need updating (new shadcn components, Vite version bump):
bash ${CLAUDE_PLUGIN_ROOT}/skills/jsx-generator/scripts/rebuild-base.sh
This recreates _base/base.tar.gz with fresh node_modules, updated shadcn components, and latest Vite config.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub equiforte/reporting-services-plugins --plugin apps-generation