Scaffolds an admin dashboard (CRUD tables, forms, auth-gated pages, basic analytics) directly into an existing web app project by detecting its schema, auth, framework, and API layer, then asking the...
Generates working dashboard code for an existing project instead of a generic templated one, by first understanding the actual project (its schema, auth system, framework, and API layer) and only asking the user about things that genuinely can't be inferred.
Most "generate me a dashboard" requests fail in one of two ways: either Claude asks a long intake questionnaire before writing anything (annoying โ most answers are visible in the codebase already), or it writes generic code that ignores the project's real stack (annoying differently โ now it has to be rewritten by hand). This skill splits the work so detection does as much as possible, and the remaining questions get sharper each time the skill runs, whether in this project or a new one.
Run these in order. Each step's output feeds the next โ don't skip ahead or ask the user things detect.js can answer itself.
node scripts/detect.js <project-root>
Scans the target project for its schema source (Prisma, Supabase, Drizzle, raw SQL), auth provider (NextAuth/Auth.js, Clerk, Supabase Auth, custom), framework/router (Next.js app router vs pages router, Remix), and API layer (tRPC, REST route handlers, GraphQL, Supabase client calls direct from components). Writes detected.json to stdout and to .dashboard-agent/detected.json in the project. Each finding carries a confidence (high/medium/low) โ treat low the same as "unknown" downstream.
If detect.js can't find a project marker (no package.json) at the given path, stop and ask the user for the correct project root rather than guessing.
node scripts/load-memory.js <project-root>
Reads two sources and merges them:
<project-root>/.dashboard-agent/qa.json โ answers this exact project has given before (e.g. "use soft deletes: yes"). These always win over global defaults, since they're specific to this codebase.memory/global-patterns.md (in this skill's own directory, not the project's) โ defaults learned across every project this skill has touched, each with a confidence count. A pattern only counts as "answered" if it's been confirmed enough times โ see the file's own header for the current threshold.Outputs merged knowledge as JSON. This is what makes repeat use faster: the fifth Next+Prisma dashboard this skill builds should ask close to nothing.
node scripts/ask.js <path-to-detected.json> <path-to-memory.json>
Compares detection + memory against the fixed list of decisions a dashboard actually needs (which entities to expose, pagination vs infinite scroll, soft-delete vs hard-delete, which fields are read-only, whether analytics charts are wanted at all). Anything already high-confidence from step 1 or already answered per step 2 is filtered out. Prints the remaining questions as JSON.
Take these questions and ask them yourself, using ask_user_input_v0 if that tool is available (these are exactly the kind of short, multiple-choice preference questions it's built for) โ don't just print ask.js's JSON at the user. If a question has more than 4 natural options or needs free text (like "which fields should be read-only?"), ask it in plain prose instead. Batch everything into as few turns as possible; don't ask one question, wait, ask another.
If ask.js returns zero questions, say so briefly and move straight to generation โ don't manufacture questions to seem thorough.
node scripts/generate.js <project-root> <path-to-detected.json> <path-to-answers.json>
Combines detection + memory + the user's fresh answers into one answer set, then renders templates/*.tsx.tmpl into real files under the project (default app/dashboard/ for app-router projects, pages/dashboard/ for pages-router โ generate.js decides based on detected.json). It picks the right adapter logic (Prisma queries vs Supabase client calls, etc.) per reference/stack-adapters.md. Existing files are never overwritten silently โ if a target path exists, generate.js writes <name>.generated.tsx alongside it and says so, so the user can diff and merge by hand.
On a Prisma project, generate.js also parses prisma/schema.prisma (scripts/parse-schema.js) and, for any entity that matches a model, builds real typed form fields and table columns instead of a TODO stub (scripts/form-fields.js): enum and relation fields become working <select>s (the relation options come from an actual findMany() call), booleans become checkboxes, dates/JSON get the right widget, the submit action coerces FormData strings into real numbers/booleans/dates/JSON, and a generated schema.ts (Zod) validates the coerced data before it ever reaches Prisma. Matched entities also get a search box, sortable column headers, and a back-relation count column (e.g. "Comments count") on the list view, and every mutation (create/update/delete/soft-delete) calls revalidatePath() so the list reflects changes immediately and surfaces a friendly message on a duplicate-@unique value instead of a raw Prisma error. Every entity โ schema-aware or not โ gets a confirm-before-delete dialog via a small shared client component. reference/schema-heuristics.md documents exactly which fields get auto-excluded (db-generated ids, @updatedAt, anything defaulting to now(), the soft-delete marker column) and why โ read it if a generated form looks wrong for a particular schema shape, since most "why did it skip that field" questions are answered there. If the entity name doesn't match any model, or the project isn't on Prisma, generation falls back to the original TODO-stub behavior (still with the confirm dialog) โ this is intentional; a wrong guess would be worse than a clearly marked gap. Note the Zod file needs the zod package in the target project โ mention it if package.json doesn't already have it.
Review the generated file list with the user before considering the task done. Point out anything generate.js flagged as a guess (e.g. it couldn't find a "name" or "title" field to use as a row label and fell back to the primary key), and mention when an entity got the schema-aware treatment vs. the TODO fallback (the JSON output's schema_aware_entities list tells you which).
node scripts/update-memory.js <project-root> <path-to-answers.json> <path-to-detected.json>
Writes the fresh answers into the project's local qa.json (so this project never gets asked the same thing twice) and bumps confidence counts in this skill's memory/global-patterns.md for any pattern that matches what other projects have also chosen (so the defaults keep converging across the user's whole body of work). Run this even if the user only answered some of the questions โ partial progress is still worth remembering.
npm install or start dev servers. Mention what new dependencies (if any) the generated code assumes, and let the user install them.