@praxisui/page-builder 9.0.0-beta.10 → 9.0.0-beta.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/README.md +1 -1
- package/ai/component-registry.json +3150 -0
- package/fesm2022/praxisui-page-builder.mjs +378 -18
- package/package.json +8 -5
- package/types/praxisui-page-builder.d.ts +13 -1
|
@@ -0,0 +1,3150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"generatedAt": "2026-06-22T22:56:44.148Z",
|
|
4
|
+
"packageName": "@praxisui/page-builder",
|
|
5
|
+
"packageVersion": "9.0.0-beta.13",
|
|
6
|
+
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
|
+
"sourceRegistryVersion": "1.0.0",
|
|
8
|
+
"componentCount": 1,
|
|
9
|
+
"components": {
|
|
10
|
+
"praxis-page-builder": {
|
|
11
|
+
"id": "praxis-page-builder",
|
|
12
|
+
"description": "Page builder using the canonical praxis-dynamic-page runtime.",
|
|
13
|
+
"category": "page",
|
|
14
|
+
"inputs": [],
|
|
15
|
+
"outputs": [
|
|
16
|
+
{
|
|
17
|
+
"name": "pageChange",
|
|
18
|
+
"type": "WidgetPageDefinition",
|
|
19
|
+
"required": false
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "widgetEvent",
|
|
23
|
+
"type": "WidgetEventEnvelope",
|
|
24
|
+
"required": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "pageSaveRequested",
|
|
28
|
+
"type": "WidgetPageDefinition",
|
|
29
|
+
"required": false
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "agenticAuthoringApplied",
|
|
33
|
+
"type": "PageBuilderApplyResult",
|
|
34
|
+
"required": false
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "agenticAuthoringSharedRuleHandoff",
|
|
38
|
+
"type": "PageBuilderAgenticAuthoringSharedRuleHandoff",
|
|
39
|
+
"required": false
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "pageRestart",
|
|
43
|
+
"type": "void",
|
|
44
|
+
"required": false
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "savedPageDeleteRequested",
|
|
48
|
+
"type": "void",
|
|
49
|
+
"required": false
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"configSchemaId": null,
|
|
53
|
+
"selector": "praxis-dynamic-page-builder",
|
|
54
|
+
"friendlyName": "Praxis Page Builder",
|
|
55
|
+
"tags": [
|
|
56
|
+
"widget",
|
|
57
|
+
"page-builder",
|
|
58
|
+
"configurable"
|
|
59
|
+
],
|
|
60
|
+
"lib": "@praxisui/page-builder",
|
|
61
|
+
"source": "projects/praxis-page-builder/src/lib/praxis-page-builder.metadata.ts",
|
|
62
|
+
"exportName": "PRAXIS_PAGE_BUILDER_COMPONENT_METADATA",
|
|
63
|
+
"componentCapabilities": [
|
|
64
|
+
{
|
|
65
|
+
"path": "uiCompositionPlan",
|
|
66
|
+
"category": "page",
|
|
67
|
+
"valueKind": "object",
|
|
68
|
+
"description": "Plano declarativo intermediario aceito em preview agentic antes do WidgetPageDefinition."
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"path": "uiCompositionPlan.version",
|
|
72
|
+
"category": "page",
|
|
73
|
+
"valueKind": "string",
|
|
74
|
+
"description": "Versao do plano. Valor atual: 1.0."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"path": "uiCompositionPlan.kind",
|
|
78
|
+
"category": "page",
|
|
79
|
+
"valueKind": "string",
|
|
80
|
+
"description": "Discriminador do plano. Valor atual: praxis.ui-composition-plan."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"path": "uiCompositionPlan.layoutPreset",
|
|
84
|
+
"category": "layout",
|
|
85
|
+
"valueKind": "string",
|
|
86
|
+
"description": "Preset semantico opcional da composicao planejada."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"path": "uiCompositionPlan.layoutPresetOptions",
|
|
90
|
+
"category": "layout",
|
|
91
|
+
"valueKind": "object",
|
|
92
|
+
"description": "Opcoes semanticas opcionais do preset, como familia visual, estrategia responsiva e politica de densidade."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "uiCompositionPlan.grouping",
|
|
96
|
+
"category": "layout",
|
|
97
|
+
"valueKind": "array",
|
|
98
|
+
"description": "Agrupamentos semanticos opcionais para organizar widgets em hero, section, tabs ou rail no runtime."
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"path": "uiCompositionPlan.slotAssignments",
|
|
102
|
+
"category": "layout",
|
|
103
|
+
"valueKind": "object",
|
|
104
|
+
"description": "Mapa opcional widgetKey -> slot semantico para alinhar widgets gerados a presets de layout sem depender de dominio."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"path": "uiCompositionPlan.deviceLayouts",
|
|
108
|
+
"category": "layout",
|
|
109
|
+
"valueKind": "object",
|
|
110
|
+
"description": "Variantes responsivas opcionais para desktop, tablet e mobile, incluindo canvas, groupingOverrides e widgetOverrides."
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"path": "uiCompositionPlan.themePreset",
|
|
114
|
+
"category": "layout",
|
|
115
|
+
"valueKind": "string",
|
|
116
|
+
"description": "Preset visual opcional do runtime, por exemplo analytics-calm, workspace-balanced ou ops-monitoring."
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"path": "uiCompositionPlan.state",
|
|
120
|
+
"category": "state",
|
|
121
|
+
"valueKind": "object",
|
|
122
|
+
"description": "Estado inicial/declarativo que sera compilado para page.state."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"path": "uiCompositionPlan.widgets",
|
|
126
|
+
"category": "widgets",
|
|
127
|
+
"valueKind": "array",
|
|
128
|
+
"description": "Widgets planejados antes da compilacao para page.widgets."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"path": "uiCompositionPlan.widgets[].key",
|
|
132
|
+
"category": "widgets",
|
|
133
|
+
"valueKind": "string",
|
|
134
|
+
"description": "ID estavel do widget planejado.",
|
|
135
|
+
"critical": true
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"path": "uiCompositionPlan.widgets[].componentId",
|
|
139
|
+
"category": "widgets",
|
|
140
|
+
"valueKind": "string",
|
|
141
|
+
"description": "Componente registrado que sera compilado para definition.id.",
|
|
142
|
+
"critical": true
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"path": "uiCompositionPlan.widgets[].inputs",
|
|
146
|
+
"category": "widgets",
|
|
147
|
+
"valueKind": "object",
|
|
148
|
+
"description": "Inputs canonicos do componente, compilados para definition.inputs."
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"path": "uiCompositionPlan.widgets[].bindingOrder",
|
|
152
|
+
"category": "widgets",
|
|
153
|
+
"valueKind": "array",
|
|
154
|
+
"description": "Ordem declarativa de binding, compilada para definition.bindingOrder."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"path": "uiCompositionPlan.bindings",
|
|
158
|
+
"category": "connections",
|
|
159
|
+
"valueKind": "array",
|
|
160
|
+
"description": "Bindings declarativos que serao compilados para page.composition.links."
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"path": "uiCompositionPlan.bindings[].id",
|
|
164
|
+
"category": "connections",
|
|
165
|
+
"valueKind": "string",
|
|
166
|
+
"description": "Identificador estavel do binding planejado."
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"path": "uiCompositionPlan.bindings[].from",
|
|
170
|
+
"category": "connections",
|
|
171
|
+
"valueKind": "object",
|
|
172
|
+
"description": "Endpoint de origem: component-port ou state."
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"path": "uiCompositionPlan.bindings[].to",
|
|
176
|
+
"category": "connections",
|
|
177
|
+
"valueKind": "object",
|
|
178
|
+
"description": "Endpoint de destino: component-port, state ou global-action."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"path": "uiCompositionPlan.bindings[].to.[actionId]",
|
|
182
|
+
"category": "connections",
|
|
183
|
+
"valueKind": "string",
|
|
184
|
+
"description": "ID da action global quando uiCompositionPlan.bindings[].to.kind = global-action."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"path": "uiCompositionPlan.bindings[].to.payload",
|
|
188
|
+
"category": "connections",
|
|
189
|
+
"valueKind": "object",
|
|
190
|
+
"description": "Payload literal opcional para destino global-action planejado."
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"path": "uiCompositionPlan.bindings[].to.payloadExpr",
|
|
194
|
+
"category": "connections",
|
|
195
|
+
"valueKind": "string",
|
|
196
|
+
"description": "Path de payload opcional para destino global-action planejado."
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath",
|
|
200
|
+
"category": "connections",
|
|
201
|
+
"valueKind": "array",
|
|
202
|
+
"description": "Caminho estruturado para porta nested de origem. Use apenas com endpoint component-port; o owner top-level continua em from.widget."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath",
|
|
206
|
+
"category": "connections",
|
|
207
|
+
"valueKind": "array",
|
|
208
|
+
"description": "Caminho estruturado para porta nested de destino. Use apenas com endpoint component-port; o owner top-level continua em to.widget."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath[].kind",
|
|
212
|
+
"category": "connections",
|
|
213
|
+
"valueKind": "string",
|
|
214
|
+
"description": "Tipo do segmento nested de origem, como tab, nav, link, expansion, panel ou widget. O ultimo segmento deve ser widget."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath[].id",
|
|
218
|
+
"category": "connections",
|
|
219
|
+
"valueKind": "string",
|
|
220
|
+
"description": "Identificador estrutural estavel do container de origem no segmento nested, quando existir."
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath[].key",
|
|
224
|
+
"category": "connections",
|
|
225
|
+
"valueKind": "string",
|
|
226
|
+
"description": "Chave estavel do widget filho no segmento terminal widget de origem. Obrigatoria para endpoint nested persistido.",
|
|
227
|
+
"critical": true
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath[].index",
|
|
231
|
+
"category": "connections",
|
|
232
|
+
"valueKind": "number",
|
|
233
|
+
"description": "Indice auxiliar de origem para contexto visual/diagnostico; nao use como identidade primaria persistida."
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"path": "uiCompositionPlan.bindings[].from.nestedPath[].componentType",
|
|
237
|
+
"category": "connections",
|
|
238
|
+
"valueKind": "string",
|
|
239
|
+
"description": "Tipo do componente real do widget filho de origem, usado como verificacao auxiliar, nao como identidade primaria."
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath[].kind",
|
|
243
|
+
"category": "connections",
|
|
244
|
+
"valueKind": "string",
|
|
245
|
+
"description": "Tipo do segmento nested de destino, como tab, nav, link, expansion, panel ou widget. O ultimo segmento deve ser widget."
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath[].id",
|
|
249
|
+
"category": "connections",
|
|
250
|
+
"valueKind": "string",
|
|
251
|
+
"description": "Identificador estrutural estavel do container de destino no segmento nested, quando existir."
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath[].key",
|
|
255
|
+
"category": "connections",
|
|
256
|
+
"valueKind": "string",
|
|
257
|
+
"description": "Chave estavel do widget filho no segmento terminal widget de destino. Obrigatoria para endpoint nested persistido.",
|
|
258
|
+
"critical": true
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath[].index",
|
|
262
|
+
"category": "connections",
|
|
263
|
+
"valueKind": "number",
|
|
264
|
+
"description": "Indice auxiliar de destino para contexto visual/diagnostico; nao use como identidade primaria persistida."
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"path": "uiCompositionPlan.bindings[].to.nestedPath[].componentType",
|
|
268
|
+
"category": "connections",
|
|
269
|
+
"valueKind": "string",
|
|
270
|
+
"description": "Tipo do componente real do widget filho de destino, usado como verificacao auxiliar, nao como identidade primaria."
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"path": "uiCompositionPlan.bindings[].intent",
|
|
274
|
+
"category": "connections",
|
|
275
|
+
"valueKind": "string",
|
|
276
|
+
"description": "Intencao semantica do binding."
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"path": "uiCompositionPlan.bindings[].condition",
|
|
280
|
+
"category": "connections",
|
|
281
|
+
"valueKind": "expression",
|
|
282
|
+
"description": "Guarda opcional em Json Logic."
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"path": "uiCompositionPlan.bindings[].transform",
|
|
286
|
+
"category": "connections",
|
|
287
|
+
"valueKind": "object",
|
|
288
|
+
"description": "Transform declarativo: pick-path, query-context, template ou constant."
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"path": "uiCompositionPlan.bindings[].policy",
|
|
292
|
+
"category": "connections",
|
|
293
|
+
"valueKind": "object",
|
|
294
|
+
"description": "Politica operacional opcional do binding."
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"path": "page",
|
|
298
|
+
"category": "page",
|
|
299
|
+
"valueKind": "object",
|
|
300
|
+
"description": "Definicao da pagina (WidgetPageDefinition)."
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"path": "context",
|
|
304
|
+
"category": "context",
|
|
305
|
+
"valueKind": "object",
|
|
306
|
+
"description": "Contexto extra mesclado ao page.context."
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"path": "enableCustomization",
|
|
310
|
+
"category": "behavior",
|
|
311
|
+
"valueKind": "boolean",
|
|
312
|
+
"description": "Habilita modo de edicao."
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"path": "showSettingsButton",
|
|
316
|
+
"category": "behavior",
|
|
317
|
+
"valueKind": "boolean",
|
|
318
|
+
"description": "Exibe botao de settings."
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"path": "strictValidation",
|
|
322
|
+
"category": "behavior",
|
|
323
|
+
"valueKind": "boolean",
|
|
324
|
+
"description": "Validacao estrita do widget loader."
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"path": "layoutOptions",
|
|
328
|
+
"category": "layout",
|
|
329
|
+
"valueKind": "object",
|
|
330
|
+
"description": "Overrides residuais do host aceitos apenas para compatibilidade de migracao."
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"path": "layoutOptions.cols",
|
|
334
|
+
"category": "layout",
|
|
335
|
+
"valueKind": "number",
|
|
336
|
+
"description": "Compat: numero de colunas usado para derivar canvas padrao."
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"path": "layoutOptions.rowHeight",
|
|
340
|
+
"category": "layout",
|
|
341
|
+
"valueKind": "number",
|
|
342
|
+
"description": "Compat: altura de linha usada para derivar rowUnit do canvas."
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"path": "layoutOptions.gap",
|
|
346
|
+
"category": "layout",
|
|
347
|
+
"valueKind": "number",
|
|
348
|
+
"description": "Compat: espacamento usado para derivar gap do canvas."
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"path": "pageIdentity",
|
|
352
|
+
"category": "identity",
|
|
353
|
+
"valueKind": "object",
|
|
354
|
+
"description": "Identidade de persistencia da pagina."
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"path": "pageIdentity.appId",
|
|
358
|
+
"category": "identity",
|
|
359
|
+
"valueKind": "string",
|
|
360
|
+
"description": "App id (opcional)."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"path": "pageIdentity.tenantId",
|
|
364
|
+
"category": "identity",
|
|
365
|
+
"valueKind": "string",
|
|
366
|
+
"description": "Tenant id."
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"path": "pageIdentity.userId",
|
|
370
|
+
"category": "identity",
|
|
371
|
+
"valueKind": "string",
|
|
372
|
+
"description": "User id."
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"path": "pageIdentity.routePath",
|
|
376
|
+
"category": "identity",
|
|
377
|
+
"valueKind": "string",
|
|
378
|
+
"description": "Rota base da pagina."
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"path": "pageIdentity.locale",
|
|
382
|
+
"category": "identity",
|
|
383
|
+
"valueKind": "string",
|
|
384
|
+
"description": "Locale."
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"path": "page.canvas",
|
|
388
|
+
"category": "layout",
|
|
389
|
+
"valueKind": "object",
|
|
390
|
+
"description": "Canvas espacial canonico da pagina."
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"path": "page.canvas.mode",
|
|
394
|
+
"category": "layout",
|
|
395
|
+
"valueKind": "string",
|
|
396
|
+
"description": "Modo do canvas. O builder usa grid canonico."
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"path": "page.canvas.columns",
|
|
400
|
+
"category": "layout",
|
|
401
|
+
"valueKind": "number",
|
|
402
|
+
"description": "Numero de colunas do canvas."
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"path": "page.canvas.rowUnit",
|
|
406
|
+
"category": "layout",
|
|
407
|
+
"valueKind": "string",
|
|
408
|
+
"description": "Altura base das linhas do canvas (ex: 80px)."
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"path": "page.canvas.gap",
|
|
412
|
+
"category": "layout",
|
|
413
|
+
"valueKind": "string",
|
|
414
|
+
"description": "Espacamento entre itens do canvas."
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"path": "page.canvas.autoRows",
|
|
418
|
+
"category": "layout",
|
|
419
|
+
"valueKind": "string",
|
|
420
|
+
"description": "Politica de auto rows do canvas."
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"path": "page.canvas.items",
|
|
424
|
+
"category": "layout",
|
|
425
|
+
"valueKind": "object",
|
|
426
|
+
"description": "Mapa canonico de posicionamento espacial por widget key."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"path": "page.canvas.items.<widgetKey>.col",
|
|
430
|
+
"category": "layout",
|
|
431
|
+
"valueKind": "number",
|
|
432
|
+
"description": "Coluna inicial (1-based)."
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"path": "page.canvas.items.<widgetKey>.row",
|
|
436
|
+
"category": "layout",
|
|
437
|
+
"valueKind": "number",
|
|
438
|
+
"description": "Linha inicial (1-based)."
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"path": "page.canvas.items.<widgetKey>.colSpan",
|
|
442
|
+
"category": "layout",
|
|
443
|
+
"valueKind": "number",
|
|
444
|
+
"description": "Colunas ocupadas."
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"path": "page.canvas.items.<widgetKey>.rowSpan",
|
|
448
|
+
"category": "layout",
|
|
449
|
+
"valueKind": "number",
|
|
450
|
+
"description": "Linhas ocupadas."
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"path": "page.state",
|
|
454
|
+
"category": "state",
|
|
455
|
+
"valueKind": "object",
|
|
456
|
+
"description": "Estado declarativo opcional da pagina."
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"path": "page.state.values",
|
|
460
|
+
"category": "state",
|
|
461
|
+
"valueKind": "object",
|
|
462
|
+
"description": "Valores primarios persistiveis do estado da pagina."
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"path": "page.state.schema",
|
|
466
|
+
"category": "state",
|
|
467
|
+
"valueKind": "object",
|
|
468
|
+
"description": "Descritores dos paths de estado primario."
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"path": "page.state.derived",
|
|
472
|
+
"category": "state",
|
|
473
|
+
"valueKind": "object",
|
|
474
|
+
"description": "Descritores de estado derivado recomputado pelo runtime."
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"path": "page.widgets",
|
|
478
|
+
"category": "widgets",
|
|
479
|
+
"valueKind": "array",
|
|
480
|
+
"description": "Widgets da pagina."
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"path": "page.widgets[].key",
|
|
484
|
+
"category": "widgets",
|
|
485
|
+
"valueKind": "string",
|
|
486
|
+
"description": "ID unico do widget.",
|
|
487
|
+
"critical": true
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"path": "page.widgets[].className",
|
|
491
|
+
"category": "widgets",
|
|
492
|
+
"valueKind": "string",
|
|
493
|
+
"description": "Classe CSS do widget."
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"path": "page.widgets[].definition",
|
|
497
|
+
"category": "widgets",
|
|
498
|
+
"valueKind": "object",
|
|
499
|
+
"description": "Definicao do widget (WidgetDefinition)."
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
"path": "page.widgets[].definition.id",
|
|
503
|
+
"category": "widgets",
|
|
504
|
+
"valueKind": "string",
|
|
505
|
+
"description": "ID do componente registrado."
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"path": "page.widgets[].definition.inputs",
|
|
509
|
+
"category": "widgets",
|
|
510
|
+
"valueKind": "object",
|
|
511
|
+
"description": "Inputs do componente."
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
"path": "page.widgets[].definition.inputs.document",
|
|
515
|
+
"category": "widgets",
|
|
516
|
+
"valueKind": "object",
|
|
517
|
+
"description": "RichContentDocument quando definition.id for praxis-rich-content."
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"path": "page.widgets[].definition.bindingOrder",
|
|
521
|
+
"category": "widgets",
|
|
522
|
+
"valueKind": "array",
|
|
523
|
+
"description": "Ordem de aplicacao dos inputs."
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"path": "ComponentDocMeta.configEditor",
|
|
527
|
+
"category": "widgets",
|
|
528
|
+
"valueKind": "object",
|
|
529
|
+
"description": "Editor canonico de inputs publicado pela lib dona do componente e aberto pelo settings-panel do host."
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"path": "ComponentDocMeta.configEditor.component",
|
|
533
|
+
"category": "widgets",
|
|
534
|
+
"valueKind": "object",
|
|
535
|
+
"description": "Componente standalone que implementa SettingsValueProvider para editar definition.inputs."
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
"path": "ComponentDocMeta.configEditor.title",
|
|
539
|
+
"category": "widgets",
|
|
540
|
+
"valueKind": "string",
|
|
541
|
+
"description": "Titulo opcional usado pelo host ao abrir o editor de inputs do componente."
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"path": "ComponentDocMeta.authoringManifestRef",
|
|
545
|
+
"category": "widgets",
|
|
546
|
+
"valueKind": "object",
|
|
547
|
+
"description": "Referencia canonica para o manifesto executavel de authoring por IA publicado pela lib dona do componente."
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"path": "ComponentDocMeta.authoringManifestRef.componentId",
|
|
551
|
+
"category": "widgets",
|
|
552
|
+
"valueKind": "string",
|
|
553
|
+
"description": "ID do componente no registry/backend de manifestos de authoring."
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"path": "ComponentDocMeta.authoringManifestRef.source",
|
|
557
|
+
"category": "widgets",
|
|
558
|
+
"valueKind": "string",
|
|
559
|
+
"description": "Simbolo, modulo ou registry id estavel do manifesto usado para delegar edicoes governadas."
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"path": "page.composition",
|
|
563
|
+
"category": "connections",
|
|
564
|
+
"valueKind": "object",
|
|
565
|
+
"description": "Envelope canonico da composicao persistida."
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
"path": "page.composition.version",
|
|
569
|
+
"category": "connections",
|
|
570
|
+
"valueKind": "string",
|
|
571
|
+
"description": "Versao do envelope de composicao."
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
"path": "page.composition.links",
|
|
575
|
+
"category": "connections",
|
|
576
|
+
"valueKind": "array",
|
|
577
|
+
"description": "Links canonicos entre widgets, estado e actions globais."
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
"path": "page.composition.links[].id",
|
|
581
|
+
"category": "connections",
|
|
582
|
+
"valueKind": "string",
|
|
583
|
+
"description": "Identificador estavel do link."
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"path": "page.composition.links[].from",
|
|
587
|
+
"category": "connections",
|
|
588
|
+
"valueKind": "object",
|
|
589
|
+
"description": "Endpoint de origem do link."
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
"path": "page.composition.links[].to",
|
|
593
|
+
"category": "connections",
|
|
594
|
+
"valueKind": "object",
|
|
595
|
+
"description": "Endpoint de destino do link."
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
"path": "page.composition.links[].to.kind",
|
|
599
|
+
"category": "connections",
|
|
600
|
+
"valueKind": "string",
|
|
601
|
+
"description": "Tipo do endpoint de destino, incluindo global-action para command-dispatch declarativo."
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
"path": "page.composition.links[].to.ref.[actionId]",
|
|
605
|
+
"category": "connections",
|
|
606
|
+
"valueKind": "string",
|
|
607
|
+
"description": "ID da action global quando page.composition.links[].to.kind = global-action."
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"path": "page.composition.links[].to.ref.payload",
|
|
611
|
+
"category": "connections",
|
|
612
|
+
"valueKind": "object",
|
|
613
|
+
"description": "Payload estruturado opcional da action global persistida; quando omitido, o valor transformado do link segue como delivery value."
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"path": "page.composition.links[].to.ref.payloadExpr",
|
|
617
|
+
"category": "connections",
|
|
618
|
+
"valueKind": "expression",
|
|
619
|
+
"description": "Escape avancado explicito de payload da action global persistida."
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
"path": "page.composition.links[].to.ref.meta",
|
|
623
|
+
"category": "connections",
|
|
624
|
+
"valueKind": "object",
|
|
625
|
+
"description": "Metadados opcionais do GlobalActionRef persistido, sem criar executor paralelo."
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"path": "page.composition.links[].from.ref.nestedPath",
|
|
629
|
+
"category": "connections",
|
|
630
|
+
"valueKind": "array",
|
|
631
|
+
"description": "NestedPath canonico em endpoint component-port de origem persistido. Omita para top-level; nao serialize nestedPath: []."
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
"path": "page.composition.links[].from.ref.nestedPath[].key",
|
|
635
|
+
"category": "connections",
|
|
636
|
+
"valueKind": "string",
|
|
637
|
+
"description": "Chave estavel do widget filho no segmento terminal widget de origem. Obrigatoria para endpoint nested persistido.",
|
|
638
|
+
"critical": true
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"path": "page.composition.links[].to.ref.nestedPath",
|
|
642
|
+
"category": "connections",
|
|
643
|
+
"valueKind": "array",
|
|
644
|
+
"description": "NestedPath canonico em endpoint component-port de destino persistido. Omita para top-level; nao serialize nestedPath: []."
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"path": "page.composition.links[].to.ref.nestedPath[].key",
|
|
648
|
+
"category": "connections",
|
|
649
|
+
"valueKind": "string",
|
|
650
|
+
"description": "Chave estavel do widget filho no segmento terminal widget de destino. Obrigatoria para endpoint nested persistido.",
|
|
651
|
+
"critical": true
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
"path": "page.composition.links[].intent",
|
|
655
|
+
"category": "connections",
|
|
656
|
+
"valueKind": "string",
|
|
657
|
+
"description": "Intencao semantica do link."
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
"path": "page.composition.links[].transform",
|
|
661
|
+
"category": "connections",
|
|
662
|
+
"valueKind": "object",
|
|
663
|
+
"description": "Pipeline de transformacao do link."
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"path": "page.composition.links[].condition",
|
|
667
|
+
"category": "connections",
|
|
668
|
+
"valueKind": "expression",
|
|
669
|
+
"description": "Guarda semantica opcional do link, expressa como um unico AST Json Logic canonico."
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
"path": "page.composition.links[].policy",
|
|
673
|
+
"category": "connections",
|
|
674
|
+
"valueKind": "object",
|
|
675
|
+
"description": "Politicas operacionais opcionais do link, separadas da condition semantica."
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
"path": "page.composition.links[].metadata",
|
|
679
|
+
"category": "connections",
|
|
680
|
+
"valueKind": "object",
|
|
681
|
+
"description": "Metadados opcionais do link."
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
"path": "page.context",
|
|
685
|
+
"category": "context",
|
|
686
|
+
"valueKind": "object",
|
|
687
|
+
"description": "Contexto da pagina (compartilhado por widgets)."
|
|
688
|
+
}
|
|
689
|
+
],
|
|
690
|
+
"componentCapabilityNotes": [
|
|
691
|
+
"page segue o modelo canonico WidgetPageDefinition (widgets, composition.links, context e state opcional); composition.links tambem pode despachar actions globais via to.kind = global-action.",
|
|
692
|
+
"Conteudo editorial rico deve ser modelado como widget praxis-rich-content com definition.inputs.document: RichContentDocument, nao como DSL local do page-builder.",
|
|
693
|
+
"Quando definition.id = praxis-rich-content em uma pagina dinamica, definition.inputs.document continua sendo o contrato persistido; hostCapabilities e mediado em runtime pelo host praxis-dynamic-page e nao deve ser serializado no JSON da pagina.",
|
|
694
|
+
"Edicao visual de inputs de widget deve usar ComponentDocMeta.configEditor ou ComponentDocMeta.authoringManifestRef publicado pela lib dona do componente; nao criar editor local no page-builder para semantica de outro pacote.",
|
|
695
|
+
"Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.",
|
|
696
|
+
"Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.",
|
|
697
|
+
"Para criacao agentic de paginas, o preview pode trazer uiCompositionPlan como plano intermediario validavel; o page-builder compila esse plano para WidgetPageDefinition antes de aplicar.",
|
|
698
|
+
"UiCompositionPlan usa widgets[].componentId e bindings declarativos. O JSON persistido continua sendo page.widgets[].definition.id e page.composition.links.",
|
|
699
|
+
"Nested component ports usam endpoint component-port com nestedPath. O owner em ref.widget ou bindings[].*.widget continua sendo o widget top-level; a porta real do filho fica em port/direction e o caminho ate o filho fica em nestedPath.",
|
|
700
|
+
"Nao gere links nested via owner.widgetEvent, bindingPath profundo, page.connections ou wrappers host-specific. widgetEvent e bridge legada/avancada, nao contrato principal de authoring.",
|
|
701
|
+
"Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.",
|
|
702
|
+
"pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page."
|
|
703
|
+
],
|
|
704
|
+
"componentContext": {
|
|
705
|
+
"version": "v1.3",
|
|
706
|
+
"optionsByPath": {
|
|
707
|
+
"page.canvas.columns": {
|
|
708
|
+
"mode": "suggested",
|
|
709
|
+
"options": [
|
|
710
|
+
{
|
|
711
|
+
"value": 6,
|
|
712
|
+
"label": "6 colunas"
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
"value": 8,
|
|
716
|
+
"label": "8 colunas"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"value": 12,
|
|
720
|
+
"label": "12 colunas"
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
"value": 16,
|
|
724
|
+
"label": "16 colunas"
|
|
725
|
+
}
|
|
726
|
+
]
|
|
727
|
+
},
|
|
728
|
+
"page.canvas.rowUnit": {
|
|
729
|
+
"mode": "suggested",
|
|
730
|
+
"options": [
|
|
731
|
+
{
|
|
732
|
+
"value": "64px",
|
|
733
|
+
"label": "64px"
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
"value": "80px",
|
|
737
|
+
"label": "80px"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
"value": "100px",
|
|
741
|
+
"label": "100px"
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"value": "120px",
|
|
745
|
+
"label": "120px"
|
|
746
|
+
}
|
|
747
|
+
]
|
|
748
|
+
},
|
|
749
|
+
"page.canvas.gap": {
|
|
750
|
+
"mode": "suggested",
|
|
751
|
+
"options": [
|
|
752
|
+
{
|
|
753
|
+
"value": "8px",
|
|
754
|
+
"label": "8px"
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"value": "12px",
|
|
758
|
+
"label": "12px"
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
"value": "16px",
|
|
762
|
+
"label": "16px"
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
"value": "24px",
|
|
766
|
+
"label": "24px"
|
|
767
|
+
}
|
|
768
|
+
]
|
|
769
|
+
},
|
|
770
|
+
"page.widgets[].definition.id": {
|
|
771
|
+
"mode": "enum",
|
|
772
|
+
"options": [
|
|
773
|
+
{
|
|
774
|
+
"value": "praxis-crud",
|
|
775
|
+
"label": "Praxis CRUD"
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
"value": "praxis-table",
|
|
779
|
+
"label": "Praxis Table"
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"value": "praxis-dynamic-form",
|
|
783
|
+
"label": "Praxis Dynamic Form"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"value": "praxis-list",
|
|
787
|
+
"label": "Praxis List"
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
"value": "praxis-tabs",
|
|
791
|
+
"label": "Praxis Tabs"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"value": "praxis-stepper",
|
|
795
|
+
"label": "Praxis Stepper"
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"value": "praxis-expansion",
|
|
799
|
+
"label": "Praxis Expansion"
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"value": "praxis-files-upload",
|
|
803
|
+
"label": "Praxis Files Upload"
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
"value": "praxis-rich-content",
|
|
807
|
+
"label": "Praxis Rich Content"
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
"value": "pdx-cron-builder",
|
|
811
|
+
"label": "Praxis Cron Builder"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"value": "praxis-settings-panel",
|
|
815
|
+
"label": "Praxis Settings Panel"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"value": "praxis-dashboard-stats",
|
|
819
|
+
"label": "Praxis Dashboard Stats"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
"value": "praxis-chart",
|
|
823
|
+
"label": "Praxis Chart"
|
|
824
|
+
}
|
|
825
|
+
]
|
|
826
|
+
},
|
|
827
|
+
"uiCompositionPlan.widgets[].componentId": {
|
|
828
|
+
"mode": "enum",
|
|
829
|
+
"options": [
|
|
830
|
+
{
|
|
831
|
+
"value": "praxis-crud",
|
|
832
|
+
"label": "Praxis CRUD"
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
"value": "praxis-table",
|
|
836
|
+
"label": "Praxis Table"
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"value": "praxis-dynamic-form",
|
|
840
|
+
"label": "Praxis Dynamic Form"
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
"value": "praxis-list",
|
|
844
|
+
"label": "Praxis List"
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
"value": "praxis-tabs",
|
|
848
|
+
"label": "Praxis Tabs"
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
"value": "praxis-stepper",
|
|
852
|
+
"label": "Praxis Stepper"
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
"value": "praxis-expansion",
|
|
856
|
+
"label": "Praxis Expansion"
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
"value": "praxis-files-upload",
|
|
860
|
+
"label": "Praxis Files Upload"
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
"value": "praxis-rich-content",
|
|
864
|
+
"label": "Praxis Rich Content"
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
"value": "pdx-cron-builder",
|
|
868
|
+
"label": "Praxis Cron Builder"
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
"value": "praxis-settings-panel",
|
|
872
|
+
"label": "Praxis Settings Panel"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
"value": "praxis-dashboard-stats",
|
|
876
|
+
"label": "Praxis Dashboard Stats"
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
"value": "praxis-chart",
|
|
880
|
+
"label": "Praxis Chart"
|
|
881
|
+
}
|
|
882
|
+
]
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
"actionCatalog": [
|
|
886
|
+
{
|
|
887
|
+
"id": "ui-composition-plan.create",
|
|
888
|
+
"intentExamples": [
|
|
889
|
+
"ui composition plan",
|
|
890
|
+
"agentic page plan",
|
|
891
|
+
"master detail",
|
|
892
|
+
"dashboard composition",
|
|
893
|
+
"nested component ports",
|
|
894
|
+
"nestedPath",
|
|
895
|
+
"planejar pagina",
|
|
896
|
+
"composicao declarativa"
|
|
897
|
+
],
|
|
898
|
+
"patchTemplate": {
|
|
899
|
+
"uiCompositionPlan": {
|
|
900
|
+
"version": "1.0",
|
|
901
|
+
"kind": "praxis.ui-composition-plan",
|
|
902
|
+
"layoutPreset": "{{params.layoutPreset}}",
|
|
903
|
+
"state": "{{params.state}}",
|
|
904
|
+
"widgets": "{{params.widgets}}",
|
|
905
|
+
"bindings": "{{params.bindings}}"
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
"id": "page.canvas.columns.set",
|
|
911
|
+
"intentExamples": [
|
|
912
|
+
"columns",
|
|
913
|
+
"canvas columns",
|
|
914
|
+
"grid columns",
|
|
915
|
+
"colunas do canvas"
|
|
916
|
+
],
|
|
917
|
+
"patchTemplate": {
|
|
918
|
+
"page": {
|
|
919
|
+
"canvas": {
|
|
920
|
+
"columns": "{{value}}"
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
"id": "page.canvas.rowUnit.set",
|
|
927
|
+
"intentExamples": [
|
|
928
|
+
"row height",
|
|
929
|
+
"row size",
|
|
930
|
+
"canvas row",
|
|
931
|
+
"altura da linha"
|
|
932
|
+
],
|
|
933
|
+
"patchTemplate": {
|
|
934
|
+
"page": {
|
|
935
|
+
"canvas": {
|
|
936
|
+
"rowUnit": "{{value}}"
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"id": "page.canvas.gap.set",
|
|
943
|
+
"intentExamples": [
|
|
944
|
+
"gap",
|
|
945
|
+
"spacing",
|
|
946
|
+
"canvas gap",
|
|
947
|
+
"espaçamento"
|
|
948
|
+
],
|
|
949
|
+
"patchTemplate": {
|
|
950
|
+
"page": {
|
|
951
|
+
"canvas": {
|
|
952
|
+
"gap": "{{value}}"
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"id": "page.context.set",
|
|
959
|
+
"intentExamples": [
|
|
960
|
+
"page context",
|
|
961
|
+
"context variable",
|
|
962
|
+
"variavel de contexto"
|
|
963
|
+
],
|
|
964
|
+
"patchTemplate": {
|
|
965
|
+
"page": {
|
|
966
|
+
"context": {
|
|
967
|
+
"{{params.key}}": "{{value}}"
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
"id": "widget.add",
|
|
974
|
+
"intentExamples": [
|
|
975
|
+
"add widget",
|
|
976
|
+
"new widget",
|
|
977
|
+
"add component",
|
|
978
|
+
"adicionar componente"
|
|
979
|
+
],
|
|
980
|
+
"patchTemplate": {
|
|
981
|
+
"page": {
|
|
982
|
+
"widgets": [
|
|
983
|
+
{
|
|
984
|
+
"key": "{{target}}",
|
|
985
|
+
"definition": {
|
|
986
|
+
"id": "{{params.componentId}}"
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
],
|
|
990
|
+
"canvas": {
|
|
991
|
+
"items": {
|
|
992
|
+
"{{target}}": {
|
|
993
|
+
"col": 1,
|
|
994
|
+
"row": 1,
|
|
995
|
+
"colSpan": 4,
|
|
996
|
+
"rowSpan": 2
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
"id": "widget.remove",
|
|
1005
|
+
"intentExamples": [
|
|
1006
|
+
"remove widget",
|
|
1007
|
+
"delete widget",
|
|
1008
|
+
"remover componente"
|
|
1009
|
+
],
|
|
1010
|
+
"patchTemplate": {
|
|
1011
|
+
"page": {
|
|
1012
|
+
"widgets": [
|
|
1013
|
+
{
|
|
1014
|
+
"key": "{{target}}",
|
|
1015
|
+
"_delete": true
|
|
1016
|
+
}
|
|
1017
|
+
]
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
"id": "widget.component.set",
|
|
1023
|
+
"intentExamples": [
|
|
1024
|
+
"widget type",
|
|
1025
|
+
"component id",
|
|
1026
|
+
"widget component",
|
|
1027
|
+
"tipo do componente"
|
|
1028
|
+
],
|
|
1029
|
+
"patchTemplate": {
|
|
1030
|
+
"page": {
|
|
1031
|
+
"widgets": [
|
|
1032
|
+
{
|
|
1033
|
+
"key": "{{target}}",
|
|
1034
|
+
"definition": {
|
|
1035
|
+
"id": "{{value}}"
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
]
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
"id": "widget.className.set",
|
|
1044
|
+
"intentExamples": [
|
|
1045
|
+
"widget class",
|
|
1046
|
+
"css class",
|
|
1047
|
+
"classe css"
|
|
1048
|
+
],
|
|
1049
|
+
"patchTemplate": {
|
|
1050
|
+
"page": {
|
|
1051
|
+
"widgets": [
|
|
1052
|
+
{
|
|
1053
|
+
"key": "{{target}}",
|
|
1054
|
+
"className": "{{value}}"
|
|
1055
|
+
}
|
|
1056
|
+
]
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
"id": "widget.canvasItem.set",
|
|
1062
|
+
"intentExamples": [
|
|
1063
|
+
"move widget",
|
|
1064
|
+
"resize widget",
|
|
1065
|
+
"widget canvas",
|
|
1066
|
+
"posicionar"
|
|
1067
|
+
],
|
|
1068
|
+
"patchTemplate": {
|
|
1069
|
+
"page": {
|
|
1070
|
+
"canvas": {
|
|
1071
|
+
"items": {
|
|
1072
|
+
"{{target}}": {
|
|
1073
|
+
"col": "{{params.col}}",
|
|
1074
|
+
"row": "{{params.row}}",
|
|
1075
|
+
"colSpan": "{{params.colSpan}}",
|
|
1076
|
+
"rowSpan": "{{params.rowSpan}}"
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
"id": "widget.inputs.set",
|
|
1085
|
+
"intentExamples": [
|
|
1086
|
+
"widget inputs",
|
|
1087
|
+
"configure widget",
|
|
1088
|
+
"set inputs",
|
|
1089
|
+
"configurar componente"
|
|
1090
|
+
],
|
|
1091
|
+
"patchTemplate": {
|
|
1092
|
+
"page": {
|
|
1093
|
+
"widgets": [
|
|
1094
|
+
{
|
|
1095
|
+
"key": "{{target}}",
|
|
1096
|
+
"definition": {
|
|
1097
|
+
"inputs": "{{value}}"
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
]
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
"id": "widget.bindingOrder.set",
|
|
1106
|
+
"intentExamples": [
|
|
1107
|
+
"binding order",
|
|
1108
|
+
"input order",
|
|
1109
|
+
"ordem de inputs"
|
|
1110
|
+
],
|
|
1111
|
+
"patchTemplate": {
|
|
1112
|
+
"page": {
|
|
1113
|
+
"widgets": [
|
|
1114
|
+
{
|
|
1115
|
+
"key": "{{target}}",
|
|
1116
|
+
"definition": {
|
|
1117
|
+
"bindingOrder": "{{value}}"
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
"id": "connection.add",
|
|
1126
|
+
"intentExamples": [
|
|
1127
|
+
"connect widgets",
|
|
1128
|
+
"link widgets",
|
|
1129
|
+
"wire output",
|
|
1130
|
+
"create connection",
|
|
1131
|
+
"nested component port",
|
|
1132
|
+
"nestedPath",
|
|
1133
|
+
"conectar"
|
|
1134
|
+
],
|
|
1135
|
+
"patchTemplate": {
|
|
1136
|
+
"page": {
|
|
1137
|
+
"composition": {
|
|
1138
|
+
"version": "1.0.0",
|
|
1139
|
+
"links": [
|
|
1140
|
+
{
|
|
1141
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1142
|
+
"from": {
|
|
1143
|
+
"kind": "component-port",
|
|
1144
|
+
"ref": {
|
|
1145
|
+
"widget": "{{params.fromWidget}}",
|
|
1146
|
+
"port": "{{params.fromOutput}}",
|
|
1147
|
+
"direction": "output"
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
"to": {
|
|
1151
|
+
"kind": "component-port",
|
|
1152
|
+
"ref": {
|
|
1153
|
+
"widget": "{{params.toWidget}}",
|
|
1154
|
+
"port": "{{params.toInput}}",
|
|
1155
|
+
"direction": "input"
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
"intent": "event-propagation",
|
|
1159
|
+
"transform": "{{value}}",
|
|
1160
|
+
"metadata": {
|
|
1161
|
+
"source": "persisted-composition-link"
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
]
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
"id": "connection.set_static",
|
|
1171
|
+
"intentExamples": [
|
|
1172
|
+
"set input value",
|
|
1173
|
+
"static connection",
|
|
1174
|
+
"valor fixo na conexao"
|
|
1175
|
+
],
|
|
1176
|
+
"patchTemplate": {
|
|
1177
|
+
"page": {
|
|
1178
|
+
"composition": {
|
|
1179
|
+
"version": "1.0.0",
|
|
1180
|
+
"links": [
|
|
1181
|
+
{
|
|
1182
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1183
|
+
"from": {
|
|
1184
|
+
"kind": "component-port",
|
|
1185
|
+
"ref": {
|
|
1186
|
+
"widget": "{{params.fromWidget}}",
|
|
1187
|
+
"port": "{{params.fromOutput}}",
|
|
1188
|
+
"direction": "output"
|
|
1189
|
+
}
|
|
1190
|
+
},
|
|
1191
|
+
"to": {
|
|
1192
|
+
"kind": "component-port",
|
|
1193
|
+
"ref": {
|
|
1194
|
+
"widget": "{{params.toWidget}}",
|
|
1195
|
+
"port": "{{params.toInput}}",
|
|
1196
|
+
"direction": "input"
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
"intent": "event-propagation",
|
|
1200
|
+
"transform": "{{value}}",
|
|
1201
|
+
"metadata": {
|
|
1202
|
+
"source": "persisted-composition-link"
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
]
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
"id": "connection.map.set",
|
|
1212
|
+
"intentExamples": [
|
|
1213
|
+
"map connection",
|
|
1214
|
+
"update map",
|
|
1215
|
+
"mapear conexao",
|
|
1216
|
+
"atualizar map"
|
|
1217
|
+
],
|
|
1218
|
+
"patchTemplate": {
|
|
1219
|
+
"page": {
|
|
1220
|
+
"composition": {
|
|
1221
|
+
"version": "1.0.0",
|
|
1222
|
+
"links": [
|
|
1223
|
+
{
|
|
1224
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1225
|
+
"from": {
|
|
1226
|
+
"kind": "component-port",
|
|
1227
|
+
"ref": {
|
|
1228
|
+
"widget": "{{params.fromWidget}}",
|
|
1229
|
+
"port": "{{params.fromOutput}}",
|
|
1230
|
+
"direction": "output"
|
|
1231
|
+
}
|
|
1232
|
+
},
|
|
1233
|
+
"to": {
|
|
1234
|
+
"kind": "component-port",
|
|
1235
|
+
"ref": {
|
|
1236
|
+
"widget": "{{params.toWidget}}",
|
|
1237
|
+
"port": "{{params.toInput}}",
|
|
1238
|
+
"direction": "input"
|
|
1239
|
+
}
|
|
1240
|
+
},
|
|
1241
|
+
"intent": "event-propagation",
|
|
1242
|
+
"transform": "{{value}}",
|
|
1243
|
+
"metadata": {
|
|
1244
|
+
"source": "persisted-composition-link"
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
]
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
"id": "connection.condition.set",
|
|
1254
|
+
"intentExamples": [
|
|
1255
|
+
"connection condition",
|
|
1256
|
+
"link condition",
|
|
1257
|
+
"json logic guard",
|
|
1258
|
+
"condicao da conexao"
|
|
1259
|
+
],
|
|
1260
|
+
"patchTemplate": {
|
|
1261
|
+
"page": {
|
|
1262
|
+
"composition": {
|
|
1263
|
+
"version": "1.0.0",
|
|
1264
|
+
"links": [
|
|
1265
|
+
{
|
|
1266
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1267
|
+
"from": {
|
|
1268
|
+
"kind": "component-port",
|
|
1269
|
+
"ref": {
|
|
1270
|
+
"widget": "{{params.fromWidget}}",
|
|
1271
|
+
"port": "{{params.fromOutput}}",
|
|
1272
|
+
"direction": "output"
|
|
1273
|
+
}
|
|
1274
|
+
},
|
|
1275
|
+
"to": {
|
|
1276
|
+
"kind": "component-port",
|
|
1277
|
+
"ref": {
|
|
1278
|
+
"widget": "{{params.toWidget}}",
|
|
1279
|
+
"port": "{{params.toInput}}",
|
|
1280
|
+
"direction": "input"
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1283
|
+
"intent": "event-propagation",
|
|
1284
|
+
"condition": "{{value}}"
|
|
1285
|
+
}
|
|
1286
|
+
]
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
"id": "connection.policy.set",
|
|
1293
|
+
"intentExamples": [
|
|
1294
|
+
"connection policy",
|
|
1295
|
+
"debounce",
|
|
1296
|
+
"distinct",
|
|
1297
|
+
"missing value policy",
|
|
1298
|
+
"politica da conexao"
|
|
1299
|
+
],
|
|
1300
|
+
"patchTemplate": {
|
|
1301
|
+
"page": {
|
|
1302
|
+
"composition": {
|
|
1303
|
+
"version": "1.0.0",
|
|
1304
|
+
"links": [
|
|
1305
|
+
{
|
|
1306
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1307
|
+
"from": {
|
|
1308
|
+
"kind": "component-port",
|
|
1309
|
+
"ref": {
|
|
1310
|
+
"widget": "{{params.fromWidget}}",
|
|
1311
|
+
"port": "{{params.fromOutput}}",
|
|
1312
|
+
"direction": "output"
|
|
1313
|
+
}
|
|
1314
|
+
},
|
|
1315
|
+
"to": {
|
|
1316
|
+
"kind": "component-port",
|
|
1317
|
+
"ref": {
|
|
1318
|
+
"widget": "{{params.toWidget}}",
|
|
1319
|
+
"port": "{{params.toInput}}",
|
|
1320
|
+
"direction": "input"
|
|
1321
|
+
}
|
|
1322
|
+
},
|
|
1323
|
+
"intent": "event-propagation",
|
|
1324
|
+
"policy": "{{value}}"
|
|
1325
|
+
}
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
"id": "connection.remove",
|
|
1333
|
+
"intentExamples": [
|
|
1334
|
+
"remove connection",
|
|
1335
|
+
"unlink widgets",
|
|
1336
|
+
"desconectar"
|
|
1337
|
+
],
|
|
1338
|
+
"patchTemplate": {
|
|
1339
|
+
"page": {
|
|
1340
|
+
"composition": {
|
|
1341
|
+
"version": "1.0.0",
|
|
1342
|
+
"links": [
|
|
1343
|
+
{
|
|
1344
|
+
"id": "{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}",
|
|
1345
|
+
"from": {
|
|
1346
|
+
"kind": "component-port",
|
|
1347
|
+
"ref": {
|
|
1348
|
+
"widget": "{{params.fromWidget}}",
|
|
1349
|
+
"port": "{{params.fromOutput}}",
|
|
1350
|
+
"direction": "output"
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1353
|
+
"to": {
|
|
1354
|
+
"kind": "component-port",
|
|
1355
|
+
"ref": {
|
|
1356
|
+
"widget": "{{params.toWidget}}",
|
|
1357
|
+
"port": "{{params.toInput}}",
|
|
1358
|
+
"direction": "input"
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
"_delete": true
|
|
1362
|
+
}
|
|
1363
|
+
]
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
],
|
|
1369
|
+
"fieldResolvers": {
|
|
1370
|
+
"page.widgets[]": [
|
|
1371
|
+
"key",
|
|
1372
|
+
"definition.id"
|
|
1373
|
+
],
|
|
1374
|
+
"page.composition.links[]": [
|
|
1375
|
+
"id"
|
|
1376
|
+
]
|
|
1377
|
+
},
|
|
1378
|
+
"hints": [
|
|
1379
|
+
"For agentic page creation, prefer returning uiCompositionPlan in the preview envelope and let the page-builder compiler emit WidgetPageDefinition.",
|
|
1380
|
+
"Use uiCompositionPlan.widgets[].componentId in plans; the compiler maps it to page.widgets[].definition.id.",
|
|
1381
|
+
"Use uiCompositionPlan.bindings as the declarative source for wiring; the compiler emits page.composition.links.",
|
|
1382
|
+
"For nested component ports, use component-port endpoints with nestedPath in uiCompositionPlan.bindings; keep widget as the top-level owner and put the real child port in port/direction.",
|
|
1383
|
+
"NestedPath must be relative to the owner widget and must end with a widget segment containing a stable key. Do not use index as the only identity.",
|
|
1384
|
+
"Do not author nested links through owner.widgetEvent, deep bindingPath, page.connections, or host-specific wrapper outputs; those are legacy or bridge mechanisms.",
|
|
1385
|
+
"Do not emit both uiCompositionPlan.bindings and hand-authored page.composition.links as competing sources of truth for the same preview.",
|
|
1386
|
+
"Use page.widgets[].key as the merge key; avoid array indexes.",
|
|
1387
|
+
"Canvas items use 1-based col/row with integer spans.",
|
|
1388
|
+
"Widget definition id must match a registered component selector.",
|
|
1389
|
+
"Use runtimeState.componentCatalog for available component ids, inputs, and outputs.",
|
|
1390
|
+
"Use page.composition.links as the canonical persisted wiring surface.",
|
|
1391
|
+
"Composition links should use stable ids and canonical component-port/state endpoints.",
|
|
1392
|
+
"For global-action targets, keep execution declarative: use to.kind = global-action with to.ref.actionId plus optional to.ref.payload, payloadExpr and meta only.",
|
|
1393
|
+
"For uiCompositionPlan transforms, use pick-path for event payload extraction, query-context for resource filters, template for structured document/input generation, and constant for fixed values.",
|
|
1394
|
+
"Write semantic guards to page.composition.links[].condition as Json Logic, not as legacy filter strings.",
|
|
1395
|
+
"Write operational behavior to page.composition.links[].policy, not mixed into condition or metadata.",
|
|
1396
|
+
"Transforms and metadata must be written under the link envelope, not as legacy connection fields.",
|
|
1397
|
+
"To remove a widget, use _delete: true with the widget key.",
|
|
1398
|
+
"To remove a link, use _delete: true with the same canonical from/to endpoints."
|
|
1399
|
+
]
|
|
1400
|
+
},
|
|
1401
|
+
"authoringManifest": {
|
|
1402
|
+
"schemaVersion": "1.0.0",
|
|
1403
|
+
"componentId": "praxis-page-builder",
|
|
1404
|
+
"ownerPackage": "@praxisui/page-builder",
|
|
1405
|
+
"configSchemaId": "WidgetPageDefinition",
|
|
1406
|
+
"manifestVersion": "1.0.0",
|
|
1407
|
+
"runtimeInputs": [
|
|
1408
|
+
{
|
|
1409
|
+
"name": "page",
|
|
1410
|
+
"type": "WidgetPageDefinition",
|
|
1411
|
+
"description": "Canonical renderable page document consumed by praxis-dynamic-page."
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"name": "pageIdentity",
|
|
1415
|
+
"type": "PageIdentity | null",
|
|
1416
|
+
"description": "Persistence identity for ui_user_config save/apply flows; not persisted inside page."
|
|
1417
|
+
},
|
|
1418
|
+
{
|
|
1419
|
+
"name": "enableCustomization",
|
|
1420
|
+
"type": "boolean",
|
|
1421
|
+
"description": "Enables page-builder authoring chrome around the runtime page."
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
"name": "context",
|
|
1425
|
+
"type": "Record<string, unknown>",
|
|
1426
|
+
"description": "Opaque host context passed to catalog resolution and agentic authoring."
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
"name": "pageChange",
|
|
1430
|
+
"type": "WidgetPageDefinition",
|
|
1431
|
+
"description": "Emitted after local apply/preview produces a renderable page."
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
"name": "agenticAuthoringEnableStreaming",
|
|
1435
|
+
"type": "boolean",
|
|
1436
|
+
"description": "Opt-in flag for the canonical streaming turn endpoints."
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
"name": "agenticAuthoringIncludeLlmDiagnostics",
|
|
1440
|
+
"type": "boolean",
|
|
1441
|
+
"description": "Opt-in flag that exposes governed diagnostics as cockpit evidence for validation and debugging."
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
"name": "agenticAuthoringContextHints",
|
|
1445
|
+
"type": "Record<string, unknown>",
|
|
1446
|
+
"description": "Host-provided semantic hints, including governed domain-catalog references and optional RAG-authored openingMessage used to ground AI-authored decisions."
|
|
1447
|
+
}
|
|
1448
|
+
],
|
|
1449
|
+
"editableTargets": [
|
|
1450
|
+
{
|
|
1451
|
+
"kind": "page",
|
|
1452
|
+
"resolver": "widget-page-definition-root",
|
|
1453
|
+
"description": "Root WidgetPageDefinition document: title, metadata, context and renderable page envelope."
|
|
1454
|
+
},
|
|
1455
|
+
{
|
|
1456
|
+
"kind": "canvas",
|
|
1457
|
+
"resolver": "widget-page-canvas",
|
|
1458
|
+
"description": "Canvas geometry and item placement for top-level widgets."
|
|
1459
|
+
},
|
|
1460
|
+
{
|
|
1461
|
+
"kind": "widget",
|
|
1462
|
+
"resolver": "widget-by-stable-key",
|
|
1463
|
+
"description": "Widget definitions addressed by stable widgetKey, never by array index."
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
"kind": "widgetShell",
|
|
1467
|
+
"resolver": "widget-shell-by-widget-key",
|
|
1468
|
+
"description": "Dashboard-card shell metadata such as title, action chrome and visual preset."
|
|
1469
|
+
},
|
|
1470
|
+
{
|
|
1471
|
+
"kind": "compositionLink",
|
|
1472
|
+
"resolver": "composition-link-by-id",
|
|
1473
|
+
"description": "Declarative wiring in page.composition.links, including component-port nestedPath endpoints."
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
"kind": "state",
|
|
1477
|
+
"resolver": "page-state-path",
|
|
1478
|
+
"description": "Page-level state entries referenced by composition links."
|
|
1479
|
+
},
|
|
1480
|
+
{
|
|
1481
|
+
"kind": "pageIdentity",
|
|
1482
|
+
"resolver": "page-builder-persistence-identity",
|
|
1483
|
+
"description": "ui_user_config identity, scope and ETag used by applyPage/save."
|
|
1484
|
+
},
|
|
1485
|
+
{
|
|
1486
|
+
"kind": "agenticPreview",
|
|
1487
|
+
"resolver": "agentic-preview-result",
|
|
1488
|
+
"description": "Compiled backend preview envelope whose patch.page is applied locally."
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
"kind": "childOperation",
|
|
1492
|
+
"resolver": "widget-child-authoring-manifest-operation",
|
|
1493
|
+
"description": "Delegated operation owned by the child widget component manifest or configEditor."
|
|
1494
|
+
}
|
|
1495
|
+
],
|
|
1496
|
+
"operations": [
|
|
1497
|
+
{
|
|
1498
|
+
"operationId": "page.configure",
|
|
1499
|
+
"title": "Configure page metadata",
|
|
1500
|
+
"scope": "global",
|
|
1501
|
+
"targetKind": "page",
|
|
1502
|
+
"target": {
|
|
1503
|
+
"kind": "page",
|
|
1504
|
+
"resolver": "widget-page-definition-root",
|
|
1505
|
+
"ambiguityPolicy": "fail",
|
|
1506
|
+
"required": false
|
|
1507
|
+
},
|
|
1508
|
+
"inputSchema": {
|
|
1509
|
+
"type": "object",
|
|
1510
|
+
"properties": {
|
|
1511
|
+
"title": {
|
|
1512
|
+
"type": "string"
|
|
1513
|
+
},
|
|
1514
|
+
"layoutPreset": {
|
|
1515
|
+
"type": "string"
|
|
1516
|
+
},
|
|
1517
|
+
"context": {
|
|
1518
|
+
"type": "object"
|
|
1519
|
+
},
|
|
1520
|
+
"metadata": {
|
|
1521
|
+
"type": "object"
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
},
|
|
1525
|
+
"effects": [
|
|
1526
|
+
{
|
|
1527
|
+
"kind": "compile-domain-patch",
|
|
1528
|
+
"handler": "page-builder-page-configure",
|
|
1529
|
+
"handlerContract": {
|
|
1530
|
+
"reads": [
|
|
1531
|
+
"WidgetPageDefinition",
|
|
1532
|
+
"DynamicPageConfigEditorComponent",
|
|
1533
|
+
"SettingsPanelBridge"
|
|
1534
|
+
],
|
|
1535
|
+
"writes": [
|
|
1536
|
+
"page.title",
|
|
1537
|
+
"page.layoutPreset",
|
|
1538
|
+
"page.context",
|
|
1539
|
+
"page.metadata"
|
|
1540
|
+
],
|
|
1541
|
+
"identityKeys": [
|
|
1542
|
+
"pageIdentity.componentId",
|
|
1543
|
+
"pageIdentity.scope"
|
|
1544
|
+
],
|
|
1545
|
+
"failureModes": [
|
|
1546
|
+
"page-not-loaded",
|
|
1547
|
+
"context-not-json",
|
|
1548
|
+
"settings-panel-bridge-missing"
|
|
1549
|
+
],
|
|
1550
|
+
"description": "Updates root page metadata while preserving the renderable WidgetPageDefinition shape."
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
],
|
|
1554
|
+
"validators": [
|
|
1555
|
+
"widget-page-definition-valid",
|
|
1556
|
+
"no-legacy-grid-page-definition",
|
|
1557
|
+
"page-context-json-valid",
|
|
1558
|
+
"settings-panel-round-trip-valid"
|
|
1559
|
+
],
|
|
1560
|
+
"affectedPaths": [
|
|
1561
|
+
"title",
|
|
1562
|
+
"layoutPreset",
|
|
1563
|
+
"context",
|
|
1564
|
+
"metadata"
|
|
1565
|
+
],
|
|
1566
|
+
"submissionImpact": "config-only",
|
|
1567
|
+
"preconditions": [
|
|
1568
|
+
"page-loaded"
|
|
1569
|
+
]
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
"operationId": "canvas.configure",
|
|
1573
|
+
"title": "Configure page canvas",
|
|
1574
|
+
"scope": "layout",
|
|
1575
|
+
"targetKind": "canvas",
|
|
1576
|
+
"target": {
|
|
1577
|
+
"kind": "canvas",
|
|
1578
|
+
"resolver": "widget-page-canvas",
|
|
1579
|
+
"ambiguityPolicy": "fail",
|
|
1580
|
+
"required": true
|
|
1581
|
+
},
|
|
1582
|
+
"inputSchema": {
|
|
1583
|
+
"type": "object",
|
|
1584
|
+
"properties": {
|
|
1585
|
+
"columns": {
|
|
1586
|
+
"type": "number"
|
|
1587
|
+
},
|
|
1588
|
+
"rowUnit": {
|
|
1589
|
+
"type": "number"
|
|
1590
|
+
},
|
|
1591
|
+
"gap": {
|
|
1592
|
+
"type": "number"
|
|
1593
|
+
},
|
|
1594
|
+
"items": {
|
|
1595
|
+
"type": "array"
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
},
|
|
1599
|
+
"effects": [
|
|
1600
|
+
{
|
|
1601
|
+
"kind": "compile-domain-patch",
|
|
1602
|
+
"handler": "page-builder-canvas-configure",
|
|
1603
|
+
"handlerContract": {
|
|
1604
|
+
"reads": [
|
|
1605
|
+
"WidgetPageDefinition.canvas",
|
|
1606
|
+
"DynamicPageBuilderComponent"
|
|
1607
|
+
],
|
|
1608
|
+
"writes": [
|
|
1609
|
+
"page.canvas.columns",
|
|
1610
|
+
"page.canvas.rowUnit",
|
|
1611
|
+
"page.canvas.gap",
|
|
1612
|
+
"page.canvas.items"
|
|
1613
|
+
],
|
|
1614
|
+
"identityKeys": [
|
|
1615
|
+
"canvas"
|
|
1616
|
+
],
|
|
1617
|
+
"failureModes": [
|
|
1618
|
+
"canvas-missing",
|
|
1619
|
+
"canvas-item-references-missing-widget",
|
|
1620
|
+
"invalid-grid-geometry"
|
|
1621
|
+
],
|
|
1622
|
+
"description": "Configures the top-level canvas without introducing legacy GridPageDefinition semantics."
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
],
|
|
1626
|
+
"validators": [
|
|
1627
|
+
"canvas-columns-integer",
|
|
1628
|
+
"canvas-row-unit-valid",
|
|
1629
|
+
"canvas-gap-valid",
|
|
1630
|
+
"canvas-items-reference-existing-widgets"
|
|
1631
|
+
],
|
|
1632
|
+
"affectedPaths": [
|
|
1633
|
+
"canvas.columns",
|
|
1634
|
+
"canvas.rowUnit",
|
|
1635
|
+
"canvas.gap",
|
|
1636
|
+
"canvas.items"
|
|
1637
|
+
],
|
|
1638
|
+
"submissionImpact": "config-only",
|
|
1639
|
+
"preconditions": [
|
|
1640
|
+
"page-loaded"
|
|
1641
|
+
]
|
|
1642
|
+
},
|
|
1643
|
+
{
|
|
1644
|
+
"operationId": "widget.add",
|
|
1645
|
+
"title": "Add widget to page",
|
|
1646
|
+
"scope": "layout",
|
|
1647
|
+
"targetKind": "widget",
|
|
1648
|
+
"target": {
|
|
1649
|
+
"kind": "widget",
|
|
1650
|
+
"resolver": "widget-by-stable-key",
|
|
1651
|
+
"ambiguityPolicy": "fail",
|
|
1652
|
+
"required": true
|
|
1653
|
+
},
|
|
1654
|
+
"inputSchema": {
|
|
1655
|
+
"type": "object",
|
|
1656
|
+
"required": [
|
|
1657
|
+
"widgetKey",
|
|
1658
|
+
"componentId"
|
|
1659
|
+
],
|
|
1660
|
+
"properties": {
|
|
1661
|
+
"widgetKey": {
|
|
1662
|
+
"type": "string"
|
|
1663
|
+
},
|
|
1664
|
+
"componentId": {
|
|
1665
|
+
"type": "string"
|
|
1666
|
+
},
|
|
1667
|
+
"title": {
|
|
1668
|
+
"type": "string"
|
|
1669
|
+
},
|
|
1670
|
+
"inputs": {
|
|
1671
|
+
"type": "object"
|
|
1672
|
+
},
|
|
1673
|
+
"canvasItem": {
|
|
1674
|
+
"type": "object"
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
},
|
|
1678
|
+
"effects": [
|
|
1679
|
+
{
|
|
1680
|
+
"kind": "compile-domain-patch",
|
|
1681
|
+
"handler": "page-builder-widget-add",
|
|
1682
|
+
"handlerContract": {
|
|
1683
|
+
"reads": [
|
|
1684
|
+
"WidgetPageDefinition.widgets",
|
|
1685
|
+
"WidgetPageDefinition.canvas",
|
|
1686
|
+
"ComponentDocRegistry",
|
|
1687
|
+
"PAGE_BUILDER_WIDGET_AI_CATALOGS"
|
|
1688
|
+
],
|
|
1689
|
+
"writes": [
|
|
1690
|
+
"page.widgets[]",
|
|
1691
|
+
"page.canvas.items[]"
|
|
1692
|
+
],
|
|
1693
|
+
"identityKeys": [
|
|
1694
|
+
"widgetKey"
|
|
1695
|
+
],
|
|
1696
|
+
"failureModes": [
|
|
1697
|
+
"widget-key-duplicate",
|
|
1698
|
+
"component-not-registered",
|
|
1699
|
+
"canvas-item-invalid",
|
|
1700
|
+
"child-input-contract-unknown"
|
|
1701
|
+
],
|
|
1702
|
+
"description": "Adds a registered component as a widget and places it on the canvas using a stable widgetKey."
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
],
|
|
1706
|
+
"validators": [
|
|
1707
|
+
"widget-key-unique",
|
|
1708
|
+
"component-registered",
|
|
1709
|
+
"canvas-item-valid",
|
|
1710
|
+
"child-inputs-delegated",
|
|
1711
|
+
"widget-key-not-array-index"
|
|
1712
|
+
],
|
|
1713
|
+
"affectedPaths": [
|
|
1714
|
+
"widgets[]",
|
|
1715
|
+
"canvas.items[]"
|
|
1716
|
+
],
|
|
1717
|
+
"submissionImpact": "config-only",
|
|
1718
|
+
"preconditions": [
|
|
1719
|
+
"page-loaded",
|
|
1720
|
+
"component-catalog-loaded"
|
|
1721
|
+
]
|
|
1722
|
+
},
|
|
1723
|
+
{
|
|
1724
|
+
"operationId": "widget.remove",
|
|
1725
|
+
"title": "Remove widget from page",
|
|
1726
|
+
"scope": "layout",
|
|
1727
|
+
"targetKind": "widget",
|
|
1728
|
+
"target": {
|
|
1729
|
+
"kind": "widget",
|
|
1730
|
+
"resolver": "widget-by-stable-key",
|
|
1731
|
+
"ambiguityPolicy": "fail",
|
|
1732
|
+
"required": true
|
|
1733
|
+
},
|
|
1734
|
+
"inputSchema": {
|
|
1735
|
+
"type": "object",
|
|
1736
|
+
"required": [
|
|
1737
|
+
"widgetKey"
|
|
1738
|
+
],
|
|
1739
|
+
"properties": {
|
|
1740
|
+
"widgetKey": {
|
|
1741
|
+
"type": "string"
|
|
1742
|
+
},
|
|
1743
|
+
"confirmed": {
|
|
1744
|
+
"type": "boolean"
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
},
|
|
1748
|
+
"effects": [
|
|
1749
|
+
{
|
|
1750
|
+
"kind": "compile-domain-patch",
|
|
1751
|
+
"handler": "page-builder-widget-remove",
|
|
1752
|
+
"handlerContract": {
|
|
1753
|
+
"reads": [
|
|
1754
|
+
"WidgetPageDefinition.widgets",
|
|
1755
|
+
"WidgetPageDefinition.canvas.items",
|
|
1756
|
+
"WidgetPageDefinition.composition.links"
|
|
1757
|
+
],
|
|
1758
|
+
"writes": [
|
|
1759
|
+
"page.widgets[]",
|
|
1760
|
+
"page.canvas.items[]",
|
|
1761
|
+
"page.composition.links[]"
|
|
1762
|
+
],
|
|
1763
|
+
"identityKeys": [
|
|
1764
|
+
"widgetKey"
|
|
1765
|
+
],
|
|
1766
|
+
"failureModes": [
|
|
1767
|
+
"widget-not-found",
|
|
1768
|
+
"destructive-removal-not-confirmed",
|
|
1769
|
+
"dangling-composition-link"
|
|
1770
|
+
],
|
|
1771
|
+
"description": "Removes a widget and cleans canvas items and composition links that reference it."
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
],
|
|
1775
|
+
"destructive": true,
|
|
1776
|
+
"requiresConfirmation": true,
|
|
1777
|
+
"validators": [
|
|
1778
|
+
"widget-exists",
|
|
1779
|
+
"destructive-removal-confirmed",
|
|
1780
|
+
"composition-links-cleaned",
|
|
1781
|
+
"canvas-items-reference-existing-widgets"
|
|
1782
|
+
],
|
|
1783
|
+
"affectedPaths": [
|
|
1784
|
+
"widgets[]",
|
|
1785
|
+
"canvas.items[]",
|
|
1786
|
+
"composition.links[]"
|
|
1787
|
+
],
|
|
1788
|
+
"submissionImpact": "config-only",
|
|
1789
|
+
"preconditions": [
|
|
1790
|
+
"page-loaded",
|
|
1791
|
+
"target-widget-exists"
|
|
1792
|
+
]
|
|
1793
|
+
},
|
|
1794
|
+
{
|
|
1795
|
+
"operationId": "widget.moveResize",
|
|
1796
|
+
"title": "Move or resize widget",
|
|
1797
|
+
"scope": "layout",
|
|
1798
|
+
"targetKind": "widget",
|
|
1799
|
+
"target": {
|
|
1800
|
+
"kind": "widget",
|
|
1801
|
+
"resolver": "widget-by-stable-key",
|
|
1802
|
+
"ambiguityPolicy": "fail",
|
|
1803
|
+
"required": true
|
|
1804
|
+
},
|
|
1805
|
+
"inputSchema": {
|
|
1806
|
+
"type": "object",
|
|
1807
|
+
"required": [
|
|
1808
|
+
"widgetKey",
|
|
1809
|
+
"canvasItem"
|
|
1810
|
+
],
|
|
1811
|
+
"properties": {
|
|
1812
|
+
"widgetKey": {
|
|
1813
|
+
"type": "string"
|
|
1814
|
+
},
|
|
1815
|
+
"canvasItem": {
|
|
1816
|
+
"type": "object"
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
},
|
|
1820
|
+
"effects": [
|
|
1821
|
+
{
|
|
1822
|
+
"kind": "compile-domain-patch",
|
|
1823
|
+
"handler": "page-builder-widget-move-resize",
|
|
1824
|
+
"handlerContract": {
|
|
1825
|
+
"reads": [
|
|
1826
|
+
"WidgetPageDefinition.canvas.items",
|
|
1827
|
+
"WidgetPageDefinition.widgets"
|
|
1828
|
+
],
|
|
1829
|
+
"writes": [
|
|
1830
|
+
"page.canvas.items[]"
|
|
1831
|
+
],
|
|
1832
|
+
"identityKeys": [
|
|
1833
|
+
"widgetKey"
|
|
1834
|
+
],
|
|
1835
|
+
"failureModes": [
|
|
1836
|
+
"widget-not-found",
|
|
1837
|
+
"canvas-item-invalid",
|
|
1838
|
+
"canvas-overlap-invalid"
|
|
1839
|
+
],
|
|
1840
|
+
"description": "Updates canvas placement for an existing widget using widgetKey as the stable identity."
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
],
|
|
1844
|
+
"validators": [
|
|
1845
|
+
"widget-exists",
|
|
1846
|
+
"canvas-item-valid",
|
|
1847
|
+
"canvas-item-targets-existing-widget",
|
|
1848
|
+
"canvas-overlap-policy-valid"
|
|
1849
|
+
],
|
|
1850
|
+
"affectedPaths": [
|
|
1851
|
+
"canvas.items[]"
|
|
1852
|
+
],
|
|
1853
|
+
"submissionImpact": "config-only",
|
|
1854
|
+
"preconditions": [
|
|
1855
|
+
"page-loaded",
|
|
1856
|
+
"target-widget-exists"
|
|
1857
|
+
]
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
"operationId": "widget.shell.configure",
|
|
1861
|
+
"title": "Configure widget shell",
|
|
1862
|
+
"scope": "templating",
|
|
1863
|
+
"targetKind": "widgetShell",
|
|
1864
|
+
"target": {
|
|
1865
|
+
"kind": "widgetShell",
|
|
1866
|
+
"resolver": "widget-shell-by-widget-key",
|
|
1867
|
+
"ambiguityPolicy": "fail",
|
|
1868
|
+
"required": true
|
|
1869
|
+
},
|
|
1870
|
+
"inputSchema": {
|
|
1871
|
+
"type": "object",
|
|
1872
|
+
"required": [
|
|
1873
|
+
"widgetKey"
|
|
1874
|
+
],
|
|
1875
|
+
"properties": {
|
|
1876
|
+
"widgetKey": {
|
|
1877
|
+
"type": "string"
|
|
1878
|
+
},
|
|
1879
|
+
"shell": {
|
|
1880
|
+
"type": "object"
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
},
|
|
1884
|
+
"effects": [
|
|
1885
|
+
{
|
|
1886
|
+
"kind": "compile-domain-patch",
|
|
1887
|
+
"handler": "page-builder-widget-shell-configure",
|
|
1888
|
+
"handlerContract": {
|
|
1889
|
+
"reads": [
|
|
1890
|
+
"WidgetPageDefinition.widgets",
|
|
1891
|
+
"WidgetShellEditorComponent",
|
|
1892
|
+
"SettingsPanelBridge"
|
|
1893
|
+
],
|
|
1894
|
+
"writes": [
|
|
1895
|
+
"page.widgets[].shell"
|
|
1896
|
+
],
|
|
1897
|
+
"identityKeys": [
|
|
1898
|
+
"widgetKey"
|
|
1899
|
+
],
|
|
1900
|
+
"failureModes": [
|
|
1901
|
+
"widget-not-found",
|
|
1902
|
+
"settings-panel-bridge-missing",
|
|
1903
|
+
"shell-config-invalid"
|
|
1904
|
+
],
|
|
1905
|
+
"description": "Updates the page-builder-owned widget shell without editing child component inputs."
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
],
|
|
1909
|
+
"validators": [
|
|
1910
|
+
"widget-exists",
|
|
1911
|
+
"widget-shell-shape-valid",
|
|
1912
|
+
"settings-panel-bridge-available",
|
|
1913
|
+
"child-inputs-not-mutated"
|
|
1914
|
+
],
|
|
1915
|
+
"affectedPaths": [
|
|
1916
|
+
"widgets[].shell"
|
|
1917
|
+
],
|
|
1918
|
+
"submissionImpact": "config-only",
|
|
1919
|
+
"preconditions": [
|
|
1920
|
+
"page-loaded",
|
|
1921
|
+
"target-widget-exists"
|
|
1922
|
+
]
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
"operationId": "composition.link.add",
|
|
1926
|
+
"title": "Add page composition link",
|
|
1927
|
+
"scope": "dataBinding",
|
|
1928
|
+
"targetKind": "compositionLink",
|
|
1929
|
+
"target": {
|
|
1930
|
+
"kind": "compositionLink",
|
|
1931
|
+
"resolver": "composition-link-by-id",
|
|
1932
|
+
"ambiguityPolicy": "fail",
|
|
1933
|
+
"required": true
|
|
1934
|
+
},
|
|
1935
|
+
"inputSchema": {
|
|
1936
|
+
"type": "object",
|
|
1937
|
+
"required": [
|
|
1938
|
+
"id",
|
|
1939
|
+
"from",
|
|
1940
|
+
"to",
|
|
1941
|
+
"intent"
|
|
1942
|
+
],
|
|
1943
|
+
"additionalProperties": false,
|
|
1944
|
+
"properties": {
|
|
1945
|
+
"id": {
|
|
1946
|
+
"type": "string"
|
|
1947
|
+
},
|
|
1948
|
+
"from": {
|
|
1949
|
+
"oneOf": [
|
|
1950
|
+
{
|
|
1951
|
+
"type": "object",
|
|
1952
|
+
"required": [
|
|
1953
|
+
"kind",
|
|
1954
|
+
"ref"
|
|
1955
|
+
],
|
|
1956
|
+
"additionalProperties": false,
|
|
1957
|
+
"properties": {
|
|
1958
|
+
"kind": {
|
|
1959
|
+
"enum": [
|
|
1960
|
+
"component-port"
|
|
1961
|
+
]
|
|
1962
|
+
},
|
|
1963
|
+
"ref": {
|
|
1964
|
+
"type": "object",
|
|
1965
|
+
"required": [
|
|
1966
|
+
"widget",
|
|
1967
|
+
"port",
|
|
1968
|
+
"direction"
|
|
1969
|
+
],
|
|
1970
|
+
"additionalProperties": false,
|
|
1971
|
+
"properties": {
|
|
1972
|
+
"widget": {
|
|
1973
|
+
"type": "string"
|
|
1974
|
+
},
|
|
1975
|
+
"port": {
|
|
1976
|
+
"type": "string"
|
|
1977
|
+
},
|
|
1978
|
+
"direction": {
|
|
1979
|
+
"enum": [
|
|
1980
|
+
"input",
|
|
1981
|
+
"output"
|
|
1982
|
+
]
|
|
1983
|
+
},
|
|
1984
|
+
"bindingPath": {
|
|
1985
|
+
"type": "string"
|
|
1986
|
+
},
|
|
1987
|
+
"nestedPath": {
|
|
1988
|
+
"type": "array"
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
},
|
|
1994
|
+
{
|
|
1995
|
+
"type": "object",
|
|
1996
|
+
"required": [
|
|
1997
|
+
"kind",
|
|
1998
|
+
"ref"
|
|
1999
|
+
],
|
|
2000
|
+
"additionalProperties": false,
|
|
2001
|
+
"properties": {
|
|
2002
|
+
"kind": {
|
|
2003
|
+
"enum": [
|
|
2004
|
+
"state"
|
|
2005
|
+
]
|
|
2006
|
+
},
|
|
2007
|
+
"ref": {
|
|
2008
|
+
"type": "object",
|
|
2009
|
+
"required": [
|
|
2010
|
+
"path"
|
|
2011
|
+
],
|
|
2012
|
+
"additionalProperties": false,
|
|
2013
|
+
"properties": {
|
|
2014
|
+
"path": {
|
|
2015
|
+
"type": "string"
|
|
2016
|
+
},
|
|
2017
|
+
"layer": {
|
|
2018
|
+
"enum": [
|
|
2019
|
+
"values",
|
|
2020
|
+
"derived",
|
|
2021
|
+
"transient"
|
|
2022
|
+
]
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
]
|
|
2029
|
+
},
|
|
2030
|
+
"to": {
|
|
2031
|
+
"oneOf": [
|
|
2032
|
+
null,
|
|
2033
|
+
null,
|
|
2034
|
+
{
|
|
2035
|
+
"type": "object",
|
|
2036
|
+
"required": [
|
|
2037
|
+
"kind",
|
|
2038
|
+
"ref"
|
|
2039
|
+
],
|
|
2040
|
+
"additionalProperties": false,
|
|
2041
|
+
"properties": {
|
|
2042
|
+
"kind": {
|
|
2043
|
+
"enum": [
|
|
2044
|
+
"global-action"
|
|
2045
|
+
]
|
|
2046
|
+
},
|
|
2047
|
+
"ref": {
|
|
2048
|
+
"type": "object",
|
|
2049
|
+
"required": [
|
|
2050
|
+
"actionId"
|
|
2051
|
+
],
|
|
2052
|
+
"additionalProperties": false,
|
|
2053
|
+
"properties": {
|
|
2054
|
+
"actionId": {
|
|
2055
|
+
"type": "string"
|
|
2056
|
+
},
|
|
2057
|
+
"payload": {
|
|
2058
|
+
"type": "object"
|
|
2059
|
+
},
|
|
2060
|
+
"payloadExpr": {
|
|
2061
|
+
"type": "string"
|
|
2062
|
+
},
|
|
2063
|
+
"meta": {
|
|
2064
|
+
"type": "object"
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
]
|
|
2071
|
+
},
|
|
2072
|
+
"intent": {
|
|
2073
|
+
"enum": [
|
|
2074
|
+
"event-propagation",
|
|
2075
|
+
"state-write",
|
|
2076
|
+
"state-read",
|
|
2077
|
+
"command-dispatch",
|
|
2078
|
+
"selection-sync",
|
|
2079
|
+
"data-projection",
|
|
2080
|
+
"status-propagation"
|
|
2081
|
+
]
|
|
2082
|
+
},
|
|
2083
|
+
"condition": {
|
|
2084
|
+
"type": "object"
|
|
2085
|
+
},
|
|
2086
|
+
"transform": {
|
|
2087
|
+
"type": "object"
|
|
2088
|
+
},
|
|
2089
|
+
"policy": {
|
|
2090
|
+
"type": "object"
|
|
2091
|
+
},
|
|
2092
|
+
"metadata": {
|
|
2093
|
+
"type": "object"
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
},
|
|
2097
|
+
"effects": [
|
|
2098
|
+
{
|
|
2099
|
+
"kind": "compile-domain-patch",
|
|
2100
|
+
"handler": "page-builder-composition-link-add",
|
|
2101
|
+
"handlerContract": {
|
|
2102
|
+
"reads": [
|
|
2103
|
+
"WidgetPageDefinition.composition.links",
|
|
2104
|
+
"WidgetPageDefinition.widgets",
|
|
2105
|
+
"PAGE_BUILDER_AI_CAPABILITIES"
|
|
2106
|
+
],
|
|
2107
|
+
"writes": [
|
|
2108
|
+
"page.composition.links[]"
|
|
2109
|
+
],
|
|
2110
|
+
"identityKeys": [
|
|
2111
|
+
"id"
|
|
2112
|
+
],
|
|
2113
|
+
"failureModes": [
|
|
2114
|
+
"link-id-duplicate",
|
|
2115
|
+
"endpoint-not-found",
|
|
2116
|
+
"nested-path-invalid",
|
|
2117
|
+
"json-logic-invalid"
|
|
2118
|
+
],
|
|
2119
|
+
"description": "Adds canonical declarative wiring in page.composition.links, including component-port nestedPath endpoints."
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
],
|
|
2123
|
+
"validators": [
|
|
2124
|
+
"composition-link-id-unique",
|
|
2125
|
+
"composition-endpoints-resolve",
|
|
2126
|
+
"nested-path-terminal-widget-key-required",
|
|
2127
|
+
"json-logic-condition-valid",
|
|
2128
|
+
"no-legacy-connections-write"
|
|
2129
|
+
],
|
|
2130
|
+
"affectedPaths": [
|
|
2131
|
+
"composition.links[]"
|
|
2132
|
+
],
|
|
2133
|
+
"submissionImpact": "config-only",
|
|
2134
|
+
"preconditions": [
|
|
2135
|
+
"page-loaded",
|
|
2136
|
+
"widgets-resolvable"
|
|
2137
|
+
]
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
"operationId": "composition.link.remove",
|
|
2141
|
+
"title": "Remove page composition link",
|
|
2142
|
+
"scope": "dataBinding",
|
|
2143
|
+
"targetKind": "compositionLink",
|
|
2144
|
+
"target": {
|
|
2145
|
+
"kind": "compositionLink",
|
|
2146
|
+
"resolver": "composition-link-by-id",
|
|
2147
|
+
"ambiguityPolicy": "fail",
|
|
2148
|
+
"required": true
|
|
2149
|
+
},
|
|
2150
|
+
"inputSchema": {
|
|
2151
|
+
"type": "object",
|
|
2152
|
+
"required": [
|
|
2153
|
+
"id"
|
|
2154
|
+
],
|
|
2155
|
+
"properties": {
|
|
2156
|
+
"id": {
|
|
2157
|
+
"type": "string"
|
|
2158
|
+
},
|
|
2159
|
+
"confirmed": {
|
|
2160
|
+
"type": "boolean"
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
},
|
|
2164
|
+
"effects": [
|
|
2165
|
+
{
|
|
2166
|
+
"kind": "compile-domain-patch",
|
|
2167
|
+
"handler": "page-builder-composition-link-remove",
|
|
2168
|
+
"handlerContract": {
|
|
2169
|
+
"reads": [
|
|
2170
|
+
"WidgetPageDefinition.composition.links"
|
|
2171
|
+
],
|
|
2172
|
+
"writes": [
|
|
2173
|
+
"page.composition.links[]"
|
|
2174
|
+
],
|
|
2175
|
+
"identityKeys": [
|
|
2176
|
+
"id"
|
|
2177
|
+
],
|
|
2178
|
+
"failureModes": [
|
|
2179
|
+
"composition-link-not-found",
|
|
2180
|
+
"destructive-removal-not-confirmed"
|
|
2181
|
+
],
|
|
2182
|
+
"description": "Removes a canonical composition link by stable id."
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
],
|
|
2186
|
+
"destructive": true,
|
|
2187
|
+
"requiresConfirmation": true,
|
|
2188
|
+
"validators": [
|
|
2189
|
+
"composition-link-exists",
|
|
2190
|
+
"destructive-removal-confirmed",
|
|
2191
|
+
"composition-links-still-valid"
|
|
2192
|
+
],
|
|
2193
|
+
"affectedPaths": [
|
|
2194
|
+
"composition.links[]"
|
|
2195
|
+
],
|
|
2196
|
+
"submissionImpact": "config-only",
|
|
2197
|
+
"preconditions": [
|
|
2198
|
+
"page-loaded",
|
|
2199
|
+
"target-link-exists"
|
|
2200
|
+
]
|
|
2201
|
+
},
|
|
2202
|
+
{
|
|
2203
|
+
"operationId": "composition.plan.compile",
|
|
2204
|
+
"title": "Compile UI composition plan",
|
|
2205
|
+
"scope": "rules",
|
|
2206
|
+
"targetKind": "agenticPreview",
|
|
2207
|
+
"target": {
|
|
2208
|
+
"kind": "agenticPreview",
|
|
2209
|
+
"resolver": "agentic-preview-result",
|
|
2210
|
+
"ambiguityPolicy": "fail",
|
|
2211
|
+
"required": true
|
|
2212
|
+
},
|
|
2213
|
+
"inputSchema": {
|
|
2214
|
+
"type": "object",
|
|
2215
|
+
"required": [
|
|
2216
|
+
"uiCompositionPlan"
|
|
2217
|
+
],
|
|
2218
|
+
"properties": {
|
|
2219
|
+
"uiCompositionPlan": {
|
|
2220
|
+
"type": "object"
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
},
|
|
2224
|
+
"effects": [
|
|
2225
|
+
{
|
|
2226
|
+
"kind": "compile-domain-patch",
|
|
2227
|
+
"handler": "page-builder-ui-composition-plan-compile",
|
|
2228
|
+
"handlerContract": {
|
|
2229
|
+
"reads": [
|
|
2230
|
+
"UiCompositionPlan",
|
|
2231
|
+
"compileUiCompositionPlan",
|
|
2232
|
+
"PAGE_BUILDER_WIDGET_AI_CATALOGS",
|
|
2233
|
+
"ComponentDocMeta.configEditor"
|
|
2234
|
+
],
|
|
2235
|
+
"writes": [
|
|
2236
|
+
"compiledFormPatch.patch.page"
|
|
2237
|
+
],
|
|
2238
|
+
"identityKeys": [
|
|
2239
|
+
"uiCompositionPlan.id",
|
|
2240
|
+
"widgetKey",
|
|
2241
|
+
"uiCompositionPlan.bindings[].id"
|
|
2242
|
+
],
|
|
2243
|
+
"failureModes": [
|
|
2244
|
+
"ui-composition-plan-invalid",
|
|
2245
|
+
"widget-catalog-missing",
|
|
2246
|
+
"compiled-page-invalid",
|
|
2247
|
+
"child-config-editor-missing"
|
|
2248
|
+
],
|
|
2249
|
+
"description": "Compiles the agentic intermediate UiCompositionPlan into a renderable WidgetPageDefinition patch.page."
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
],
|
|
2253
|
+
"validators": [
|
|
2254
|
+
"ui-composition-plan-valid",
|
|
2255
|
+
"compiled-page-valid",
|
|
2256
|
+
"widget-keys-unique",
|
|
2257
|
+
"composition-endpoints-resolve",
|
|
2258
|
+
"canvas-items-reference-existing-widgets"
|
|
2259
|
+
],
|
|
2260
|
+
"affectedPaths": [
|
|
2261
|
+
"uiCompositionPlan",
|
|
2262
|
+
"compiledFormPatch.patch.page"
|
|
2263
|
+
],
|
|
2264
|
+
"submissionImpact": "none",
|
|
2265
|
+
"preconditions": [
|
|
2266
|
+
"agentic-preview-loaded",
|
|
2267
|
+
"component-catalog-loaded"
|
|
2268
|
+
]
|
|
2269
|
+
},
|
|
2270
|
+
{
|
|
2271
|
+
"operationId": "state.set",
|
|
2272
|
+
"title": "Set page state value",
|
|
2273
|
+
"scope": "dataBinding",
|
|
2274
|
+
"targetKind": "state",
|
|
2275
|
+
"target": {
|
|
2276
|
+
"kind": "state",
|
|
2277
|
+
"resolver": "page-state-path",
|
|
2278
|
+
"ambiguityPolicy": "fail",
|
|
2279
|
+
"required": true
|
|
2280
|
+
},
|
|
2281
|
+
"inputSchema": {
|
|
2282
|
+
"type": "object",
|
|
2283
|
+
"required": [
|
|
2284
|
+
"path",
|
|
2285
|
+
"value"
|
|
2286
|
+
],
|
|
2287
|
+
"properties": {
|
|
2288
|
+
"path": {
|
|
2289
|
+
"type": "string"
|
|
2290
|
+
},
|
|
2291
|
+
"value": {},
|
|
2292
|
+
"layer": {
|
|
2293
|
+
"enum": [
|
|
2294
|
+
"page",
|
|
2295
|
+
"session"
|
|
2296
|
+
]
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
},
|
|
2300
|
+
"effects": [
|
|
2301
|
+
{
|
|
2302
|
+
"kind": "compile-domain-patch",
|
|
2303
|
+
"handler": "page-builder-state-set",
|
|
2304
|
+
"handlerContract": {
|
|
2305
|
+
"reads": [
|
|
2306
|
+
"WidgetPageDefinition.state",
|
|
2307
|
+
"WidgetPageDefinition.composition.links"
|
|
2308
|
+
],
|
|
2309
|
+
"writes": [
|
|
2310
|
+
"page.state"
|
|
2311
|
+
],
|
|
2312
|
+
"identityKeys": [
|
|
2313
|
+
"path"
|
|
2314
|
+
],
|
|
2315
|
+
"failureModes": [
|
|
2316
|
+
"state-path-invalid",
|
|
2317
|
+
"state-json-invalid",
|
|
2318
|
+
"composition-state-link-invalid"
|
|
2319
|
+
],
|
|
2320
|
+
"description": "Sets canonical page state used by composition links without creating host-only binding paths."
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
],
|
|
2324
|
+
"validators": [
|
|
2325
|
+
"state-path-valid",
|
|
2326
|
+
"state-layer-valid",
|
|
2327
|
+
"state-json-valid",
|
|
2328
|
+
"composition-state-links-still-valid"
|
|
2329
|
+
],
|
|
2330
|
+
"affectedPaths": [
|
|
2331
|
+
"state"
|
|
2332
|
+
],
|
|
2333
|
+
"submissionImpact": "config-only",
|
|
2334
|
+
"preconditions": [
|
|
2335
|
+
"page-loaded"
|
|
2336
|
+
]
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
"operationId": "page.preview.apply",
|
|
2340
|
+
"title": "Apply agentic preview locally",
|
|
2341
|
+
"scope": "interaction",
|
|
2342
|
+
"targetKind": "agenticPreview",
|
|
2343
|
+
"target": {
|
|
2344
|
+
"kind": "agenticPreview",
|
|
2345
|
+
"resolver": "agentic-preview-result",
|
|
2346
|
+
"ambiguityPolicy": "fail",
|
|
2347
|
+
"required": true
|
|
2348
|
+
},
|
|
2349
|
+
"inputSchema": {
|
|
2350
|
+
"type": "object",
|
|
2351
|
+
"required": [
|
|
2352
|
+
"previewId"
|
|
2353
|
+
],
|
|
2354
|
+
"properties": {
|
|
2355
|
+
"previewId": {
|
|
2356
|
+
"type": "string"
|
|
2357
|
+
},
|
|
2358
|
+
"compiledFormPatch": {
|
|
2359
|
+
"type": "object"
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
},
|
|
2363
|
+
"effects": [
|
|
2364
|
+
{
|
|
2365
|
+
"kind": "compile-domain-patch",
|
|
2366
|
+
"handler": "page-builder-preview-apply",
|
|
2367
|
+
"handlerContract": {
|
|
2368
|
+
"reads": [
|
|
2369
|
+
"PageBuilderAiAdapter.applyCompiledFormPatch",
|
|
2370
|
+
"compiledFormPatch.patch.page",
|
|
2371
|
+
"PraxisAssistantTurnViewState"
|
|
2372
|
+
],
|
|
2373
|
+
"writes": [
|
|
2374
|
+
"DynamicPageBuilderComponent.page",
|
|
2375
|
+
"pageChange"
|
|
2376
|
+
],
|
|
2377
|
+
"identityKeys": [
|
|
2378
|
+
"previewId"
|
|
2379
|
+
],
|
|
2380
|
+
"failureModes": [
|
|
2381
|
+
"preview-result-invalid",
|
|
2382
|
+
"patch-page-missing",
|
|
2383
|
+
"runtime-page-invalid",
|
|
2384
|
+
"patch-envelope-persistence-attempted"
|
|
2385
|
+
],
|
|
2386
|
+
"description": "Applies only compiledFormPatch.patch.page to the local runtime page; the backend envelope remains diagnostic data."
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
],
|
|
2390
|
+
"validators": [
|
|
2391
|
+
"preview-result-valid",
|
|
2392
|
+
"compiled-page-patch-present",
|
|
2393
|
+
"no-envelope-runtime-persistence",
|
|
2394
|
+
"runtime-page-valid"
|
|
2395
|
+
],
|
|
2396
|
+
"affectedPaths": [
|
|
2397
|
+
"compiledFormPatch.patch.page",
|
|
2398
|
+
"page"
|
|
2399
|
+
],
|
|
2400
|
+
"submissionImpact": "visual-only",
|
|
2401
|
+
"preconditions": [
|
|
2402
|
+
"agentic-preview-loaded"
|
|
2403
|
+
]
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
"operationId": "page.persist.save",
|
|
2407
|
+
"title": "Persist page through config API",
|
|
2408
|
+
"scope": "interaction",
|
|
2409
|
+
"targetKind": "pageIdentity",
|
|
2410
|
+
"target": {
|
|
2411
|
+
"kind": "pageIdentity",
|
|
2412
|
+
"resolver": "page-builder-persistence-identity",
|
|
2413
|
+
"ambiguityPolicy": "fail",
|
|
2414
|
+
"required": true
|
|
2415
|
+
},
|
|
2416
|
+
"inputSchema": {
|
|
2417
|
+
"type": "object",
|
|
2418
|
+
"required": [
|
|
2419
|
+
"pageIdentity"
|
|
2420
|
+
],
|
|
2421
|
+
"properties": {
|
|
2422
|
+
"pageIdentity": {
|
|
2423
|
+
"type": "object"
|
|
2424
|
+
},
|
|
2425
|
+
"page": {
|
|
2426
|
+
"type": "object"
|
|
2427
|
+
},
|
|
2428
|
+
"etag": {
|
|
2429
|
+
"type": "string"
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
},
|
|
2433
|
+
"effects": [
|
|
2434
|
+
{
|
|
2435
|
+
"kind": "compile-domain-patch",
|
|
2436
|
+
"handler": "page-builder-page-persist-save",
|
|
2437
|
+
"handlerContract": {
|
|
2438
|
+
"reads": [
|
|
2439
|
+
"pageIdentity",
|
|
2440
|
+
"WidgetPageDefinition",
|
|
2441
|
+
"PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS",
|
|
2442
|
+
"ui_user_config ETag"
|
|
2443
|
+
],
|
|
2444
|
+
"writes": [
|
|
2445
|
+
"POST/PUT /api/praxis/config/ui-user-config",
|
|
2446
|
+
"If-Match"
|
|
2447
|
+
],
|
|
2448
|
+
"identityKeys": [
|
|
2449
|
+
"pageIdentity.componentType",
|
|
2450
|
+
"pageIdentity.componentId",
|
|
2451
|
+
"pageIdentity.scope"
|
|
2452
|
+
],
|
|
2453
|
+
"failureModes": [
|
|
2454
|
+
"page-identity-incomplete",
|
|
2455
|
+
"etag-conflict",
|
|
2456
|
+
"runtime-page-invalid",
|
|
2457
|
+
"patch-envelope-persistence-attempted"
|
|
2458
|
+
],
|
|
2459
|
+
"description": "Persists the renderable WidgetPageDefinition with pageIdentity and ETag delegated to praxis-config-starter."
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
],
|
|
2463
|
+
"validators": [
|
|
2464
|
+
"page-identity-complete",
|
|
2465
|
+
"etag-policy-valid",
|
|
2466
|
+
"runtime-page-valid",
|
|
2467
|
+
"no-envelope-runtime-persistence"
|
|
2468
|
+
],
|
|
2469
|
+
"affectedPaths": [
|
|
2470
|
+
"page",
|
|
2471
|
+
"pageIdentity",
|
|
2472
|
+
"etag"
|
|
2473
|
+
],
|
|
2474
|
+
"submissionImpact": "config-only",
|
|
2475
|
+
"preconditions": [
|
|
2476
|
+
"page-loaded",
|
|
2477
|
+
"page-identity-known"
|
|
2478
|
+
]
|
|
2479
|
+
},
|
|
2480
|
+
{
|
|
2481
|
+
"operationId": "childOperation.delegate",
|
|
2482
|
+
"title": "Delegate widget child operation",
|
|
2483
|
+
"scope": "global",
|
|
2484
|
+
"targetKind": "childOperation",
|
|
2485
|
+
"target": {
|
|
2486
|
+
"kind": "childOperation",
|
|
2487
|
+
"resolver": "widget-child-authoring-manifest-operation",
|
|
2488
|
+
"ambiguityPolicy": "fail",
|
|
2489
|
+
"required": false
|
|
2490
|
+
},
|
|
2491
|
+
"inputSchema": {
|
|
2492
|
+
"type": "object",
|
|
2493
|
+
"required": [
|
|
2494
|
+
"widgetKey",
|
|
2495
|
+
"childComponentId",
|
|
2496
|
+
"childOperationId",
|
|
2497
|
+
"reason"
|
|
2498
|
+
],
|
|
2499
|
+
"properties": {
|
|
2500
|
+
"widgetKey": {
|
|
2501
|
+
"type": "string"
|
|
2502
|
+
},
|
|
2503
|
+
"childComponentId": {
|
|
2504
|
+
"type": "string"
|
|
2505
|
+
},
|
|
2506
|
+
"childOperationId": {
|
|
2507
|
+
"type": "string"
|
|
2508
|
+
},
|
|
2509
|
+
"reason": {
|
|
2510
|
+
"type": "string"
|
|
2511
|
+
},
|
|
2512
|
+
"childTarget": {
|
|
2513
|
+
"type": "object"
|
|
2514
|
+
},
|
|
2515
|
+
"childParams": {
|
|
2516
|
+
"type": "object"
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
},
|
|
2520
|
+
"effects": [
|
|
2521
|
+
{
|
|
2522
|
+
"kind": "compile-domain-patch",
|
|
2523
|
+
"handler": "page-builder-child-operation-delegate",
|
|
2524
|
+
"handlerContract": {
|
|
2525
|
+
"reads": [
|
|
2526
|
+
"WidgetPageDefinition.widgets",
|
|
2527
|
+
"ComponentDocMeta.configEditor",
|
|
2528
|
+
"child ComponentAuthoringManifest",
|
|
2529
|
+
"PAGE_BUILDER_WIDGET_AI_CATALOGS"
|
|
2530
|
+
],
|
|
2531
|
+
"writes": [
|
|
2532
|
+
"page.widgets[].definition.inputs"
|
|
2533
|
+
],
|
|
2534
|
+
"identityKeys": [
|
|
2535
|
+
"widgetKey",
|
|
2536
|
+
"childComponentId",
|
|
2537
|
+
"childOperationId"
|
|
2538
|
+
],
|
|
2539
|
+
"failureModes": [
|
|
2540
|
+
"widget-not-found",
|
|
2541
|
+
"child-manifest-missing",
|
|
2542
|
+
"child-operation-unknown",
|
|
2543
|
+
"local-child-input-write-attempted"
|
|
2544
|
+
],
|
|
2545
|
+
"description": "Delegates child widget input edits to the owning manifest or configEditor instead of redefining child semantics in page-builder."
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
],
|
|
2549
|
+
"validators": [
|
|
2550
|
+
"widget-exists",
|
|
2551
|
+
"child-manifest-available",
|
|
2552
|
+
"child-operation-known",
|
|
2553
|
+
"component-config-editor-respected",
|
|
2554
|
+
"no-local-child-input-write"
|
|
2555
|
+
],
|
|
2556
|
+
"affectedPaths": [
|
|
2557
|
+
"widgets[].definition.inputs"
|
|
2558
|
+
],
|
|
2559
|
+
"submissionImpact": "config-only",
|
|
2560
|
+
"preconditions": [
|
|
2561
|
+
"page-loaded",
|
|
2562
|
+
"target-widget-exists",
|
|
2563
|
+
"child-authoring-contract-available"
|
|
2564
|
+
]
|
|
2565
|
+
}
|
|
2566
|
+
],
|
|
2567
|
+
"validators": [
|
|
2568
|
+
{
|
|
2569
|
+
"validatorId": "widget-page-definition-valid",
|
|
2570
|
+
"level": "error",
|
|
2571
|
+
"code": "PAGE_BUILDER_PAGE_VALID",
|
|
2572
|
+
"description": "The document must remain a renderable WidgetPageDefinition."
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
"validatorId": "no-legacy-grid-page-definition",
|
|
2576
|
+
"level": "error",
|
|
2577
|
+
"code": "PAGE_BUILDER_NO_GRID_PAGE",
|
|
2578
|
+
"description": "Legacy GridPageDefinition semantics cannot be reintroduced."
|
|
2579
|
+
},
|
|
2580
|
+
{
|
|
2581
|
+
"validatorId": "page-context-json-valid",
|
|
2582
|
+
"level": "error",
|
|
2583
|
+
"code": "PAGE_BUILDER_CONTEXT_JSON",
|
|
2584
|
+
"description": "Page context must stay JSON-serializable."
|
|
2585
|
+
},
|
|
2586
|
+
{
|
|
2587
|
+
"validatorId": "settings-panel-round-trip-valid",
|
|
2588
|
+
"level": "error",
|
|
2589
|
+
"code": "PAGE_BUILDER_SETTINGS_ROUND_TRIP",
|
|
2590
|
+
"description": "Settings panel apply/save/reset/reopen must preserve the same page shape."
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
"validatorId": "canvas-columns-integer",
|
|
2594
|
+
"level": "error",
|
|
2595
|
+
"code": "PAGE_BUILDER_CANVAS_COLUMNS",
|
|
2596
|
+
"description": "Canvas columns must be an integer grid count."
|
|
2597
|
+
},
|
|
2598
|
+
{
|
|
2599
|
+
"validatorId": "canvas-row-unit-valid",
|
|
2600
|
+
"level": "error",
|
|
2601
|
+
"code": "PAGE_BUILDER_CANVAS_ROW_UNIT",
|
|
2602
|
+
"description": "Canvas row unit must be a positive layout unit."
|
|
2603
|
+
},
|
|
2604
|
+
{
|
|
2605
|
+
"validatorId": "canvas-gap-valid",
|
|
2606
|
+
"level": "error",
|
|
2607
|
+
"code": "PAGE_BUILDER_CANVAS_GAP",
|
|
2608
|
+
"description": "Canvas gap must be a valid non-negative spacing value."
|
|
2609
|
+
},
|
|
2610
|
+
{
|
|
2611
|
+
"validatorId": "canvas-items-reference-existing-widgets",
|
|
2612
|
+
"level": "error",
|
|
2613
|
+
"code": "PAGE_BUILDER_CANVAS_WIDGET_REFS",
|
|
2614
|
+
"description": "Every canvas item must reference an existing widgetKey."
|
|
2615
|
+
},
|
|
2616
|
+
{
|
|
2617
|
+
"validatorId": "widget-key-unique",
|
|
2618
|
+
"level": "error",
|
|
2619
|
+
"code": "PAGE_BUILDER_WIDGET_KEY_UNIQUE",
|
|
2620
|
+
"description": "Widget keys must be unique."
|
|
2621
|
+
},
|
|
2622
|
+
{
|
|
2623
|
+
"validatorId": "component-registered",
|
|
2624
|
+
"level": "error",
|
|
2625
|
+
"code": "PAGE_BUILDER_COMPONENT_REGISTERED",
|
|
2626
|
+
"description": "Widget component id must exist in the component registry/catalog."
|
|
2627
|
+
},
|
|
2628
|
+
{
|
|
2629
|
+
"validatorId": "canvas-item-valid",
|
|
2630
|
+
"level": "error",
|
|
2631
|
+
"code": "PAGE_BUILDER_CANVAS_ITEM",
|
|
2632
|
+
"description": "Canvas item geometry must be valid."
|
|
2633
|
+
},
|
|
2634
|
+
{
|
|
2635
|
+
"validatorId": "child-inputs-delegated",
|
|
2636
|
+
"level": "error",
|
|
2637
|
+
"code": "PAGE_BUILDER_CHILD_INPUTS_DELEGATED",
|
|
2638
|
+
"description": "Child component input edits must delegate to the child owner."
|
|
2639
|
+
},
|
|
2640
|
+
{
|
|
2641
|
+
"validatorId": "widget-key-not-array-index",
|
|
2642
|
+
"level": "error",
|
|
2643
|
+
"code": "PAGE_BUILDER_WIDGET_KEY_INDEX",
|
|
2644
|
+
"description": "Array index is not a stable widget identity."
|
|
2645
|
+
},
|
|
2646
|
+
{
|
|
2647
|
+
"validatorId": "widget-exists",
|
|
2648
|
+
"level": "error",
|
|
2649
|
+
"code": "PAGE_BUILDER_WIDGET_EXISTS",
|
|
2650
|
+
"description": "Target widget must exist."
|
|
2651
|
+
},
|
|
2652
|
+
{
|
|
2653
|
+
"validatorId": "destructive-removal-confirmed",
|
|
2654
|
+
"level": "error",
|
|
2655
|
+
"code": "PAGE_BUILDER_DESTRUCTIVE_CONFIRMED",
|
|
2656
|
+
"description": "Destructive removals require explicit confirmation."
|
|
2657
|
+
},
|
|
2658
|
+
{
|
|
2659
|
+
"validatorId": "composition-links-cleaned",
|
|
2660
|
+
"level": "error",
|
|
2661
|
+
"code": "PAGE_BUILDER_LINKS_CLEANED",
|
|
2662
|
+
"description": "Removing a widget must remove dangling composition links."
|
|
2663
|
+
},
|
|
2664
|
+
{
|
|
2665
|
+
"validatorId": "canvas-item-targets-existing-widget",
|
|
2666
|
+
"level": "error",
|
|
2667
|
+
"code": "PAGE_BUILDER_CANVAS_ITEM_TARGET",
|
|
2668
|
+
"description": "Moved canvas item must target an existing widget."
|
|
2669
|
+
},
|
|
2670
|
+
{
|
|
2671
|
+
"validatorId": "canvas-overlap-policy-valid",
|
|
2672
|
+
"level": "warning",
|
|
2673
|
+
"code": "PAGE_BUILDER_CANVAS_OVERLAP",
|
|
2674
|
+
"description": "Canvas overlap policy must be respected."
|
|
2675
|
+
},
|
|
2676
|
+
{
|
|
2677
|
+
"validatorId": "widget-shell-shape-valid",
|
|
2678
|
+
"level": "error",
|
|
2679
|
+
"code": "PAGE_BUILDER_SHELL_SHAPE",
|
|
2680
|
+
"description": "Widget shell config must match the shell editor contract."
|
|
2681
|
+
},
|
|
2682
|
+
{
|
|
2683
|
+
"validatorId": "settings-panel-bridge-available",
|
|
2684
|
+
"level": "error",
|
|
2685
|
+
"code": "PAGE_BUILDER_SETTINGS_BRIDGE",
|
|
2686
|
+
"description": "Settings panel bridge must be available for shell/page editors."
|
|
2687
|
+
},
|
|
2688
|
+
{
|
|
2689
|
+
"validatorId": "child-inputs-not-mutated",
|
|
2690
|
+
"level": "error",
|
|
2691
|
+
"code": "PAGE_BUILDER_CHILD_INPUTS_NOT_MUTATED",
|
|
2692
|
+
"description": "Shell edits cannot mutate child inputs."
|
|
2693
|
+
},
|
|
2694
|
+
{
|
|
2695
|
+
"validatorId": "composition-link-id-unique",
|
|
2696
|
+
"level": "error",
|
|
2697
|
+
"code": "PAGE_BUILDER_LINK_ID_UNIQUE",
|
|
2698
|
+
"description": "Composition link ids must be unique."
|
|
2699
|
+
},
|
|
2700
|
+
{
|
|
2701
|
+
"validatorId": "composition-endpoints-resolve",
|
|
2702
|
+
"level": "error",
|
|
2703
|
+
"code": "PAGE_BUILDER_LINK_ENDPOINTS",
|
|
2704
|
+
"description": "Composition endpoints must resolve to known widgets, ports and nested paths."
|
|
2705
|
+
},
|
|
2706
|
+
{
|
|
2707
|
+
"validatorId": "nested-path-terminal-widget-key-required",
|
|
2708
|
+
"level": "error",
|
|
2709
|
+
"code": "PAGE_BUILDER_NESTED_PATH_WIDGET_KEY",
|
|
2710
|
+
"description": "Nested component-port paths must terminate at a stable widget key."
|
|
2711
|
+
},
|
|
2712
|
+
{
|
|
2713
|
+
"validatorId": "json-logic-condition-valid",
|
|
2714
|
+
"level": "error",
|
|
2715
|
+
"code": "PAGE_BUILDER_JSON_LOGIC",
|
|
2716
|
+
"description": "Composition link condition must be valid Json Logic."
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
"validatorId": "no-legacy-connections-write",
|
|
2720
|
+
"level": "error",
|
|
2721
|
+
"code": "PAGE_BUILDER_NO_LEGACY_CONNECTIONS",
|
|
2722
|
+
"description": "Operations must write page.composition.links, not legacy connections."
|
|
2723
|
+
},
|
|
2724
|
+
{
|
|
2725
|
+
"validatorId": "composition-link-exists",
|
|
2726
|
+
"level": "error",
|
|
2727
|
+
"code": "PAGE_BUILDER_LINK_EXISTS",
|
|
2728
|
+
"description": "Target composition link must exist."
|
|
2729
|
+
},
|
|
2730
|
+
{
|
|
2731
|
+
"validatorId": "composition-links-still-valid",
|
|
2732
|
+
"level": "error",
|
|
2733
|
+
"code": "PAGE_BUILDER_LINKS_STILL_VALID",
|
|
2734
|
+
"description": "Remaining composition links must still validate after the operation."
|
|
2735
|
+
},
|
|
2736
|
+
{
|
|
2737
|
+
"validatorId": "ui-composition-plan-valid",
|
|
2738
|
+
"level": "error",
|
|
2739
|
+
"code": "PAGE_BUILDER_UI_PLAN_VALID",
|
|
2740
|
+
"description": "UiCompositionPlan must match the intermediate agentic plan contract."
|
|
2741
|
+
},
|
|
2742
|
+
{
|
|
2743
|
+
"validatorId": "compiled-page-valid",
|
|
2744
|
+
"level": "error",
|
|
2745
|
+
"code": "PAGE_BUILDER_COMPILED_PAGE_VALID",
|
|
2746
|
+
"description": "Compiled output must be a valid WidgetPageDefinition."
|
|
2747
|
+
},
|
|
2748
|
+
{
|
|
2749
|
+
"validatorId": "widget-keys-unique",
|
|
2750
|
+
"level": "error",
|
|
2751
|
+
"code": "PAGE_BUILDER_WIDGET_KEYS_UNIQUE",
|
|
2752
|
+
"description": "Compiled plan must produce unique widget keys."
|
|
2753
|
+
},
|
|
2754
|
+
{
|
|
2755
|
+
"validatorId": "state-path-valid",
|
|
2756
|
+
"level": "error",
|
|
2757
|
+
"code": "PAGE_BUILDER_STATE_PATH",
|
|
2758
|
+
"description": "State paths must be valid page state paths."
|
|
2759
|
+
},
|
|
2760
|
+
{
|
|
2761
|
+
"validatorId": "state-layer-valid",
|
|
2762
|
+
"level": "error",
|
|
2763
|
+
"code": "PAGE_BUILDER_STATE_LAYER",
|
|
2764
|
+
"description": "State layer must be page or session."
|
|
2765
|
+
},
|
|
2766
|
+
{
|
|
2767
|
+
"validatorId": "state-json-valid",
|
|
2768
|
+
"level": "error",
|
|
2769
|
+
"code": "PAGE_BUILDER_STATE_JSON",
|
|
2770
|
+
"description": "State values must be JSON-serializable."
|
|
2771
|
+
},
|
|
2772
|
+
{
|
|
2773
|
+
"validatorId": "composition-state-links-still-valid",
|
|
2774
|
+
"level": "error",
|
|
2775
|
+
"code": "PAGE_BUILDER_STATE_LINKS",
|
|
2776
|
+
"description": "State edits must not break composition links."
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
"validatorId": "preview-result-valid",
|
|
2780
|
+
"level": "error",
|
|
2781
|
+
"code": "PAGE_BUILDER_PREVIEW_VALID",
|
|
2782
|
+
"description": "Agentic preview result must be structurally valid."
|
|
2783
|
+
},
|
|
2784
|
+
{
|
|
2785
|
+
"validatorId": "compiled-page-patch-present",
|
|
2786
|
+
"level": "error",
|
|
2787
|
+
"code": "PAGE_BUILDER_PATCH_PAGE_PRESENT",
|
|
2788
|
+
"description": "Preview envelope must include compiledFormPatch.patch.page."
|
|
2789
|
+
},
|
|
2790
|
+
{
|
|
2791
|
+
"validatorId": "no-envelope-runtime-persistence",
|
|
2792
|
+
"level": "error",
|
|
2793
|
+
"code": "PAGE_BUILDER_NO_ENVELOPE_PERSISTENCE",
|
|
2794
|
+
"description": "Runtime persistence cannot save the full preview envelope."
|
|
2795
|
+
},
|
|
2796
|
+
{
|
|
2797
|
+
"validatorId": "runtime-page-valid",
|
|
2798
|
+
"level": "error",
|
|
2799
|
+
"code": "PAGE_BUILDER_RUNTIME_PAGE_VALID",
|
|
2800
|
+
"description": "Runtime page must remain renderable by praxis-dynamic-page."
|
|
2801
|
+
},
|
|
2802
|
+
{
|
|
2803
|
+
"validatorId": "page-identity-complete",
|
|
2804
|
+
"level": "error",
|
|
2805
|
+
"code": "PAGE_BUILDER_PAGE_IDENTITY",
|
|
2806
|
+
"description": "Save requires component type, component id and scope identity."
|
|
2807
|
+
},
|
|
2808
|
+
{
|
|
2809
|
+
"validatorId": "etag-policy-valid",
|
|
2810
|
+
"level": "error",
|
|
2811
|
+
"code": "PAGE_BUILDER_ETAG_POLICY",
|
|
2812
|
+
"description": "Save must respect backend ETag/If-Match policy."
|
|
2813
|
+
},
|
|
2814
|
+
{
|
|
2815
|
+
"validatorId": "child-manifest-available",
|
|
2816
|
+
"level": "error",
|
|
2817
|
+
"code": "PAGE_BUILDER_CHILD_MANIFEST_AVAILABLE",
|
|
2818
|
+
"description": "Delegated child component must expose an authoring manifest or configEditor."
|
|
2819
|
+
},
|
|
2820
|
+
{
|
|
2821
|
+
"validatorId": "child-operation-known",
|
|
2822
|
+
"level": "error",
|
|
2823
|
+
"code": "PAGE_BUILDER_CHILD_OPERATION_KNOWN",
|
|
2824
|
+
"description": "Delegated child operation id must be known."
|
|
2825
|
+
},
|
|
2826
|
+
{
|
|
2827
|
+
"validatorId": "component-config-editor-respected",
|
|
2828
|
+
"level": "error",
|
|
2829
|
+
"code": "PAGE_BUILDER_CONFIG_EDITOR_RESPECTED",
|
|
2830
|
+
"description": "ComponentDocMeta.configEditor must remain the source for child input editing."
|
|
2831
|
+
},
|
|
2832
|
+
{
|
|
2833
|
+
"validatorId": "no-local-child-input-write",
|
|
2834
|
+
"level": "error",
|
|
2835
|
+
"code": "PAGE_BUILDER_NO_LOCAL_CHILD_INPUT_WRITE",
|
|
2836
|
+
"description": "Page-builder must not define child component input semantics locally."
|
|
2837
|
+
}
|
|
2838
|
+
],
|
|
2839
|
+
"roundTripRequirements": [
|
|
2840
|
+
"WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.",
|
|
2841
|
+
"UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.",
|
|
2842
|
+
"Widget keys and composition link ids are stable identities; array indexes are never canonical identities.",
|
|
2843
|
+
"Persisted wiring uses page.composition.links and must not write legacy connections.",
|
|
2844
|
+
"Nested component ports use component-port refs with nestedPath ending in a stable widget key.",
|
|
2845
|
+
"Child widget definition.inputs edits delegate to the child manifest or ComponentDocMeta.configEditor.",
|
|
2846
|
+
"Agentic preview applies only compiledFormPatch.patch.page to runtime; the full patch envelope is diagnostics/audit data.",
|
|
2847
|
+
"Save uses pageIdentity and ETag policy from praxis-config-starter; pageIdentity is not persisted inside WidgetPageDefinition.",
|
|
2848
|
+
"Settings panel apply/save/reset/reopen must preserve page settings and widget shell config without hidden normalization drift."
|
|
2849
|
+
],
|
|
2850
|
+
"examples": [
|
|
2851
|
+
{
|
|
2852
|
+
"id": "configure-dashboard-page",
|
|
2853
|
+
"request": "Set this page title to Payroll Overview and store payrollPeriod in the page context.",
|
|
2854
|
+
"operationId": "page.configure",
|
|
2855
|
+
"params": {
|
|
2856
|
+
"title": "Payroll Overview",
|
|
2857
|
+
"context": {
|
|
2858
|
+
"payrollPeriod": "current"
|
|
2859
|
+
}
|
|
2860
|
+
},
|
|
2861
|
+
"isPositive": true
|
|
2862
|
+
},
|
|
2863
|
+
{
|
|
2864
|
+
"id": "configure-canvas-grid",
|
|
2865
|
+
"request": "Use a 12 column dashboard grid with compact gaps.",
|
|
2866
|
+
"operationId": "canvas.configure",
|
|
2867
|
+
"target": "canvas",
|
|
2868
|
+
"params": {
|
|
2869
|
+
"columns": 12,
|
|
2870
|
+
"rowUnit": 8,
|
|
2871
|
+
"gap": 8
|
|
2872
|
+
},
|
|
2873
|
+
"isPositive": true
|
|
2874
|
+
},
|
|
2875
|
+
{
|
|
2876
|
+
"id": "add-employees-table-widget",
|
|
2877
|
+
"request": "Add an employees table widget to the left half of the first row.",
|
|
2878
|
+
"operationId": "widget.add",
|
|
2879
|
+
"target": "employees-table",
|
|
2880
|
+
"params": {
|
|
2881
|
+
"widgetKey": "employees-table",
|
|
2882
|
+
"componentId": "praxis-table",
|
|
2883
|
+
"canvasItem": {
|
|
2884
|
+
"x": 0,
|
|
2885
|
+
"y": 0,
|
|
2886
|
+
"w": 6,
|
|
2887
|
+
"h": 8
|
|
2888
|
+
}
|
|
2889
|
+
},
|
|
2890
|
+
"isPositive": true
|
|
2891
|
+
},
|
|
2892
|
+
{
|
|
2893
|
+
"id": "remove-summary-card",
|
|
2894
|
+
"request": "Remove the summary-card widget and its links.",
|
|
2895
|
+
"operationId": "widget.remove",
|
|
2896
|
+
"target": "summary-card",
|
|
2897
|
+
"params": {
|
|
2898
|
+
"widgetKey": "summary-card",
|
|
2899
|
+
"confirmed": true
|
|
2900
|
+
},
|
|
2901
|
+
"isPositive": true
|
|
2902
|
+
},
|
|
2903
|
+
{
|
|
2904
|
+
"id": "move-payroll-chart",
|
|
2905
|
+
"request": "Move payroll-chart to the right column and make it taller.",
|
|
2906
|
+
"operationId": "widget.moveResize",
|
|
2907
|
+
"target": "payroll-chart",
|
|
2908
|
+
"params": {
|
|
2909
|
+
"widgetKey": "payroll-chart",
|
|
2910
|
+
"canvasItem": {
|
|
2911
|
+
"x": 6,
|
|
2912
|
+
"y": 0,
|
|
2913
|
+
"w": 6,
|
|
2914
|
+
"h": 10
|
|
2915
|
+
}
|
|
2916
|
+
},
|
|
2917
|
+
"isPositive": true
|
|
2918
|
+
},
|
|
2919
|
+
{
|
|
2920
|
+
"id": "configure-widget-shell",
|
|
2921
|
+
"request": "Rename the employees widget card and enable the refresh shell action.",
|
|
2922
|
+
"operationId": "widget.shell.configure",
|
|
2923
|
+
"target": "employees-table",
|
|
2924
|
+
"params": {
|
|
2925
|
+
"widgetKey": "employees-table",
|
|
2926
|
+
"shell": {
|
|
2927
|
+
"title": "Employees",
|
|
2928
|
+
"actions": [
|
|
2929
|
+
{
|
|
2930
|
+
"id": "refresh"
|
|
2931
|
+
}
|
|
2932
|
+
]
|
|
2933
|
+
}
|
|
2934
|
+
},
|
|
2935
|
+
"isPositive": true
|
|
2936
|
+
},
|
|
2937
|
+
{
|
|
2938
|
+
"id": "link-department-selection-to-table",
|
|
2939
|
+
"request": "When department-list selection changes, filter employees-table by department id.",
|
|
2940
|
+
"operationId": "composition.link.add",
|
|
2941
|
+
"target": "department-selection-to-employees",
|
|
2942
|
+
"params": {
|
|
2943
|
+
"id": "department-selection-to-employees",
|
|
2944
|
+
"from": {
|
|
2945
|
+
"widget": "department-list",
|
|
2946
|
+
"port": "selection"
|
|
2947
|
+
},
|
|
2948
|
+
"to": {
|
|
2949
|
+
"widget": "employees-table",
|
|
2950
|
+
"port": "filter"
|
|
2951
|
+
},
|
|
2952
|
+
"intent": "selection-sync"
|
|
2953
|
+
},
|
|
2954
|
+
"isPositive": true
|
|
2955
|
+
},
|
|
2956
|
+
{
|
|
2957
|
+
"id": "remove-obsolete-link",
|
|
2958
|
+
"request": "Remove the old payroll-filter-link composition link.",
|
|
2959
|
+
"operationId": "composition.link.remove",
|
|
2960
|
+
"target": "payroll-filter-link",
|
|
2961
|
+
"params": {
|
|
2962
|
+
"id": "payroll-filter-link",
|
|
2963
|
+
"confirmed": true
|
|
2964
|
+
},
|
|
2965
|
+
"isPositive": true
|
|
2966
|
+
},
|
|
2967
|
+
{
|
|
2968
|
+
"id": "compile-resource-dashboard-plan",
|
|
2969
|
+
"request": "Compile the resource-dashboard plan returned by the assistant into a renderable page preview.",
|
|
2970
|
+
"operationId": "composition.plan.compile",
|
|
2971
|
+
"target": "preview-payroll-dashboard",
|
|
2972
|
+
"params": {
|
|
2973
|
+
"uiCompositionPlan": {
|
|
2974
|
+
"layoutPreset": "resource-dashboard"
|
|
2975
|
+
}
|
|
2976
|
+
},
|
|
2977
|
+
"isPositive": true
|
|
2978
|
+
},
|
|
2979
|
+
{
|
|
2980
|
+
"id": "set-selected-department-state",
|
|
2981
|
+
"request": "Store selectedDepartmentId in page state for downstream links.",
|
|
2982
|
+
"operationId": "state.set",
|
|
2983
|
+
"target": "state.selectedDepartmentId",
|
|
2984
|
+
"params": {
|
|
2985
|
+
"path": "selectedDepartmentId",
|
|
2986
|
+
"value": "sales",
|
|
2987
|
+
"layer": "page"
|
|
2988
|
+
},
|
|
2989
|
+
"isPositive": true
|
|
2990
|
+
},
|
|
2991
|
+
{
|
|
2992
|
+
"id": "apply-agentic-preview",
|
|
2993
|
+
"request": "Apply the current assistant preview to the local page.",
|
|
2994
|
+
"operationId": "page.preview.apply",
|
|
2995
|
+
"target": "preview-current",
|
|
2996
|
+
"params": {
|
|
2997
|
+
"previewId": "preview-current"
|
|
2998
|
+
},
|
|
2999
|
+
"isPositive": true
|
|
3000
|
+
},
|
|
3001
|
+
{
|
|
3002
|
+
"id": "persist-page",
|
|
3003
|
+
"request": "Save this page configuration using the current ETag.",
|
|
3004
|
+
"operationId": "page.persist.save",
|
|
3005
|
+
"target": "tenant-dashboard-page",
|
|
3006
|
+
"params": {
|
|
3007
|
+
"pageIdentity": {
|
|
3008
|
+
"componentType": "page-builder",
|
|
3009
|
+
"componentId": "tenant-dashboard",
|
|
3010
|
+
"scope": "tenant"
|
|
3011
|
+
},
|
|
3012
|
+
"etag": "\"v7\""
|
|
3013
|
+
},
|
|
3014
|
+
"isPositive": true
|
|
3015
|
+
},
|
|
3016
|
+
{
|
|
3017
|
+
"id": "delegate-table-column-edit",
|
|
3018
|
+
"request": "Add a salary column to the employees table widget.",
|
|
3019
|
+
"operationId": "childOperation.delegate",
|
|
3020
|
+
"target": "employees-table",
|
|
3021
|
+
"params": {
|
|
3022
|
+
"widgetKey": "employees-table",
|
|
3023
|
+
"childComponentId": "praxis-table",
|
|
3024
|
+
"childOperationId": "column.add",
|
|
3025
|
+
"reason": "TableConfig is owned by praxis-table."
|
|
3026
|
+
},
|
|
3027
|
+
"isPositive": true
|
|
3028
|
+
},
|
|
3029
|
+
{
|
|
3030
|
+
"id": "reject-direct-dynamic-form-field-write",
|
|
3031
|
+
"request": "Directly write a new dynamic-form field into the widget inputs from page-builder.",
|
|
3032
|
+
"operationId": "childOperation.delegate",
|
|
3033
|
+
"target": "employee-form",
|
|
3034
|
+
"params": {
|
|
3035
|
+
"widgetKey": "employee-form",
|
|
3036
|
+
"childComponentId": "praxis-dynamic-form",
|
|
3037
|
+
"childOperationId": "field.add",
|
|
3038
|
+
"reason": "Dynamic form fields are delegated."
|
|
3039
|
+
},
|
|
3040
|
+
"isPositive": false
|
|
3041
|
+
},
|
|
3042
|
+
{
|
|
3043
|
+
"id": "reject-legacy-connections",
|
|
3044
|
+
"request": "Create the widget link under the old connections collection.",
|
|
3045
|
+
"operationId": "composition.link.add",
|
|
3046
|
+
"target": "legacy-connection",
|
|
3047
|
+
"params": {
|
|
3048
|
+
"id": "legacy-connection",
|
|
3049
|
+
"collection": "connections"
|
|
3050
|
+
},
|
|
3051
|
+
"isPositive": false
|
|
3052
|
+
}
|
|
3053
|
+
]
|
|
3054
|
+
},
|
|
3055
|
+
"chunks": [
|
|
3056
|
+
{
|
|
3057
|
+
"chunkIndex": 0,
|
|
3058
|
+
"chunkKind": "summary",
|
|
3059
|
+
"content": "Component ID: praxis-page-builder\nSelector: praxis-dynamic-page-builder\nFriendly Name: Praxis Page Builder\nDescription: Page builder using the canonical praxis-dynamic-page runtime.\nCategory: page\nLib/Package: @praxisui/page-builder\nTags: widget, page-builder, configurable\nOutputs:\n - pageChange (WidgetPageDefinition)\n - widgetEvent (WidgetEventEnvelope)\n - pageSaveRequested (WidgetPageDefinition)\n - agenticAuthoringApplied (PageBuilderApplyResult)\n - agenticAuthoringSharedRuleHandoff (PageBuilderAgenticAuthoringSharedRuleHandoff)\n - pageRestart (void)\n - savedPageDeleteRequested (void)\n",
|
|
3060
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-page-builder/src/lib/praxis-page-builder.metadata.ts",
|
|
3061
|
+
"contentHash": "3d0b5965e3c48d62afbc44f4cf7f98b7b89251cbca472efefa0d525e22531958",
|
|
3062
|
+
"sourceKind": "component_definition",
|
|
3063
|
+
"sourceId": "praxis-page-builder",
|
|
3064
|
+
"corpusVersion": "1.0.0"
|
|
3065
|
+
},
|
|
3066
|
+
{
|
|
3067
|
+
"chunkIndex": 1,
|
|
3068
|
+
"chunkKind": "capabilities",
|
|
3069
|
+
"content": "Component Capabilities:\n - Path: uiCompositionPlan\n Category: page\n Kind: object\n Description: Plano declarativo intermediario aceito em preview agentic antes do WidgetPageDefinition.\n - Path: uiCompositionPlan.version\n Category: page\n Kind: string\n Description: Versao do plano. Valor atual: 1.0.\n - Path: uiCompositionPlan.kind\n Category: page\n Kind: string\n Description: Discriminador do plano. Valor atual: praxis.ui-composition-plan.\n - Path: uiCompositionPlan.layoutPreset\n Category: layout\n Kind: string\n Description: Preset semantico opcional da composicao planejada.\n - Path: uiCompositionPlan.layoutPresetOptions\n Category: layout\n Kind: object\n Description: Opcoes semanticas opcionais do preset, como familia visual, estrategia responsiva e politica de densidade.\n - Path: uiCompositionPlan.grouping\n Category: layout\n Kind: array\n Description: Agrupamentos semanticos opcionais para organizar widgets em hero, section, tabs ou rail no runtime.\n - Path: uiCompositionPlan.slotAssignments\n Category: layout\n Kind: object\n Description: Mapa opcional widgetKey -> slot semantico para alinhar widgets gerados a presets de layout sem depender de dominio.\n - Path: uiCompositionPlan.deviceLayouts\n Category: layout\n Kind: object\n Description: Variantes responsivas opcionais para desktop, tablet e mobile, incluindo canvas, groupingOverrides e widgetOverrides.\n - Path: uiCompositionPlan.themePreset\n Category: layout\n Kind: string\n Description: Preset visual opcional do runtime, por exemplo analytics-calm, workspace-balanced ou ops-monitoring.\n - Path: uiCompositionPlan.state\n Category: state\n Kind: object\n Description: Estado inicial/declarativo que sera compilado para page.state.\n - Path: uiCompositionPlan.widgets\n Category: widgets\n Kind: array\n Description: Widgets planejados antes da compilacao para page.widgets.\n - Path: uiCompositionPlan.widgets[].key\n Category: widgets\n Kind: string\n Description: ID estavel do widget planejado.\n - Path: uiCompositionPlan.widgets[].componentId\n Category: widgets\n Kind: string\n Description: Componente registrado que sera compilado para definition.id.\n - Path: uiCompositionPlan.widgets[].inputs\n Category: widgets\n Kind: object\n Description: Inputs canonicos do componente, compilados para definition.inputs.\n - Path: uiCompositionPlan.widgets[].bindingOrder\n Category: widgets\n Kind: array\n Description: Ordem declarativa de binding, compilada para definition.bindingOrder.\n - Path: uiCompositionPlan.bindings\n Category: connections\n Kind: array\n Description: Bindings declarativos que serao compilados para page.composition.links.\n - Path: uiCompositionPlan.bindings[].id\n Category: connections\n Kind: string\n Description: Identificador estavel do binding planejado.\n - Path: uiCompositionPlan.bindings[].from\n Category: connections\n Kind: object\n Description: Endpoint de origem: component-port ou state.\n - Path: uiCompositionPlan.bindings[].to\n Category: connections\n Kind: object\n Description: Endpoint de destino: component-port, state ou global-action.\n - Path: uiCompositionPlan.bindings[].to.[actionId]\n Category: connections\n Kind: string\n Description: ID da action global quando uiCompositionPlan.bindings[].to.kind = global-action.\n - Path: uiCompositionPlan.bindings[].to.payload\n Category: connections\n Kind: object\n Description: Payload literal opcional para destino global-action planejado.\n - Path: uiCompositionPlan.bindings[].to.payloadExpr\n Category: connections\n Kind: string\n Description: Path de payload opcional para destino global-action planejado.\n - Path: uiCompositionPlan.bindings[].from.nestedPath\n Category: connections\n Kind: array\n Description: Caminho estruturado para porta nested de origem. Use apenas com endpoint component-port; o owner top-level continua em from.widget.\n - Path: uiCompositionPlan.bindings[].to.nestedPath\n Category: connections\n Kind: array\n Description: Caminho estruturado para porta nested de destino. Use apenas com endpoint component-port; o owner top-level continua em to.widget.\n - Path: uiCompositionPlan.bindings[].from.nestedPath[].kind\n Category: connections\n Kind: string\n Description: Tipo do segmento nested de origem, como tab, nav, link, expansion, panel ou widget. O ultimo segmento deve ser widget.\n - Path: uiCompositionPlan.bindings[].from.nestedPath[].id\n Category: connections\n Kind: string\n Description: Identificador estrutural estavel do container de origem no segmento nested, quando existir.\n - Path: uiCompositionPlan.bindings[].from.nestedPath[].key\n Category: connections\n Kind: string\n Description: Chave estavel do widget filho no segmento terminal widget de origem. Obrigatoria para endpoint nested persistido.\n - Path: uiCompositionPlan.bindings[].from.nestedPath[].index\n Category: connections\n Kind: number\n Description: Indice auxiliar de origem para contexto visual/diagnostico; nao use como identidade primaria persistida.\n - Path: uiCompositionPlan.bindings[].from.nestedPath[].componentType\n Category: connections\n Kind: string\n Description: Tipo do componente real do widget filho de origem, usado como verificacao auxiliar, nao como identidade primaria.\n - Path: uiCompositionPlan.bindings[].to.nestedPath[].kind\n Category: connections\n Kind: string\n Description: Tipo do segmento nested de destino, como tab, nav, link, expansion, panel ou widget. O ultimo segmento deve ser widget.\n - Path: uiCompositionPlan.bindings[].to.nestedPath[].id\n Category: connections\n Kind: string\n Description: Identificador estrutural estavel do container de destino no segmento nested, quando existir.\n - Path: uiCompositionPlan.bindings[].to.nestedPath[].key\n Category: connections\n Kind: string\n Description: Chave estavel do widget filho no segmento terminal widget de destino. Obrigatoria para endpoint nested persistido.\n - Path: uiCompositionPlan.bindings[].to.nestedPath[].index\n Category: connections\n Kind: number\n Description: Indice auxiliar de destino para contexto visual/diagnostico; nao use como identidade primaria persistida.\n - Path: uiCompositionPlan.bindings[].to.nestedPath[].componentType\n Category: connections\n Kind: string\n Description: Tipo do componente real do widget filho de destino, usado como verificacao auxiliar, nao como identidade primaria.\n - Path: uiCompositionPlan.bindings[].intent\n Category: connections\n Kind: string\n Description: Intencao semantica do binding.\n - Path: uiCompositionPlan.bindings[].condition\n Category: connections\n Kind: expression\n Description: Guarda opcional em Json Logic.\n - Path: uiCompositionPlan.bindings[].transform\n Category: connections\n Kind: object\n Description: Transform declarativo: pick-path, query-context, template ou constant.\n - Path: uiCompositionPlan.bindings[].policy\n Category: connections\n Kind: object\n Description: Politica operacional opcional do binding.\n - Path: page\n Category: page\n Kind: object\n Description: Definicao da pagina (WidgetPageDefinition).\n - Path: context\n Category: context\n Kind: object\n Description: Contexto extra mesclado ao page.context.\n - Path: enableCustomization\n Category: behavior\n Kind: boolean\n Description: Habilita modo de edicao.\n - Path: showSettingsButton\n Category: behavior\n Kind: boolean\n Description: Exibe botao de settings.\n - Path: strictValidation\n Category: behavior\n Kind: boolean\n Description: Validacao estrita do widget loader.\n - Path: layoutOptions\n Category: layout\n Kind: object\n Description: Overrides residuais do host aceitos apenas para compatibilidade de migracao.\n - Path: layoutOptions.cols\n Category: layout\n Kind: number\n Description: Compat: numero de colunas usado para derivar canvas padrao.\n - Path: layoutOptions.rowHeight\n Category: layout\n Kind: number\n Description: Compat: altura de linha usada para derivar rowUnit do canvas.\n - Path: layoutOptions.gap\n Category: layout\n Kind: number\n Description: Compat: espacamento usado para derivar gap do canvas.\n - Path: pageIdentity\n Category: identity\n Kind: object\n Description: Identidade de persistencia da pagina.\n - Path: pageIdentity.appId\n Category: identity\n Kind: string\n Description: App id (opcional).\n - Path: pageIdentity.tenantId\n Category: identity\n Kind: string\n Description: Tenant id.\n - Path: pageIdentity.userId\n Category: identity\n Kind: string\n Description: User id.\n - Path: pageIdentity.routePath\n Category: identity\n Kind: string\n Description: Rota base da pagina.\n - Path: pageIdentity.locale\n Category: identity\n Kind: string\n Description: Locale.\n - Path: page.canvas\n Category: layout\n Kind: object\n Description: Canvas espacial canonico da pagina.\n - Path: page.canvas.mode\n Category: layout\n Kind: string\n Description: Modo do canvas. O builder usa grid canonico.\n - Path: page.canvas.columns\n Category: layout\n Kind: number\n Description: Numero de colunas do canvas.\n - Path: page.canvas.rowUnit\n Category: layout\n Kind: string\n Description: Altura base das linhas do canvas (ex: 80px).\n - Path: page.canvas.gap\n Category: layout\n Kind: string\n Description: Espacamento entre itens do canvas.\n - Path: page.canvas.autoRows\n Category: layout\n Kind: string\n Description: Politica de auto rows do canvas.\n - Path: page.canvas.items\n Category: layout\n Kind: object\n Description: Mapa canonico de posicionamento espacial por widget key.\n - Path: page.canvas.items.<widgetKey>.col\n Category: layout\n Kind: number\n Description: Coluna inicial (1-based).\n - Path: page.canvas.items.<widgetKey>.row\n Category: layout\n Kind: number\n Description: Linha inicial (1-based).\n - Path: page.canvas.items.<widgetKey>.colSpan\n Category: layout\n Kind: number\n Description: Colunas ocupadas.\n - Path: page.canvas.items.<widgetKey>.rowSpan\n Category: layout\n Kind: number\n Description: Linhas ocupadas.\n - Path: page.state\n Category: state\n Kind: object\n Description: Estado declarativo opcional da pagina.\n - Path: page.state.values\n Category: state\n Kind: object\n Description: Valores primarios persistiveis do estado da pagina.\n - Path: page.state.schema\n Category: state\n Kind: object\n Description: Descritores dos paths de estado primario.\n - Path: page.state.derived\n Category: state\n Kind: object\n Description: Descritores de estado derivado recomputado pelo runtime.\n - Path: page.widgets\n Category: widgets\n Kind: array\n Description: Widgets da pagina.\n - Path: page.widgets[].key\n Category: widgets\n Kind: string\n Description: ID unico do widget.\n - Path: page.widgets[].className\n Category: widgets\n Kind: string\n Description: Classe CSS do widget.\n - Path: page.widgets[].definition\n Category: widgets\n Kind: object\n Description: Definicao do widget (WidgetDefinition).\n - Path: page.widgets[].definition.id\n Category: widgets\n Kind: string\n Description: ID do componente registrado.\n - Path: page.widgets[].definition.inputs\n Category: widgets\n Kind: object\n Description: Inputs do componente.\n - Path: page.widgets[].definition.inputs.document\n Category: widgets\n Kind: object\n Description: RichContentDocument quando definition.id for praxis-rich-content.\n - Path: page.widgets[].definition.bindingOrder\n Category: widgets\n Kind: array\n Description: Ordem de aplicacao dos inputs.\n - Path: ComponentDocMeta.configEditor\n Category: widgets\n Kind: object\n Description: Editor canonico de inputs publicado pela lib dona do componente e aberto pelo settings-panel do host.\n - Path: ComponentDocMeta.configEditor.component\n Category: widgets\n Kind: object\n Description: Componente standalone que implementa SettingsValueProvider para editar definition.inputs.\n - Path: ComponentDocMeta.configEditor.title\n Category: widgets\n Kind: string\n Description: Titulo opcional usado pelo host ao abrir o editor de inputs do componente.\n - Path: ComponentDocMeta.authoringManifestRef\n Category: widgets\n Kind: object\n Description: Referencia canonica para o manifesto executavel de authoring por IA publicado pela lib dona do componente.\n - Path: ComponentDocMeta.authoringManifestRef.componentId\n Category: widgets\n Kind: string\n Description: ID do componente no registry/backend de manifestos de authoring.\n - Path: ComponentDocMeta.authoringManifestRef.source\n Category: widgets\n Kind: string\n Description: Simbolo, modulo ou registry id estavel do manifesto usado para delegar edicoes governadas.\n - Path: page.composition\n Category: connections\n Kind: object\n Description: Envelope canonico da composicao persistida.\n - Path: page.composition.version\n Category: connections\n Kind: string\n Description: Versao do envelope de composicao.\n - Path: page.composition.links\n Category: connections\n Kind: array\n Description: Links canonicos entre widgets, estado e actions globais.\n - Path: page.composition.links[].id\n Category: connections\n Kind: string\n Description: Identificador estavel do link.\n - Path: page.composition.links[].from\n Category: connections\n Kind: object\n Description: Endpoint de origem do link.\n - Path: page.composition.links[].to\n Category: connections\n Kind: object\n Description: Endpoint de destino do link.\n - Path: page.composition.links[].to.kind\n Category: connections\n Kind: string\n Description: Tipo do endpoint de destino, incluindo global-action para command-dispatch declarativo.\n - Path: page.composition.links[].to.ref.[actionId]\n Category: connections\n Kind: string\n Description: ID da action global quando page.composition.links[].to.kind = global-action.\n - Path: page.composition.links[].to.ref.payload\n Category: connections\n Kind: object\n Description: Payload estruturado opcional da action global persistida; quando omitido, o valor transformado do link segue como delivery value.\n - Path: page.composition.links[].to.ref.payloadExpr\n Category: connections\n Kind: expression\n Description: Escape avancado explicito de payload da action global persistida.\n - Path: page.composition.links[].to.ref.meta\n Category: connections\n Kind: object\n Description: Metadados opcionais do GlobalActionRef persistido, sem criar executor paralelo.\n - Path: page.composition.links[].from.ref.nestedPath\n Category: connections\n Kind: array\n Description: NestedPath canonico em endpoint component-port de origem persistido. Omita para top-level; nao serialize nestedPath: [].\n - Path: page.composition.links[].from.ref.nestedPath[].key\n Category: connections\n Kind: string\n Description: Chave estavel do widget filho no segmento terminal widget de origem. Obrigatoria para endpoint nested persistido.\n - Path: page.composition.links[].to.ref.nestedPath\n Category: connections\n Kind: array\n Description: NestedPath canonico em endpoint component-port de destino persistido. Omita para top-level; nao serialize nestedPath: [].\n - Path: page.composition.links[].to.ref.nestedPath[].key\n Category: connections\n Kind: string\n Description: Chave estavel do widget filho no segmento terminal widget de destino. Obrigatoria para endpoint nested persistido.\n - Path: page.composition.links[].intent\n Category: connections\n Kind: string\n Description: Intencao semantica do link.\n - Path: page.composition.links[].transform\n Category: connections\n Kind: object\n Description: Pipeline de transformacao do link.\n - Path: page.composition.links[].condition\n Category: connections\n Kind: expression\n Description: Guarda semantica opcional do link, expressa como um unico AST Json Logic canonico.\n - Path: page.composition.links[].policy\n Category: connections\n Kind: object\n Description: Politicas operacionais opcionais do link, separadas da condition semantica.\n - Path: page.composition.links[].metadata\n Category: connections\n Kind: object\n Description: Metadados opcionais do link.\n - Path: page.context\n Category: context\n Kind: object\n Description: Contexto da pagina (compartilhado por widgets).\nCapability Notes:\n - page segue o modelo canonico WidgetPageDefinition (widgets, composition.links, context e state opcional); composition.links tambem pode despachar actions globais via to.kind = global-action.\n - Conteudo editorial rico deve ser modelado como widget praxis-rich-content com definition.inputs.document: RichContentDocument, nao como DSL local do page-builder.\n - Quando definition.id = praxis-rich-content em uma pagina dinamica, definition.inputs.document continua sendo o contrato persistido; hostCapabilities e mediado em runtime pelo host praxis-dynamic-page e nao deve ser serializado no JSON da pagina.\n - Edicao visual de inputs de widget deve usar ComponentDocMeta.configEditor ou ComponentDocMeta.authoringManifestRef publicado pela lib dona do componente; nao criar editor local no page-builder para semantica de outro pacote.\n - Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.\n - Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.\n - Para criacao agentic de paginas, o preview pode trazer uiCompositionPlan como plano intermediario validavel; o page-builder compila esse plano para WidgetPageDefinition antes de aplicar.\n - UiCompositionPlan usa widgets[].componentId e bindings declarativos. O JSON persistido continua sendo page.widgets[].definition.id e page.composition.links.\n - Nested component ports usam endpoint component-port com nestedPath. O owner em ref.widget ou bindings[].*.widget continua sendo o widget top-level; a porta real do filho fica em port/direction e o caminho ate o filho fica em nestedPath.\n - Nao gere links nested via owner.widgetEvent, bindingPath profundo, page.connections ou wrappers host-specific. widgetEvent e bridge legada/avancada, nao contrato principal de authoring.\n - Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.\n - pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page.\n",
|
|
3070
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-page-builder/src/lib/ai/page-builder-ai-capabilities.ts",
|
|
3071
|
+
"contentHash": "4b4fa6a061fc733eaa82674d8a7990539be7809df4d09dddf93834493f222ff3",
|
|
3072
|
+
"sourceKind": "component_definition",
|
|
3073
|
+
"sourceId": "praxis-page-builder",
|
|
3074
|
+
"corpusVersion": "1.0.0"
|
|
3075
|
+
},
|
|
3076
|
+
{
|
|
3077
|
+
"chunkIndex": 2,
|
|
3078
|
+
"chunkKind": "authoring_manifest",
|
|
3079
|
+
"content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-page-builder\",\n \"ownerPackage\": \"@praxisui/page-builder\",\n \"configSchemaId\": \"WidgetPageDefinition\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"page\",\n \"type\": \"WidgetPageDefinition\",\n \"description\": \"Canonical renderable page document consumed by praxis-dynamic-page.\"\n },\n {\n \"name\": \"pageIdentity\",\n \"type\": \"PageIdentity | null\",\n \"description\": \"Persistence identity for ui_user_config save/apply flows; not persisted inside page.\"\n },\n {\n \"name\": \"enableCustomization\",\n \"type\": \"boolean\",\n \"description\": \"Enables page-builder authoring chrome around the runtime page.\"\n },\n {\n \"name\": \"context\",\n \"type\": \"Record<string, unknown>\",\n \"description\": \"Opaque host context passed to catalog resolution and agentic authoring.\"\n },\n {\n \"name\": \"pageChange\",\n \"type\": \"WidgetPageDefinition\",\n \"description\": \"Emitted after local apply/preview produces a renderable page.\"\n },\n {\n \"name\": \"agenticAuthoringEnableStreaming\",\n \"type\": \"boolean\",\n \"description\": \"Opt-in flag for the canonical streaming turn endpoints.\"\n },\n {\n \"name\": \"agenticAuthoringIncludeLlmDiagnostics\",\n \"type\": \"boolean\",\n \"description\": \"Opt-in flag that exposes governed diagnostics as cockpit evidence for validation and debugging.\"\n },\n {\n \"name\": \"agenticAuthoringContextHints\",\n \"type\": \"Record<string, unknown>\",\n \"description\": \"Host-provided semantic hints, including governed domain-catalog references and optional RAG-authored openingMessage used to ground AI-authored decisions.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"page\",\n \"resolver\": \"widget-page-definition-root\",\n \"description\": \"Root WidgetPageDefinition document: title, metadata, context and renderable page envelope.\"\n },\n {\n \"kind\": \"canvas\",\n \"resolver\": \"widget-page-canvas\",\n \"description\": \"Canvas geometry and item placement for top-level widgets.\"\n },\n {\n \"kind\": \"widget\",\n \"resolver\": \"widget-by-stable-key\",\n \"description\": \"Widget definitions addressed by stable widgetKey, never by array index.\"\n },\n {\n \"kind\": \"widgetShell\",\n \"resolver\": \"widget-shell-by-widget-key\",\n \"description\": \"Dashboard-card shell metadata such as title, action chrome and visual preset.\"\n },\n {\n \"kind\": \"compositionLink\",\n \"resolver\": \"composition-link-by-id\",\n \"description\": \"Declarative wiring in page.composition.links, including component-port nestedPath endpoints.\"\n },\n {\n \"kind\": \"state\",\n \"resolver\": \"page-state-path\",\n \"description\": \"Page-level state entries referenced by composition links.\"\n },\n {\n \"kind\": \"pageIdentity\",\n \"resolver\": \"page-builder-persistence-identity\",\n \"description\": \"ui_user_config identity, scope and ETag used by applyPage/save.\"\n },\n {\n \"kind\": \"agenticPreview\",\n \"resolver\": \"agentic-preview-result\",\n \"description\": \"Compiled backend preview envelope whose patch.page is applied locally.\"\n },\n {\n \"kind\": \"childOperation\",\n \"resolver\": \"widget-child-authoring-manifest-operation\",\n \"description\": \"Delegated operation owned by the child widget component manifest or configEditor.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"page.configure\",\n \"title\": \"Configure page metadata\",\n \"scope\": \"global\",\n \"targetKind\": \"page\",\n \"target\": {\n \"kind\": \"page\",\n \"resolver\": \"widget-page-definition-root\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"layoutPreset\": {\n \"type\": \"string\"\n },\n \"context\": {\n \"type\": \"object\"\n },\n \"metadata\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-page-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition\",\n \"DynamicPageConfigEditorComponent\",\n \"SettingsPanelBridge\"\n ],\n \"writes\": [\n \"page.title\",\n \"page.layoutPreset\",\n \"page.context\",\n \"page.metadata\"\n ],\n \"identityKeys\": [\n \"pageIdentity.componentId\",\n \"pageIdentity.scope\"\n ],\n \"failureModes\": [\n \"page-not-loaded\",\n \"context-not-json\",\n \"settings-panel-bridge-missing\"\n ],\n \"description\": \"Updates root page metadata while preserving the renderable WidgetPageDefinition shape.\"\n }\n }\n ],\n \"validators\": [\n \"widget-page-definition-valid\",\n \"no-legacy-grid-page-definition\",\n \"page-context-json-valid\",\n \"settings-panel-round-trip-valid\"\n ],\n \"affectedPaths\": [\n \"title\",\n \"layoutPreset\",\n \"context\",\n \"metadata\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\"\n ]\n },\n {\n \"operationId\": \"canvas.configure\",\n \"title\": \"Configure page canvas\",\n \"scope\": \"layout\",\n \"targetKind\": \"canvas\",\n \"target\": {\n \"kind\": \"canvas\",\n \"resolver\": \"widget-page-canvas\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"columns\": {\n \"type\": \"number\"\n },\n \"rowUnit\": {\n \"type\": \"number\"\n },\n \"gap\": {\n \"type\": \"number\"\n },\n \"items\": {\n \"type\": \"array\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-canvas-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.canvas\",\n \"DynamicPageBuilderComponent\"\n ],\n \"writes\": [\n \"page.canvas.columns\",\n \"page.canvas.rowUnit\",\n \"page.canvas.gap\",\n \"page.canvas.items\"\n ],\n \"identityKeys\": [\n \"canvas\"\n ],\n \"failureModes\": [\n \"canvas-missing\",\n \"canvas-item-references-missing-widget\",\n \"invalid-grid-geometry\"\n ],\n \"description\": \"Configures the top-level canvas without introducing legacy GridPageDefinition semantics.\"\n }\n }\n ],\n \"validators\": [\n \"canvas-columns-integer\",\n \"canvas-row-unit-valid\",\n \"canvas-gap-valid\",\n \"canvas-items-reference-existing-widgets\"\n ],\n \"affectedPaths\": [\n \"canvas.columns\",\n \"canvas.rowUnit\",\n \"canvas.gap\",\n \"canvas.items\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\"\n ]\n },\n {\n \"operationId\": \"widget.add\",\n \"title\": \"Add widget to page\",\n \"scope\": \"layout\",\n \"targetKind\": \"widget\",\n \"target\": {\n \"kind\": \"widget\",\n \"resolver\": \"widget-by-stable-key\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"widgetKey\",\n \"componentId\"\n ],\n \"properties\": {\n \"widgetKey\": {\n \"type\": \"string\"\n },\n \"componentId\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"type\": \"string\"\n },\n \"inputs\": {\n \"type\": \"object\"\n },\n \"canvasItem\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-widget-add\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.widgets\",\n \"WidgetPageDefinition.canvas\",\n \"ComponentDocRegistry\",\n \"PAGE_BUILDER_WIDGET_AI_CATALOGS\"\n ],\n \"writes\": [\n \"page.widgets[]\",\n \"page.canvas.items[]\"\n ],\n \"identityKeys\": [\n \"widgetKey\"\n ],\n \"failureModes\": [\n \"widget-key-duplicate\",\n \"component-not-registered\",\n \"canvas-item-invalid\",\n \"child-input-contract-unknown\"\n ],\n \"description\": \"Adds a registered component as a widget and places it on the canvas using a stable widgetKey.\"\n }\n }\n ],\n \"validators\": [\n \"widget-key-unique\",\n \"component-registered\",\n \"canvas-item-valid\",\n \"child-inputs-delegated\",\n \"widget-key-not-array-index\"\n ],\n \"affectedPaths\": [\n \"widgets[]\",\n \"canvas.items[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"component-catalog-loaded\"\n ]\n },\n {\n \"operationId\": \"widget.remove\",\n \"title\": \"Remove widget from page\",\n \"scope\": \"layout\",\n \"targetKind\": \"widget\",\n \"target\": {\n \"kind\": \"widget\",\n \"resolver\": \"widget-by-stable-key\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"widgetKey\"\n ],\n \"properties\": {\n \"widgetKey\": {\n \"type\": \"string\"\n },\n \"confirmed\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-widget-remove\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.widgets\",\n \"WidgetPageDefinition.canvas.items\",\n \"WidgetPageDefinition.composition.links\"\n ],\n \"writes\": [\n \"page.widgets[]\",\n \"page.canvas.items[]\",\n \"page.composition.links[]\"\n ],\n \"identityKeys\": [\n \"widgetKey\"\n ],\n \"failureModes\": [\n \"widget-not-found\",\n \"destructive-removal-not-confirmed\",\n \"dangling-composition-link\"\n ],\n \"description\": \"Removes a widget and cleans canvas items and composition links that reference it.\"\n }\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"widget-exists\",\n \"destructive-removal-confirmed\",\n \"composition-links-cleaned\",\n \"canvas-items-reference-existing-widgets\"\n ],\n \"affectedPaths\": [\n \"widgets[]\",\n \"canvas.items[]\",\n \"composition.links[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"target-widget-exists\"\n ]\n },\n {\n \"operationId\": \"widget.moveResize\",\n \"title\": \"Move or resize widget\",\n \"scope\": \"layout\",\n \"targetKind\": \"widget\",\n \"target\": {\n \"kind\": \"widget\",\n \"resolver\": \"widget-by-stable-key\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"widgetKey\",\n \"canvasItem\"\n ],\n \"properties\": {\n \"widgetKey\": {\n \"type\": \"string\"\n },\n \"canvasItem\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-widget-move-resize\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.canvas.items\",\n \"WidgetPageDefinition.widgets\"\n ],\n \"writes\": [\n \"page.canvas.items[]\"\n ],\n \"identityKeys\": [\n \"widgetKey\"\n ],\n \"failureModes\": [\n \"widget-not-found\",\n \"canvas-item-invalid\",\n \"canvas-overlap-invalid\"\n ],\n \"description\": \"Updates canvas placement for an existing widget using widgetKey as the stable identity.\"\n }\n }\n ],\n \"validators\": [\n \"widget-exists\",\n \"canvas-item-valid\",\n \"canvas-item-targets-existing-widget\",\n \"canvas-overlap-policy-valid\"\n ],\n \"affectedPaths\": [\n \"canvas.items[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"target-widget-exists\"\n ]\n },\n {\n \"operationId\": \"widget.shell.configure\",\n \"title\": \"Configure widget shell\",\n \"scope\": \"templating\",\n \"targetKind\": \"widgetShell\",\n \"target\": {\n \"kind\": \"widgetShell\",\n \"resolver\": \"widget-shell-by-widget-key\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"widgetKey\"\n ],\n \"properties\": {\n \"widgetKey\": {\n \"type\": \"string\"\n },\n \"shell\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-widget-shell-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.widgets\",\n \"WidgetShellEditorComponent\",\n \"SettingsPanelBridge\"\n ],\n \"writes\": [\n \"page.widgets[].shell\"\n ],\n \"identityKeys\": [\n \"widgetKey\"\n ],\n \"failureModes\": [\n \"widget-not-found\",\n \"settings-panel-bridge-missing\",\n \"shell-config-invalid\"\n ],\n \"description\": \"Updates the page-builder-owned widget shell without editing child component inputs.\"\n }\n }\n ],\n \"validators\": [\n \"widget-exists\",\n \"widget-shell-shape-valid\",\n \"settings-panel-bridge-available\",\n \"child-inputs-not-mutated\"\n ],\n \"affectedPaths\": [\n \"widgets[].shell\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"target-widget-exists\"\n ]\n },\n {\n \"operationId\": \"composition.link.add\",\n \"title\": \"Add page composition link\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"compositionLink\",\n \"target\": {\n \"kind\": \"compositionLink\",\n \"resolver\": \"composition-link-by-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"id\",\n \"from\",\n \"to\",\n \"intent\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"from\": {\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"required\": [\n \"kind\",\n \"ref\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"component-port\"\n ]\n },\n \"ref\": {\n \"type\": \"object\",\n \"required\": [\n \"widget\",\n \"port\",\n \"direction\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"widget\": {\n \"type\": \"string\"\n },\n \"port\": {\n \"type\": \"string\"\n },\n \"direction\": {\n \"enum\": [\n \"input\",\n \"output\"\n ]\n },\n \"bindingPath\": {\n \"type\": \"string\"\n },\n \"nestedPath\": {\n \"type\": \"array\"\n }\n }\n }\n }\n },\n {\n \"type\": \"object\",\n \"required\": [\n \"kind\",\n \"ref\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"state\"\n ]\n },\n \"ref\": {\n \"type\": \"object\",\n \"required\": [\n \"path\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"path\": {\n \"type\": \"string\"\n },\n \"layer\": {\n \"enum\": [\n \"values\",\n \"derived\",\n \"transient\"\n ]\n }\n }\n }\n }\n }\n ]\n },\n \"to\": {\n \"oneOf\": [\n null,\n null,\n {\n \"type\": \"object\",\n \"required\": [\n \"kind\",\n \"ref\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"global-action\"\n ]\n },\n \"ref\": {\n \"type\": \"object\",\n \"required\": [\n \"actionId\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"actionId\": {\n \"type\": \"string\"\n },\n \"payload\": {\n \"type\": \"object\"\n },\n \"payloadExpr\": {\n \"type\": \"string\"\n },\n \"meta\": {\n \"type\": \"object\"\n }\n }\n }\n }\n }\n ]\n },\n \"intent\": {\n \"enum\": [\n \"event-propagation\",\n \"state-write\",\n \"state-read\",\n \"command-dispatch\",\n \"selection-sync\",\n \"data-projection\",\n \"status-propagation\"\n ]\n },\n \"condition\": {\n \"type\": \"object\"\n },\n \"transform\": {\n \"type\": \"object\"\n },\n \"policy\": {\n \"type\": \"object\"\n },\n \"metadata\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-composition-link-add\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.composition.links\",\n \"WidgetPageDefinition.widgets\",\n \"PAGE_BUILDER_AI_CAPABILITIES\"\n ],\n \"writes\": [\n \"page.composition.links[]\"\n ],\n \"identityKeys\": [\n \"id\"\n ],\n \"failureModes\": [\n \"link-id-duplicate\",\n \"endpoint-not-found\",\n \"nested-path-invalid\",\n \"json-logic-invalid\"\n ],\n \"description\": \"Adds canonical declarative wiring in page.composition.links, including component-port nestedPath endpoints.\"\n }\n }\n ],\n \"validators\": [\n \"composition-link-id-unique\",\n \"composition-endpoints-resolve\",\n \"nested-path-terminal-widget-key-required\",\n \"json-logic-condition-valid\",\n \"no-legacy-connections-write\"\n ],\n \"affectedPaths\": [\n \"composition.links[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"widgets-resolvable\"\n ]\n },\n {\n \"operationId\": \"composition.link.remove\",\n \"title\": \"Remove page composition link\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"compositionLink\",\n \"target\": {\n \"kind\": \"compositionLink\",\n \"resolver\": \"composition-link-by-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"id\"\n ],\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"confirmed\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-composition-link-remove\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.composition.links\"\n ],\n \"writes\": [\n \"page.composition.links[]\"\n ],\n \"identityKeys\": [\n \"id\"\n ],\n \"failureModes\": [\n \"composition-link-not-found\",\n \"destructive-removal-not-confirmed\"\n ],\n \"description\": \"Removes a canonical composition link by stable id.\"\n }\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"composition-link-exists\",\n \"destructive-removal-confirmed\",\n \"composition-links-still-valid\"\n ],\n \"affectedPaths\": [\n \"composition.links[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"target-link-exists\"\n ]\n },\n {\n \"operationId\": \"composition.plan.compile\",\n \"title\": \"Compile UI composition plan\",\n \"scope\": \"rules\",\n \"targetKind\": \"agenticPreview\",\n \"target\": {\n \"kind\": \"agenticPreview\",\n \"resolver\": \"agentic-preview-result\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"uiCompositionPlan\"\n ],\n \"properties\": {\n \"uiCompositionPlan\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-ui-composition-plan-compile\",\n \"handlerContract\": {\n \"reads\": [\n \"UiCompositionPlan\",\n \"compileUiCompositionPlan\",\n \"PAGE_BUILDER_WIDGET_AI_CATALOGS\",\n \"ComponentDocMeta.configEditor\"\n ],\n \"writes\": [\n \"compiledFormPatch.patch.page\"\n ],\n \"identityKeys\": [\n \"uiCompositionPlan.id\",\n \"widgetKey\",\n \"uiCompositionPlan.bindings[].id\"\n ],\n \"failureModes\": [\n \"ui-composition-plan-invalid\",\n \"widget-catalog-missing\",\n \"compiled-page-invalid\",\n \"child-config-editor-missing\"\n ],\n \"description\": \"Compiles the agentic intermediate UiCompositionPlan into a renderable WidgetPageDefinition patch.page.\"\n }\n }\n ],\n \"validators\": [\n \"ui-composition-plan-valid\",\n \"compiled-page-valid\",\n \"widget-keys-unique\",\n \"composition-endpoints-resolve\",\n \"canvas-items-reference-existing-widgets\"\n ],\n \"affectedPaths\": [\n \"uiCompositionPlan\",\n \"compiledFormPatch.patch.page\"\n ],\n \"submissionImpact\": \"none\",\n \"preconditions\": [\n \"agentic-preview-loaded\",\n \"component-catalog-loaded\"\n ]\n },\n {\n \"operationId\": \"state.set\",\n \"title\": \"Set page state value\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"state\",\n \"target\": {\n \"kind\": \"state\",\n \"resolver\": \"page-state-path\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"path\",\n \"value\"\n ],\n \"properties\": {\n \"path\": {\n \"type\": \"string\"\n },\n \"value\": {},\n \"layer\": {\n \"enum\": [\n \"page\",\n \"session\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-state-set\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.state\",\n \"WidgetPageDefinition.composition.links\"\n ],\n \"writes\": [\n \"page.state\"\n ],\n \"identityKeys\": [\n \"path\"\n ],\n \"failureModes\": [\n \"state-path-invalid\",\n \"state-json-invalid\",\n \"composition-state-link-invalid\"\n ],\n \"description\": \"Sets canonical page state used by composition links without creating host-only binding paths.\"\n }\n }\n ],\n \"validators\": [\n \"state-path-valid\",\n \"state-layer-valid\",\n \"state-json-valid\",\n \"composition-state-links-still-valid\"\n ],\n \"affectedPaths\": [\n \"state\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\"\n ]\n },\n {\n \"operationId\": \"page.preview.apply\",\n \"title\": \"Apply agentic preview locally\",\n \"scope\": \"interaction\",\n \"targetKind\": \"agenticPreview\",\n \"target\": {\n \"kind\": \"agenticPreview\",\n \"resolver\": \"agentic-preview-result\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"previewId\"\n ],\n \"properties\": {\n \"previewId\": {\n \"type\": \"string\"\n },\n \"compiledFormPatch\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-preview-apply\",\n \"handlerContract\": {\n \"reads\": [\n \"PageBuilderAiAdapter.applyCompiledFormPatch\",\n \"compiledFormPatch.patch.page\",\n \"PraxisAssistantTurnViewState\"\n ],\n \"writes\": [\n \"DynamicPageBuilderComponent.page\",\n \"pageChange\"\n ],\n \"identityKeys\": [\n \"previewId\"\n ],\n \"failureModes\": [\n \"preview-result-invalid\",\n \"patch-page-missing\",\n \"runtime-page-invalid\",\n \"patch-envelope-persistence-attempted\"\n ],\n \"description\": \"Applies only compiledFormPatch.patch.page to the local runtime page; the backend envelope remains diagnostic data.\"\n }\n }\n ],\n \"validators\": [\n \"preview-result-valid\",\n \"compiled-page-patch-present\",\n \"no-envelope-runtime-persistence\",\n \"runtime-page-valid\"\n ],\n \"affectedPaths\": [\n \"compiledFormPatch.patch.page\",\n \"page\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"agentic-preview-loaded\"\n ]\n },\n {\n \"operationId\": \"page.persist.save\",\n \"title\": \"Persist page through config API\",\n \"scope\": \"interaction\",\n \"targetKind\": \"pageIdentity\",\n \"target\": {\n \"kind\": \"pageIdentity\",\n \"resolver\": \"page-builder-persistence-identity\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"pageIdentity\"\n ],\n \"properties\": {\n \"pageIdentity\": {\n \"type\": \"object\"\n },\n \"page\": {\n \"type\": \"object\"\n },\n \"etag\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-page-persist-save\",\n \"handlerContract\": {\n \"reads\": [\n \"pageIdentity\",\n \"WidgetPageDefinition\",\n \"PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS\",\n \"ui_user_config ETag\"\n ],\n \"writes\": [\n \"POST/PUT /api/praxis/config/ui-user-config\",\n \"If-Match\"\n ],\n \"identityKeys\": [\n \"pageIdentity.componentType\",\n \"pageIdentity.componentId\",\n \"pageIdentity.scope\"\n ],\n \"failureModes\": [\n \"page-identity-incomplete\",\n \"etag-conflict\",\n \"runtime-page-invalid\",\n \"patch-envelope-persistence-attempted\"\n ],\n \"description\": \"Persists the renderable WidgetPageDefinition with pageIdentity and ETag delegated to praxis-config-starter.\"\n }\n }\n ],\n \"validators\": [\n \"page-identity-complete\",\n \"etag-policy-valid\",\n \"runtime-page-valid\",\n \"no-envelope-runtime-persistence\"\n ],\n \"affectedPaths\": [\n \"page\",\n \"pageIdentity\",\n \"etag\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"page-identity-known\"\n ]\n },\n {\n \"operationId\": \"childOperation.delegate\",\n \"title\": \"Delegate widget child operation\",\n \"scope\": \"global\",\n \"targetKind\": \"childOperation\",\n \"target\": {\n \"kind\": \"childOperation\",\n \"resolver\": \"widget-child-authoring-manifest-operation\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"widgetKey\",\n \"childComponentId\",\n \"childOperationId\",\n \"reason\"\n ],\n \"properties\": {\n \"widgetKey\": {\n \"type\": \"string\"\n },\n \"childComponentId\": {\n \"type\": \"string\"\n },\n \"childOperationId\": {\n \"type\": \"string\"\n },\n \"reason\": {\n \"type\": \"string\"\n },\n \"childTarget\": {\n \"type\": \"object\"\n },\n \"childParams\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"page-builder-child-operation-delegate\",\n \"handlerContract\": {\n \"reads\": [\n \"WidgetPageDefinition.widgets\",\n \"ComponentDocMeta.configEditor\",\n \"child ComponentAuthoringManifest\",\n \"PAGE_BUILDER_WIDGET_AI_CATALOGS\"\n ],\n \"writes\": [\n \"page.widgets[].definition.inputs\"\n ],\n \"identityKeys\": [\n \"widgetKey\",\n \"childComponentId\",\n \"childOperationId\"\n ],\n \"failureModes\": [\n \"widget-not-found\",\n \"child-manifest-missing\",\n \"child-operation-unknown\",\n \"local-child-input-write-attempted\"\n ],\n \"description\": \"Delegates child widget input edits to the owning manifest or configEditor instead of redefining child semantics in page-builder.\"\n }\n }\n ],\n \"validators\": [\n \"widget-exists\",\n \"child-manifest-available\",\n \"child-operation-known\",\n \"component-config-editor-respected\",\n \"no-local-child-input-write\"\n ],\n \"affectedPaths\": [\n \"widgets[].definition.inputs\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"page-loaded\",\n \"target-widget-exists\",\n \"child-authoring-contract-available\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"widget-page-definition-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_PAGE_VALID\",\n \"description\": \"The document must remain a renderable WidgetPageDefinition.\"\n },\n {\n \"validatorId\": \"no-legacy-grid-page-definition\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_NO_GRID_PAGE\",\n \"description\": \"Legacy GridPageDefinition semantics cannot be reintroduced.\"\n },\n {\n \"validatorId\": \"page-context-json-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CONTEXT_JSON\",\n \"description\": \"Page context must stay JSON-serializable.\"\n },\n {\n \"validatorId\": \"settings-panel-round-trip-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_SETTINGS_ROUND_TRIP\",\n \"description\": \"Settings panel apply/save/reset/reopen must preserve the same page shape.\"\n },\n {\n \"validatorId\": \"canvas-columns-integer\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_COLUMNS\",\n \"description\": \"Canvas columns must be an integer grid count.\"\n },\n {\n \"validatorId\": \"canvas-row-unit-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_ROW_UNIT\",\n \"description\": \"Canvas row unit must be a positive layout unit.\"\n },\n {\n \"validatorId\": \"canvas-gap-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_GAP\",\n \"description\": \"Canvas gap must be a valid non-negative spacing value.\"\n },\n {\n \"validatorId\": \"canvas-items-reference-existing-widgets\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_WIDGET_REFS\",\n \"description\": \"Every canvas item must reference an existing widgetKey.\"\n },\n {\n \"validatorId\": \"widget-key-unique\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_WIDGET_KEY_UNIQUE\",\n \"description\": \"Widget keys must be unique.\"\n },\n {\n \"validatorId\": \"component-registered\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_COMPONENT_REGISTERED\",\n \"description\": \"Widget component id must exist in the component registry/catalog.\"\n },\n {\n \"validatorId\": \"canvas-item-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_ITEM\",\n \"description\": \"Canvas item geometry must be valid.\"\n },\n {\n \"validatorId\": \"child-inputs-delegated\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CHILD_INPUTS_DELEGATED\",\n \"description\": \"Child component input edits must delegate to the child owner.\"\n },\n {\n \"validatorId\": \"widget-key-not-array-index\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_WIDGET_KEY_INDEX\",\n \"description\": \"Array index is not a stable widget identity.\"\n },\n {\n \"validatorId\": \"widget-exists\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_WIDGET_EXISTS\",\n \"description\": \"Target widget must exist.\"\n },\n {\n \"validatorId\": \"destructive-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_DESTRUCTIVE_CONFIRMED\",\n \"description\": \"Destructive removals require explicit confirmation.\"\n },\n {\n \"validatorId\": \"composition-links-cleaned\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_LINKS_CLEANED\",\n \"description\": \"Removing a widget must remove dangling composition links.\"\n },\n {\n \"validatorId\": \"canvas-item-targets-existing-widget\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CANVAS_ITEM_TARGET\",\n \"description\": \"Moved canvas item must target an existing widget.\"\n },\n {\n \"validatorId\": \"canvas-overlap-policy-valid\",\n \"level\": \"warning\",\n \"code\": \"PAGE_BUILDER_CANVAS_OVERLAP\",\n \"description\": \"Canvas overlap policy must be respected.\"\n },\n {\n \"validatorId\": \"widget-shell-shape-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_SHELL_SHAPE\",\n \"description\": \"Widget shell config must match the shell editor contract.\"\n },\n {\n \"validatorId\": \"settings-panel-bridge-available\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_SETTINGS_BRIDGE\",\n \"description\": \"Settings panel bridge must be available for shell/page editors.\"\n },\n {\n \"validatorId\": \"child-inputs-not-mutated\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CHILD_INPUTS_NOT_MUTATED\",\n \"description\": \"Shell edits cannot mutate child inputs.\"\n },\n {\n \"validatorId\": \"composition-link-id-unique\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_LINK_ID_UNIQUE\",\n \"description\": \"Composition link ids must be unique.\"\n },\n {\n \"validatorId\": \"composition-endpoints-resolve\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_LINK_ENDPOINTS\",\n \"description\": \"Composition endpoints must resolve to known widgets, ports and nested paths.\"\n },\n {\n \"validatorId\": \"nested-path-terminal-widget-key-required\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_NESTED_PATH_WIDGET_KEY\",\n \"description\": \"Nested component-port paths must terminate at a stable widget key.\"\n },\n {\n \"validatorId\": \"json-logic-condition-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_JSON_LOGIC\",\n \"description\": \"Composition link condition must be valid Json Logic.\"\n },\n {\n \"validatorId\": \"no-legacy-connections-write\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_NO_LEGACY_CONNECTIONS\",\n \"description\": \"Operations must write page.composition.links, not legacy connections.\"\n },\n {\n \"validatorId\": \"composition-link-exists\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_LINK_EXISTS\",\n \"description\": \"Target composition link must exist.\"\n },\n {\n \"validatorId\": \"composition-links-still-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_LINKS_STILL_VALID\",\n \"description\": \"Remaining composition links must still validate after the operation.\"\n },\n {\n \"validatorId\": \"ui-composition-plan-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_UI_PLAN_VALID\",\n \"description\": \"UiCompositionPlan must match the intermediate agentic plan contract.\"\n },\n {\n \"validatorId\": \"compiled-page-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_COMPILED_PAGE_VALID\",\n \"description\": \"Compiled output must be a valid WidgetPageDefinition.\"\n },\n {\n \"validatorId\": \"widget-keys-unique\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_WIDGET_KEYS_UNIQUE\",\n \"description\": \"Compiled plan must produce unique widget keys.\"\n },\n {\n \"validatorId\": \"state-path-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_STATE_PATH\",\n \"description\": \"State paths must be valid page state paths.\"\n },\n {\n \"validatorId\": \"state-layer-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_STATE_LAYER\",\n \"description\": \"State layer must be page or session.\"\n },\n {\n \"validatorId\": \"state-json-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_STATE_JSON\",\n \"description\": \"State values must be JSON-serializable.\"\n },\n {\n \"validatorId\": \"composition-state-links-still-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_STATE_LINKS\",\n \"description\": \"State edits must not break composition links.\"\n },\n {\n \"validatorId\": \"preview-result-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_PREVIEW_VALID\",\n \"description\": \"Agentic preview result must be structurally valid.\"\n },\n {\n \"validatorId\": \"compiled-page-patch-present\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_PATCH_PAGE_PRESENT\",\n \"description\": \"Preview envelope must include compiledFormPatch.patch.page.\"\n },\n {\n \"validatorId\": \"no-envelope-runtime-persistence\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_NO_ENVELOPE_PERSISTENCE\",\n \"description\": \"Runtime persistence cannot save the full preview envelope.\"\n },\n {\n \"validatorId\": \"runtime-page-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_RUNTIME_PAGE_VALID\",\n \"description\": \"Runtime page must remain renderable by praxis-dynamic-page.\"\n },\n {\n \"validatorId\": \"page-identity-complete\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_PAGE_IDENTITY\",\n \"description\": \"Save requires component type, component id and scope identity.\"\n },\n {\n \"validatorId\": \"etag-policy-valid\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_ETAG_POLICY\",\n \"description\": \"Save must respect backend ETag/If-Match policy.\"\n },\n {\n \"validatorId\": \"child-manifest-available\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CHILD_MANIFEST_AVAILABLE\",\n \"description\": \"Delegated child component must expose an authoring manifest or configEditor.\"\n },\n {\n \"validatorId\": \"child-operation-known\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CHILD_OPERATION_KNOWN\",\n \"description\": \"Delegated child operation id must be known.\"\n },\n {\n \"validatorId\": \"component-config-editor-respected\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_CONFIG_EDITOR_RESPECTED\",\n \"description\": \"ComponentDocMeta.configEditor must remain the source for child input editing.\"\n },\n {\n \"validatorId\": \"no-local-child-input-write\",\n \"level\": \"error\",\n \"code\": \"PAGE_BUILDER_NO_LOCAL_CHILD_INPUT_WRITE\",\n \"description\": \"Page-builder must not define child component input semantics locally.\"\n }\n ],\n \"roundTripRequirements\": [\n \"WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.\",\n \"UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.\",\n \"Widget keys and composition link ids are stable identities; array indexes are never canonical identities.\",\n \"Persisted wiring uses page.composition.links and must not write legacy connections.\",\n \"Nested component ports use component-port refs with nestedPath ending in a stable widget key.\",\n \"Child widget definition.inputs edits delegate to the child manifest or ComponentDocMeta.configEditor.\",\n \"Agentic preview applies only compiledFormPatch.patch.page to runtime; the full patch envelope is diagnostics/audit data.\",\n \"Save uses pageIdentity and ETag policy from praxis-config-starter; pageIdentity is not persisted inside WidgetPageDefinition.\",\n \"Settings panel apply/save/reset/reopen must preserve page settings and widget shell config without hidden normalization drift.\"\n ],\n \"examples\": [\n {\n \"id\": \"configure-dashboard-page\",\n \"request\": \"Set this page title to Payroll Overview and store payrollPeriod in the page context.\",\n \"operationId\": \"page.configure\",\n \"params\": {\n \"title\": \"Payroll Overview\",\n \"context\": {\n \"payrollPeriod\": \"current\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-canvas-grid\",\n \"request\": \"Use a 12 column dashboard grid with compact gaps.\",\n \"operationId\": \"canvas.configure\",\n \"target\": \"canvas\",\n \"params\": {\n \"columns\": 12,\n \"rowUnit\": 8,\n \"gap\": 8\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-employees-table-widget\",\n \"request\": \"Add an employees table widget to the left half of the first row.\",\n \"operationId\": \"widget.add\",\n \"target\": \"employees-table\",\n \"params\": {\n \"widgetKey\": \"employees-table\",\n \"componentId\": \"praxis-table\",\n \"canvasItem\": {\n \"x\": 0,\n \"y\": 0,\n \"w\": 6,\n \"h\": 8\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-summary-card\",\n \"request\": \"Remove the summary-card widget and its links.\",\n \"operationId\": \"widget.remove\",\n \"target\": \"summary-card\",\n \"params\": {\n \"widgetKey\": \"summary-card\",\n \"confirmed\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"move-payroll-chart\",\n \"request\": \"Move payroll-chart to the right column and make it taller.\",\n \"operationId\": \"widget.moveResize\",\n \"target\": \"payroll-chart\",\n \"params\": {\n \"widgetKey\": \"payroll-chart\",\n \"canvasItem\": {\n \"x\": 6,\n \"y\": 0,\n \"w\": 6,\n \"h\": 10\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-widget-shell\",\n \"request\": \"Rename the employees widget card and enable the refresh shell action.\",\n \"operationId\": \"widget.shell.configure\",\n \"target\": \"employees-table\",\n \"params\": {\n \"widgetKey\": \"employees-table\",\n \"shell\": {\n \"title\": \"Employees\",\n \"actions\": [\n {\n \"id\": \"refresh\"\n }\n ]\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"link-department-selection-to-table\",\n \"request\": \"When department-list selection changes, filter employees-table by department id.\",\n \"operationId\": \"composition.link.add\",\n \"target\": \"department-selection-to-employees\",\n \"params\": {\n \"id\": \"department-selection-to-employees\",\n \"from\": {\n \"widget\": \"department-list\",\n \"port\": \"selection\"\n },\n \"to\": {\n \"widget\": \"employees-table\",\n \"port\": \"filter\"\n },\n \"intent\": \"selection-sync\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-obsolete-link\",\n \"request\": \"Remove the old payroll-filter-link composition link.\",\n \"operationId\": \"composition.link.remove\",\n \"target\": \"payroll-filter-link\",\n \"params\": {\n \"id\": \"payroll-filter-link\",\n \"confirmed\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"compile-resource-dashboard-plan\",\n \"request\": \"Compile the resource-dashboard plan returned by the assistant into a renderable page preview.\",\n \"operationId\": \"composition.plan.compile\",\n \"target\": \"preview-payroll-dashboard\",\n \"params\": {\n \"uiCompositionPlan\": {\n \"layoutPreset\": \"resource-dashboard\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"set-selected-department-state\",\n \"request\": \"Store selectedDepartmentId in page state for downstream links.\",\n \"operationId\": \"state.set\",\n \"target\": \"state.selectedDepartmentId\",\n \"params\": {\n \"path\": \"selectedDepartmentId\",\n \"value\": \"sales\",\n \"layer\": \"page\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"apply-agentic-preview\",\n \"request\": \"Apply the current assistant preview to the local page.\",\n \"operationId\": \"page.preview.apply\",\n \"target\": \"preview-current\",\n \"params\": {\n \"previewId\": \"preview-current\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"persist-page\",\n \"request\": \"Save this page configuration using the current ETag.\",\n \"operationId\": \"page.persist.save\",\n \"target\": \"tenant-dashboard-page\",\n \"params\": {\n \"pageIdentity\": {\n \"componentType\": \"page-builder\",\n \"componentId\": \"tenant-dashboard\",\n \"scope\": \"tenant\"\n },\n \"etag\": \"\\\"v7\\\"\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"delegate-table-column-edit\",\n \"request\": \"Add a salary column to the employees table widget.\",\n \"operationId\": \"childOperation.delegate\",\n \"target\": \"employees-table\",\n \"params\": {\n \"widgetKey\": \"employees-table\",\n \"childComponentId\": \"praxis-table\",\n \"childOperationId\": \"column.add\",\n \"reason\": \"TableConfig is owned by praxis-table.\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-direct-dynamic-form-field-write\",\n \"request\": \"Directly write a new dynamic-form field into the widget inputs from page-builder.\",\n \"operationId\": \"childOperation.delegate\",\n \"target\": \"employee-form\",\n \"params\": {\n \"widgetKey\": \"employee-form\",\n \"childComponentId\": \"praxis-dynamic-form\",\n \"childOperationId\": \"field.add\",\n \"reason\": \"Dynamic form fields are delegated.\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-legacy-connections\",\n \"request\": \"Create the widget link under the old connections collection.\",\n \"operationId\": \"composition.link.add\",\n \"target\": \"legacy-connection\",\n \"params\": {\n \"id\": \"legacy-connection\",\n \"collection\": \"connections\"\n },\n \"isPositive\": false\n }\n ]\n}",
|
|
3080
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-page-builder/src/lib/ai/praxis-page-builder-authoring-manifest.ts",
|
|
3081
|
+
"contentHash": "b6ad872e46a8dc9727446be9844040ad0d242cb77eb3931dd44b5c4fb8c049b3",
|
|
3082
|
+
"sourceKind": "component_definition",
|
|
3083
|
+
"sourceId": "praxis-page-builder",
|
|
3084
|
+
"corpusVersion": "1.0.0"
|
|
3085
|
+
},
|
|
3086
|
+
{
|
|
3087
|
+
"chunkIndex": 3,
|
|
3088
|
+
"chunkKind": "context_pack",
|
|
3089
|
+
"content": "{\n \"componentContext\": {\n \"version\": \"v1.3\",\n \"optionsByPath\": {\n \"page.canvas.columns\": {\n \"mode\": \"suggested\",\n \"options\": [\n {\n \"value\": 6,\n \"label\": \"6 colunas\"\n },\n {\n \"value\": 8,\n \"label\": \"8 colunas\"\n },\n {\n \"value\": 12,\n \"label\": \"12 colunas\"\n },\n {\n \"value\": 16,\n \"label\": \"16 colunas\"\n }\n ]\n },\n \"page.canvas.rowUnit\": {\n \"mode\": \"suggested\",\n \"options\": [\n {\n \"value\": \"64px\",\n \"label\": \"64px\"\n },\n {\n \"value\": \"80px\",\n \"label\": \"80px\"\n },\n {\n \"value\": \"100px\",\n \"label\": \"100px\"\n },\n {\n \"value\": \"120px\",\n \"label\": \"120px\"\n }\n ]\n },\n \"page.canvas.gap\": {\n \"mode\": \"suggested\",\n \"options\": [\n {\n \"value\": \"8px\",\n \"label\": \"8px\"\n },\n {\n \"value\": \"12px\",\n \"label\": \"12px\"\n },\n {\n \"value\": \"16px\",\n \"label\": \"16px\"\n },\n {\n \"value\": \"24px\",\n \"label\": \"24px\"\n }\n ]\n },\n \"page.widgets[].definition.id\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"praxis-crud\",\n \"label\": \"Praxis CRUD\"\n },\n {\n \"value\": \"praxis-table\",\n \"label\": \"Praxis Table\"\n },\n {\n \"value\": \"praxis-dynamic-form\",\n \"label\": \"Praxis Dynamic Form\"\n },\n {\n \"value\": \"praxis-list\",\n \"label\": \"Praxis List\"\n },\n {\n \"value\": \"praxis-tabs\",\n \"label\": \"Praxis Tabs\"\n },\n {\n \"value\": \"praxis-stepper\",\n \"label\": \"Praxis Stepper\"\n },\n {\n \"value\": \"praxis-expansion\",\n \"label\": \"Praxis Expansion\"\n },\n {\n \"value\": \"praxis-files-upload\",\n \"label\": \"Praxis Files Upload\"\n },\n {\n \"value\": \"praxis-rich-content\",\n \"label\": \"Praxis Rich Content\"\n },\n {\n \"value\": \"pdx-cron-builder\",\n \"label\": \"Praxis Cron Builder\"\n },\n {\n \"value\": \"praxis-settings-panel\",\n \"label\": \"Praxis Settings Panel\"\n },\n {\n \"value\": \"praxis-dashboard-stats\",\n \"label\": \"Praxis Dashboard Stats\"\n },\n {\n \"value\": \"praxis-chart\",\n \"label\": \"Praxis Chart\"\n }\n ]\n },\n \"uiCompositionPlan.widgets[].componentId\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"praxis-crud\",\n \"label\": \"Praxis CRUD\"\n },\n {\n \"value\": \"praxis-table\",\n \"label\": \"Praxis Table\"\n },\n {\n \"value\": \"praxis-dynamic-form\",\n \"label\": \"Praxis Dynamic Form\"\n },\n {\n \"value\": \"praxis-list\",\n \"label\": \"Praxis List\"\n },\n {\n \"value\": \"praxis-tabs\",\n \"label\": \"Praxis Tabs\"\n },\n {\n \"value\": \"praxis-stepper\",\n \"label\": \"Praxis Stepper\"\n },\n {\n \"value\": \"praxis-expansion\",\n \"label\": \"Praxis Expansion\"\n },\n {\n \"value\": \"praxis-files-upload\",\n \"label\": \"Praxis Files Upload\"\n },\n {\n \"value\": \"praxis-rich-content\",\n \"label\": \"Praxis Rich Content\"\n },\n {\n \"value\": \"pdx-cron-builder\",\n \"label\": \"Praxis Cron Builder\"\n },\n {\n \"value\": \"praxis-settings-panel\",\n \"label\": \"Praxis Settings Panel\"\n },\n {\n \"value\": \"praxis-dashboard-stats\",\n \"label\": \"Praxis Dashboard Stats\"\n },\n {\n \"value\": \"praxis-chart\",\n \"label\": \"Praxis Chart\"\n }\n ]\n }\n },\n \"actionCatalog\": [\n {\n \"id\": \"ui-composition-plan.create\",\n \"intentExamples\": [\n \"ui composition plan\",\n \"agentic page plan\",\n \"master detail\",\n \"dashboard composition\",\n \"nested component ports\",\n \"nestedPath\",\n \"planejar pagina\",\n \"composicao declarativa\"\n ],\n \"patchTemplate\": {\n \"uiCompositionPlan\": {\n \"version\": \"1.0\",\n \"kind\": \"praxis.ui-composition-plan\",\n \"layoutPreset\": \"{{params.layoutPreset}}\",\n \"state\": \"{{params.state}}\",\n \"widgets\": \"{{params.widgets}}\",\n \"bindings\": \"{{params.bindings}}\"\n }\n }\n },\n {\n \"id\": \"page.canvas.columns.set\",\n \"intentExamples\": [\n \"columns\",\n \"canvas columns\",\n \"grid columns\",\n \"colunas do canvas\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"canvas\": {\n \"columns\": \"{{value}}\"\n }\n }\n }\n },\n {\n \"id\": \"page.canvas.rowUnit.set\",\n \"intentExamples\": [\n \"row height\",\n \"row size\",\n \"canvas row\",\n \"altura da linha\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"canvas\": {\n \"rowUnit\": \"{{value}}\"\n }\n }\n }\n },\n {\n \"id\": \"page.canvas.gap.set\",\n \"intentExamples\": [\n \"gap\",\n \"spacing\",\n \"canvas gap\",\n \"espaçamento\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"canvas\": {\n \"gap\": \"{{value}}\"\n }\n }\n }\n },\n {\n \"id\": \"page.context.set\",\n \"intentExamples\": [\n \"page context\",\n \"context variable\",\n \"variavel de contexto\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"context\": {\n \"{{params.key}}\": \"{{value}}\"\n }\n }\n }\n },\n {\n \"id\": \"widget.add\",\n \"intentExamples\": [\n \"add widget\",\n \"new widget\",\n \"add component\",\n \"adicionar componente\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"definition\": {\n \"id\": \"{{params.componentId}}\"\n }\n }\n ],\n \"canvas\": {\n \"items\": {\n \"{{target}}\": {\n \"col\": 1,\n \"row\": 1,\n \"colSpan\": 4,\n \"rowSpan\": 2\n }\n }\n }\n }\n }\n },\n {\n \"id\": \"widget.remove\",\n \"intentExamples\": [\n \"remove widget\",\n \"delete widget\",\n \"remover componente\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"_delete\": true\n }\n ]\n }\n }\n },\n {\n \"id\": \"widget.component.set\",\n \"intentExamples\": [\n \"widget type\",\n \"component id\",\n \"widget component\",\n \"tipo do componente\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"definition\": {\n \"id\": \"{{value}}\"\n }\n }\n ]\n }\n }\n },\n {\n \"id\": \"widget.className.set\",\n \"intentExamples\": [\n \"widget class\",\n \"css class\",\n \"classe css\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"className\": \"{{value}}\"\n }\n ]\n }\n }\n },\n {\n \"id\": \"widget.canvasItem.set\",\n \"intentExamples\": [\n \"move widget\",\n \"resize widget\",\n \"widget canvas\",\n \"posicionar\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"canvas\": {\n \"items\": {\n \"{{target}}\": {\n \"col\": \"{{params.col}}\",\n \"row\": \"{{params.row}}\",\n \"colSpan\": \"{{params.colSpan}}\",\n \"rowSpan\": \"{{params.rowSpan}}\"\n }\n }\n }\n }\n }\n },\n {\n \"id\": \"widget.inputs.set\",\n \"intentExamples\": [\n \"widget inputs\",\n \"configure widget\",\n \"set inputs\",\n \"configurar componente\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"definition\": {\n \"inputs\": \"{{value}}\"\n }\n }\n ]\n }\n }\n },\n {\n \"id\": \"widget.bindingOrder.set\",\n \"intentExamples\": [\n \"binding order\",\n \"input order\",\n \"ordem de inputs\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"widgets\": [\n {\n \"key\": \"{{target}}\",\n \"definition\": {\n \"bindingOrder\": \"{{value}}\"\n }\n }\n ]\n }\n }\n },\n {\n \"id\": \"connection.add\",\n \"intentExamples\": [\n \"connect widgets\",\n \"link widgets\",\n \"wire output\",\n \"create connection\",\n \"nested component port\",\n \"nestedPath\",\n \"conectar\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"intent\": \"event-propagation\",\n \"transform\": \"{{value}}\",\n \"metadata\": {\n \"source\": \"persisted-composition-link\"\n }\n }\n ]\n }\n }\n }\n },\n {\n \"id\": \"connection.set_static\",\n \"intentExamples\": [\n \"set input value\",\n \"static connection\",\n \"valor fixo na conexao\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"intent\": \"event-propagation\",\n \"transform\": \"{{value}}\",\n \"metadata\": {\n \"source\": \"persisted-composition-link\"\n }\n }\n ]\n }\n }\n }\n },\n {\n \"id\": \"connection.map.set\",\n \"intentExamples\": [\n \"map connection\",\n \"update map\",\n \"mapear conexao\",\n \"atualizar map\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"intent\": \"event-propagation\",\n \"transform\": \"{{value}}\",\n \"metadata\": {\n \"source\": \"persisted-composition-link\"\n }\n }\n ]\n }\n }\n }\n },\n {\n \"id\": \"connection.condition.set\",\n \"intentExamples\": [\n \"connection condition\",\n \"link condition\",\n \"json logic guard\",\n \"condicao da conexao\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"intent\": \"event-propagation\",\n \"condition\": \"{{value}}\"\n }\n ]\n }\n }\n }\n },\n {\n \"id\": \"connection.policy.set\",\n \"intentExamples\": [\n \"connection policy\",\n \"debounce\",\n \"distinct\",\n \"missing value policy\",\n \"politica da conexao\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"intent\": \"event-propagation\",\n \"policy\": \"{{value}}\"\n }\n ]\n }\n }\n }\n },\n {\n \"id\": \"connection.remove\",\n \"intentExamples\": [\n \"remove connection\",\n \"unlink widgets\",\n \"desconectar\"\n ],\n \"patchTemplate\": {\n \"page\": {\n \"composition\": {\n \"version\": \"1.0.0\",\n \"links\": [\n {\n \"id\": \"{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.fromWidget}}\",\n \"port\": \"{{params.fromOutput}}\",\n \"direction\": \"output\"\n }\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"ref\": {\n \"widget\": \"{{params.toWidget}}\",\n \"port\": \"{{params.toInput}}\",\n \"direction\": \"input\"\n }\n },\n \"_delete\": true\n }\n ]\n }\n }\n }\n }\n ],\n \"fieldResolvers\": {\n \"page.widgets[]\": [\n \"key\",\n \"definition.id\"\n ],\n \"page.composition.links[]\": [\n \"id\"\n ]\n },\n \"hints\": [\n \"For agentic page creation, prefer returning uiCompositionPlan in the preview envelope and let the page-builder compiler emit WidgetPageDefinition.\",\n \"Use uiCompositionPlan.widgets[].componentId in plans; the compiler maps it to page.widgets[].definition.id.\",\n \"Use uiCompositionPlan.bindings as the declarative source for wiring; the compiler emits page.composition.links.\",\n \"For nested component ports, use component-port endpoints with nestedPath in uiCompositionPlan.bindings; keep widget as the top-level owner and put the real child port in port/direction.\",\n \"NestedPath must be relative to the owner widget and must end with a widget segment containing a stable key. Do not use index as the only identity.\",\n \"Do not author nested links through owner.widgetEvent, deep bindingPath, page.connections, or host-specific wrapper outputs; those are legacy or bridge mechanisms.\",\n \"Do not emit both uiCompositionPlan.bindings and hand-authored page.composition.links as competing sources of truth for the same preview.\",\n \"Use page.widgets[].key as the merge key; avoid array indexes.\",\n \"Canvas items use 1-based col/row with integer spans.\",\n \"Widget definition id must match a registered component selector.\",\n \"Use runtimeState.componentCatalog for available component ids, inputs, and outputs.\",\n \"Use page.composition.links as the canonical persisted wiring surface.\",\n \"Composition links should use stable ids and canonical component-port/state endpoints.\",\n \"For global-action targets, keep execution declarative: use to.kind = global-action with to.ref.actionId plus optional to.ref.payload, payloadExpr and meta only.\",\n \"For uiCompositionPlan transforms, use pick-path for event payload extraction, query-context for resource filters, template for structured document/input generation, and constant for fixed values.\",\n \"Write semantic guards to page.composition.links[].condition as Json Logic, not as legacy filter strings.\",\n \"Write operational behavior to page.composition.links[].policy, not mixed into condition or metadata.\",\n \"Transforms and metadata must be written under the link envelope, not as legacy connection fields.\",\n \"To remove a widget, use _delete: true with the widget key.\",\n \"To remove a link, use _delete: true with the same canonical from/to endpoints.\"\n ]\n }\n}",
|
|
3090
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-page-builder/src/lib/ai/page-builder-context-pack.ts",
|
|
3091
|
+
"contentHash": "3800c5f2da7db2e2f01bc2122ddc4c6dafedf371efe9c76a12eca55221c49715",
|
|
3092
|
+
"sourceKind": "component_definition",
|
|
3093
|
+
"sourceId": "praxis-page-builder",
|
|
3094
|
+
"corpusVersion": "1.0.0"
|
|
3095
|
+
},
|
|
3096
|
+
{
|
|
3097
|
+
"chunkIndex": 4,
|
|
3098
|
+
"chunkKind": "recipe",
|
|
3099
|
+
"content": "{\n \"_comment\": \"Receita de Dashboard (Grid Page) com Tabela Mestre e Formulário Detalhe conectados.\",\n \"_comment2\": \"resourcePath deve ser o path base do recurso (sem /filter).\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-page-builder\",\n \"variantId\": \"master-detail\",\n \"useWhen\": \"Page builder layout with master table and detail form.\",\n \"examplePrompts\": [\n \"create a master detail page with table and form\",\n \"set up a grid page with table + detail form\"\n ]\n },\n \"options\": {\n \"cols\": 12,\n \"rowHeight\": 80,\n \"gap\": 16,\n \"compactType\": \"vertical\"\n },\n \"widgets\": [\n {\n \"key\": \"userTable\",\n \"layout\": { \"col\": 1, \"row\": 1, \"colSpan\": 7, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-table\",\n \"bindingOrder\": [\"config\", \"resourcePath\"],\n \"inputs\": {\n \"resourcePath\": \"{{resourcePath}}\",\n \"tableId\": \"{{resourceKey}}-master\",\n \"config\": {\n \"columns\": [\n { \"field\": \"id\", \"header\": \"ID\", \"width\": \"60px\" },\n { \"field\": \"name\", \"header\": \"Nome\" },\n { \"field\": \"email\", \"header\": \"Email\" },\n { \"field\": \"status\", \"header\": \"Status\", \"renderer\": { \"type\": \"chip\" } }\n ],\n \"toolbar\": { \"visible\": true, \"title\": \"{{resourceLabel}}\" },\n \"behavior\": { \"selection\": { \"enabled\": true, \"type\": \"single\" } }\n }\n },\n \"outputs\": { \"rowClick\": \"emit\" }\n }\n },\n {\n \"key\": \"userDetailForm\",\n \"layout\": { \"col\": 8, \"row\": 1, \"colSpan\": 5, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-dynamic-form\",\n \"bindingOrder\": [\"resourcePath\", \"formId\", \"resourceId\"],\n \"inputs\": {\n \"formId\": \"{{resourceKey}}-detail-view\",\n \"resourcePath\": \"{{resourcePath}}\",\n \"mode\": \"view\",\n \"config\": {\n \"sections\": [\n {\n \"title\": \"Detalhes de {{resourceLabel}}\",\n \"rows\": [\n { \"columns\": [{ \"fields\": [\"name\", \"email\"] }] },\n { \"columns\": [{ \"fields\": [\"role\", \"status\"] }] }\n ]\n }\n ]\n }\n }\n }\n },\n {\n \"key\": \"statsCard\",\n \"layout\": { \"col\": 1, \"row\": 7, \"colSpan\": 4, \"rowSpan\": 2 },\n \"definition\": {\n \"id\": \"praxis-custom-card\", \n \"inputs\": {\n \"title\": \"Total Selecionado\",\n \"content\": \"Nenhum\"\n }\n }\n }\n ],\n \"connections\": [\n {\n \"_comment\": \"Ao clicar na linha da tabela, carrega o formulário com o ID correspondente\",\n \"from\": { \"widget\": \"userTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"userDetailForm\", \"input\": \"resourceId\" },\n \"map\": \"payload.row.{{idField}}\"\n },\n {\n \"_comment\": \"Ao clicar na linha, atualiza o título do card de estatísticas\",\n \"from\": { \"widget\": \"userTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"statsCard\", \"input\": \"inputs.content\" },\n \"map\": \"Selecionado: ${payload.row.name}\"\n }\n ]\n}\n",
|
|
3100
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-dynamic-grid-page.json",
|
|
3101
|
+
"contentHash": "c1211ac90d7f97608a3c40643f402f66cc235df4d0865e141929fc7e06c471eb",
|
|
3102
|
+
"sourceKind": "component_definition",
|
|
3103
|
+
"sourceId": "praxis-page-builder",
|
|
3104
|
+
"corpusVersion": "1.0.0"
|
|
3105
|
+
},
|
|
3106
|
+
{
|
|
3107
|
+
"chunkIndex": 5,
|
|
3108
|
+
"chunkKind": "recipe",
|
|
3109
|
+
"content": "{\n \"_comment\": \"Receita para Page Builder usando Gridster e conexões entre widgets.\",\n \"_comment2\": \"resourcePath deve ser o path base do recurso (sem /filter).\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-page-builder\",\n \"variantId\": \"base\",\n \"useWhen\": \"Base page builder layout with gridster widgets.\",\n \"examplePrompts\": [\n \"create a page builder layout\",\n \"set up a gridster page with table and form\"\n ]\n },\n \"page\": {\n \"options\": {\n \"cols\": 12,\n \"rowHeight\": 100,\n \"gap\": 12\n },\n \"widgets\": [\n {\n \"key\": \"userTable\",\n \"layout\": { \"col\": 1, \"row\": 1, \"colSpan\": 7, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-table\",\n \"bindingOrder\": [\"config\", \"resourcePath\"],\n \"inputs\": {\n \"resourcePath\": \"{{resourcePath}}\",\n \"tableId\": \"{{resourceKey}}-master\",\n \"config\": {\n \"columns\": [\n { \"field\": \"id\", \"header\": \"ID\", \"width\": \"60px\" },\n { \"field\": \"name\", \"header\": \"Nome\" },\n { \"field\": \"email\", \"header\": \"Email\" },\n { \"field\": \"status\", \"header\": \"Status\", \"renderer\": { \"type\": \"chip\" } }\n ],\n \"toolbar\": { \"visible\": true, \"title\": \"{{resourceLabel}}\" },\n \"behavior\": { \"selection\": { \"enabled\": true, \"type\": \"single\" } }\n }\n },\n \"outputs\": { \"rowClick\": \"emit\" }\n }\n },\n {\n \"key\": \"userDetailForm\",\n \"layout\": { \"col\": 8, \"row\": 1, \"colSpan\": 5, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-dynamic-form\",\n \"bindingOrder\": [\"resourcePath\", \"formId\", \"resourceId\"],\n \"inputs\": {\n \"formId\": \"{{resourceKey}}-detail-view\",\n \"resourcePath\": \"{{resourcePath}}\",\n \"mode\": \"view\",\n \"config\": {\n \"sections\": [\n {\n \"title\": \"Detalhes de {{resourceLabel}}\",\n \"rows\": [\n { \"columns\": [{ \"fields\": [\"name\", \"email\"] }] },\n { \"columns\": [{ \"fields\": [\"role\", \"status\"] }] }\n ]\n }\n ]\n }\n }\n }\n },\n {\n \"_comment\": \"Componente custom do app; substitua por um id registrado no ComponentMetadataRegistry.\",\n \"key\": \"statsCard\",\n \"layout\": { \"col\": 1, \"row\": 7, \"colSpan\": 4, \"rowSpan\": 2 },\n \"definition\": {\n \"id\": \"praxis-custom-card\",\n \"inputs\": {\n \"title\": \"Total Selecionado\",\n \"content\": \"Nenhum\"\n }\n }\n }\n ],\n \"connections\": [\n {\n \"_comment\": \"Ao clicar na linha da tabela, carrega o formulário com o ID correspondente\",\n \"from\": { \"widget\": \"userTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"userDetailForm\", \"input\": \"resourceId\" },\n \"map\": \"payload.row.{{idField}}\"\n },\n {\n \"_comment\": \"Ao clicar na linha, atualiza o título do card de estatísticas\",\n \"from\": { \"widget\": \"userTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"statsCard\", \"input\": \"inputs.content\" },\n \"map\": \"Selecionado: ${payload.row.name}\"\n }\n ]\n }\n}\n",
|
|
3110
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-dynamic-gridster-page.json",
|
|
3111
|
+
"contentHash": "44dbe1127834e80957db8b458caccbb44c43d7c21e3bc18a7a4a3f2cd8eb89a6",
|
|
3112
|
+
"sourceKind": "component_definition",
|
|
3113
|
+
"sourceId": "praxis-page-builder",
|
|
3114
|
+
"corpusVersion": "1.0.0"
|
|
3115
|
+
},
|
|
3116
|
+
{
|
|
3117
|
+
"chunkIndex": 6,
|
|
3118
|
+
"chunkKind": "recipe",
|
|
3119
|
+
"content": "{\n \"_comment\": \"Template base para Praxis Page Builder (gridster).\",\n \"_comment2\": \"resourcePath deve ser o path base do recurso (sem /filter).\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-page-builder\",\n \"variantId\": \"base\",\n \"defaultVariantId\": \"base\",\n \"variants\": [\n {\n \"id\": \"base\",\n \"registryKey\": \"praxis-page-builder:base\",\n \"variantId\": \"base\",\n \"description\": \"Cria um workspace base do page builder com widgets em gridster.\",\n \"useWhen\": \"Base page builder layout with gridster widgets.\"\n },\n {\n \"id\": \"master-detail\",\n \"registryKey\": \"praxis-page-builder:master-detail\",\n \"variantId\": \"master-detail\",\n \"description\": \"Cria workspace com tabela, formulário de detalhes e superfícies editoriais governadas por rich-content.\",\n \"useWhen\": \"Page builder layout with master table, detail form and governed editorial action surfaces.\"\n }\n ],\n \"useWhen\": \"Base page builder layout with gridster widgets and optional governed editorial action surfaces.\",\n \"examplePrompts\": [\n \"create a page builder layout\",\n \"set up a gridster page with table and form\",\n \"add a governed action card to a page-builder master-detail workspace\"\n ]\n },\n \"page\": {\n \"options\": {\n \"cols\": 12,\n \"rowHeight\": 100,\n \"gap\": 12\n },\n \"widgets\": [\n {\n \"key\": \"masterTable\",\n \"layout\": { \"col\": 1, \"row\": 1, \"colSpan\": 7, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-table\",\n \"bindingOrder\": [\"config\", \"resourcePath\"],\n \"inputs\": {\n \"resourcePath\": \"{{resourcePath}}\",\n \"tableId\": \"{{resourceKey}}-master\",\n \"config\": {\n \"columns\": [\n { \"field\": \"id\", \"header\": \"ID\", \"width\": \"60px\" },\n { \"field\": \"name\", \"header\": \"Nome\" },\n { \"field\": \"status\", \"header\": \"Status\", \"renderer\": { \"type\": \"chip\" } }\n ],\n \"toolbar\": { \"visible\": true, \"title\": \"{{resourceLabel}}\" },\n \"behavior\": { \"selection\": { \"enabled\": true, \"type\": \"single\" } }\n }\n },\n \"outputs\": { \"rowClick\": \"emit\" }\n }\n },\n {\n \"key\": \"detailForm\",\n \"layout\": { \"col\": 8, \"row\": 1, \"colSpan\": 5, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-dynamic-form\",\n \"bindingOrder\": [\"resourcePath\", \"formId\", \"resourceId\"],\n \"inputs\": {\n \"formId\": \"{{resourceKey}}-detail-view\",\n \"resourcePath\": \"{{resourcePath}}\",\n \"mode\": \"view\",\n \"config\": {\n \"sections\": [\n {\n \"title\": \"Detalhes de {{resourceLabel}}\",\n \"rows\": [\n { \"columns\": [{ \"fields\": [\"name\", \"status\"] }] }\n ]\n }\n ]\n }\n }\n }\n }\n ],\n \"connections\": [\n {\n \"_comment\": \"Ao clicar na linha da tabela, carrega o formulário com o ID correspondente\",\n \"from\": { \"widget\": \"masterTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"detailForm\", \"input\": \"resourceId\" },\n \"map\": \"payload.row.{{idField}}\"\n }\n ]\n }\n}\n",
|
|
3120
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-page-builder.json",
|
|
3121
|
+
"contentHash": "4ef3088454778e5531f7500ef938646741807d0aa32f0f6e1c64b7a516619ea9",
|
|
3122
|
+
"sourceKind": "component_definition",
|
|
3123
|
+
"sourceId": "praxis-page-builder",
|
|
3124
|
+
"corpusVersion": "1.0.0"
|
|
3125
|
+
},
|
|
3126
|
+
{
|
|
3127
|
+
"chunkIndex": 7,
|
|
3128
|
+
"chunkKind": "recipe",
|
|
3129
|
+
"content": "{\n \"_comment\": \"Template master-detail para Praxis Page Builder (gridster).\",\n \"_comment2\": \"resourcePath deve ser o path base do recurso (sem /filter).\",\n \"_comment3\": \"Widgets praxis-rich-content podem complementar o workspace com orientacao editorial e actions mediadas por host, mas hostCapabilities nao pertence ao JSON persistido.\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-page-builder\",\n \"variantId\": \"master-detail\",\n \"useWhen\": \"Page builder layout with master table, detail form and governed editorial workspace.\",\n \"examplePrompts\": [\n \"create a master detail page with table and form\",\n \"build a page with a table and a detail form\",\n \"add a governed editorial panel to a page-builder master-detail workspace\"\n ]\n },\n \"page\": {\n \"options\": {\n \"cols\": 12,\n \"rowHeight\": 100,\n \"gap\": 12\n },\n \"widgets\": [\n {\n \"key\": \"masterTable\",\n \"layout\": { \"col\": 1, \"row\": 1, \"colSpan\": 7, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-table\",\n \"bindingOrder\": [\"config\", \"resourcePath\"],\n \"inputs\": {\n \"resourcePath\": \"{{resourcePath}}\",\n \"tableId\": \"{{resourceKey}}-master\",\n \"config\": {\n \"columns\": [\n { \"field\": \"id\", \"header\": \"ID\", \"width\": \"60px\" },\n { \"field\": \"name\", \"header\": \"Nome\" },\n { \"field\": \"status\", \"header\": \"Status\", \"renderer\": { \"type\": \"chip\" } }\n ],\n \"toolbar\": { \"visible\": true, \"title\": \"{{resourceLabel}}\" },\n \"behavior\": { \"selection\": { \"enabled\": true, \"type\": \"single\" } }\n }\n },\n \"outputs\": { \"rowClick\": \"emit\" }\n }\n },\n {\n \"key\": \"detailForm\",\n \"layout\": { \"col\": 8, \"row\": 1, \"colSpan\": 5, \"rowSpan\": 6 },\n \"definition\": {\n \"id\": \"praxis-dynamic-form\",\n \"bindingOrder\": [\"resourcePath\", \"formId\", \"resourceId\", \"config\"],\n \"inputs\": {\n \"formId\": \"{{resourceKey}}-detail-view\",\n \"resourcePath\": \"{{resourcePath}}\",\n \"mode\": \"view\",\n \"config\": {\n \"formBlocksBefore\": {\n \"kind\": \"praxis.rich-content\",\n \"version\": \"1.0.0\",\n \"nodes\": [\n {\n \"type\": \"callout\",\n \"tone\": \"neutral\",\n \"icon\": \"dashboard_customize\",\n \"title\": \"Page-builder host\",\n \"message\": \"Mesmo no page builder, rich-content continua sendo documento portavel e host-mediated em runtime.\"\n }\n ]\n },\n \"sections\": [\n {\n \"title\": \"Detalhes de {{resourceLabel}}\",\n \"rows\": [\n { \"columns\": [{ \"fields\": [\"name\", \"status\"] }] }\n ]\n }\n ]\n }\n },\n \"outputs\": { \"customAction\": \"emit\" }\n }\n },\n {\n \"key\": \"editorialGuide\",\n \"layout\": { \"col\": 8, \"row\": 7, \"colSpan\": 5, \"rowSpan\": 3 },\n \"definition\": {\n \"id\": \"praxis-rich-content\",\n \"bindingOrder\": [\"document\", \"context\"],\n \"inputs\": {\n \"context\": {\n \"workspace\": {\n \"resourceLabel\": \"{{resourceLabel}}\",\n \"layout\": \"gridster\",\n \"governance\": \"host-mediated runtime actions\"\n }\n },\n \"document\": {\n \"kind\": \"praxis.rich-content\",\n \"version\": \"1.0.0\",\n \"nodes\": [\n {\n \"type\": \"recordSummary\",\n \"title\": \"Master-detail workspace\",\n \"subtitleExpr\": \"${workspace.resourceLabel}\",\n \"meta\": \"praxis-page-builder\",\n \"fields\": [\n {\n \"label\": \"Layout\",\n \"valueExpr\": \"${workspace.layout}\"\n },\n {\n \"label\": \"Governance\",\n \"valueExpr\": \"${workspace.governance}\"\n }\n ]\n },\n {\n \"type\": \"statGroup\",\n \"title\": \"Workspace signals\",\n \"subtitle\": \"Portable summary cards inside the builder workspace\",\n \"layout\": \"grid\",\n \"items\": [\n {\n \"label\": \"Layout\",\n \"valueExpr\": \"${workspace.layout}\",\n \"caption\": \"gridster\",\n \"icon\": \"grid_view\"\n },\n {\n \"label\": \"Governance\",\n \"value\": \"host\",\n \"captionExpr\": \"${workspace.governance}\",\n \"icon\": \"shield\"\n }\n ]\n },\n {\n \"type\": \"tabs\",\n \"title\": \"Builder views\",\n \"subtitle\": \"Canonical editorial tabs inside the page-builder workspace.\",\n \"appearance\": \"underline\",\n \"defaultTabId\": \"overview\",\n \"items\": [\n {\n \"id\": \"overview\",\n \"label\": \"Overview\",\n \"icon\": \"dashboard\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Tabs let the builder workspace organize guidance, runtime notes and next steps without inventing builder-specific markup.\"\n }\n ]\n },\n {\n \"id\": \"governance\",\n \"label\": \"Governance\",\n \"icon\": \"shield\",\n \"badge\": \"Host\",\n \"content\": [\n {\n \"type\": \"keyValueList\",\n \"layout\": \"stacked\",\n \"items\": [\n {\n \"label\": \"Layout\",\n \"valueExpr\": \"${workspace.layout}\"\n },\n {\n \"label\": \"Governance\",\n \"valueExpr\": \"${workspace.governance}\"\n },\n {\n \"label\": \"Persistence rule\",\n \"value\": \"hostCapabilities stay outside persisted page JSON.\"\n }\n ]\n }\n ]\n }\n ]\n },\n {\n \"type\": \"ctaGroup\",\n \"title\": \"Next steps\",\n \"subtitle\": \"Governed builder actions\",\n \"message\": \"Use a semantic CTA cluster for builder-side flows without embedding handlers in the document.\",\n \"layout\": \"split\",\n \"actions\": [\n {\n \"type\": \"actionButton\",\n \"label\": \"Abrir fluxo governado\",\n \"icon\": \"open_in_new\",\n \"variant\": \"raised\",\n \"color\": \"primary\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"editorialGuide\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n }\n },\n {\n \"type\": \"actionButton\",\n \"label\": \"Inspecionar workspace\",\n \"icon\": \"manage_search\",\n \"variant\": \"stroked\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"detailForm\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n }\n }\n ]\n },\n {\n \"type\": \"disclosure\",\n \"title\": \"Persisted versus runtime\",\n \"subtitle\": \"A pagina salva document/config; o host injeta capabilities apenas em runtime\",\n \"appearance\": \"card\",\n \"defaultExpanded\": true,\n \"content\": [\n {\n \"type\": \"keyValueList\",\n \"layout\": \"stacked\",\n \"items\": [\n {\n \"label\": \"Persistir\",\n \"value\": \"document, context e config do widget\"\n },\n {\n \"label\": \"Nao persistir\",\n \"value\": \"hostCapabilities\"\n }\n ]\n }\n ]\n },\n {\n \"type\": \"relatedRecord\",\n \"title\": \"Selected related record\",\n \"subtitleExpr\": \"${workspace.resourceLabel}\",\n \"relationLabel\": \"Builder selection\",\n \"meta\": \"resolved relationship\",\n \"ctaLabel\": \"Abrir relacionado\",\n \"variant\": \"raised\",\n \"color\": \"primary\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"editorialGuide\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n },\n \"fields\": [\n {\n \"label\": \"Layout\",\n \"valueExpr\": \"${workspace.layout}\",\n \"hint\": \"Resolved from the same builder workspace context.\"\n }\n ],\n \"secondaryActions\": [\n {\n \"type\": \"actionButton\",\n \"label\": \"Inspecionar workspace\",\n \"icon\": \"manage_search\",\n \"variant\": \"stroked\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"detailForm\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n }\n }\n ]\n },\n {\n \"type\": \"actionCard\",\n \"title\": \"Open governed builder flow\",\n \"subtitleExpr\": \"${workspace.resourceLabel}\",\n \"message\": \"Use actionCard when the page-builder workspace needs a governed host action from a portable editorial document.\",\n \"meta\": \"praxis-page-builder\",\n \"ctaLabel\": \"Abrir fluxo governado\",\n \"variant\": \"raised\",\n \"color\": \"primary\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"editorialGuide\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n },\n \"secondaryActions\": [\n {\n \"type\": \"actionButton\",\n \"label\": \"Inspecionar workspace\",\n \"icon\": \"manage_search\",\n \"variant\": \"stroked\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"detailForm\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n }\n }\n ]\n },\n {\n \"type\": \"emptyState\",\n \"icon\": \"hub\",\n \"title\": \"Acione um fluxo governado pelo host\",\n \"message\": \"Use actionButton para abrir surface, drawer ou modal sem embutir manipuladores no documento.\",\n \"actions\": [\n {\n \"type\": \"actionButton\",\n \"label\": \"Abrir painel\",\n \"icon\": \"open_in_new\",\n \"variant\": \"stroked\",\n \"color\": \"primary\",\n \"action\": {\n \"actionId\": \"openBuilderPanel\",\n \"payload\": {\n \"widgetKey\": \"editorialGuide\",\n \"resourceKey\": \"{{resourceKey}}\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n }\n }\n ],\n \"connections\": [\n {\n \"_comment\": \"Ao clicar na linha da tabela, carrega o formulário com o ID correspondente\",\n \"from\": { \"widget\": \"masterTable\", \"output\": \"rowClick\" },\n \"to\": { \"widget\": \"detailForm\", \"input\": \"resourceId\" },\n \"map\": \"payload.row.{{idField}}\"\n }\n ]\n }\n}\n",
|
|
3130
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-page-builder.master-detail.json",
|
|
3131
|
+
"contentHash": "76733630ba62cb3ca02e5210b583d267cec6a571d9e528c7f980428548753d4e",
|
|
3132
|
+
"sourceKind": "component_definition",
|
|
3133
|
+
"sourceId": "praxis-page-builder",
|
|
3134
|
+
"corpusVersion": "1.0.0"
|
|
3135
|
+
},
|
|
3136
|
+
{
|
|
3137
|
+
"chunkIndex": 8,
|
|
3138
|
+
"chunkKind": "recipe",
|
|
3139
|
+
"content": "{\n \"_comment\": \"Contrato operacional para orientar LLM/backend a emitir UiCompositionPlan antes do WidgetPageDefinition final.\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-page-builder\",\n \"variantId\": \"ui-composition-plan\",\n \"status\": \"golden-fixture\",\n \"useWhen\": \"Agentic page creation or modification needs multiple Praxis widgets, state and bindings before compiling the persisted page JSON.\",\n \"examplePrompts\": [\n \"Crie uma tela master detail de departamentos com funcionarios, folha e resumo\",\n \"Monte um dashboard com lista mestre, tabela detalhe, grafico e texto dinamico\"\n ]\n },\n \"outputEnvelope\": {\n \"uiCompositionPlan\": {\n \"version\": \"1.0\",\n \"kind\": \"praxis.ui-composition-plan\",\n \"layoutPreset\": \"{{layoutPreset}}\",\n \"state\": {\n \"values\": {\n \"{{stateKey}}\": null\n }\n },\n \"widgets\": [\n {\n \"key\": \"{{stableWidgetKey}}\",\n \"componentId\": \"{{registeredComponentId}}\",\n \"role\": \"{{semanticRole}}\",\n \"bindingOrder\": [\"{{inputName}}\"],\n \"inputs\": {\n \"{{inputName}}\": \"{{canonicalInputValue}}\"\n }\n }\n ],\n \"bindings\": [\n {\n \"id\": \"{{stableBindingId}}\",\n \"from\": {\n \"kind\": \"component-port\",\n \"widget\": \"{{sourceWidgetKey}}\",\n \"port\": \"{{outputPort}}\",\n \"direction\": \"output\"\n },\n \"to\": {\n \"kind\": \"state\",\n \"path\": \"{{statePath}}\"\n },\n \"intent\": \"state-write\",\n \"transform\": {\n \"kind\": \"pick-path\",\n \"id\": \"{{transformId}}\",\n \"path\": \"{{payloadPath}}\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\"\n }\n }\n ]\n },\n \"compiledFormPatch\": {\n \"version\": \"1.1\",\n \"patch\": {}\n }\n },\n \"validationRules\": [\n \"uiCompositionPlan.version deve ser 1.0.\",\n \"uiCompositionPlan.kind deve ser praxis.ui-composition-plan.\",\n \"widgets[].key deve ser estavel e unico.\",\n \"widgets[].componentId deve existir no catalogo de componentes registrado do Page Builder.\",\n \"bindings[].from/to com kind component-port devem referenciar widgets existentes no proprio plano.\",\n \"bindings[].from/to com kind state devem usar paths declarados ou justificaveis em state.values/state.derived.\",\n \"bindings[].to com kind global-action deve declarar actionId e compila para page.composition.links[].to.ref.[actionId].\",\n \"Use intent command-dispatch para bindings cujo destino e global-action.\",\n \"Use bindings como fonte declarativa. Nao emita connections legado nem page.composition.links concorrente no mesmo plano.\",\n \"Use pick-path para extrair payload/evento, query-context para filtros de recurso, template para gerar inputs estruturados e constant para valores fixos.\",\n \"Se API, metadata, surface, action, capability ou porta de componente nao estiver confirmada, retorne clarification/diagnostic em vez de alucinar o plano.\"\n ],\n \"example\": {\n \"uiCompositionPlan\": {\n \"version\": \"1.0\",\n \"kind\": \"praxis.ui-composition-plan\",\n \"layoutPreset\": \"master-detail-dashboard\",\n \"state\": {\n \"values\": {\n \"selectedDepartmentId\": null,\n \"selectedDepartmentName\": null\n }\n },\n \"widgets\": [\n {\n \"key\": \"department-master\",\n \"componentId\": \"praxis-list\",\n \"role\": \"master\",\n \"inputs\": {\n \"config\": {\n \"dataSource\": {\n \"resourcePath\": \"/api/human-resources/departamentos\"\n }\n }\n }\n },\n {\n \"key\": \"department-employees\",\n \"componentId\": \"praxis-table\",\n \"role\": \"detail\",\n \"inputs\": {\n \"resourcePath\": \"/api/human-resources/funcionarios\",\n \"tableId\": \"department-employees\"\n }\n },\n {\n \"key\": \"department-payroll\",\n \"componentId\": \"praxis-chart\",\n \"role\": \"detail\",\n \"inputs\": {\n \"config\": {\n \"chartId\": \"department-payroll\",\n \"resourcePath\": \"/api/human-resources/vw-analytics-folha-pagamento\"\n }\n }\n },\n {\n \"key\": \"department-summary\",\n \"componentId\": \"praxis-rich-content\",\n \"role\": \"detail\",\n \"inputs\": {\n \"document\": {\n \"kind\": \"praxis.rich-content.document\",\n \"version\": \"1.0.0\",\n \"nodes\": [\n {\n \"type\": \"text\",\n \"text\": \"Selecione um departamento para revisar funcionarios, folha e observacoes.\"\n }\n ]\n }\n }\n }\n ],\n \"bindings\": [\n {\n \"id\": \"department-master.itemSelect->state.selectedDepartmentId\",\n \"from\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-master\",\n \"port\": \"itemSelect\",\n \"direction\": \"output\"\n },\n \"to\": {\n \"kind\": \"state\",\n \"path\": \"selectedDepartmentId\"\n },\n \"intent\": \"state-write\",\n \"transform\": {\n \"kind\": \"pick-path\",\n \"id\": \"pick-department-id\",\n \"path\": \"payload.item.id\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"state\"]\n }\n },\n {\n \"id\": \"department-master.itemSelect->state.selectedDepartmentName\",\n \"from\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-master\",\n \"port\": \"itemSelect\",\n \"direction\": \"output\"\n },\n \"to\": {\n \"kind\": \"state\",\n \"path\": \"selectedDepartmentName\"\n },\n \"intent\": \"state-write\",\n \"transform\": {\n \"kind\": \"pick-path\",\n \"id\": \"pick-department-name\",\n \"path\": \"payload.item.nome\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"state\"]\n }\n },\n {\n \"id\": \"department-master.itemSelect->global-action.department-selection-audit\",\n \"from\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-master\",\n \"port\": \"itemSelect\",\n \"direction\": \"output\"\n },\n \"to\": {\n \"kind\": \"global-action\",\n \"actionId\": \"department.selection.audit\",\n \"payloadExpr\": \"payload.item\",\n \"meta\": {\n \"label\": \"Audit department selection\"\n }\n },\n \"intent\": \"command-dispatch\",\n \"policy\": {\n \"distinct\": true,\n \"distinctBy\": \"payload.item.id\",\n \"missingValuePolicy\": \"skip\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"global-action\"]\n }\n },\n {\n \"id\": \"state.selectedDepartmentId->department-employees.queryContext\",\n \"from\": {\n \"kind\": \"state\",\n \"path\": \"selectedDepartmentId\"\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-employees\",\n \"port\": \"queryContext\",\n \"direction\": \"input\"\n },\n \"intent\": \"state-read\",\n \"condition\": {\n \"!=\": [\n {\n \"var\": \"state.selectedDepartmentId\"\n },\n null\n ]\n },\n \"transform\": {\n \"kind\": \"query-context\",\n \"id\": \"department-filter\",\n \"field\": \"departamentoId\"\n },\n \"policy\": {\n \"distinct\": true,\n \"distinctBy\": \"value\",\n \"missingValuePolicy\": \"skip\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"table-filter\"]\n }\n },\n {\n \"id\": \"state.selectedDepartmentId->department-payroll.queryContext\",\n \"from\": {\n \"kind\": \"state\",\n \"path\": \"selectedDepartmentId\"\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-payroll\",\n \"port\": \"queryContext\",\n \"direction\": \"input\"\n },\n \"intent\": \"state-read\",\n \"condition\": {\n \"!=\": [\n {\n \"var\": \"state.selectedDepartmentId\"\n },\n null\n ]\n },\n \"transform\": {\n \"kind\": \"query-context\",\n \"id\": \"department-payroll-filter\",\n \"field\": \"departamentoId\"\n },\n \"policy\": {\n \"distinct\": true,\n \"missingValuePolicy\": \"skip\"\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"chart-filter\"]\n }\n },\n {\n \"id\": \"state.selectedDepartmentName->department-summary.document\",\n \"from\": {\n \"kind\": \"state\",\n \"path\": \"selectedDepartmentName\"\n },\n \"to\": {\n \"kind\": \"component-port\",\n \"widget\": \"department-summary\",\n \"port\": \"document\",\n \"direction\": \"input\"\n },\n \"intent\": \"state-read\",\n \"condition\": {\n \"!!\": [\n {\n \"var\": \"state.selectedDepartmentName\"\n }\n ]\n },\n \"transform\": {\n \"kind\": \"template\",\n \"id\": \"department-summary-document\",\n \"template\": {\n \"kind\": \"praxis.rich-content.document\",\n \"version\": \"1.0.0\",\n \"nodes\": [\n {\n \"type\": \"text\",\n \"text\": {\n \"concat\": [\n \"Departamento selecionado: \",\n {\n \"var\": \"value\"\n }\n ]\n }\n }\n ]\n }\n },\n \"metadata\": {\n \"source\": \"ui-composition-plan\",\n \"tags\": [\"master-detail\", \"rich-content\"]\n }\n }\n ]\n }\n },\n \"compiledOutput\": {\n \"summary\": \"O compilador gera WidgetPageDefinition com page.widgets[].definition.id, page.widgets[].definition.inputs e page.composition.links version 1.0.0. O JSON persistido nao deve conter connections legado.\",\n \"forbiddenLegacyPaths\": [\"page.options\", \"page.widgets[].layout\", \"page.connections\", \"connections\"]\n }\n}\n",
|
|
3140
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-page-builder.ui-composition-plan.json",
|
|
3141
|
+
"contentHash": "e7016945a2b2e3181ff2301d04a1f088e7c33ec6c77a093202f84afd325312e8",
|
|
3142
|
+
"sourceKind": "component_definition",
|
|
3143
|
+
"sourceId": "praxis-page-builder",
|
|
3144
|
+
"corpusVersion": "1.0.0"
|
|
3145
|
+
}
|
|
3146
|
+
]
|
|
3147
|
+
}
|
|
3148
|
+
},
|
|
3149
|
+
"note": "Package-scoped Praxis component registry for source-free agent discovery. Use the canonical ingestion registry for cross-package aggregate analysis."
|
|
3150
|
+
}
|