create-restforge-skills 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,512 +1,740 @@
1
- ---
2
- name: restforge
3
- description: >
4
- RESTForge end-to-end workflow — use for any task involving RESTForge: SDF
5
- (Schema Definition File), RDF (Resource Definition File), UDF (UI Definition
6
- File), dbschema, defineModel, codegen, payload, generate endpoint, generate
7
- dashboard, generate frontend, migrate schema, setup project, add authentication
8
- (project auth backend, embedded rfx_auth frontend auth), or design-to-SDF
9
- (deriving a schema from an HTML mockup, screenshot, image, or UI design). Also
10
- active for the codegen_*, designer_*, setup_*, runtime_* MCP tools and the
11
- @restforgejs/platform / @restforgejs/mcp-server packages. Defines the canonical
12
- operation order for the backend track (setup → schema → payload → codegen →
13
- runtime) and the frontend track (init → udf → validate → generate), the
14
- grounding-first catalog rules, decision branches, and destructive-operation
15
- guardrails. Active whenever working on a RESTForge project, not only when the
16
- word "skill" is mentioned.
17
- license: MIT
18
- compatibility: >
19
- Requires the RESTForge MCP server (@restforgejs/mcp-server) registered in the
20
- client, plus a RESTForge license for codegen_*, runtime_*, and
21
- setup_validate_config operations. Designer tools do not require a license.
22
- ---
23
-
24
- ## Mental Model
25
-
26
- RESTForge is a deterministic, definition-first generator with two output tracks:
27
-
28
- - **Backend track** — SDF defines the database schema; RDF defines REST API
29
- endpoints. One SDF produces identical DDL; one RDF payload produces an
30
- identical endpoint module on every execution.
31
- - **Frontend track** — UDF defines the frontend application. One UDF payload
32
- produces identical HTML/JS/CSS via `restforge-designer`, plugin-driven,
33
- no build step required.
34
-
35
- The agent interacts with the platform **exclusively through MCP tools**. The
36
- agent does not write generation code itself, does not modify generated output,
37
- and does not guess options outside the catalog. All valid options come from the
38
- catalog returned by grounding tools.
39
-
40
- The platform exposes its capabilities as MCP tools grouped by domain: `health_*`,
41
- `setup_*`, `codegen_*`, `runtime_*`, `designer_*`, `data_*`, `key_*`,
42
- `project_*`. Two facts follow from this and shape every task:
43
-
44
- 1. **The skill describes intent and order; the MCP server executes.** If the
45
- RESTForge MCP server is not registered in the client, this skill cannot do
46
- anything — there is nothing to call. Confirm the tools are available before
47
- planning a multi-step operation.
48
- 2. **The catalog is the source of truth, not memory.** Field types, constraints,
49
- validation rules, and plugin capabilities belong to the *installed* platform
50
- version. Always ground against the catalog before proposing definition
51
- content (see Grounding-First Rules, below).
52
-
53
- ---
54
-
55
- ## Preflight (run before any RESTForge task)
56
-
57
- Verify readiness before planning or producing anything:
58
-
59
- 1. **Are the RESTForge MCP tools present?** If `codegen_*` / `designer_*` are not
60
- in your available tools, the MCP server is **not active**. Stop and tell the
61
- user to register the RESTForge MCP server and restart the client. Do **not**
62
- finish the task by hand-reading the bundled `references/` — that bypasses the
63
- generator and yields slower, non-deterministic output.
64
- 2. **Backend work** → confirm the project and config are ready with
65
- `runtime_detect_project`, then the `setup_validate_config` gate.
66
- 3. **Frontend work** → the Designer tools pre-check that `restforge-designer` is
67
- on PATH; if it is missing, surface that before proceeding.
68
-
69
- If a prerequisite is missing, report it as the next step — do not improvise around it.
70
-
71
- ---
72
-
73
- ## Backend Pipeline (canonical)
74
-
75
- This is the canonical (golden) path. For state-dependent choices see Decision
76
- Points; for failure handling see Guardrails and Common Errors.
77
-
78
- The sequence below applies to a **new project from scratch**. For an existing
79
- project, start from the step that matches the current state — do not re-run
80
- earlier steps that already succeeded.
81
-
82
- ```
83
- 1. setup_create_folder
84
- Create a new project folder at the specified location.
85
-
86
- 2. setup_install_package
87
- Install @restforgejs/platform into the project folder.
88
-
89
- 3. setup_init_config
90
- Write config/db-connection.env from the default template.
91
-
92
- 4. setup_write_env / setup_update_env
93
- Set values: LICENSE, SERVER_ADDRESS, SERVER_PORT, DB_TYPE,
94
- DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME (9 required parameters).
95
- Use setup_read_env to read existing values before overwriting.
96
-
97
- 5. setup_validate_config
98
- ── GATE ── Must pass before any codegen_* operation starts.
99
- Validates database connection and license. Running codegen before this
100
- gate passes produces uninformative errors.
101
-
102
- 6. codegen_get_dbschema_catalog
103
- ── GROUNDING ── Source of truth before defining SDF: field types,
104
- constraints, shorthand syntax, relations, referential actions,
105
- check operations, and the soft-delete contract.
106
- → references/dbschema-catalog.md
107
-
108
- 7a. codegen_dbschema_init (empty DB — scaffold SDF with audit columns)
109
- codegen_dbschema_template (minimal template, no DB connection required)
110
- 7b. codegen_dbschema_introspect (existing DB — generate SDF from actual schema)
111
-
112
- 8. codegen_dbschema_validate
113
- Validate SDF before any DDL is generated. Catch errors here, not at migrate.
114
-
115
- 9. codegen_dbschema_generate_ddl (optional — preview DDL without executing)
116
-
117
- 10a. codegen_dbschema_migrate (empty DB — apply DDL directly)
118
- 10b. codegen_dbschema_diff (existing DB — review the differences first)
119
- → codegen_dbschema_apply (apply only after confirming the drift)
120
-
121
- 11. codegen_get_field_validation_catalog
122
- ── GROUNDING ── before defining fieldValidation in a payload.
123
- → references/field-validation.md
124
-
125
- 12. codegen_get_query_declarative_catalog
126
- ── GROUNDING ── when the payload contains datatablesQuery, viewQuery,
127
- viewName, exportQuery, or detailQuery.
128
-
129
- 13. codegen_generate_payload
130
- Generate payload JSON from a table. Foundation for all subsequent
131
- codegen operations.
132
-
133
- 14. codegen_validate_payload
134
- Validate the payload before codegen. Catch errors here.
135
-
136
- 15. codegen_diff_payload (when a payload exists and the DB schema has changed)
137
- → codegen_sync_payload (sync payload to the current DB state — non-breaking)
138
- → codegen_migrate_payload (when the payload has breaking changes)
139
-
140
- 16a. codegen_create_endpoint (standard CRUD module)
141
- 16b. codegen_get_dashboard_catalog
142
- → codegen_create_dashboard (analytic dashboard with SQL widgets)
143
- 16c. codegen_create_processor (background processing)
144
- 16d. codegen_create_kafka_consumer (Kafka event streaming)
145
-
146
- 17. runtime_generate_launcher
147
- Generate the launcher script. The agent STOPS here. The user executes
148
- the launcher — the server runs independently of the agent session.
149
-
150
- 18. (user executes the launcher)
151
-
152
- 19. runtime_check_status
153
- Verify the server is running and endpoints are reachable.
154
- ```
155
-
156
- Two hard checkpoints (see Guardrails): **step 5** is a gate — no `codegen_*` call
157
- before `setup_validate_config` passes; **step 17** is where the agent stops (it
158
- generates the launcher, never runs the server).
159
-
160
- ---
161
-
162
- ## Frontend Pipeline (canonical)
163
-
164
- This is the canonical (golden) path for the frontend track. It runs
165
- **independently** from the backend pipeline. The backend API must be running and
166
- reachable at `apiBaseUrl` before the generated frontend is useful, but the
167
- frontend can be defined and generated without the backend live.
168
-
169
- ```
170
- 1. designer_list_plugins
171
- ── GROUNDING ── list available output plugins before initializing.
172
- Built-in: vanilla-js-basic (no auth), vanilla-js-auth (JWT auth).
173
- → references/udf-catalog.md § Plugins
174
-
175
- 2. designer_init_project
176
- Scaffold a new frontend project from a plugin. Creates the project folder,
177
- the initial UDF payload (payload.json), and plugin assets.
178
-
179
- 3. designer_get_udf_catalog
180
- ── GROUNDING ── call before defining or editing any UDF payload.
181
- Returns valid field types, page anatomy, features, data-source formats,
182
- and validation rules for the installed plugin version.
183
- → references/udf-catalog.md
184
-
185
- 4. [define / edit UDF payload JSON]
186
- Edit payload.json: appConfig, pages[], navigation[], homepage.
187
- One page entry = one CRUD page or one dashboard page.
188
-
189
- 5. designer_validate_payload
190
- ── GATE ── validate the UDF payload. Catches structural errors before
191
- generation. Run before preview or generate, every time.
192
-
193
- 6. designer_preview_files
194
- Dry-run: list files that would be generated, without writing to disk.
195
- Use to verify scope before an overwrite.
196
-
197
- 7. designer_generate
198
- Generate frontend HTML/JS/CSS from the UDF payload. Writes output files.
199
- The agent STOPS here — the user opens the output in a browser.
200
- ```
201
-
202
- For plugin development (custom output plugins):
203
-
204
- ```
205
- designer_scaffold_plugin → [develop plugin templates]
206
- → designer_inspect_plugin (verify plugin metadata and capabilities)
207
- → designer_generate (test generation with the custom plugin)
208
- ```
209
-
210
- Two checkpoints (see Guardrails): **step 5** is a gate — never `designer_generate`
211
- an unvalidated payload; **step 7** is where the agent stops (generates files, does
212
- not serve or deploy).
213
-
214
- Licensing note: the Designer tools (`designer_preview_files`, `designer_generate`,
215
- etc.) do **not** require a RESTForge license, unlike the `codegen_*`, `runtime_*`,
216
- and `setup_validate_config` tools on the backend track.
217
-
218
- ---
219
-
220
- ## Auth Extension
221
-
222
- RESTForge has **two different auth mechanisms — do not confuse them.** Pick the
223
- right one; never describe one as the other, and never claim the extension does RBAC.
224
-
225
- | Mechanism | RBAC? | How |
226
- |---|---|---|
227
- | **Plugin auth** — built into the frontend at generation time | **Yes (auth + RBAC)** | `vanilla-js-auth` or `vanilla-js-custom` plugin in `designer_init_project`; disable with `noAuth: true` (`--no-auth`) |
228
- | **Auth extension** — bolt-on added to an existing project | **No RBAC** | backend `project_auth`; frontend `designer_auth_create` (embedded `rfx_auth`) |
229
-
230
- Confirm which plugins provide auth with `designer_list_plugins` — do not hardcode
231
- it. The rest of this section covers the **extension** (the no-RBAC bolt-on); for
232
- plugin auth see Decision Points § Frontend plugin choice. Google Sign-In and
233
- `@restforgejs/auth` are out of scope for the extension.
234
-
235
- ### Backend auth — `project_auth`
236
-
237
- Adds the auth backend to an existing RESTForge project (run the standard backend
238
- pipeline first; the project and its endpoint must already exist, and the DB must
239
- be active).
240
-
241
- ```
242
- project_auth (wraps: npx restforge project auth --create --project=<name>)
243
- ```
244
-
245
- Installs auth SDF (`rfx`), DB tables, middleware, router, six processors
246
- (register/login/refresh/logout/me/reset-password), a random `JWT_SECRET`, and
247
- `bcrypt`+`jsonwebtoken`. Idempotent. → references/auth.md § Backend
248
-
249
- ### Frontend auth — `designer_auth_create` / `designer_auth_remove`
250
-
251
- Adds (or removes) an **embedded** login / signup / forget-password overlay
252
- (`rfx_auth`) on an existing frontend project, at route
253
- `/api/<project>/rfx_auth`. This is independent of the `vanilla-js-auth` plugin.
254
-
255
- ```
256
- designer_auth_create (wraps: restforge-designer auth --create --project=<name>)
257
- designer_auth_remove (wraps: restforge-designer auth --remove --project=<name> --force)
258
- ```
259
-
260
- `create` writes the auth pages + `js/rfx_auth.js` and injects a guard into existing
261
- pages; `remove` deletes them. Idempotent. `restforge-designer` must be on PATH.
262
- → references/auth.md § Frontend
263
-
264
- Do not combine the two mechanisms on one app: if an app already has plugin auth
265
- (`vanilla-js-auth` / `vanilla-js-custom`), do not also add embedded `rfx_auth`.
266
-
267
- ---
268
-
269
- ## Grounding-First Rules
270
-
271
- Before reasoning about, proposing, or generating any **definition content** —
272
- SDF fields, RDF `fieldValidation`, queries, dashboard widgets, or UDF pages —
273
- call the matching grounding tool first and use only what it returns. Never write
274
- definition content from memory.
275
-
276
- | Context | Grounding tool | Reference |
277
- |---|---|---|
278
- | Defining or reviewing SDF | `codegen_get_dbschema_catalog` | references/dbschema-catalog.md |
279
- | Deriving SDF from a UI design (HTML / image / screenshot) | `codegen_get_dbschema_catalog` | references/design-to-sdf.md |
280
- | Defining `fieldValidation` in an RDF payload | `codegen_get_field_validation_catalog` | references/field-validation.md |
281
- | Defining queries in an RDF payload | `codegen_get_query_declarative_catalog` | — |
282
- | Defining a dashboard payload | `codegen_get_dashboard_catalog` | — |
283
- | Defining UDF (frontend) | `designer_get_udf_catalog` | references/udf-catalog.md |
284
- | Listing available frontend plugins | `designer_list_plugins` | references/udf-catalog.md § Plugins |
285
-
286
- **Why this rule exists.** The catalog is the source of truth for valid options
287
- in the *installed* platform version. Reasoning without it produces confident but
288
- wrong output — field types that do not exist, constraints not applicable to a
289
- type, or wrong semantics. Two concrete failure modes this rule prevents:
290
-
291
- - **Inventing options.** Without grounding, an agent may write a made-up key
292
- (e.g. `"toUpper": true`) that the validator rejects. The catalog gives the
293
- exact key and value type.
294
- - **Misreading semantics.** A constraint can mean something different from its
295
- plain-English name. For example, `uppercase` on a `string` field is a
296
- *normalization transform* (it forces the stored value to upper case), grouped
297
- with `trim` and `lowercase` — it is **not** a validator that rejects
298
- non-uppercase input. If the user wants rejection, the answer is `pattern`, not
299
- `uppercase`; if they want database-level enforcement, that is an SDF check
300
- constraint, not RDF `fieldValidation`. Grounding surfaces this distinction
301
- before the agent commits to the wrong one.
302
-
303
- The reference files help you *understand* the catalog; they do **not** replace
304
- the tool. Call the tool to ground, produce, and validate — do not hand-produce
305
- output a tool would generate. The live tool is authoritative; when a reference and
306
- the tool disagree, trust the tool.
307
-
308
- ---
309
-
310
- ## Decision Points
311
-
312
- Use these to pick the correct branch when the request is state-dependent. Each
313
- branch still obeys the Grounding-First Rules above.
314
-
315
- ### Schema (SDF)
316
-
317
- - **DB does not exist** → `codegen_dbschema_init` (scaffold with audit columns)
318
- or `codegen_dbschema_template` (minimal template, no DB connection required).
319
- - **DB already exists** → `codegen_dbschema_introspect` to generate SDF from the
320
- actual schema. Do not hand-write a schema that a real DB can describe.
321
- - **Starting from a UI design** (HTML mockup, screenshot, image, Figma export)
322
- → first confirm the design is an entity to model, not a dashboard/analytics
323
- screen (those map to the Dashboard RDF branch below, not to a new SDF table).
324
- Then classify visible elements into stored / derived / relation / audit, draft
325
- the SDF, and run `codegen_dbschema_validate`. The design shows presentation,
326
- not storage — do not turn every visible label into a column.
327
- → references/design-to-sdf.md
328
- - **DB exists with drift** → `codegen_dbschema_diff` to review, then
329
- `codegen_dbschema_apply`. Not `codegen_dbschema_migrate` — that is for empty
330
- DBs only.
331
-
332
- ### RDF Payload
333
-
334
- - **No payload yet** → `codegen_generate_payload`.
335
- - **Payload exists, edit is API-layer only** (e.g. add/adjust `fieldValidation`,
336
- messages, or a query — no column added or dropped) → ground via the matching
337
- catalog, edit `payload.json`, run `codegen_validate_payload`, then regenerate
338
- with `codegen_create_endpoint`. No DB migration: the schema (SDF) is unchanged.
339
- - **Payload exists, DB schema changed** → `codegen_diff_payload` first, then
340
- `codegen_sync_payload` (non-breaking) or `codegen_migrate_payload` (breaking).
341
- - **Custom query needed** → ground via `codegen_get_query_declarative_catalog`,
342
- then set `datatablesQuery`, `viewQuery`, or `exportQuery` in the payload.
343
- External SQL files use the `file:` prefix
344
- (e.g. `"datatablesQuery": "file:sql/orders.sql"`).
345
-
346
- > **"Add an uppercase / case constraint" is ambiguous — disambiguate first.**
347
- > In RESTForge `uppercase` is an RDF `fieldValidation` *normalization transform*
348
- > (forces the stored value to upper case), not a reject-if-not-uppercase
349
- > validator. If the user wants rejection, use `pattern`. If the user wants the
350
- > database to enforce it, that is an SDF check constraint, not RDF. Confirm which
351
- > one is meant before editing — see Grounding-First Rules § Misreading semantics.
352
-
353
- ### Backend module type
354
-
355
- - **Standard CRUD** → `codegen_create_endpoint`. One payload = one module.
356
- - **Analytic dashboard** → `codegen_create_dashboard`. Payload must have
357
- `widgets` (not `tableName`); page name must be prefixed `dash-`.
358
- - **Background job** → `codegen_create_processor`.
359
- - **Kafka event consumer** → `codegen_create_kafka_consumer`; requires
360
- `KAFKA_ENABLED=true` in config.
361
- - **Workflow (status transitions)** → add `workflow` and `workflowActions` to the
362
- RDF payload; generates a `/change-status` endpoint automatically.
363
- → references/rdf-advanced.md § Workflow
364
- - **Master-detail (composite CRUD)** → add `details[]` to the RDF payload;
365
- generates `/create-composite`, `/update-composite`, `/read-composite`.
366
- → references/rdf-advanced.md § Master-Detail
367
-
368
- ### Soft-delete vs hard-delete
369
-
370
- - Use soft-delete when deleted rows must be audited or recoverable. Declare
371
- `softDelete: { enabled: true }` in SDF and add the three contract columns
372
- (`is_deleted`, `deleted_at`, `deleted_by`).
373
- - Soft-delete is supported on PostgreSQL only (Phase 1).
374
- - Tables with composite UNIQUE constraints are incompatible with soft-delete.
375
-
376
- ### Frontend page type
377
-
378
- - **Standard CRUD page** → `pageType: "crud"` (default) with `apiPath`,
379
- `primaryKey`, `displayField`, and `fields[]`.
380
- - **Dashboard page** → `pageType: "dashboard"` with `dataSources[]` and `rows[]`
381
- containing widget columns.
382
- → references/udf-catalog.md § Dashboard Page
383
- - **Page with approval workflow** → add `workflow.statusField` and
384
- `workflowActions[]` to the page.
385
-
386
- ### Frontend plugin choice
387
-
388
- - **No auth** → `vanilla-js-basic`.
389
- - **Auth WITH RBAC, built into the app** → `vanilla-js-auth` or
390
- `vanilla-js-custom` at `designer_init_project`. Use `noAuth: true` (`--no-auth`)
391
- to get the plugin's UI without its auth.
392
- - **Custom branding / new plugin** → `designer_scaffold_plugin`.
393
- - **Bolt-on auth WITHOUT RBAC** → not a plugin; see Authentication below.
394
- → references/udf-catalog.md § Plugins
395
-
396
- ### Authentication
397
-
398
- - **Needs RBAC** → plugin auth (`vanilla-js-auth` / `vanilla-js-custom`) at
399
- `designer_init_project`. The extension below does **not** do RBAC.
400
- - **Backend auth on an existing project (no RBAC)** → `project_auth` (after the
401
- project and its endpoint exist, with an active DB).
402
- - **Frontend auth on an app built WITHOUT plugin auth (no RBAC)** →
403
- `designer_auth_create` (embedded `rfx_auth`).
404
- - **Remove embedded frontend auth** → `designer_auth_remove` — destructive,
405
- confirm first (see Guardrails).
406
-
407
- ---
408
-
409
- ## Guardrails
410
-
411
- These are hard rules. They override convenience and override an eager reading of
412
- the user's request. When a guardrail conflicts with finishing faster, the
413
- guardrail wins.
414
-
415
- **1. Confirm before destructive operations.**
416
- The following require explicit user confirmation before execution:
417
-
418
- - `codegen_dbschema_migrate` or `codegen_dbschema_apply` that drops a table or
419
- column, or alters a column in a way that loses data.
420
- - `project_delete` — permanent project deletion.
421
-
422
- For schema changes, run `codegen_dbschema_diff` first, present a summary of the
423
- destructive parts (dropped tables/columns, type narrowing), and wait for
424
- confirmation before calling `codegen_dbschema_apply`. Never infer approval from
425
- the original request — "update the schema" is not consent to drop a column.
426
-
427
- **2. The agent does not run the server.**
428
- The agent's last step on the backend track is `runtime_generate_launcher`. The
429
- user executes the launcher in their own terminal. The agent never calls shell
430
- commands to start, stop, or restart the server, and never assumes the server is
431
- running — verify with `runtime_check_status` instead.
432
-
433
- **3. The `validate_config` gate is mandatory.**
434
- `setup_validate_config` must pass before any `codegen_*` operation starts. Do not
435
- skip it "to save a step" — running codegen against an invalid config produces
436
- uninformative errors that cost more time than the gate.
437
-
438
- **4. Validate before generating.**
439
- Always run `codegen_validate_payload` before `codegen_create_*`, and
440
- `designer_validate_payload` before `designer_generate`. Generation on an invalid
441
- payload produces incomplete or broken output that looks like it succeeded.
442
-
443
- **5. Stay inside the task scope.**
444
- Do not modify files outside the requested task. If the change is a backend
445
- payload edit, do not also "tidy up" the SDF, the runtime, or the frontend. If a
446
- change genuinely requires touching another area (e.g. an RDF edit that needs a
447
- new column, which is an SDF change), stop and report the cross-over, then ask
448
- before expanding scope.
449
-
450
- **6. Ground before defining — repeated here because it is a guardrail, not a
451
- suggestion.** Never write SDF fields, `fieldValidation`, queries, dashboard
452
- widgets, or UDF content from memory. Call the matching catalog tool first (see
453
- Grounding-First Rules). Inventing an option that "should" exist is the most
454
- common way to produce confidently wrong output.
455
-
456
- **7. Confirm before removing embedded auth.**
457
- `designer_auth_remove` deletes the auth files (`login.html`, `signup.html`, the
458
- forget-password overlay, `js/rfx_auth.js`) and strips the guard from existing
459
- pages. Under MCP it runs with `--force` (no interactive prompt), so confirm the
460
- project name and intent with the user **before** calling it.
461
-
462
- **8. Execute through tools; never emulate them.** The bundled `references/` help
463
- you *understand* options — they do not replace the tools. When a tool can produce
464
- or validate an artifact (`codegen_dbschema_template`/`init`,
465
- `codegen_generate_payload`, any `*_validate_*`), **call it**; do not hand-write its
466
- output by reading a reference. Emulating the generator is slower, loses
467
- determinism, and drifts from what the installed version emits. If the tool is not
468
- available, stop (see Preflight) rather than improvising from the references.
469
-
470
- ---
471
-
472
- ## Prerequisites and Common Errors
473
-
474
- ### Environment prerequisites
475
-
476
- - Node.js ≥ 18.
477
- - A reachable database matching the configured `DB_TYPE` (PostgreSQL, MySQL,
478
- Oracle, or SQLite).
479
- - A valid RESTForge license for `codegen_*`, `runtime_*`, and
480
- `setup_validate_config`. Designer tools do not require a license.
481
- - The RESTForge MCP server registered in the client
482
- (`npm install -g @restforgejs/mcp-server`, then registered as the `restforge`
483
- MCP server). Without it, none of the tools below exist.
484
- - Redis if using cache, distributed lock, or live sync.
485
- - Kafka if using a Kafka consumer (`KAFKA_ENABLED=true`).
486
-
487
- ### Required backend config parameters
488
-
489
- Nine of the full parameter set are mandatory before `setup_validate_config` can
490
- pass:
491
-
492
- `LICENSE`, `SERVER_ADDRESS`, `SERVER_PORT`, `DB_TYPE`, `DB_HOST`, `DB_PORT`,
493
- `DB_USER`, `DB_PASSWORD`, `DB_NAME`.
494
-
495
- → references/config-schema.md for the full parameter list.
496
-
497
- ### Common error patterns
498
-
499
- | Symptom | Cause | Recovery |
500
- |---|---|---|
501
- | Tool not found / no `codegen_*` tools available | MCP server not registered in the client | Install `@restforgejs/mcp-server`, register it as the `restforge` MCP server, restart the client |
502
- | "authenticity check failed" / HTTP 401 | License not active or expired | Set `LICENSE` in `config/db-connection.env`, run `setup_validate_config` |
503
- | HTTP 429 from license server | Rate limit (10 req/min/IP) | Expected since v5.1.15 — the client falls back to cache; wait or retry |
504
- | DB connection failed | Wrong DB config or DB not running | Check `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`; verify the DB is running |
505
- | "softDelete contract violation" | Contract columns missing or wrong type | Fix the SDF declaration, run `codegen_dbschema_validate` |
506
- | "Widget uses undeclared placeholder" | `:paramName` in SQL not in `params` | Add the entry to `params` in the dashboard payload |
507
- | "tableName and widgets conflict" | Payload contains both | Dashboard uses `widgets`; CRUD uses `tableName` — remove the wrong one |
508
- | UDF validation error on field type | Field type not supported by the active plugin | Run `designer_list_plugins` + `designer_get_udf_catalog` to verify supported types |
509
-
510
- When an error is not in this table, do not guess a fix. Re-run the relevant
511
- `*_validate_*` tool, read its message, and ground against the catalog before
512
- changing the definition.
1
+ ---
2
+ name: restforge
3
+ description: >
4
+ RESTForge end-to-end workflow — use for any task involving RESTForge: SDF
5
+ (Schema Definition File), RDF (Resource Definition File), UDF (UI Definition
6
+ File), dbschema, defineModel, codegen, payload, generate endpoint, generate
7
+ dashboard, generate frontend, migrate schema, setup project, add authentication
8
+ (project auth backend, embedded rfx_auth frontend auth), or design-to-SDF
9
+ (deriving a schema from an HTML mockup, screenshot, image, or UI design). Also
10
+ active for the codegen_*, designer_*, setup_*, runtime_* MCP tools and the
11
+ @restforgejs/platform / @restforgejs/mcp-server packages. Defines the canonical
12
+ operation order for the backend track (setup → schema → payload → codegen →
13
+ runtime) and the frontend track (init → udf → validate → generate), the
14
+ grounding-first catalog rules, decision branches, and destructive-operation
15
+ guardrails. Active whenever working on a RESTForge project, not only when the
16
+ word "skill" is mentioned.
17
+ license: MIT
18
+ compatibility: >
19
+ Requires the RESTForge MCP server (@restforgejs/mcp-server) registered in the
20
+ client, plus a RESTForge license for codegen_*, runtime_*, and
21
+ setup_validate_config operations. Designer tools do not require a license.
22
+ ---
23
+
24
+ ## Mental Model
25
+
26
+ RESTForge is a deterministic, definition-first generator with two output tracks:
27
+
28
+ - **Backend track** — SDF defines the database schema; RDF defines REST API
29
+ endpoints. One SDF produces identical DDL; one RDF payload produces an
30
+ identical endpoint module on every execution.
31
+ - **Frontend track** — UDF defines the frontend application. One UDF payload
32
+ produces identical HTML/JS/CSS via `npx restforge-designer`, plugin-driven,
33
+ no build step required.
34
+
35
+ The agent interacts with the platform **exclusively through MCP tools**. The
36
+ agent does not write generation code itself, does not modify generated output,
37
+ and does not guess options outside the catalog. All valid options come from the
38
+ catalog returned by grounding tools.
39
+
40
+ The platform exposes its capabilities as MCP tools grouped by domain: `health_*`,
41
+ `setup_*`, `codegen_*`, `runtime_*`, `designer_*`, `data_*`, `key_*`,
42
+ `project_*`, `license_*`. Two facts follow from this and shape every task:
43
+
44
+ 1. **The skill describes intent and order; the MCP server executes.** If the
45
+ RESTForge MCP server is not registered in the client, this skill cannot do
46
+ anything — there is nothing to call. Confirm the tools are available before
47
+ planning a multi-step operation.
48
+ 2. **The catalog is the source of truth, not memory.** Field types, constraints,
49
+ validation rules, and plugin capabilities belong to the *installed* platform
50
+ version. Always ground against the catalog before proposing definition
51
+ content (see Grounding-First Rules, below).
52
+
53
+ ---
54
+
55
+ ## Preflight (run before any RESTForge task)
56
+
57
+ Verify readiness before planning or producing anything:
58
+
59
+ 1. **Are the RESTForge MCP tools present?** If `codegen_*` / `designer_*` are not
60
+ in your available tools, the MCP server is **not active**. Stop and tell the
61
+ user to register the RESTForge MCP server and restart the client. Do **not**
62
+ finish the task by hand-reading the bundled `references/` — that bypasses the
63
+ generator and yields slower, non-deterministic output.
64
+ 2. **Backend work** → confirm the project and config are ready with
65
+ `runtime_detect_project`, list the candidate `.env` files in `config/` with
66
+ `runtime_detect_config` when the config to use is not obvious, then the
67
+ `setup_validate_config` gate.
68
+ 3. **Before writing a launcher** → `runtime_validate_preflight`. It re-runs the
69
+ config validation and adds the two runtime-only checks the gate does not
70
+ cover: a possibly-running server (`.restforge/server.pid`) and availability
71
+ of the local port. Use it as the last check before `runtime_generate_launcher`,
72
+ not as a replacement for the `setup_validate_config` gate earlier in the run.
73
+ 4. **License questions** → `license_info` reports the activation stored on this
74
+ machine (key, e-mail, type, machine id, last validation, expiry) and changes
75
+ nothing. Repeat the key, e-mail, or machine id back to the user only when
76
+ they asked for them. Activation and `license deactivate` are deliberately
77
+ **not** wrapped by MCP — deactivation frees a machine slot across machines,
78
+ so the user runs it in their own terminal.
79
+ 5. **Frontend work** → the Designer tools pre-check that `npx restforge-designer`
80
+ can run (its binary is bundled in `@restforgejs/platform`, so it is available
81
+ once the project is created with `npx create-restforge-app` / the platform is
82
+ installed); if it cannot run, surface that before proceeding.
83
+
84
+ If a prerequisite is missing, report it as the next step — do not improvise around it.
85
+
86
+ ---
87
+
88
+ ## Backend Pipeline (canonical)
89
+
90
+ This is the canonical (golden) path. For state-dependent choices see Decision
91
+ Points; for failure handling see Guardrails and Common Errors.
92
+
93
+ The sequence below applies to a **new project from scratch**. For an existing
94
+ project, start from the step that matches the current state — do not re-run
95
+ earlier steps that already succeeded.
96
+
97
+ ```
98
+ 1. npx create-restforge-app <name> ── PRIMARY ── human-run scaffolder
99
+ One shot: creates the project folder, runs
100
+ npm install @restforgejs/platform (local), and bundles the designer
101
+ binary. This is the dominant way to start a new project.
102
+ Granular alternative (agent scaffolds step by step):
103
+ setup_create_folder → create the project folder.
104
+
105
+ 2. setup_install_package (granular path only)
106
+ Install @restforgejs/platform into the folder. SKIP when the project
107
+ was created with create-restforge-app (already installed). Plain
108
+ 'npm install @restforgejs/platform' stays valid but is not the
109
+ primary entry point.
110
+
111
+ 3. setup_init_config
112
+ Write config/db-connection.env from the default template.
113
+ setup_get_init_template returns that same template WITHOUT writing a
114
+ file — use it to compare an edited config against the defaults.
115
+
116
+ 4. setup_write_env / setup_update_env
117
+ Set values: LICENSE, SERVER_ADDRESS, SERVER_PORT, DB_TYPE,
118
+ DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME (9 required parameters).
119
+ Use setup_read_env to read existing values before overwriting.
120
+ Grounding for the full parameter set: setup_get_config_schema.
121
+
122
+ 5. setup_validate_config
123
+ ── GATE ── Must pass before any codegen_* operation starts.
124
+ Validates database connection and license. Running codegen before this
125
+ gate passes produces uninformative errors.
126
+ Read-only by default. Set autoCreateDb=true only when the target database
127
+ itself does not exist yet AND the user agreed to have it created: it runs
128
+ CREATE DATABASE on the server (postgres/mysql only, ignored for sqlite and
129
+ oracle), and validation has to be repeated afterwards.
130
+
131
+ 6. codegen_get_dbschema_catalog
132
+ ── GROUNDING ── Source of truth before defining SDF: field types,
133
+ constraints, shorthand syntax, relations, referential actions,
134
+ check operations, and the soft-delete contract.
135
+ → references/dbschema-catalog.md
136
+
137
+ 7a. codegen_dbschema_init (empty DB — scaffold SDF with audit columns)
138
+ codegen_dbschema_template (minimal template, no DB connection required)
139
+ 7b. codegen_list_tables (existing DB — what is actually in there)
140
+ → codegen_describe_table (columns, PK, FKs, indexes of one table)
141
+ → codegen_dbschema_introspect (generate SDF from the actual schema)
142
+ list/describe are read-only catalog reads: they answer "what does this
143
+ database already hold?" without writing an SDF file. Use them before
144
+ introspecting a subset, and whenever a question about an existing table
145
+ would otherwise be answered from memory.
146
+
147
+ 8. codegen_dbschema_validate
148
+ Validate SDF before any DDL is generated. Catch errors here, not at migrate.
149
+ codegen_dbschema_models (optional) lists the models already defined in the
150
+ SDF files with field count, primary key kind, indexes, uniques, relations.
151
+
152
+ 9. codegen_dbschema_generate_ddl (optional — preview DDL without executing)
153
+
154
+ 10a. codegen_dbschema_migrate (empty DB — apply DDL directly)
155
+ 10b. codegen_dbschema_diff (existing DB — review the differences first)
156
+ → codegen_dbschema_apply (apply only after confirming the drift)
157
+
158
+ 11. codegen_get_field_validation_catalog
159
+ ── GROUNDING ── before defining fieldValidation in a payload.
160
+ → references/field-validation.md
161
+
162
+ 12. codegen_get_query_declarative_catalog
163
+ ── GROUNDING ── when the payload contains datatablesQuery, viewQuery,
164
+ viewName, exportQuery, or detailQuery.
165
+ codegen_validate_sql
166
+ Check the SELECT / WITH statement against the live database (EXPLAIN, no
167
+ rows executed) BEFORE pasting it into the payload: syntax, column
168
+ references, function existence, type compatibility, JOIN resolution.
169
+ Needs a platform that provides the 'query validate' sub-command
170
+ (confirmed present in 5.5.5).
171
+
172
+ 13. codegen_generate_payload
173
+ Generate payload JSON from a table. Foundation for all subsequent
174
+ codegen operations.
175
+
176
+ 14. codegen_validate_payload
177
+ Validate the payload before codegen. Catch errors here.
178
+
179
+ 15. codegen_diff_payload (when a payload exists and the DB schema has changed)
180
+ → codegen_sync_payload (sync payload to the current DB state — non-breaking)
181
+ → codegen_migrate_payload (when the payload has breaking changes)
182
+
183
+ 16a. codegen_create_endpoint (standard CRUD module)
184
+ Leave 'database' UNSET unless the user named a database: the CLI then
185
+ auto-detects DB_TYPE from the active config (fallback postgres), so a
186
+ MySQL/Oracle/SQLite project generates for its own dialect. 'config'
187
+ selects that .env explicitly. createDemo (default true) writes the
188
+ curl / Postman / Insomnia examples. force defaults to true — an existing
189
+ module is overwritten and the previous version archived as .archive.NNN;
190
+ force=false stops without writing anything when the module exists, which
191
+ is the closest thing to a conflict dry run.
192
+ 16b. codegen_get_dashboard_catalog
193
+ → codegen_validate_dashboard_payload
194
+ ── GATE ── structural check of a dashboard payload; writes nothing.
195
+ Needs a platform NEWER than 5.5.5 ('dashboard create --validate-only').
196
+ On an older platform the tool answers with an upgrade suggestion instead
197
+ of a validation result — then let the generator itself validate, since it
198
+ runs the same validator before it writes.
199
+ → codegen_create_dashboard (analytic dashboard with SQL widgets)
200
+ No database auto-detection here: the dashboard command uses 'database'
201
+ when given and plain postgres otherwise, so pass it whenever the project
202
+ is not postgres. force defaults to true and then re-registers the project
203
+ under the database type carried by this call; force=false refuses cleanly
204
+ instead of writing.
205
+ 16c. codegen_create_processor (background processing)
206
+ 16d. codegen_create_kafka_consumer (Kafka event streaming)
207
+ → runtime_generate_consumer_launcher
208
+ Prepare a way to RUN that consumer: mode=host writes the fixed
209
+ consumer-start/consumer-stop pair in the project root, mode=pm2 produces
210
+ ecosystem.config.js + consumer-manager.sh in ./deploy/. 'config' is
211
+ required and must end with .env.
212
+ → (user runs the consumer) — the agent never starts it, same rule as the
213
+ server launcher below.
214
+
215
+ 17. codegen_generate_test (optional)
216
+ Jest + Supertest integration test for an endpoint that ALREADY exists.
217
+ Natural follow-up once the module is generated.
218
+
219
+ 18. project_sdk_generate (optional)
220
+ Write the JavaScript SDK source for the project (one resource file per
221
+ registered endpoint, plus client.auth when the backend auth extension is
222
+ installed) so a frontend calls client.<resource>.<verb>(payload). Source
223
+ only: the user runs install / build / deploy. Without force it refuses
224
+ when an SDK exists; with force=true it overwrites IN PLACE with no
225
+ archive, so local edits in the SDK folder are lost.
226
+
227
+ 19. runtime_check_launcher_exists → runtime_validate_preflight
228
+ → runtime_generate_launcher
229
+ Check what is already there (read-only), validate the runtime
230
+ prerequisites, then write the launcher script. The agent STOPS here. The
231
+ user executes the launcher — the server runs independently of the agent
232
+ session.
233
+
234
+ 20. (user executes the launcher)
235
+
236
+ 21. runtime_check_status
237
+ Verify the server is running and endpoints are reachable.
238
+ ```
239
+
240
+ Two hard checkpoints (see Guardrails): **step 5** is a gate — no `codegen_*` call
241
+ before `setup_validate_config` passes; **step 19** is where the agent stops (it
242
+ generates the launcher, never runs the server).
243
+
244
+ **Payload naming differs per generator** — the value is handed to the CLI and
245
+ each verb resolves it differently:
246
+
247
+ | Tool | Accepted form |
248
+ |---|---|
249
+ | `codegen_create_endpoint`, `codegen_create_processor` | bare name, with or without `.json`; lowercased by the CLI; path forms are rejected |
250
+ | `codegen_create_dashboard`, `codegen_validate_dashboard_payload` | name or relative path **with** the extension, used verbatim (`dash-sales.json`, `payload/dash-sales.json`) — nothing is appended |
251
+ | `codegen_create_kafka_consumer` | name or path |
252
+
253
+ **Config selection across calls.** Most backend tools take an optional `config`
254
+ and otherwise fall back to the default recorded per working directory in
255
+ `.restforge/defaults.json`. Manage that default instead of repeating the file
256
+ name on every call: `setup_list_configs` (which `.env` files exist),
257
+ `setup_set_default_config` (record one), `setup_get_default_config` (which one is
258
+ active), `setup_clear_default_config` (remove it — afterwards every call must
259
+ name its config explicitly).
260
+
261
+ ---
262
+
263
+ ## Frontend Pipeline (canonical)
264
+
265
+ This is the canonical (golden) path for the frontend track. It runs
266
+ **independently** from the backend pipeline. The backend API must be running and
267
+ reachable at `apiBaseUrl` before the generated frontend is useful, but the
268
+ frontend can be defined and generated without the backend live.
269
+
270
+ ```
271
+ 1. designer_list_plugins
272
+ ── GROUNDING ── list available output plugins before initializing.
273
+ Built-in: vanilla-js-basic (no auth), vanilla-js-auth (JWT auth).
274
+ → references/udf-catalog.md § Plugins
275
+
276
+ 2. designer_init_project
277
+ Scaffold a new frontend project from a plugin. Creates the project folder,
278
+ the initial UDF payload (payload.json), and plugin assets.
279
+
280
+ 3. designer_get_udf_catalog
281
+ ── GROUNDING ── call before defining or editing any UDF payload.
282
+ Returns valid field types, page anatomy, features, data-source formats,
283
+ and validation rules for the installed plugin version.
284
+ → references/udf-catalog.md
285
+
286
+ 4. [define / edit UDF payload JSON]
287
+ Edit payload.json: appConfig, pages[], navigation[], homepage.
288
+ One page entry = one CRUD page or one dashboard page.
289
+
290
+ 5. designer_validate_payload
291
+ ── GATE ── validate the UDF payload. Catches structural errors before
292
+ generation. Run before preview or generate, every time.
293
+
294
+ 6. designer_preview_files
295
+ Dry-run: list files that would be generated, without writing to disk.
296
+ Use to verify scope before an overwrite.
297
+
298
+ 7. designer_generate
299
+ Generate frontend HTML/JS/CSS from the UDF payload. Writes output files.
300
+ The agent STOPS here — the user opens the output in a browser.
301
+ ```
302
+
303
+ For plugin development (custom output plugins):
304
+
305
+ ```
306
+ designer_scaffold_plugin → [develop plugin templates]
307
+ → designer_inspect_plugin (verify plugin metadata and capabilities)
308
+ → designer_generate (test generation with the custom plugin)
309
+ ```
310
+
311
+ Two checkpoints (see Guardrails): **step 5** is a gate — never `designer_generate`
312
+ an unvalidated payload; **step 7** is where the agent stops (generates files, does
313
+ not serve or deploy).
314
+
315
+ Licensing note: the Designer tools (`designer_preview_files`, `designer_generate`,
316
+ etc.) do **not** require a RESTForge license, unlike the `codegen_*`, `runtime_*`,
317
+ and `setup_validate_config` tools on the backend track.
318
+
319
+ ---
320
+
321
+ ## Auth Extension
322
+
323
+ RESTForge has **two different auth mechanisms — do not confuse them.** Pick the
324
+ right one; never describe one as the other, and never claim the extension does RBAC.
325
+
326
+ | Mechanism | RBAC? | How |
327
+ |---|---|---|
328
+ | **Plugin auth** — built into the frontend at generation time | **Yes (auth + RBAC)** | `vanilla-js-auth` or `vanilla-js-custom` plugin in `designer_init_project`; disable with `noAuth: true` (`--no-auth`) |
329
+ | **Auth extension** — bolt-on added to an existing project | **No RBAC** | backend `project_auth`; frontend `designer_auth_create` (embedded `rfx_auth`) |
330
+
331
+ Confirm which plugins provide auth with `designer_list_plugins` — do not hardcode
332
+ it. The rest of this section covers the **extension** (the no-RBAC bolt-on); for
333
+ plugin auth see Decision Points § Frontend plugin choice. Google Sign-In and
334
+ `@restforgejs/auth` are out of scope for the extension.
335
+
336
+ ### Backend auth — `project_auth`
337
+
338
+ Adds the auth backend to an existing RESTForge project (run the standard backend
339
+ pipeline first; the project and its endpoint must already exist, and the DB must
340
+ be active).
341
+
342
+ ```
343
+ project_auth (wraps: npx restforge project auth --create --project=<name>)
344
+ ```
345
+
346
+ Installs auth SDF (`rfx`), DB tables, middleware, router, six processors
347
+ (register/login/refresh/logout/me/reset-password), a random `JWT_SECRET`, and
348
+ `bcrypt`+`jsonwebtoken`. Idempotent. → references/auth.md § Backend
349
+
350
+ ### Frontend auth — `designer_auth_create` / `designer_auth_remove`
351
+
352
+ Adds (or removes) an **embedded** login / signup / forget-password overlay
353
+ (`rfx_auth`) on an existing frontend project, at route
354
+ `/api/<project>/rfx_auth`. This is independent of the `vanilla-js-auth` plugin.
355
+
356
+ ```
357
+ designer_auth_create (wraps: npx restforge-designer auth --create --project=<name>)
358
+ designer_auth_remove (wraps: npx restforge-designer auth --remove --project=<name> --force)
359
+ ```
360
+
361
+ `create` writes the auth pages + `js/rfx_auth.js` and injects a guard into existing
362
+ pages; `remove` deletes them. Idempotent. Runs via `npx restforge-designer`
363
+ (bundled in `@restforgejs/platform`; available once the project was created with
364
+ `npx create-restforge-app` / the platform is installed).
365
+ → references/auth.md § Frontend
366
+
367
+ ### Retrofit on a generated app — `designer_auth_attach`
368
+
369
+ ```
370
+ designer_auth_attach (wraps: npx restforge-designer auth --attach --project=<name>)
371
+ ```
372
+
373
+ The "turn auth on afterwards" path for an app whose pages already exist. It
374
+ installs `js/rfx_auth.js`, injects the script tag into the existing pages (except
375
+ the login page), and writes the `embeddedAuth` marker — **page files themselves
376
+ are never touched**, so customisations survive. When the project payload has an
377
+ auth block on an auth-capable plugin (`vanilla-js-auth` / `vanilla-js-custom`) it
378
+ additionally renders the plugin login artifacts (`js/auth.js`, `login.html`,
379
+ `js/login.js`) and extends `js/config.js` with a marked block; in that mode the
380
+ `rfx_auth` login/signup pages are not written, and the storage key is aligned with
381
+ the plugin login so both sides read the same session. Idempotent — existing files
382
+ are skipped unless `overwrite` is set.
383
+
384
+ Pick between the two: `designer_auth_create` when the app just needs a standalone
385
+ login/signup overlay and no auth-capable plugin is in play;
386
+ `designer_auth_attach` when the pages already exist, the plugin is
387
+ `vanilla-js-auth` / `vanilla-js-custom`, or `designer_generate` reported missing
388
+ auth artifacts. The CLI accepts exactly one of `--create` / `--attach` /
389
+ `--remove` per invocation.
390
+
391
+ Do not combine the two mechanisms on one app: if an app already has plugin auth
392
+ (`vanilla-js-auth` / `vanilla-js-custom`), do not also add embedded `rfx_auth`.
393
+
394
+ ---
395
+
396
+ ## Grounding-First Rules
397
+
398
+ Before reasoning about, proposing, or generating any **definition content** —
399
+ SDF fields, RDF `fieldValidation`, queries, dashboard widgets, or UDF pages —
400
+ call the matching grounding tool first and use only what it returns. Never write
401
+ definition content from memory.
402
+
403
+ | Context | Grounding tool | Reference |
404
+ |---|---|---|
405
+ | Defining or reviewing SDF | `codegen_get_dbschema_catalog` | references/dbschema-catalog.md |
406
+ | Deriving SDF from a UI design (HTML / image / screenshot) | `codegen_get_dbschema_catalog` | references/design-to-sdf.md |
407
+ | Defining `fieldValidation` in an RDF payload | `codegen_get_field_validation_catalog` | references/field-validation.md |
408
+ | Defining queries in an RDF payload | `codegen_get_query_declarative_catalog` | — |
409
+ | Defining a dashboard payload | `codegen_get_dashboard_catalog` | — |
410
+ | Defining UDF (frontend) | `designer_get_udf_catalog` | references/udf-catalog.md |
411
+ | Listing available frontend plugins | `designer_list_plugins` | references/udf-catalog.md § Plugins |
412
+ | Setting `db-connection.env` parameters | `setup_get_config_schema` | references/config-schema.md |
413
+
414
+ **Why this rule exists.** The catalog is the source of truth for valid options
415
+ in the *installed* platform version. Reasoning without it produces confident but
416
+ wrong output — field types that do not exist, constraints not applicable to a
417
+ type, or wrong semantics. Two concrete failure modes this rule prevents:
418
+
419
+ - **Inventing options.** Without grounding, an agent may write a made-up key
420
+ (e.g. `"toUpper": true`) that the validator rejects. The catalog gives the
421
+ exact key and value type.
422
+ - **Misreading semantics.** A constraint can mean something different from its
423
+ plain-English name. For example, `uppercase` on a `string` field is a
424
+ *normalization transform* (it forces the stored value to upper case), grouped
425
+ with `trim` and `lowercase` — it is **not** a validator that rejects
426
+ non-uppercase input. If the user wants rejection, the answer is `pattern`, not
427
+ `uppercase`; if they want database-level enforcement, that is an SDF check
428
+ constraint, not RDF `fieldValidation`. Grounding surfaces this distinction
429
+ before the agent commits to the wrong one.
430
+
431
+ The reference files help you *understand* the catalog; they do **not** replace
432
+ the tool. Call the tool to ground, produce, and validate — do not hand-produce
433
+ output a tool would generate. The live tool is authoritative; when a reference and
434
+ the tool disagree, trust the tool.
435
+
436
+ ---
437
+
438
+ ## Decision Points
439
+
440
+ Use these to pick the correct branch when the request is state-dependent. Each
441
+ branch still obeys the Grounding-First Rules above.
442
+
443
+ ### Schema (SDF)
444
+
445
+ - **DB does not exist** → `codegen_dbschema_init` (scaffold with audit columns)
446
+ or `codegen_dbschema_template` (minimal template, no DB connection required).
447
+ - **DB already exists** → `codegen_dbschema_introspect` to generate SDF from the
448
+ actual schema. Do not hand-write a schema that a real DB can describe.
449
+ - **Question about what the DB already contains** → `codegen_list_tables` (tables
450
+ and views) and `codegen_describe_table` (columns, primary key, foreign keys,
451
+ indexes of one table). Both are read-only live introspection; they are the
452
+ safe way to answer such a question without generating anything.
453
+ - **Starting from a UI design** (HTML mockup, screenshot, image, Figma export)
454
+ → first confirm the design is an entity to model, not a dashboard/analytics
455
+ screen (those map to the Dashboard RDF branch below, not to a new SDF table).
456
+ Then classify visible elements into stored / derived / relation / audit, draft
457
+ the SDF, and run `codegen_dbschema_validate`. The design shows presentation,
458
+ not storage — do not turn every visible label into a column.
459
+ → references/design-to-sdf.md
460
+ - **DB exists with drift** → `codegen_dbschema_diff` to review, then
461
+ `codegen_dbschema_apply`. Not `codegen_dbschema_migrate` — that is for empty
462
+ DBs only.
463
+
464
+ ### RDF Payload
465
+
466
+ - **No payload yet** → `codegen_generate_payload`.
467
+ - **Payload exists, edit is API-layer only** (e.g. add/adjust `fieldValidation`,
468
+ messages, or a query — no column added or dropped) → ground via the matching
469
+ catalog, edit `payload.json`, run `codegen_validate_payload`, then regenerate
470
+ with `codegen_create_endpoint`. No DB migration: the schema (SDF) is unchanged.
471
+ - **Payload exists, DB schema changed** → `codegen_diff_payload` first, then
472
+ `codegen_sync_payload` (non-breaking) or `codegen_migrate_payload` (breaking).
473
+ - **Custom query needed** → ground via `codegen_get_query_declarative_catalog`,
474
+ check the statement with `codegen_validate_sql` against the live database, then
475
+ set `datatablesQuery`, `viewQuery`, or `exportQuery` in the payload. External
476
+ SQL files use the `file:` prefix
477
+ (e.g. `"datatablesQuery": "file:sql/orders.sql"`). Validating first turns a
478
+ runtime 500 into an error message before the payload is even written.
479
+
480
+ > **"Add an uppercase / case constraint" is ambiguous — disambiguate first.**
481
+ > In RESTForge `uppercase` is an RDF `fieldValidation` *normalization transform*
482
+ > (forces the stored value to upper case), not a reject-if-not-uppercase
483
+ > validator. If the user wants rejection, use `pattern`. If the user wants the
484
+ > database to enforce it, that is an SDF check constraint, not RDF. Confirm which
485
+ > one is meant before editing — see Grounding-First Rules § Misreading semantics.
486
+
487
+ ### Backend module type
488
+
489
+ - **Standard CRUD** → `codegen_create_endpoint`. One payload = one module.
490
+ - **Analytic dashboard** → `codegen_validate_dashboard_payload`, then
491
+ `codegen_create_dashboard`. Payload must have `widgets` (not `tableName`); page
492
+ name must be prefixed `dash-`; the payload argument keeps its `.json`
493
+ extension.
494
+ - **Background job** → `codegen_create_processor`.
495
+ - **Kafka event consumer** → `codegen_create_kafka_consumer`; requires
496
+ `KAFKA_ENABLED=true` in config. The consumer runtime is a separate process:
497
+ `runtime_generate_consumer_launcher` prepares it (host scripts or PM2 deploy
498
+ files) and the user starts it.
499
+ - **JavaScript client for a generated project** → `project_sdk_generate`. Run it
500
+ after the endpoints exist, and after `project_auth` when the project needs
501
+ auth, so `client.auth` is included.
502
+ - **Integration test for an existing endpoint** → `codegen_generate_test`.
503
+ - **Workflow (status transitions)** → add `workflow` and `workflowActions` to the
504
+ RDF payload; generates a `/change-status` endpoint automatically.
505
+ → references/rdf-advanced.md § Workflow
506
+ - **Master-detail (composite CRUD)** → add `details[]` to the RDF payload;
507
+ generates `/create-composite`, `/update-composite`, `/read-composite`.
508
+ → references/rdf-advanced.md § Master-Detail
509
+ - **Excel export** → `/export` works by default (falls back to
510
+ `SELECT {fields} FROM tableName`); customise the columns/filter with
511
+ `exportQuery` in the RDF payload. Tune `EXPORT_FILE_EXPIRY` / `EXPORT_CHUNK_SIZE`
512
+ in config. Ground `exportQuery` via `codegen_get_query_declarative_catalog`.
513
+ → references/rdf-advanced.md § Data Source Resolution
514
+ - **Excel import (.xlsx)** → add `importConfig` (sheet, startRow, strategy,
515
+ upsertKey, columns header→fieldName, optional lookup) to the RDF payload;
516
+ generates `/import-preview` (validates, returns a diff) and `/import-commit`
517
+ (applies). → references/rdf-advanced.md § Import Config
518
+ - Activate on an existing project: edit the payload to add `importConfig`
519
+ (and/or `exportQuery`) → `codegen_validate_payload` → `codegen_create_endpoint`.
520
+
521
+ ### Soft-delete vs hard-delete
522
+
523
+ - Use soft-delete when deleted rows must be audited or recoverable. Declare
524
+ `softDelete: { enabled: true }` in SDF and add the three contract columns
525
+ (`is_deleted`, `deleted_at`, `deleted_by`).
526
+ - Soft-delete is supported on PostgreSQL only (Phase 1).
527
+ - Tables with composite UNIQUE constraints are incompatible with soft-delete.
528
+
529
+ ### Data seeding / migration (rows, not schema)
530
+
531
+ Move table **rows** through SDF-driven envelope files. This is for data, never
532
+ for schema — use the dbschema tools for structure.
533
+
534
+ **Default output location:** `data-storage/<schema>/<table>.json`, relative to the
535
+ project cwd. The `data-storage` folder is the default of the `storagePath` param
536
+ (CLI `--storage-path <folder>`); override it to write elsewhere. The SDF read from
537
+ is `schemaPath` (CLI `--schema-path`, default `schema`).
538
+
539
+ - **Export / dump / snapshot / back up rows** → `data_pull`. Scope is exactly one
540
+ of `table`, `schema`, or `allSchemas`. Only tables registered in the SDF can be
541
+ pulled. `force: true` overwrites existing envelope files. Optional `limit`,
542
+ `batchSize`, `config` (falls back to the default set via `config set-default`,
543
+ i.e. `.restforge/defaults.json`), `schemaPath`, `storagePath`.
544
+ - **Import / load / seed / restore rows** → `data_push`. Same file names as
545
+ `data_pull`, so pulled files push back directly. Scope is exactly one of `table`,
546
+ `schema`, or `allSchemas`; for `schema`/`allSchemas` tables load in FK
547
+ parent→child order.
548
+ - **Move data between databases** → `data_pull` from the source, then `data_push`
549
+ into the target (`config` selects the env per side).
550
+ - ⚠ `data_push` is **APPEND-ONLY** (batch INSERT, no upsert/replace). Running it
551
+ twice inserts the rows twice. Confirm with the user before pushing into a
552
+ database that may already hold those rows.
553
+
554
+ ### Frontend page type
555
+
556
+ - **Standard CRUD page** → `pageType: "crud"` (default) with `apiPath`,
557
+ `primaryKey`, `displayField`, and `fields[]`.
558
+ - **Dashboard page** → `pageType: "dashboard"` with `dataSources[]` and `rows[]`
559
+ containing widget columns.
560
+ → references/udf-catalog.md § Dashboard Page
561
+ - **Page with approval workflow** → add `workflow.statusField` and
562
+ `workflowActions[]` to the page.
563
+
564
+ ### Frontend plugin choice
565
+
566
+ - **No auth** → `vanilla-js-basic`.
567
+ - **Auth WITH RBAC, built into the app** → `vanilla-js-auth` or
568
+ `vanilla-js-custom` at `designer_init_project`. Use `noAuth: true` (`--no-auth`)
569
+ to get the plugin's UI without its auth.
570
+ - **Custom branding / new plugin** → `designer_scaffold_plugin`.
571
+ - **Bolt-on auth WITHOUT RBAC** → not a plugin; see Authentication below.
572
+ → references/udf-catalog.md § Plugins
573
+
574
+ ### Authentication
575
+
576
+ - **Needs RBAC** → plugin auth (`vanilla-js-auth` / `vanilla-js-custom`) at
577
+ `designer_init_project`. The extension below does **not** do RBAC.
578
+ - **Backend auth on an existing project (no RBAC)** → `project_auth` (after the
579
+ project and its endpoint exist, with an active DB).
580
+ - **Frontend auth on an app built WITHOUT plugin auth (no RBAC)** →
581
+ `designer_auth_create` (embedded `rfx_auth`).
582
+ - **Remove embedded frontend auth** → `designer_auth_remove` — destructive,
583
+ confirm first (see Guardrails).
584
+
585
+ ---
586
+
587
+ ## Guardrails
588
+
589
+ These are hard rules. They override convenience and override an eager reading of
590
+ the user's request. When a guardrail conflicts with finishing faster, the
591
+ guardrail wins.
592
+
593
+ **1. Confirm before destructive operations.**
594
+ The following require explicit user confirmation before execution:
595
+
596
+ - `codegen_dbschema_migrate` or `codegen_dbschema_apply` that drops a table or
597
+ column, or alters a column in a way that loses data.
598
+ - `project_delete` — permanent project deletion.
599
+ - `project_sdk_generate` with `force: true` — the SDK files are rewritten in
600
+ place with **no** archive backup, so hand edits inside the SDK folder are lost,
601
+ and resource files of endpoints that no longer exist are left behind.
602
+ - `setup_validate_config` with `autoCreateDb: true` — it runs CREATE DATABASE on
603
+ the database server. The default call is read-only.
604
+
605
+ `codegen_create_endpoint` and `codegen_create_dashboard` overwrite by default
606
+ (`force` is true) but archive the previous version as `.archive.NNN` first, so
607
+ they need a plain intent confirmation rather than a destructive-operation
608
+ confirmation. Use `force: false` when the point is to find out whether the module
609
+ already exists: the endpoint command then stops at its confirmation question
610
+ without writing, and the dashboard command refuses with a clean error.
611
+
612
+ For schema changes, run `codegen_dbschema_diff` first, present a summary of the
613
+ destructive parts (dropped tables/columns, type narrowing), and wait for
614
+ confirmation before calling `codegen_dbschema_apply`. Never infer approval from
615
+ the original request — "update the schema" is not consent to drop a column.
616
+
617
+ **2. The agent does not run the server.**
618
+ The agent's last step on the backend track is `runtime_generate_launcher`. The
619
+ user executes the launcher in their own terminal. The agent never calls shell
620
+ commands to start, stop, or restart the server, and never assumes the server is
621
+ running — verify with `runtime_check_status` instead. The same rule covers the
622
+ Kafka consumer runtime: `runtime_generate_consumer_launcher` only writes the
623
+ scripts or the PM2 deploy files; starting the consumer belongs to the user. A
624
+ process spawned from an agent session dies with the session.
625
+
626
+ **3. The `validate_config` gate is mandatory.**
627
+ `setup_validate_config` must pass before any `codegen_*` operation starts. Do not
628
+ skip it "to save a step" — running codegen against an invalid config produces
629
+ uninformative errors that cost more time than the gate.
630
+
631
+ **4. Validate before generating.**
632
+ Always run `codegen_validate_payload` before `codegen_create_*`, and
633
+ `designer_validate_payload` before `designer_generate`. For a dashboard payload
634
+ the matching validator is `codegen_validate_dashboard_payload` — the general one
635
+ does not understand the `widgets` shape. Generation on an invalid payload
636
+ produces incomplete or broken output that looks like it succeeded.
637
+
638
+ **5. Stay inside the task scope.**
639
+ Do not modify files outside the requested task. If the change is a backend
640
+ payload edit, do not also "tidy up" the SDF, the runtime, or the frontend. If a
641
+ change genuinely requires touching another area (e.g. an RDF edit that needs a
642
+ new column, which is an SDF change), stop and report the cross-over, then ask
643
+ before expanding scope.
644
+
645
+ **6. Ground before defining — repeated here because it is a guardrail, not a
646
+ suggestion.** Never write SDF fields, `fieldValidation`, queries, dashboard
647
+ widgets, or UDF content from memory. Call the matching catalog tool first (see
648
+ Grounding-First Rules). Inventing an option that "should" exist is the most
649
+ common way to produce confidently wrong output.
650
+
651
+ **7. Confirm before removing embedded auth.**
652
+ `designer_auth_remove` deletes the auth files (`login.html`, `signup.html`, the
653
+ forget-password overlay, `js/rfx_auth.js`) and strips the guard from existing
654
+ pages. Under MCP it runs with `--force` (no interactive prompt), so confirm the
655
+ project name and intent with the user **before** calling it.
656
+
657
+ **8. Execute through tools; never emulate them.** The bundled `references/` help
658
+ you *understand* options — they do not replace the tools. When a tool can produce
659
+ or validate an artifact (`codegen_dbschema_template`/`init`,
660
+ `codegen_generate_payload`, any `*_validate_*`), **call it**; do not hand-write its
661
+ output by reading a reference. Emulating the generator is slower, loses
662
+ determinism, and drifts from what the installed version emits. If the tool is not
663
+ available, stop (see Preflight) rather than improvising from the references.
664
+
665
+ ---
666
+
667
+ ## Tools outside this skill's workflows
668
+
669
+ These MCP tools exist and are callable, but they are not steps of the backend or
670
+ frontend pipeline. They are listed here so their absence from the pipelines reads
671
+ as a decision, not an omission — call them when the user asks for exactly that,
672
+ not as part of a generation run.
673
+
674
+ | Tool | Why it is outside the pipeline |
675
+ |---|---|
676
+ | `health_ping` | Transport smoke test — answers "is the MCP server itself responsive", touches nothing in RESTForge |
677
+ | `key_generate`, `key_list`, `key_revoke` | API key bookkeeping inside `.env` files; independent of definition files and code generation |
678
+ | `project_list` | Registry inventory (endpoint count, database type, creation date) — useful for orientation, never a prerequisite of a later step |
679
+
680
+ `license deactivate` has no MCP tool at all, on purpose: it frees a machine slot
681
+ across machines, so the user runs it manually. `license_info` (read-only) is the
682
+ wrapped half of that pair.
683
+
684
+ ---
685
+
686
+ ## Prerequisites and Common Errors
687
+
688
+ ### Environment prerequisites
689
+
690
+ - Node.js ≥ 18.
691
+ - A reachable database matching the configured `DB_TYPE` (PostgreSQL, MySQL,
692
+ Oracle, or SQLite).
693
+ - A valid RESTForge license for `codegen_*`, `runtime_*`, and
694
+ `setup_validate_config`. Designer tools do not require a license.
695
+ - The RESTForge MCP server registered in the client
696
+ (`npm install -g @restforgejs/mcp-server`, then registered as the `restforge`
697
+ MCP server). Without it, none of the tools below exist.
698
+ - Redis if using cache, distributed lock, or live sync.
699
+ - Kafka if using a Kafka consumer (`KAFKA_ENABLED=true`).
700
+
701
+ ### Required backend config parameters
702
+
703
+ Nine of the full parameter set are mandatory before `setup_validate_config` can
704
+ pass:
705
+
706
+ `LICENSE`, `SERVER_ADDRESS`, `SERVER_PORT`, `DB_TYPE`, `DB_HOST`, `DB_PORT`,
707
+ `DB_USER`, `DB_PASSWORD`, `DB_NAME`.
708
+
709
+ → references/config-schema.md for the full parameter list, and
710
+ `setup_get_config_schema` for the live version of it.
711
+
712
+ ### Tools that depend on the installed platform version
713
+
714
+ Two tools wrap CLI sub-commands that older platforms do not have. Both fail in a
715
+ recognisable way, so treat the failure as a version answer, not a payload problem:
716
+
717
+ | Tool | Requirement | Symptom on an older platform |
718
+ |---|---|---|
719
+ | `codegen_validate_sql` | a platform providing `query validate` (confirmed present in 5.5.5; the exact minimum is not established) | `Unknown command: query` |
720
+ | `codegen_validate_dashboard_payload` | a platform providing `dashboard create --validate-only`, which exists only after 5.5.5 | `Unknown flag: --validate-only`; the tool reports it as an upgrade requirement |
721
+
722
+ When `codegen_validate_dashboard_payload` is unavailable, the fallback is
723
+ `codegen_create_dashboard` itself — it runs the same validator before writing.
724
+
725
+ ### Common error patterns
726
+
727
+ | Symptom | Cause | Recovery |
728
+ |---|---|---|
729
+ | Tool not found / no `codegen_*` tools available | MCP server not registered in the client | Install `@restforgejs/mcp-server`, register it as the `restforge` MCP server, restart the client |
730
+ | "authenticity check failed" / HTTP 401 | License not active or expired | Set `LICENSE` in `config/db-connection.env`, run `setup_validate_config` |
731
+ | HTTP 429 from license server | Rate limit (10 req/min/IP) | Expected since v5.1.15 — the client falls back to cache; wait or retry |
732
+ | DB connection failed | Wrong DB config or DB not running | Check `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`; verify the DB is running |
733
+ | "softDelete contract violation" | Contract columns missing or wrong type | Fix the SDF declaration, run `codegen_dbschema_validate` |
734
+ | "Widget uses undeclared placeholder" | `:paramName` in SQL not in `params` | Add the entry to `params` in the dashboard payload |
735
+ | "tableName and widgets conflict" | Payload contains both | Dashboard uses `widgets`; CRUD uses `tableName` — remove the wrong one |
736
+ | UDF validation error on field type | Field type not supported by the active plugin | Run `designer_list_plugins` + `designer_get_udf_catalog` to verify supported types |
737
+
738
+ When an error is not in this table, do not guess a fix. Re-run the relevant
739
+ `*_validate_*` tool, read its message, and ground against the catalog before
740
+ changing the definition.