@dforge-core/dforge-mcp 0.1.0-rc.11 → 0.1.0-rc.13
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.
- package/CHANGELOG.md +132 -0
- package/README.md +75 -21
- package/dist/server.js +2405 -272
- package/docs/creating-modules.md +7 -3
- package/package.json +11 -6
- package/resources/docs/conventions.md +20 -14
- package/resources/schemas/entity.schema.json +8 -1
- package/resources/schemas/reports.schema.json +4 -0
- package/skills/dforge-mcp-author/SKILL.md +227 -95
- package/skills/dforge-mcp-author/examples/simple-todo/README.md +38 -0
- package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_item.json +83 -0
- package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_list.json +43 -0
- package/skills/dforge-mcp-author/examples/simple-todo/logic/actions/mark_done.dsl +6 -0
- package/skills/dforge-mcp-author/examples/simple-todo/manifest.json +32 -0
- package/skills/dforge-mcp-author/examples/simple-todo/security/roles.json +10 -0
- package/skills/dforge-mcp-author/examples/simple-todo/seed-data/01-lists.json +17 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/actions.json +11 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/data_views.json +35 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/menus.json +28 -0
- package/skills/dforge-mcp-author/references/action-dsl.md +397 -0
- package/skills/dforge-mcp-author/references/column-types.md +168 -0
- package/skills/dforge-mcp-author/references/conventions.md +177 -0
- package/skills/dforge-mcp-author/references/data-migration.md +270 -0
- package/skills/dforge-mcp-author/references/data-views.md +192 -0
- package/skills/dforge-mcp-author/references/excel-import.md +61 -0
- package/skills/dforge-mcp-author/references/field-types.md +144 -0
- package/skills/dforge-mcp-author/references/filters.md +326 -0
- package/skills/dforge-mcp-author/references/flags.md +73 -0
- package/skills/dforge-mcp-author/references/formulas.md +206 -0
- package/skills/dforge-mcp-author/references/jobs.md +149 -0
- package/skills/dforge-mcp-author/references/manifest.md +123 -0
- package/skills/dforge-mcp-author/references/menus.md +164 -0
- package/skills/dforge-mcp-author/references/number-sequences.md +117 -0
- package/skills/dforge-mcp-author/references/print-templates.md +159 -0
- package/skills/dforge-mcp-author/references/queries.md +312 -0
- package/skills/dforge-mcp-author/references/reports.md +398 -0
- package/skills/dforge-mcp-author/references/schema-import.md +331 -0
- package/skills/dforge-mcp-author/references/security.md +244 -0
- package/skills/dforge-mcp-author/references/settings.md +120 -0
- package/skills/dforge-mcp-author/references/traits.md +153 -0
- package/skills/dforge-mcp-author/references/translations.md +158 -0
- package/skills/dforge-mcp-author/references/validation-checklist.md +182 -0
- package/skills/dforge-mcp-author/scripts/xlsx_to_model.py +198 -0
package/docs/creating-modules.md
CHANGED
|
@@ -64,10 +64,14 @@ You: "I want a module to collect end-user feedback on app pages."
|
|
|
64
64
|
|
|
65
65
|
The wizard runs:
|
|
66
66
|
|
|
67
|
-
### Phase 0 —
|
|
67
|
+
### Phase 0 — Identity, requirements, design, validation (required)
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
A documented chain the `dforge-mcp-author` skill enforces — the AI authors each artifact directly (drafts it, you approve, your client writes the file):
|
|
70
|
+
|
|
71
|
+
- **0a Identity** — write `CLAUDE.md` (identity + MCP-first rules + a live status tracker).
|
|
72
|
+
- **0b Requirements** — intake questions (purpose / users / dependencies / language scope), then write `docs/REQUIREMENTS.md`. **You review it before moving on.**
|
|
73
|
+
- **0c Design** — entity list, relationships, status machines, then write `docs/DESIGN.md`. **You review it before moving on.**
|
|
74
|
+
- **0d Validation** — the AI cross-checks the documents, reports every gap/flaw/inconsistency to `docs/VALIDATION.md`, and must reach a clean pass before scaffolding.
|
|
71
75
|
|
|
72
76
|
### Phase 1 — Domain (required, looping)
|
|
73
77
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dforge-core/dforge-mcp",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.13",
|
|
4
4
|
"description": "MCP server for dForge module authoring. Exposes scaffold/pack/install tools and schema resources so AI agents (Claude Code, Cursor, Zed) can create and ship dForge modules.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/iash44/dForge-core",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"docs/",
|
|
17
17
|
"resources/",
|
|
18
18
|
"skills/",
|
|
19
|
-
"README.md"
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md"
|
|
20
21
|
],
|
|
21
22
|
"main": "dist/server.js",
|
|
22
23
|
"engines": {
|
|
@@ -24,17 +25,21 @@
|
|
|
24
25
|
},
|
|
25
26
|
"scripts": {
|
|
26
27
|
"build": "tsup",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
28
|
+
"sync-schemas": "node scripts/vendor-schemas.cjs",
|
|
29
|
+
"prepublishOnly": "node scripts/vendor-schemas.cjs && tsup",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run"
|
|
29
32
|
},
|
|
30
33
|
"dependencies": {
|
|
31
|
-
"@dforge-core/dforge-cli": "^0.
|
|
34
|
+
"@dforge-core/dforge-cli": "^0.2.2",
|
|
35
|
+
"@dforge-core/metadata": "^0.0.2",
|
|
32
36
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
37
|
"zod": "^4.4.3"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
40
|
"@types/node": "^22.10.2",
|
|
37
41
|
"tsup": "^8.5.1",
|
|
38
|
-
"typescript": "^6.0.3"
|
|
42
|
+
"typescript": "^6.0.3",
|
|
43
|
+
"vitest": "^3.2.0"
|
|
39
44
|
}
|
|
40
45
|
}
|
|
@@ -84,7 +84,7 @@ Use the CRM sample module (`modules/crm/`) as a reference implementation.
|
|
|
84
84
|
```json
|
|
85
85
|
{
|
|
86
86
|
"packageFormat": 1,
|
|
87
|
-
"moduleId": "
|
|
87
|
+
"moduleId": "REPLACE-WITH-A-FRESH-UUID",
|
|
88
88
|
"code": "hr",
|
|
89
89
|
"version": "0.0.1",
|
|
90
90
|
"dbSchemaVersion": "0.0.1",
|
|
@@ -492,7 +492,7 @@ before the install pipeline touches the database.
|
|
|
492
492
|
- Key is the role code (convention: `module.role-name`)
|
|
493
493
|
- **Property name is `"rights"` (NOT `"entityRights"`)** — this maps to `RoleDef.Rights`
|
|
494
494
|
- Each entry in `rights` maps entity code → rights string
|
|
495
|
-
- Rights characters: `S` (Select), `I` (Insert), `U` (Update), `D` (Delete), `C` (Clone)
|
|
495
|
+
- Rights characters: `S` (Select), `I` (Insert), `U` (Update), `D` (Delete), `C` (Clone) for entities, and `E` (Execute) for actions, reports, and folder access (e.g. `"action:create_quote": "E"`). The roles JSON schema enforces `^[SIUDCE]*$`.
|
|
496
496
|
- Every entity should appear in every role (even if only `"S"` for read-only)
|
|
497
497
|
|
|
498
498
|
**Common Mistakes:**
|
|
@@ -518,7 +518,7 @@ seed-data/
|
|
|
518
518
|
"entityCode": "department",
|
|
519
519
|
"records": [
|
|
520
520
|
{
|
|
521
|
-
"department_id":
|
|
521
|
+
"department_id": 3001,
|
|
522
522
|
"department_code": "EXEC",
|
|
523
523
|
"department_name": "Executive / Leadership",
|
|
524
524
|
"is_active": true
|
|
@@ -530,10 +530,10 @@ seed-data/
|
|
|
530
530
|
**Rules:**
|
|
531
531
|
- Files are loaded alphabetically — use numbered prefixes (01-, 02-, etc.)
|
|
532
532
|
- Parent tables must come before child tables (FK dependency order)
|
|
533
|
-
- Include explicit PK values
|
|
534
|
-
- Use a stable
|
|
533
|
+
- Include explicit PK values so child records can reference them
|
|
534
|
+
- PKs from the `identity` trait are `cuid` — physically `int8` (bigint), **not** UUID strings. Use numeric integers with a stable per-entity scheme: `1001`–`1099` for the first entity type, `2001`–`2099` for the next, etc. Using UUID strings here fails the seed load against `int8` columns.
|
|
535
535
|
- Inserts use `ON CONFLICT DO NOTHING` (idempotent)
|
|
536
|
-
-
|
|
536
|
+
- Dates in string format are auto-converted by the seed runner
|
|
537
537
|
- Omit auto-generated fields (`created_date`, `last_updated`) — they use DB defaults
|
|
538
538
|
- Omit cross-module FK fields (e.g., `owner_id` referencing `user` table)
|
|
539
539
|
|
|
@@ -593,13 +593,16 @@ Cron-driven action fires. Each entry pairs an existing action (declared in `ui/a
|
|
|
593
593
|
"menus": {
|
|
594
594
|
"hr_menu": { "label": "Human Resources" }
|
|
595
595
|
},
|
|
596
|
-
"
|
|
597
|
-
"
|
|
598
|
-
"hr.viewer": { "label": "HR Viewer" }
|
|
596
|
+
"actions": {
|
|
597
|
+
"approve_leave": { "label": "Approve Leave", "desc": "Approve a leave request" }
|
|
599
598
|
}
|
|
600
599
|
}
|
|
601
600
|
```
|
|
602
601
|
|
|
602
|
+
**Translatable sections (consumed by the installer):** `entities` (+ nested `fields`), `folders`, `views`, `menus` (+ nested `items`), `actions` (+ `params`), `reports` (+ `datasets.caption`, `params`).
|
|
603
|
+
|
|
604
|
+
**Silently ignored at runtime:** `roles` and `print_templates` — the resource rows have no `res_id`, so translations are reserved for future use. `settings` is validated for completeness (when listed in `supportedLocales`) but the registrar does not display the translated labels, so don't expect localized output. Display names for these come from the source manifest (`description` for roles, `label` for print templates and settings).
|
|
605
|
+
|
|
603
606
|
---
|
|
604
607
|
|
|
605
608
|
## Entity Definitions (`entities/*.json`)
|
|
@@ -613,7 +616,7 @@ Cron-driven action fires. Each entry pairs an existing action (declared in `ui/a
|
|
|
613
616
|
"toString": "{first_name} {last_name}",
|
|
614
617
|
"fields": {
|
|
615
618
|
"employee_id": {
|
|
616
|
-
"dbDatatype": "
|
|
619
|
+
"dbDatatype": "cuid",
|
|
617
620
|
"isPk": true,
|
|
618
621
|
"isIdentity": true,
|
|
619
622
|
"isNullable": false,
|
|
@@ -630,7 +633,8 @@ Cron-driven action fires. Each entry pairs an existing action (declared in `ui/a
|
|
|
630
633
|
"description": "Employee Code"
|
|
631
634
|
},
|
|
632
635
|
"department_id": {
|
|
633
|
-
"dbDatatype": "
|
|
636
|
+
"dbDatatype": "cuid",
|
|
637
|
+
"fieldTypeCd": "hidden",
|
|
634
638
|
"flags": "EM",
|
|
635
639
|
"orderNum": 30,
|
|
636
640
|
"description": "Department ID"
|
|
@@ -703,7 +707,8 @@ For every foreign key relationship, create TWO columns:
|
|
|
703
707
|
### 1. Hidden FK Column (Database)
|
|
704
708
|
```json
|
|
705
709
|
"department_id": {
|
|
706
|
-
"dbDatatype": "
|
|
710
|
+
"dbDatatype": "cuid",
|
|
711
|
+
"fieldTypeCd": "hidden",
|
|
707
712
|
"flags": "EM",
|
|
708
713
|
"orderNum": 30,
|
|
709
714
|
"description": "Department ID"
|
|
@@ -742,6 +747,7 @@ For every foreign key relationship, create TWO columns:
|
|
|
742
747
|
- `params` is used for other purposes (e.g., dropdown `options`)
|
|
743
748
|
- Hidden FK column: `flags: "EM"` (no `V` = hidden from UI)
|
|
744
749
|
- Visible reference column: `flags: "VEM"`, `columnType: "R"`
|
|
750
|
+
- The FK column's `dbDatatype` **MUST match the referenced PK's type** — use `cuid` for `identity`-trait PKs (`cuid` is physically `int8`, **not** a UUID). A mismatch (e.g. FK `uuid` → PK `cuid`) fails install with *"foreign key constraint … cannot be implemented"*.
|
|
745
751
|
|
|
746
752
|
---
|
|
747
753
|
|
|
@@ -921,8 +927,8 @@ When creating a module, ensure:
|
|
|
921
927
|
- [ ] `folders.json` uses entity dictionary with `{ viewName, quickAdd }` objects
|
|
922
928
|
- [ ] `roles.json` uses `"rights"` property (not `"entityRights"`)
|
|
923
929
|
- [ ] Seed data files are numbered for FK dependency order (01-, 02-, etc.)
|
|
924
|
-
- [ ] Seed data includes explicit
|
|
925
|
-
- [ ] `translations
|
|
930
|
+
- [ ] Seed data includes explicit numeric (int8) PKs for cross-entity references — NOT UUID strings (`cuid` is `int8`)
|
|
931
|
+
- [ ] `translations/<locale>.json` covers entities (+ fields), folders, views, menus (+ items), actions (+ params), and reports (+ dataset captions, + params) for every locale declared in `manifest.supportedLocales`. Do not include `en`/`en-US`. Sections `roles` and `print_templates` are not displayed even if listed.
|
|
926
932
|
- [ ] Constraints have clear user-facing `message` values
|
|
927
933
|
- [ ] Check constraint `expression` uses standard SQL subset (test in PostgreSQL first)
|
|
928
934
|
- [ ] Number sequences declared as `numberSequence` on entity definitions (auto-fills on INSERT, never manual counting)
|
|
@@ -46,7 +46,10 @@
|
|
|
46
46
|
},
|
|
47
47
|
"fields": {
|
|
48
48
|
"type": "object",
|
|
49
|
-
"description": "Column definitions keyed by column code",
|
|
49
|
+
"description": "Column definitions keyed by column code. Column codes must start with a letter or underscore and contain only letters, digits, and underscores — a leading `-` is reserved for the sort descending prefix in `view_json.order`.",
|
|
50
|
+
"propertyNames": {
|
|
51
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
|
|
52
|
+
},
|
|
50
53
|
"additionalProperties": {
|
|
51
54
|
"$ref": "#/$defs/field"
|
|
52
55
|
}
|
|
@@ -196,6 +199,10 @@
|
|
|
196
199
|
"$ref": "#/$defs/fieldLink",
|
|
197
200
|
"description": "Relationship link for Reference (R) and Set (S) columns"
|
|
198
201
|
},
|
|
202
|
+
"cyclic": {
|
|
203
|
+
"type": "boolean",
|
|
204
|
+
"description": "On a self-referencing reference column (R column whose link.entity is the owning entity), set true to ALLOW parent/child cycles. When absent the self-reference is treated as an acyclic hierarchy and DB-level guards reject loops. Ignored on non-self-referencing columns."
|
|
205
|
+
},
|
|
199
206
|
"refFilter": {
|
|
200
207
|
"description": "Filter criteria for reference lookups"
|
|
201
208
|
}
|
|
@@ -159,6 +159,10 @@
|
|
|
159
159
|
"description": "Field type code (see settings.schema.json for the common list)"
|
|
160
160
|
},
|
|
161
161
|
"label": { "type": "string" },
|
|
162
|
+
"orderNum": {
|
|
163
|
+
"type": "integer",
|
|
164
|
+
"description": "Display order of the parameter in the report's parameter form. Read by ReportRegistrar (paramDef.OrderNum); falls back to declaration order when omitted."
|
|
165
|
+
},
|
|
162
166
|
"required": {
|
|
163
167
|
"type": "boolean",
|
|
164
168
|
"default": false,
|