@dforge-core/dforge-mcp 0.1.0-rc.1 → 0.1.0-rc.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dforge-core/dforge-mcp",
3
- "version": "0.1.0-rc.1",
3
+ "version": "0.1.0-rc.3",
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",
@@ -27,9 +27,9 @@
27
27
  "typecheck": "tsc --noEmit"
28
28
  },
29
29
  "dependencies": {
30
- "@dforge-core/dforge-cli": "0.1.0-rc.6",
31
- "@modelcontextprotocol/sdk": "^1.0.4",
32
- "zod": "^3.24.1"
30
+ "@dforge-core/dforge-cli": "^0.1.0",
31
+ "@modelcontextprotocol/sdk": "^1.29.0",
32
+ "zod": "^4.4.3"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "^22.10.2",
@@ -38,7 +38,8 @@
38
38
  "description": "Data sources providing data for this view"
39
39
  },
40
40
  "filter": {
41
- "description": "Default filter criteria"
41
+ "$ref": "#/$defs/filter",
42
+ "description": "Default filter criteria (applied to all dataSources unless one declares its own)"
42
43
  },
43
44
  "order": {
44
45
  "description": "Default sort order"
@@ -291,6 +292,56 @@
291
292
  "parentSetField": {
292
293
  "type": "string",
293
294
  "description": "Set field name on parent entity linking to this detail level"
295
+ },
296
+ "filter": {
297
+ "$ref": "#/$defs/filter",
298
+ "description": "Per-source filter criteria; overrides the view-level filter for this source"
299
+ },
300
+ "order": {
301
+ "description": "Per-source sort order (array of {c, d} entries, where d is 'asc' or 'desc')"
302
+ }
303
+ },
304
+ "additionalProperties": false
305
+ },
306
+
307
+ "filter": {
308
+ "description": "Canonical dForge filter expression. Either a single condition `{c, o, v}` or a group `{g, i: [...]}`. Used by data views, reports, folders (row-level security), and the API.",
309
+ "oneOf": [
310
+ { "$ref": "#/$defs/filterCondition" },
311
+ { "$ref": "#/$defs/filterGroup" }
312
+ ]
313
+ },
314
+ "filterCondition": {
315
+ "type": "object",
316
+ "required": ["c", "o"],
317
+ "properties": {
318
+ "c": {
319
+ "type": "string",
320
+ "description": "Column code (supports dot navigation: 'customer.name')"
321
+ },
322
+ "o": {
323
+ "type": "string",
324
+ "description": "Operator: eq, neq, =, !=, gt, gtEq, grEq, lt, ltEq, in, nIn, like, isNull, isNotNull, etc."
325
+ },
326
+ "v": {
327
+ "description": "Comparison value. Scalars, arrays (for in/nIn), or parameter references like '@param_code'."
328
+ }
329
+ },
330
+ "additionalProperties": false
331
+ },
332
+ "filterGroup": {
333
+ "type": "object",
334
+ "required": ["g", "i"],
335
+ "properties": {
336
+ "g": {
337
+ "type": "string",
338
+ "enum": ["and", "or"],
339
+ "description": "Group combinator"
340
+ },
341
+ "i": {
342
+ "type": "array",
343
+ "items": { "$ref": "#/$defs/filter" },
344
+ "description": "Group items: nested conditions or sub-groups"
294
345
  }
295
346
  },
296
347
  "additionalProperties": false
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/folders.schema.json",
4
+ "title": "dForge Folders",
5
+ "description": "Folder definitions for a dForge module",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/folder"
9
+ },
10
+ "$defs": {
11
+ "folder": {
12
+ "type": "object",
13
+ "required": ["label"],
14
+ "properties": {
15
+ "label": {
16
+ "type": "string",
17
+ "description": "Folder display name"
18
+ },
19
+ "description": {
20
+ "type": "string",
21
+ "description": "Optional description text (shown in breadcrumb/header area)"
22
+ },
23
+ "parentCode": {
24
+ "type": ["string", "null"],
25
+ "description": "Parent folder code (null for root folders)"
26
+ },
27
+ "folderPath": {
28
+ "type": "string",
29
+ "description": "URL-friendly folder path"
30
+ },
31
+ "color": {
32
+ "type": "string",
33
+ "description": "Folder accent color (hex)"
34
+ },
35
+ "icon": {
36
+ "type": "string",
37
+ "description": "Bootstrap icon class (e.g. 'bi-folder')"
38
+ },
39
+ "inheritSecurity": {
40
+ "type": "boolean",
41
+ "description": "Whether to inherit security from parent folder"
42
+ },
43
+ "entities": {
44
+ "type": "object",
45
+ "description": "Entity code → folder-entity config",
46
+ "additionalProperties": {
47
+ "$ref": "#/$defs/folderEntity"
48
+ }
49
+ }
50
+ },
51
+ "additionalProperties": false
52
+ },
53
+ "folderEntity": {
54
+ "type": "object",
55
+ "properties": {
56
+ "viewName": {
57
+ "type": "string",
58
+ "description": "Entity view name to use in this folder"
59
+ },
60
+ "quickAdd": {
61
+ "type": "boolean",
62
+ "description": "Enable quick-add for this entity in this folder"
63
+ },
64
+ "rowFilter": {
65
+ "description": "Row-level filter criteria for this entity in this folder"
66
+ }
67
+ },
68
+ "additionalProperties": false
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,83 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "dForge Module Scheduled Jobs",
4
+ "description": "Cron job declarations for a dForge module package (logic/jobs.json). The dForge.Scheduler service polls these and fires each job on its schedule.",
5
+ "type": "object",
6
+ "required": ["jobs"],
7
+ "properties": {
8
+ "jobs": {
9
+ "type": "array",
10
+ "maxItems": 50,
11
+ "description": "At most 50 jobs per module — guard against accidental fan-out from generated declarations.",
12
+ "items": {
13
+ "type": "object",
14
+ "required": ["code", "action", "schedule", "timeout"],
15
+ "properties": {
16
+ "code": {
17
+ "type": "string",
18
+ "maxLength": 100,
19
+ "pattern": "^[a-z][a-z0-9_]*$",
20
+ "description": "Unique identifier within the module."
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "description": "Human-readable description of what the job does."
25
+ },
26
+ "action": {
27
+ "type": "string",
28
+ "description": "Action code in this module (e.g. 'generate_invoices'). The scheduler resolves it to action_implementation.impl_id at install time."
29
+ },
30
+ "schedule": {
31
+ "type": "string",
32
+ "description": "Five-field cron expression (minute granularity). Sub-minute schedules are rejected.",
33
+ "pattern": "^\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+$"
34
+ },
35
+ "params": {
36
+ "type": "object",
37
+ "description": "Static parameters passed to the action as __params. Folder-scoped overrides go through module settings, not here.",
38
+ "additionalProperties": true
39
+ },
40
+ "timeout": {
41
+ "type": "integer",
42
+ "minimum": 1,
43
+ "maximum": 3600,
44
+ "description": "Hard timeout in seconds. Required — there is no implicit default. Must be > 300 only if class = 'long_running' (60-minute hard ceiling)."
45
+ },
46
+ "concurrency": {
47
+ "type": "integer",
48
+ "minimum": 1,
49
+ "maximum": 5,
50
+ "default": 1,
51
+ "description": "Max parallel runs. 1 means single-instance; the scheduler skips a new fire if a previous one is still in flight (Phase 3 enforcement)."
52
+ },
53
+ "idempotencyKey": {
54
+ "type": "string",
55
+ "description": "Template like '{job_cd}:{run.month}'. Resolved at fire time. A successful run with the same key blocks re-dispatch (Phase 3 enforcement)."
56
+ },
57
+ "class": {
58
+ "type": "string",
59
+ "enum": ["standard", "long_running"],
60
+ "default": "standard",
61
+ "description": "Routing class. 'long_running' is opt-in and required for any timeout > 300 seconds."
62
+ },
63
+ "timeZone": {
64
+ "type": "string",
65
+ "description": "IANA tz name (e.g. 'Asia/Tokyo'). Overrides the tenant default. Omit to fall back to auth.tenant.time_zone."
66
+ },
67
+ "enabled": {
68
+ "type": "boolean",
69
+ "default": true,
70
+ "description": "Master switch. False fully disables (no scheduler, no manual trigger)."
71
+ },
72
+ "paused": {
73
+ "type": "boolean",
74
+ "default": false,
75
+ "description": "Soft pause. Scheduler skips firing, but admin 'trigger now' still works."
76
+ }
77
+ },
78
+ "additionalProperties": false
79
+ }
80
+ }
81
+ },
82
+ "additionalProperties": false
83
+ }
@@ -86,6 +86,11 @@
86
86
  "type": "string",
87
87
  "description": "Module category for display (e.g. 'Integration', 'Finance')"
88
88
  },
89
+ "tags": {
90
+ "type": "array",
91
+ "items": { "type": "string" },
92
+ "description": "Free-form tags for search and discovery (e.g. ['crm', 'sales', 'leads']). Convention: lowercase, hyphen-separated."
93
+ },
89
94
  "icon": {
90
95
  "type": "string",
91
96
  "description": "Bootstrap icon class (e.g. 'bi-link-45deg')"
@@ -94,6 +99,16 @@
94
99
  "type": "array",
95
100
  "items": { "type": "string", "pattern": "^[a-z]{2,3}(-[A-Z]{2})?$" },
96
101
  "description": "Non-English locales the package promises to translate. Each entry MUST match a translations/<locale>.json file, and every translatable resource (entity/field labels, folders, views, menus + items, actions + params, reports + datasets + params, settings) MUST have a label in that file. English is the default — don't list 'en' or 'en-US'."
102
+ },
103
+ "created": {
104
+ "type": "string",
105
+ "format": "date",
106
+ "description": "Initial creation date of the module package (YYYY-MM-DD). Informational only; not enforced by the installer."
107
+ },
108
+ "updated": {
109
+ "type": "string",
110
+ "format": "date",
111
+ "description": "Last edit date of the manifest (YYYY-MM-DD). Informational; bump when shipping a new version."
97
112
  }
98
113
  },
99
114
  "additionalProperties": false
@@ -0,0 +1,86 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/menus.schema.json",
4
+ "title": "dForge Menus",
5
+ "description": "Menu definitions for a dForge module",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/menu"
9
+ },
10
+ "$defs": {
11
+ "menu": {
12
+ "type": "object",
13
+ "required": ["label", "items"],
14
+ "properties": {
15
+ "label": {
16
+ "type": "string",
17
+ "description": "Menu display name"
18
+ },
19
+ "description": {
20
+ "type": "string",
21
+ "description": "Optional description text (tooltip, subtitle)"
22
+ },
23
+ "folders": {
24
+ "type": "array",
25
+ "items": { "type": "string" },
26
+ "description": "Folder codes where this menu is available"
27
+ },
28
+ "items": {
29
+ "type": "object",
30
+ "description": "Menu items keyed by item code",
31
+ "additionalProperties": {
32
+ "$ref": "#/$defs/menuItem"
33
+ }
34
+ }
35
+ },
36
+ "additionalProperties": false
37
+ },
38
+ "menuItem": {
39
+ "type": "object",
40
+ "required": ["orderNum", "label"],
41
+ "properties": {
42
+ "itemType": {
43
+ "type": ["string", "null"],
44
+ "enum": ["V", "D", "R", null],
45
+ "description": "Item type: V=Data View, D=Document, R=Report, null=folder/section"
46
+ },
47
+ "dataViewCode": {
48
+ "type": "string",
49
+ "description": "Data view code (when itemType is 'V')"
50
+ },
51
+ "documentCode": {
52
+ "type": "string",
53
+ "description": "Document code (when itemType is 'D')"
54
+ },
55
+ "reportCode": {
56
+ "type": "string",
57
+ "description": "Report code (when itemType is 'R')"
58
+ },
59
+ "orderNum": {
60
+ "type": "integer",
61
+ "description": "Display order"
62
+ },
63
+ "label": {
64
+ "type": "string",
65
+ "description": "Menu item display text"
66
+ },
67
+ "description": {
68
+ "type": "string",
69
+ "description": "Optional description text (tooltip, subtitle)"
70
+ },
71
+ "icon": {
72
+ "type": "string",
73
+ "description": "Bootstrap icon name"
74
+ },
75
+ "children": {
76
+ "type": "object",
77
+ "description": "Child menu items (for folder/section items)",
78
+ "additionalProperties": {
79
+ "$ref": "#/$defs/menuItem"
80
+ }
81
+ }
82
+ },
83
+ "additionalProperties": false
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,204 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/reports.schema.json",
4
+ "title": "dForge Module Reports",
5
+ "description": "Report definitions for a dForge module: a map of report code → report definition. Reports are not listed in manifest.json; the install pipeline picks up ui/reports.json automatically.",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/report"
9
+ },
10
+ "$defs": {
11
+ "report": {
12
+ "type": "object",
13
+ "required": ["description", "layout", "datasets"],
14
+ "properties": {
15
+ "description": {
16
+ "type": "string",
17
+ "description": "Human-readable report title"
18
+ },
19
+ "layout": {
20
+ "$ref": "#/$defs/layout"
21
+ },
22
+ "datasets": {
23
+ "type": "object",
24
+ "description": "Map of dataset code → dataset definition. Panels reference datasets by code via `datasetCd`.",
25
+ "additionalProperties": { "$ref": "#/$defs/dataset" }
26
+ },
27
+ "parameters": {
28
+ "type": "object",
29
+ "description": "Report-level parameters (alternative to per-dataset `params`). Map of param code → param definition.",
30
+ "additionalProperties": { "$ref": "#/$defs/paramDef" }
31
+ }
32
+ },
33
+ "additionalProperties": false
34
+ },
35
+
36
+ "layout": {
37
+ "type": "object",
38
+ "required": ["panels"],
39
+ "properties": {
40
+ "panels": {
41
+ "type": "array",
42
+ "items": { "$ref": "#/$defs/panel" }
43
+ }
44
+ },
45
+ "additionalProperties": false
46
+ },
47
+
48
+ "panel": {
49
+ "type": "object",
50
+ "required": ["vizType", "datasetCd"],
51
+ "properties": {
52
+ "vizType": {
53
+ "type": "string",
54
+ "enum": ["table", "chart", "metric", "pivot"],
55
+ "description": "Visualization type"
56
+ },
57
+ "datasetCd": {
58
+ "type": "string",
59
+ "description": "Dataset code (key in the parent `datasets` map)"
60
+ },
61
+ "title": { "type": "string" },
62
+ "config": {
63
+ "type": "object",
64
+ "description": "Viz-type-specific configuration. For chart: { chartType, categoryCol, valueCol, agg, chartSize }. For table: { groupRules, aggregations }."
65
+ }
66
+ },
67
+ "additionalProperties": false
68
+ },
69
+
70
+ "dataset": {
71
+ "type": "object",
72
+ "required": ["datasetType"],
73
+ "properties": {
74
+ "caption": {
75
+ "type": "string",
76
+ "description": "Display label for the dataset (used in panel headings if no `title`)"
77
+ },
78
+ "datasetType": {
79
+ "type": "string",
80
+ "enum": ["Q", "S"],
81
+ "description": "Q = SQL/entity query, S = stored procedure"
82
+ },
83
+ "query": {
84
+ "$ref": "#/$defs/query",
85
+ "description": "Used when datasetType is 'Q'"
86
+ },
87
+ "procedureName": {
88
+ "type": "string",
89
+ "description": "Used when datasetType is 'S'"
90
+ },
91
+ "columnsDef": {
92
+ "type": "object",
93
+ "description": "Optional column metadata overrides: field code → { label, visible, ... }",
94
+ "additionalProperties": { "$ref": "#/$defs/columnDef" }
95
+ },
96
+ "params": {
97
+ "type": "object",
98
+ "description": "Dataset-level parameters (alternative to top-level `parameters`)",
99
+ "additionalProperties": { "$ref": "#/$defs/paramDef" }
100
+ }
101
+ },
102
+ "additionalProperties": false
103
+ },
104
+
105
+ "query": {
106
+ "type": "object",
107
+ "required": ["entityCd"],
108
+ "properties": {
109
+ "entityCd": {
110
+ "type": "string",
111
+ "description": "Source entity code"
112
+ },
113
+ "columns": {
114
+ "type": "array",
115
+ "items": { "type": "string" },
116
+ "description": "Column codes to select (supports dot navigation: 'customer.name')"
117
+ },
118
+ "filter": {
119
+ "$ref": "#/$defs/filter"
120
+ },
121
+ "sort": {
122
+ "type": "array",
123
+ "items": { "$ref": "#/$defs/sortClause" }
124
+ }
125
+ },
126
+ "additionalProperties": false
127
+ },
128
+
129
+ "sortClause": {
130
+ "type": "object",
131
+ "required": ["c"],
132
+ "properties": {
133
+ "c": { "type": "string", "description": "Column code" },
134
+ "d": {
135
+ "type": "string",
136
+ "enum": ["asc", "desc"],
137
+ "description": "Sort direction (default: asc)"
138
+ }
139
+ },
140
+ "additionalProperties": false
141
+ },
142
+
143
+ "columnDef": {
144
+ "type": "object",
145
+ "properties": {
146
+ "label": { "type": "string" },
147
+ "visible": { "type": "boolean" },
148
+ "width": { "type": "integer", "minimum": 1 }
149
+ },
150
+ "additionalProperties": false
151
+ },
152
+
153
+ "paramDef": {
154
+ "type": "object",
155
+ "required": ["fieldTypeCd"],
156
+ "properties": {
157
+ "fieldTypeCd": {
158
+ "type": "string",
159
+ "description": "Field type code (see settings.schema.json for the common list)"
160
+ },
161
+ "label": { "type": "string" },
162
+ "required": { "type": "boolean", "default": false },
163
+ "default": {
164
+ "description": "Default value applied if the user doesn't provide one"
165
+ },
166
+ "params": {
167
+ "type": "object",
168
+ "description": "Field-type-specific params (e.g. lookup → { link: { entity, otherKey } })"
169
+ }
170
+ },
171
+ "additionalProperties": false
172
+ },
173
+
174
+ "filter": {
175
+ "description": "Canonical dForge filter expression — same shape as data_views.json filter. Either `{c, o, v}` or `{g, i: [...]}`.",
176
+ "oneOf": [
177
+ { "$ref": "#/$defs/filterCondition" },
178
+ { "$ref": "#/$defs/filterGroup" }
179
+ ]
180
+ },
181
+ "filterCondition": {
182
+ "type": "object",
183
+ "required": ["c", "o"],
184
+ "properties": {
185
+ "c": { "type": "string" },
186
+ "o": { "type": "string" },
187
+ "v": {}
188
+ },
189
+ "additionalProperties": false
190
+ },
191
+ "filterGroup": {
192
+ "type": "object",
193
+ "required": ["g", "i"],
194
+ "properties": {
195
+ "g": { "type": "string", "enum": ["and", "or"] },
196
+ "i": {
197
+ "type": "array",
198
+ "items": { "$ref": "#/$defs/filter" }
199
+ }
200
+ },
201
+ "additionalProperties": false
202
+ }
203
+ }
204
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/roles.schema.json",
4
+ "title": "dForge Roles",
5
+ "description": "Role definitions with entity rights for a dForge module",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/role"
9
+ },
10
+ "$defs": {
11
+ "role": {
12
+ "type": "object",
13
+ "required": ["description", "rights"],
14
+ "properties": {
15
+ "description": {
16
+ "type": "string",
17
+ "description": "Role display name"
18
+ },
19
+ "rights": {
20
+ "type": "object",
21
+ "description": "Entity rights: entity code → rights string",
22
+ "additionalProperties": {
23
+ "type": "string",
24
+ "pattern": "^[SIUDCE]*$",
25
+ "description": "Rights: S=Select, I=Insert, U=Update, D=Delete, C=Clone, E=Execute"
26
+ }
27
+ }
28
+ },
29
+ "additionalProperties": false
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/seed_data.schema.json",
4
+ "title": "dForge Seed Data",
5
+ "description": "Seed data records for a dForge entity",
6
+ "type": "object",
7
+ "required": ["entityCode", "records"],
8
+ "properties": {
9
+ "entityCode": {
10
+ "type": "string",
11
+ "description": "Target entity code to insert records into"
12
+ },
13
+ "records": {
14
+ "type": "array",
15
+ "description": "Array of records, each record is an object with column_code → value",
16
+ "items": {
17
+ "type": "object",
18
+ "additionalProperties": true
19
+ }
20
+ }
21
+ },
22
+ "additionalProperties": false
23
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://dforge.dev/schemas/settings.schema.json",
4
+ "title": "dForge Module Settings",
5
+ "description": "Module-level settings definitions: a flat map of setting code → setting definition. Settings are folder-scoped at runtime (values inherit through the folder tree) and surface in the Module Settings UI.",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "$ref": "#/$defs/setting"
9
+ },
10
+ "$defs": {
11
+ "setting": {
12
+ "type": "object",
13
+ "required": ["fieldTypeCd"],
14
+ "properties": {
15
+ "fieldTypeCd": {
16
+ "type": "string",
17
+ "description": "Field type code (must match one in dforge.field_type). Common values: text, number, integer, decimal, boolean, checkbox, dropdown, multiSelect, date, dateTime, time, image, file, fileList, lookup, color, currency, percent, html, markdown, password, email, phone, url, textarea, json."
18
+ },
19
+ "baseDatatypeCd": {
20
+ "type": "string",
21
+ "enum": ["string", "number", "bool", "date", "dateTime", "time", "json"],
22
+ "description": "Underlying primitive datatype. Older settings declare this explicitly; newer settings (using `formula`) often omit it."
23
+ },
24
+ "label": {
25
+ "type": "string",
26
+ "description": "Display label (newer style). Prefer this over `description`/`desc` for new settings."
27
+ },
28
+ "description": {
29
+ "type": "string",
30
+ "description": "Display label (older style). Use `label` for new settings."
31
+ },
32
+ "desc": {
33
+ "type": "string",
34
+ "description": "Alternative label key used by some older modules. Prefer `label`."
35
+ },
36
+ "defaultValue": {
37
+ "description": "Default value before the user sets one. Type matches `baseDatatypeCd`."
38
+ },
39
+ "formula": {
40
+ "type": "string",
41
+ "description": "Formula expression to evaluate the default (e.g. \"'USD'\"). Alternative to `defaultValue`."
42
+ },
43
+ "required": {
44
+ "type": "boolean",
45
+ "description": "If true, the setting must be set somewhere in the folder chain for installation to proceed."
46
+ },
47
+ "params": {
48
+ "type": "object",
49
+ "description": "Field-type-specific parameters. Examples: dropdown → { options: [...] }; number → { min, max }; lookup → { link: { entity, otherKey } }."
50
+ }
51
+ },
52
+ "additionalProperties": false
53
+ }
54
+ }
55
+ }