skills/nocobase-prototype-repro/SKILL.md
Use when the task hands over a prototype to reproduce in NocoBase — an HTML file, an image, or a link, INCLUDING the published form "Build a NocoBase app — X … Match the layout and signature visuals of this reference prototype: <url>" — or when someone says a built page "doesn't match the prototype / looks monotone / is ugly". A prototype/URL being present is what triggers this skill, EVEN WHEN the same prompt also says "build an app" — the verb "build" does not cancel the prototype. Skip it only when there is NO prototype at all: a bare "build me a CRM/app" → nocobase-app- discipline; a one-field edit / rename → nocobase-ui-builder. It turns "here is the prototype, build it" into a faithful app — analyze prototype, native CRUD, the right native block per region, then a screenshot-vs-prototype visual loop. Native-first; JS only inside a native container; never a full-page JS block. Mechanics live in nocobase-ui-builder, nocobase-data-modeling, nocobase-app-discipline.
npx skillsauth add nocobase/skills nocobase-prototype-reproInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Turn a prototype + a one-line ask into a faithful NocoBase app. This is a meta / orchestration skill — it sequences nocobase-data-modeling + nocobase-ui-builder + nocobase-app-discipline and adds the two things that decide fidelity: a region → native-block mapping and a visual convergence loop. It does not re-teach the CLI; it routes to the sibling skills for mechanics and owns only the reproduction-specific judgment.
Hard gate (check before selecting this skill): there must be an actual prototype in hand — an HTML file, a screenshot, or a link to one — that you are matching against. No prototype, no fidelity gap → this is not the skill; a plain "build me an app / a page" request belongs to nocobase-app-discipline (whole system) or nocobase-ui-builder (single page/edit). Do not let this skill shadow the normal build flow.
Use when:
public/prototypes/... URL to curl) and wants it reproduced in NocoBase.Non-Goals — hand off, do not do here:
nocobase-data-modeling.nocobase-workflow-manage. ACL / permissions → nocobase-acl-manage. Plugin work → nocobase-plugin-development.nocobase-ui-builder directly. This skill is only worth its overhead when you are matching a prototype's look/behavior; for a mechanical surface edit, skip straight to ui-builder.nocobase-ui-builder's applyBlueprint.Hit one route, read its "first" doc, and only open the "then" docs when that route is still not enough. Sibling skills own the mechanics; the reference files here own the reproduction-specific judgment.
| Task shape | Read first | Then, as needed |
|---|---|---|
| Prototype handed over → reproduce end-to-end | spec-template.md (Phase 1 SPEC) | decomposition-grammar.md, block-recipes.md, gotchas.md, visual-loop.md |
| Existing page is monotone / ugly / off | visual-loop.md | block-recipes.md, gotchas.md |
| "Which block for this region?" | the Region → native block table below | decomposition-grammar.md, block-recipes.md |
| Need a JS body for a widget (KPI card, donut, leaderboard, due-soon alert, progress bar, trend, facet filter, card grid, …) | template-library/_index.md — 57 copy-pastable widget bodies, each with its $p input contract | block-recipes.md |
| Build/edit JS, flow-surfaces, popup, chart mechanics + runnable CLI | nocobase-ui-builder (its js.md / popup.md / chart.md / runjs-* / page-archetypes.md) | — |
| Collections / fields / relations | nocobase-data-modeling | — |
| Scope discipline, seed standards, naming, final report | nocobase-app-discipline | — |
| No prototype given, must author one | prototype-authoring.md | — |
| Hand the build to another agent from a one-line prompt | handoff.md | — |
| Full reference list | index.md | — |
Observed across many reproductions, in order of impact:
Do it in order. Stop at each ▣ CONFIRM gate and get the user's go-ahead before the next stage. For anything beyond a small single-region tweak, plan it as a multi-round conversation rather than one silent mega-run — the user wants to steer at each big step.
Phase 0 — Load the target. If you already have the prototype, skip to loading it; only author one if the user gave a business sentence with no prototype (prototype-authoring.md). Curl/read the prototype (the visual target; without it, builds degrade to a generic table or one big JS block). Check for an embedded <script type="application/nb-spec+json"> — if present, parse it as the authoritative spec (data model, per-region block, interactions, JS kernels) and honor its notes/jsKernels, instead of inferring. Load block-recipes.md + gotchas.md. Identify env; pass -e <env> -y on every nb api; get live page/block uids (flow-surfaces get / desktopRoutes), never trust uids from docs.
Phase 1 — Analyze & plan → SPEC ▣ CONFIRM. Produce a structured SPEC from spec-template.md (LLM judgment vs the rendered prototype, not a parser): data model; page list incl. the signature page(s); region → block map (prevents "everything is a table"); and the interaction checklist — go region by region and list every affordance (faceted/multi-select filters with counts, status pills, search, sort, fill-the-width grid, click→popup, inline edit, drag, live refresh); each maps to a recipe, anything non-native is flagged a JS kernel. Show the SPEC, get explicit confirmation.
Phase 2 — Model + native CRUD + seed ▣ CONFIRM. Build collections/fields/relations in one pass (nocobase-data-modeling); never edit while building. Stand up plain-native backend (Table + Filter + Add new + View/Edit; View opens a drawer with Details + association sub-tables via associationName + sourceId={{ctx.view.inputArgs.filterByTk}}). Seed every enum branch, ≥2 children/parent, all-English for public demos, and enough density (fill 1–2 months for a calendar — sparse reads as broken). Confirm CRUD works.
Phase 3 — Refine to the prototype, region by region. Native-first. For each signature region, pick its block and build it; add JS only for the kernel a native block can't express; never collapse the page into one JS block. One region at a time so each is verifiable. Mechanics + runnable snippets in block-recipes.md.
Phase 4 — Visual convergence loop ▣ CONFIRM + report. Render → screenshot → compare against the prototype with a vision-capable pass → concrete gap list → fix → re-shoot, until it matches. Reviewer may be the same agent self-checking or a separate vision model — let the model choose by situation. Full procedure in visual-loop.md. Deliver the report (uids touched, what changed, gaps/tradeoffs, screenshots) and confirm.
The native-first ladder — climb only as far as the prototype forces you. Pick the lowest rung that matches.
$p, paste into the model's runJs.code, adjust.The table maps each prototype region to its rung; the "JS kernel?" column is the content rendered inside the native container, never a replacement for it.
| Prototype region looks like… | Use | JS kernel? |
|---|---|---|
| Form — compose / create / edit, with custom controls or a live preview | native Form block with JS items / JS actions nested inside (pills, counter, live preview bound to form values). Not a freestanding JSBlock form. | yes — items/preview |
| Spreadsheet / dense rows of fields | Table | optional: one JS column (whole-record cell) for a rich first column |
| Feed / list of cards, contacts, activity, "currently X" | List + JS item (whole-record renderer per row); single-column card feed | yes — the card body |
| Catalog with left facet rail + status pills + grid | Rich catalog archetype: JS facet rail (multi-select + counts) + status pill bar + List + JS card + CSS auto-fill grid, cross-filtered. block-recipes.md §3b | yes — facets, pills, card |
| Responsive card grid that fills the width | List + JS card + CSS auto-fill (repeat(auto-fill, minmax(280px,1fr))). block-recipes.md §3 | yes — the card body |
| Plain fixed-breakpoint card grid (no facets, no fill) | GridCard + JS card — add-field --renderer js on GridCardItemModel, remove sibling DetailsItemModel nodes, showLabel:false. block-recipes.md §3 | yes — the card body |
| Photo / avatar gallery, people directory (native fields only) | GridCard (native fields, no JS) | optional |
| Board with status columns, pipeline | Kanban, groupField=<status>; card field limit 2 → add a JS card field | yes — the card |
| Calendar / schedule / room booking by day | Calendar (startField/endField/titleField) | rarely |
| Charts, KPIs, analytics dashboard | Chart (builder for single-table aggregates; custom raw ECharts for gauge/heatmap). Big-number KPI → small JS block | KPI only |
| Tree / org chart / nested categories | Tree block | no |
| Filter bar that drives another region | FilterForm + cross-block filter | sometimes |
| Quick-filter pills / custom control on a data block | JS item in the block's top-right toolbar (add-action --use JSItemActionModel) | yes — the toolbar widget |
| Detail drawer/popup on click | native popup via a real ViewActionModel (ctx.openView(<viewActionUid>, {filterByTk})) | n/a |
| Custom viz with NO data container: glowing map, kiosk, gauge, standalone feed | JS block (the only legitimate freestanding-JS case) | yes |
The container/content split (the core rule). For any region backed by data the container is always a native block (Form/Table/List/GridCard/Kanban/Calendar) — it gives resource binding, CRUD, filter, pagination, ACL for free. JS only renders the content inside that container: a JS item (form field / list card), JS column (table cell), JS field (whole-record card), JS action (button), or a JS item in the top-right toolbar (pills / custom controls). Reproduce the prototype's exact look inside the native container; never throw the container away. A freestanding JS block is reserved for a region with no data container (map, kiosk, gauge). Any non-native or interactive element MUST be a JS item/block — never skipped, never faked with a static native field (a live phone-preview in a composer is a JS item bound to ctx.form.getFieldsValue() + formValuesChange, not a static card).
curl flowModels:save (flat full-field upsert, preserves parentId). Never flowModels:update (clears parentId, node vanishes).props.layout + legacy props.rows + stepParams.gridSettings.grid consistently, or the client throws a false "Collection may have been deleted".ctx.libs.React/antd/antdIcons in JSFieldModel (not ctx.antdIcons); no window/document/localStorage; no local var named location; font strings can't contain spaces (SFMono-Regular); read whole record via ctx.getVar('ctx.record'). Full list: gotchas.md.localStorage NOCOBASE_TOKEN, open /admin/<pageSchemaUid>, confirm every block renders, no console/page errors, interactions work — and a visual pass vs the prototype.Full list with "read first / then" routing in index.md. The reproduction-specific docs: spec-template.md · decomposition-grammar.md · block-recipes.md · visual-loop.md · gotchas.md · prototype-authoring.md · handoff.md. Ready-made widget bodies: template-library/_index.md (57 JS block/item/column bodies + their $p contracts).
tools
Use when building a NocoBase app with NocoBase skills or the nb CLI and you want to save a completed, meaningful milestone as a restorable revision.
tools
Use when users need to inspect, create, revise, enable, or diagnose NocoBase workflows through the `nb` CLI, including trigger selection, node-chain changes, version safety checks, and execution troubleshooting.
development
General-purpose NocoBase reference utilities covering cross-cutting topics such as evaluator engines, expression syntax, UID generation, and more. Use when you need authoritative reference information or reusable snippets that apply across multiple NocoBase features.
tools
DEFAULT entry point for NocoBase Modern UI authoring or tweaks: new pages, blocks, menu items, and localized edits to blocks, fields, actions, layouts, or reactions on an already-running app via backend flow-surfaces through nb api. Also handles AI employee / AI assistant action placement on UI surfaces. Hand off employee lifecycle work such as discovering, judging, creating, or configuring profile, prompt, model, skills, tools, or knowledge base to nocobase-ai-employee, then return for the UI write. Only hand off to nocobase-dsl-reconciler when the user explicitly asks for DSL, YAML, git, or cli push workflow. Does not handle ACL, data modeling, workflow orchestration, browser reproduction, page error postmortems, or non-Modern page navigation.