Claude
Skills
Sign in
Back

nocobase-dsl-reconciler

Included with Lifetime
$97 forever

**Opt-in DSL path** for NocoBase app building. Use ONLY when the user explicitly asks for YAML / DSL / committed-to-git / `cli push` / spec files — e.g. "use the DSL reconciler", "I want YAML I can commit", "build this as a workspaces/ project". For any other UI authoring request (new page, new block, tweak an existing screen), default to `nocobase-ui-builder` instead — this reconciler is still in active development and has rough edges that the live-UI path avoids. When the user opts in: produces/changes files under `workspaces/<project>/`, supports new pages, menus, modules, whole systems, collections, tables, sub-tables, popups, dashboards, approval workflows, recordActions, and deploys them via `cli push`.

Designscripts

What this skill does


# NocoBase Application Builder (DSL path)

## Before you use this skill

This is the **opt-in DSL path**. Default is `nocobase-ui-builder`.
Stay on this skill only when the user explicitly wants YAML files they
can commit + `cli push`. If you arrived here from a generic "build me a
NocoBase app" request without the user naming DSL/YAML/git, switch to
`nocobase-ui-builder` instead — it's the default entry point.

## Golden rule

`templates/crm/` is a **read-only reference library**. When you're
unsure how a specific field, block, or popup is shaped, open the
closest CRM example, read it, then write your own adapted version in
your workspace. Per-scenario pointers live in the workflow sections below.

**Never** copy CRM files wholesale into your workspace. Do not
`cp -r templates/crm/...` to get started, do not duplicate
`collections/nb_crm_*.yaml`, do not base your `routes.yaml` on CRM's.
Bulk-copying drags unrelated leads/opportunities/orders state and
workflows into your project — you then spend the whole session fighting
hundreds of irrelevant validator errors instead of building your module.

The pre-deploy spec validator catches most structural mistakes with a
clear error message. **Trust the validator**: when it errors, fix what
it says rather than guessing — don't grep through `src/deploy/*.ts`.

## When NOT to use this skill

Hand off to the matching skill when the user's request is orthogonal:

| User asks for… | Skill |
|---|---|
| One-off live-UI tweak on an already-running page (move / reorder / reconfigure a single block, field, action) — **no DSL commit wanted** | `nocobase-ui-builder` |
| ACL / role permissions / route permissions | `nocobase-acl-manage` |
| Workflow create / update / revision / execution | `nocobase-workflow-manage` (this skill only wires the trigger button; authoring the graph goes there) |
| Collection / field / relation authoring outside a DSL project | `nocobase-data-modeling` |
| Plugin development (`.tsx` components, server code) | `nocobase-plugin-development` |
| Install / enable plugin | `nocobase-plugin-manage` |
| Environment setup / app install / upgrade | `nocobase-env-manage` |

Any change that should live as a committed YAML file under
`workspaces/<project>/` — stays here.

## Environment

```bash
cd <skill-dir>/src
export [email protected] NB_PASSWORD=admin123 NB_URL=http://localhost:14000
```

## Quick start — new build

**Default path for "build me a NocoBase app"**: copy the starter and
modify it. Do not hand-write the skeleton; do not study CRM first.

```bash
cd <skill-dir>/src
cp -r ../templates/starter ../workspaces/<name>

# First push: --copy bypasses validation rules that only matter once
# popups exist (m2o popup binding, clickToOpen file presence). The
# starter ships with its own popups so the first push is actually fully
# valid — --copy is for your *extensions* before popups are wired.
npx tsx cli/cli.ts push <name> --force
```

The starter is a complete minimal CRUD — 1 collection (Projects),
1 Dashboard page (4 KPI tiles + 2 charts), 1 list page with
filterForm / table / addNew popup / detail popup / 2 updateRecord
recordActions. Push as-is → visible in NB → then edit.

### Customizing the starter (the agile loop)

Iterate one concern at a time, push between each:

1. **Rename identifiers** to match the user's domain.
   - `collections/nb_starter_projects.yaml` → your collection name
     (match the `nb_<module>_<entity>` convention)
   - `routes.yaml`: change "Starter" / "Projects" titles
   - `pages/starter/` directory name if you want (match `routes.yaml`
     key)
   - Find-replace `nb_starter_projects` across all files
2. **Adjust the field list** in your collection YAML to match the
   user's entity. Update `pages/<...>/layout.yaml` `fields:` and the
   popup templates' `field_layout:` accordingly.
3. **Add a 2nd entity** only when the first one works end-to-end.
   Create a new `collections/*.yaml` + `pages/<module>/<entity>/` dir,
   copy `pages/starter/projects/layout.yaml` as a starting point.
4. **Extend incrementally**: add a tab, a chart, a workflow trigger.
   Push after every change. See "Advanced patterns" below for which
   CRM file matches which pattern.

**Never write the whole module in one shot.** For customer-facing
builds — land the skeleton, show the user, gather feedback, iterate.
The starter push takes minutes; a hand-built module takes hours.

### Fast-track: when `--copy` helps

Pass `--copy` when the workspace has **no popup files yet** (early
stage — validator would fire errors about "m2o field X has no popup
binding" that the user will fix in the next push). The reconciler
auto-bypasses spec errors in this state. Once any `popups/*.yaml`
exists, drop `--copy` and let validation run.

## Incremental edits — existing workspace

- **Add** a block / field / action / popup → write the DSL → push.
- **Remove** from DSL → push. The reconciler destroys the matching
  live model on the NB side and cleans `state.yaml`. Manual NB-UI
  authored elements (not tracked in `state.yaml`) are left alone.
- **Rename** → not supported automatically. Delete + re-add.

Targeted pushes:
- `--group <key>` scopes to one menu subtree
- `--page <key>` scopes to one page
- `--incremental` skips pages whose DSL hasn't changed since last push

**For pure live-UI tweaks without a DSL commit, hand off to
`nocobase-ui-builder` instead** (see the routing table above).

## Advanced workflow — when the starter isn't enough

Triggers for going beyond the agile starter loop:

- More than ~3 collections with cross-relations (m2m, tree structures)
- Dedicated workflow / approval / permission logic that the user wants
  designed up-front
- Multi-tab pages, sub-tables, or cross-module navigation
- Dashboard with bespoke KPIs mapped to the user's domain language

Progression: Round 0 design → Round 1 scaffold → Round 2 fill →
Round 2' seed → Round 3 JS. Each round is a deployable state.

### Round 0: System architecture — confirm with user

Write a `DESIGN.md` (markdown, not YAML) covering:

1. **Collections** — every table, its fields, and its relations.
   See `nocobase-data-modeling` skill for field-interface reference.
2. **Page list** — every page, one-line purpose each, grouped by menu.
3. **Navigation wiring** — which m2o fields open which popup
   templates; which pages link to each other.

Wait for user confirmation before writing YAML. A single design pass
saves 3× redesigns.

Skip Round 0 if the user's ask fits the starter shape (single entity,
basic CRUD).

Example:

```markdown
## Collections
- nb_lib_books (title, author, isbn, category, status, loans: o2m → nb_lib_loans)
- nb_lib_members (name, email, phone, join_date, loans: o2m → nb_lib_loans)
- nb_lib_loans (loan_no, book: m2o, member: m2o, borrowed_at, due_date, returned_at, status)

## Pages (under menu "Library")
- Books list — browse + search books, add new
- Members list — browse members, their loan history
- Loans list — active/overdue loans, return action
- Dashboard — KPIs + charts

## Navigation
- books.table.title → books detail popup (shared template)
- loans.table.book → books detail popup (shared via defaults.yaml)
- loans.table.member → members detail popup (shared via defaults.yaml)
```

### Round 0.5: Sub-agent CWD (only when spawning)

If launching a sub-agent (kimi TUI, Claude Code subprocess), its
CWD becomes the default write target. **Set it before launch:**

```bash
mkdir -p <user-workdir>
cd <user-workdir>
kimi --yolo       # or claude, codex
```

Skip the `cd` and the agent writes to the parent project root.

### Round 1: Scaffold — still start from the starter

Even in the advanced path, don't hand-write `routes.yaml` +
`collections/*.yaml` from scratch. Copy the starter, then grow:

| Step | What to do |
|---|---|
| Base | `cp -r templates/starter workspaces/<name>` — push once |
| Add collection | Write `collections/<next_coll>.yaml` (format matches starter's). Match `nb_<module>_<entity>` co
Files: 585
Size: 2254.1 KB
Complexity: 84/100
Category: Design

Related in Design