@praxisui/page-builder 9.0.4-rc.48 → 9.0.4-rc.49

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 CHANGED
@@ -204,6 +204,27 @@ providers: [
204
204
 
205
205
  The package exports `PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST` for governed operation discovery. The persisted runtime page is still `WidgetPageDefinition`; intermediate AI plans such as `UiCompositionPlan` must compile before preview, apply, or save.
206
206
 
207
+ Repeated selection projections can be authored once through `UiCompositionPlan.selectionSyncs`. A sync declares structured component-output sources, a base state target, and a field-to-payload mapping. `compileUiCompositionPlan` expands every source/mapping pair into explicit `page.composition.links` with stable ids, canonical `pick-path` transforms, policy, condition, and `selection-sync` intent. The shorthand is never persisted in `WidgetPageDefinition`, so runtime inspection and audit continue to see the complete executable graph.
208
+
209
+ ```ts
210
+ selectionSyncs: [{
211
+ id: 'employee-selection',
212
+ intent: 'selection-sync',
213
+ sources: [
214
+ { kind: 'component-port', widget: 'employee-portfolio', port: 'rowClick', direction: 'output' },
215
+ { kind: 'component-port', widget: 'employee-portfolio', port: 'rowAction', direction: 'output' },
216
+ ],
217
+ target: { kind: 'state', path: 'selection', layer: 'values' },
218
+ mapping: {
219
+ employeeId: 'payload.row.id',
220
+ employeeIdentity: 'payload.resourceIdentity',
221
+ employee: 'payload.row',
222
+ },
223
+ }]
224
+ ```
225
+
226
+ Repeated parent/resource context can be declared through `UiCompositionPlan.contextScopes`. Each context value is explicitly either `constant` or `state`; each target uses a stable owner widget and optional canonical `nestedPath`. During compilation, constants are materialized into component inputs through core's `NestedWidgetConfigAccessor`, while state values become normal `state-read` links. Targets can inherit all keys or an explicit subset. The persisted page therefore contains only concrete widget inputs and `composition.links`, never ambient or implicit context inheritance.
227
+
207
228
  Streaming apply is fail-closed. A preview is persistable only when it is the unchanged payload of an applicable terminal `result` event and its diagnostics carry the matching `streamId`, `threadId`, `turnId`, and `resultEventId`. A locally regenerated or normalized preview remains available for review, but it cannot reuse an older terminal reference or call `page-apply`; the backend must issue a new terminal result for the new patch.
208
229
 
209
230
  ## Public API
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-11T15:53:18.549Z",
3
+ "generatedAt": "2026-08-11T17:25:06.956Z",
4
4
  "packageName": "@praxisui/page-builder",
5
- "packageVersion": "9.0.4-rc.48",
5
+ "packageVersion": "9.0.4-rc.49",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -2621,6 +2621,8 @@
2621
2621
  "handlerContract": {
2622
2622
  "reads": [
2623
2623
  "UiCompositionPlan",
2624
+ "UiCompositionPlan.selectionSyncs",
2625
+ "UiCompositionPlan.contextScopes",
2624
2626
  "compileUiCompositionPlan",
2625
2627
  "PAGE_BUILDER_WIDGET_AI_CATALOGS",
2626
2628
  "ComponentDocMeta.configEditor"
@@ -2631,7 +2633,9 @@
2631
2633
  "identityKeys": [
2632
2634
  "uiCompositionPlan.id",
2633
2635
  "widgetKey",
2634
- "uiCompositionPlan.bindings[].id"
2636
+ "uiCompositionPlan.bindings[].id",
2637
+ "uiCompositionPlan.selectionSyncs[].id",
2638
+ "uiCompositionPlan.contextScopes[].id"
2635
2639
  ],
2636
2640
  "failureModes": [
2637
2641
  "ui-composition-plan-invalid",
@@ -3261,6 +3265,8 @@
3261
3265
  "roundTripRequirements": [
3262
3266
  "WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.",
3263
3267
  "UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.",
3268
+ "UiCompositionPlan.selectionSyncs is an authoring shorthand that compiles into explicit canonical page.composition.links and is never persisted in WidgetPageDefinition.",
3269
+ "UiCompositionPlan.contextScopes compiles constant context into explicit widget inputs and state context into explicit page.composition.links; runtime inheritance is never ambient.",
3264
3270
  "Widget keys and composition link ids are stable identities; array indexes are never canonical identities.",
3265
3271
  "Persisted wiring uses page.composition.links and must not write legacy connections.",
3266
3272
  "Nested component ports use component-port refs with nestedPath ending in a stable widget key.",
@@ -3688,9 +3694,9 @@
3688
3694
  {
3689
3695
  "chunkIndex": 21,
3690
3696
  "chunkKind": "authoring_manifest",
3691
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-page-builder\",\"ownerPackage\":\"@praxisui/page-builder\",\"configSchemaId\":\"WidgetPageDefinition\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"composition.link.add\",\"title\":\"Add page composition link\",\"scope\":\"dataBinding\",\"targetKind\":\"compositionLink\",\"target\":{\"kind\":\"compositionLink\",\"resolver\":\"composition-link-by-id\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"from\",\"to\",\"intent\"],\"additionalProperties\":false,\"properties\":{\"id\":{\"type\":\"string\"},\"from\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}}]},\"to\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"global-action\"]},\"ref\":{\"type\":\"object\",\"required\":[\"actionId\"],\"additionalProperties\":false,\"properties\":{\"actionId\":{\"type\":\"string\"},\"payload\":{\"type\":\"object\"},\"payloadExpr\":{\"type\":\"string\"},\"meta\":{\"type\":\"object\"}}}}}]},\"intent\":{\"enum\":[\"event-propagation\",\"state-write\",\"state-read\",\"command-dispatch\",\"selection-sync\",\"data-projection\",\"status-propagation\"]},\"condition\":{\"type\":\"object\"},\"transform\":{\"type\":\"object\"},\"policy\":{\"type\":\"object\"},\"metadata\":{\"type\":\"object\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-composition-link-add\",\"handlerContract\":{\"reads\":[\"WidgetPageDefinition.composition.links\",\"WidgetPageDefinition.widgets\",\"PAGE_BUILDER_AI_CAPABILITIES\"],\"writes\":[\"page.composition.links[]\"],\"identityKeys\":[\"id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"from\",\"to\",\"intent\"],\"additionalProperties\":false,\"properties\":{\"id\":{\"type\":\"string\"},\"from\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}}]},\"to\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"global-action\"]},\"ref\":{\"type\":\"object\",\"required\":[\"actionId\"],\"additionalProperties\":false,\"properties\":{\"actionId\":{\"type\":\"string\"},\"payload\":{\"type\":\"object\"},\"payloadExpr\":{\"type\":\"string\"},\"meta\":{\"type\":\"object\"}}}}}]},\"intent\":{\"enum\":[\"event-propagation\",\"state-write\",\"state-read\",\"command-dispatch\",\"selection-sync\",\"data-projection\",\"status-propagation\"]},\"condition\":{\"type\":\"object\"},\"transform\":{\"type\":\"object\"},\"policy\":{\"type\":\"object\"},\"metadata\":{\"type\":\"object\"}}},\"failureModes\":[\"link-id-duplicate\",\"endpoint-not-found\",\"nested-path-invalid\",\"json-logic-invalid\"],\"description\":\"Adds canonical declarative wiring in page.composition.links, including component-port nestedPath endpoints.\"}}],\"validators\":[\"composition-link-id-unique\",\"composition-endpoints-resolve\",\"nested-path-terminal-widget-key-required\",\"json-logic-condition-valid\",\"no-legacy-connections-write\"],\"affectedPaths\":[\"composition.links[]\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"page-loaded\",\"widgets-resolvable\"]},{\"operationId\":\"composition.link.remove\",\"title\":\"Remove page composition link\",\"scope\":\"dataBinding\",\"targetKind\":\"compositionLink\",\"target\":{\"kind\":\"compositionLink\",\"resolver\":\"composition-link-by-id\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\"],\"properties\":{\"id\":{\"type\":\"string\"},\"confirmed\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-composition-link-remove\",\"handlerContract\":{\"reads\":[\"WidgetPageDefinition.composition.links\"],\"writes\":[\"page.composition.links[]\"],\"identityKeys\":[\"id\"],\"failureModes\":[\"composition-link-not-found\",\"destructive-removal-not-confirmed\"],\"description\":\"Removes a canonical composition link by stable id.\"}}],\"destructive\":true,\"requiresConfirmation\":true,\"validators\":[\"composition-link-exists\",\"destructive-removal-confirmed\",\"composition-links-still-valid\"],\"affectedPaths\":[\"composition.links[]\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"page-loaded\",\"target-link-exists\"]},{\"operationId\":\"composition.plan.compile\",\"title\":\"Compile UI composition plan\",\"scope\":\"rules\",\"targetKind\":\"agenticPreview\",\"target\":{\"kind\":\"agenticPreview\",\"resolver\":\"agentic-preview-result\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"uiCompositionPlan\"],\"properties\":{\"uiCompositionPlan\":{\"type\":\"object\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-ui-composition-plan-compile\",\"handlerContract\":{\"reads\":[\"UiCompositionPlan\",\"compileUiCompositionPlan\",\"PAGE_BUILDER_WIDGET_AI_CATALOGS\",\"ComponentDocMeta.configEditor\"],\"writes\":[\"compiledFormPatch.patch.page\"],\"identityKeys\":[\"uiCompositionPlan.id\",\"widgetKey\",\"uiCompositionPlan.bindings[].id\"],\"failureModes\":[\"ui-composition-plan-invalid\",\"widget-catalog-missing\",\"compiled-page-invalid\",\"child-config-editor-missing\"],\"description\":\"Compiles the agentic intermediate UiCompositionPlan into a renderable WidgetPageDefinition patch.page.\"}}],\"validators\":[\"ui-composition-plan-valid\",\"compiled-page-valid\",\"widget-keys-unique\",\"composition-endpoints-resolve\",\"canvas-items-reference-existing-widgets\"],\"affectedPaths\":[\"uiCompositionPlan\",\"compiledFormPatch.patch.page\"],\"submissionImpact\":\"none\",\"preconditions\":[\"agentic-preview-loaded\",\"component-catalog-loaded\"]}]}",
3697
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-page-builder\",\"ownerPackage\":\"@praxisui/page-builder\",\"configSchemaId\":\"WidgetPageDefinition\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"composition.link.add\",\"title\":\"Add page composition link\",\"scope\":\"dataBinding\",\"targetKind\":\"compositionLink\",\"target\":{\"kind\":\"compositionLink\",\"resolver\":\"composition-link-by-id\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"from\",\"to\",\"intent\"],\"additionalProperties\":false,\"properties\":{\"id\":{\"type\":\"string\"},\"from\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}}]},\"to\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"global-action\"]},\"ref\":{\"type\":\"object\",\"required\":[\"actionId\"],\"additionalProperties\":false,\"properties\":{\"actionId\":{\"type\":\"string\"},\"payload\":{\"type\":\"object\"},\"payloadExpr\":{\"type\":\"string\"},\"meta\":{\"type\":\"object\"}}}}}]},\"intent\":{\"enum\":[\"event-propagation\",\"state-write\",\"state-read\",\"command-dispatch\",\"selection-sync\",\"data-projection\",\"status-propagation\"]},\"condition\":{\"type\":\"object\"},\"transform\":{\"type\":\"object\"},\"policy\":{\"type\":\"object\"},\"metadata\":{\"type\":\"object\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-composition-link-add\",\"handlerContract\":{\"reads\":[\"WidgetPageDefinition.composition.links\",\"WidgetPageDefinition.widgets\",\"PAGE_BUILDER_AI_CAPABILITIES\"],\"writes\":[\"page.composition.links[]\"],\"identityKeys\":[\"id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\",\"from\",\"to\",\"intent\"],\"additionalProperties\":false,\"properties\":{\"id\":{\"type\":\"string\"},\"from\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}}]},\"to\":{\"oneOf\":[{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"component-port\"]},\"ref\":{\"type\":\"object\",\"required\":[\"widget\",\"port\",\"direction\"],\"additionalProperties\":false,\"properties\":{\"widget\":{\"type\":\"string\"},\"port\":{\"type\":\"string\"},\"direction\":{\"enum\":[\"input\",\"output\"]},\"bindingPath\":{\"type\":\"string\"},\"nestedPath\":{\"type\":\"array\"}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"state\"]},\"ref\":{\"type\":\"object\",\"required\":[\"path\"],\"additionalProperties\":false,\"properties\":{\"path\":{\"type\":\"string\"},\"layer\":{\"enum\":[\"values\",\"derived\",\"transient\"]}}}}},{\"type\":\"object\",\"required\":[\"kind\",\"ref\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"enum\":[\"global-action\"]},\"ref\":{\"type\":\"object\",\"required\":[\"actionId\"],\"additionalProperties\":false,\"properties\":{\"actionId\":{\"type\":\"string\"},\"payload\":{\"type\":\"object\"},\"payloadExpr\":{\"type\":\"string\"},\"meta\":{\"type\":\"object\"}}}}}]},\"intent\":{\"enum\":[\"event-propagation\",\"state-write\",\"state-read\",\"command-dispatch\",\"selection-sync\",\"data-projection\",\"status-propagation\"]},\"condition\":{\"type\":\"object\"},\"transform\":{\"type\":\"object\"},\"policy\":{\"type\":\"object\"},\"metadata\":{\"type\":\"object\"}}},\"failureModes\":[\"link-id-duplicate\",\"endpoint-not-found\",\"nested-path-invalid\",\"json-logic-invalid\"],\"description\":\"Adds canonical declarative wiring in page.composition.links, including component-port nestedPath endpoints.\"}}],\"validators\":[\"composition-link-id-unique\",\"composition-endpoints-resolve\",\"nested-path-terminal-widget-key-required\",\"json-logic-condition-valid\",\"no-legacy-connections-write\"],\"affectedPaths\":[\"composition.links[]\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"page-loaded\",\"widgets-resolvable\"]},{\"operationId\":\"composition.link.remove\",\"title\":\"Remove page composition link\",\"scope\":\"dataBinding\",\"targetKind\":\"compositionLink\",\"target\":{\"kind\":\"compositionLink\",\"resolver\":\"composition-link-by-id\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"id\"],\"properties\":{\"id\":{\"type\":\"string\"},\"confirmed\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-composition-link-remove\",\"handlerContract\":{\"reads\":[\"WidgetPageDefinition.composition.links\"],\"writes\":[\"page.composition.links[]\"],\"identityKeys\":[\"id\"],\"failureModes\":[\"composition-link-not-found\",\"destructive-removal-not-confirmed\"],\"description\":\"Removes a canonical composition link by stable id.\"}}],\"destructive\":true,\"requiresConfirmation\":true,\"validators\":[\"composition-link-exists\",\"destructive-removal-confirmed\",\"composition-links-still-valid\"],\"affectedPaths\":[\"composition.links[]\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"page-loaded\",\"target-link-exists\"]},{\"operationId\":\"composition.plan.compile\",\"title\":\"Compile UI composition plan\",\"scope\":\"rules\",\"targetKind\":\"agenticPreview\",\"target\":{\"kind\":\"agenticPreview\",\"resolver\":\"agentic-preview-result\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"uiCompositionPlan\"],\"properties\":{\"uiCompositionPlan\":{\"type\":\"object\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"page-builder-ui-composition-plan-compile\",\"handlerContract\":{\"reads\":[\"UiCompositionPlan\",\"UiCompositionPlan.selectionSyncs\",\"UiCompositionPlan.contextScopes\",\"compileUiCompositionPlan\",\"PAGE_BUILDER_WIDGET_AI_CATALOGS\",\"ComponentDocMeta.configEditor\"],\"writes\":[\"compiledFormPatch.patch.page\"],\"identityKeys\":[\"uiCompositionPlan.id\",\"widgetKey\",\"uiCompositionPlan.bindings[].id\",\"uiCompositionPlan.selectionSyncs[].id\",\"uiCompositionPlan.contextScopes[].id\"],\"failureModes\":[\"ui-composition-plan-invalid\",\"widget-catalog-missing\",\"compiled-page-invalid\",\"child-config-editor-missing\"],\"description\":\"Compiles the agentic intermediate UiCompositionPlan into a renderable WidgetPageDefinition patch.page.\"}}],\"validators\":[\"ui-composition-plan-valid\",\"compiled-page-valid\",\"widget-keys-unique\",\"composition-endpoints-resolve\",\"canvas-items-reference-existing-widgets\"],\"affectedPaths\":[\"uiCompositionPlan\",\"compiledFormPatch.patch.page\"],\"submissionImpact\":\"none\",\"preconditions\":[\"agentic-preview-loaded\",\"component-catalog-loaded\"]}]}",
3692
3698
  "sourcePointer": "projects/praxis-page-builder/src/lib/ai/praxis-page-builder-authoring-manifest.ts",
3693
- "contentHash": "a0e20e86811cdd1302049dbd6ec4f133d5fe9a60d962bc0cc60a9a772e2a4703",
3699
+ "contentHash": "f3de19943a6dfbd0452ecd46b1c1e5f4860cd71fd43eab9aa83958b6037604e9",
3694
3700
  "sourceKind": "component_definition",
3695
3701
  "sourceId": "praxis-page-builder",
3696
3702
  "corpusVersion": "1.0.0"
@@ -3718,9 +3724,9 @@
3718
3724
  {
3719
3725
  "chunkIndex": 24,
3720
3726
  "chunkKind": "authoring_manifest",
3721
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-page-builder\",\"ownerPackage\":\"@praxisui/page-builder\",\"configSchemaId\":\"WidgetPageDefinition\",\"chunkSection\":\"roundTripRequirements\",\"roundTripRequirements\":[\"WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.\",\"UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.\",\"Widget keys and composition link ids are stable identities; array indexes are never canonical identities.\",\"Persisted wiring uses page.composition.links and must not write legacy connections.\",\"Nested component ports use component-port refs with nestedPath ending in a stable widget key.\",\"Child widget definition.inputs edits delegate to the child manifest or ComponentDocMeta.configEditor.\",\"Agentic preview applies only compiledFormPatch.patch.page to runtime; the full patch envelope is diagnostics/audit data.\",\"Save uses pageIdentity and ETag policy from praxis-config-starter; pageIdentity is not persisted inside WidgetPageDefinition.\",\"Settings panel apply/save/reset/reopen must preserve page settings and widget shell config without hidden normalization drift.\"]}",
3727
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-page-builder\",\"ownerPackage\":\"@praxisui/page-builder\",\"configSchemaId\":\"WidgetPageDefinition\",\"chunkSection\":\"roundTripRequirements\",\"roundTripRequirements\":[\"WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.\",\"UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.\",\"UiCompositionPlan.selectionSyncs is an authoring shorthand that compiles into explicit canonical page.composition.links and is never persisted in WidgetPageDefinition.\",\"UiCompositionPlan.contextScopes compiles constant context into explicit widget inputs and state context into explicit page.composition.links; runtime inheritance is never ambient.\",\"Widget keys and composition link ids are stable identities; array indexes are never canonical identities.\",\"Persisted wiring uses page.composition.links and must not write legacy connections.\",\"Nested component ports use component-port refs with nestedPath ending in a stable widget key.\",\"Child widget definition.inputs edits delegate to the child manifest or ComponentDocMeta.configEditor.\",\"Agentic preview applies only compiledFormPatch.patch.page to runtime; the full patch envelope is diagnostics/audit data.\",\"Save uses pageIdentity and ETag policy from praxis-config-starter; pageIdentity is not persisted inside WidgetPageDefinition.\",\"Settings panel apply/save/reset/reopen must preserve page settings and widget shell config without hidden normalization drift.\"]}",
3722
3728
  "sourcePointer": "projects/praxis-page-builder/src/lib/ai/praxis-page-builder-authoring-manifest.ts",
3723
- "contentHash": "42dad9779ac9ce50930e0b2954939f93d07bdaeb2dbe445835d1f980db78aaab",
3729
+ "contentHash": "01d817d6b28effa45c76146f3bf01e15e2c3488f97efa19eabbb62375a315f64",
3724
3730
  "sourceKind": "component_definition",
3725
3731
  "sourceId": "praxis-page-builder",
3726
3732
  "corpusVersion": "1.0.0"
@@ -3808,9 +3814,9 @@
3808
3814
  {
3809
3815
  "chunkIndex": 33,
3810
3816
  "chunkKind": "recipe",
3811
- "content": "{\"_comment\":\"Contrato operacional para orientar LLM/backend a emitir UiCompositionPlan antes do WidgetPageDefinition final.\",\"templateMeta\":{\"registryKey\":\"praxis-page-builder\",\"variantId\":\"ui-composition-plan\",\"status\":\"golden-fixture\",\"useWhen\":\"Agentic page creation or modification needs multiple Praxis widgets, state and bindings before compiling the persisted page JSON.\",\"examplePrompts\":[\"Crie uma tela master detail de departamentos com funcionarios, folha e resumo\",\"Monte um dashboard com lista mestre, tabela detalhe, grafico e texto dinamico\"]},\"outputEnvelope\":{\"uiCompositionPlan\":{\"version\":\"1.0\",\"kind\":\"praxis.ui-composition-plan\",\"layoutPreset\":\"{{layoutPreset}}\",\"state\":{\"values\":{\"{{stateKey}}\":null}},\"widgets\":[{\"key\":\"{{stableWidgetKey}}\",\"componentId\":\"{{registeredComponentId}}\",\"role\":\"{{semanticRole}}\",\"bindingOrder\":[\"{{inputName}}\"],\"inputs\":{\"{{inputName}}\":\"{{canonicalInputValue}}\"}}],\"bindings\":[{\"id\":\"{{stableBindingId}}\",\"from\":{\"kind\":\"component-port\",\"widget\":\"{{sourceWidgetKey}}\",\"port\":\"{{outputPort}}\",\"direction\":\"output\"},\"to\":{\"kind\":\"state\",\"path\":\"{{statePath}}\"},\"intent\":\"state-write\",\"transform\":{\"kind\":\"pick-path\",\"id\":\"{{transformId}}\",\"path\":\"{{payloadPath}}\"},\"metadata\":{\"source\":\"ui-composition-plan\"}}]},\"compiledFormPatch\":{\"version\":\"1.1\",\"patch\":{}}},\"validationRules\":[\"uiCompositionPlan.version deve ser 1.0.\",\"uiCompositionPlan.kind deve ser praxis.ui-composition-plan.\",\"widgets[].key deve ser estavel e unico.\",\"widgets[].componentId deve existir no catalogo de componentes registrado do Page Builder.\",\"bindings[].from/to com kind component-port devem referenciar widgets existentes no proprio plano.\",\"bindings[].from/to com kind state devem usar paths declarados ou justificaveis em state.values/state.derived.\",\"bindings[].to com kind global-action deve declarar actionId e compila para page.composition.links[].to.ref.[actionId].\",\"Use intent command-dispatch para bindings cujo destino e global-action.\",\"Use bindings como fonte declarativa. Nao emita connections legado nem page.composition.links concorrente no mesmo plano.\",\"Use pick-path para extrair payload/evento, query-context para filtros de recurso, template para gerar inputs estruturados e constant para valores fixos.\",\"Se API, metadata, surface, action, capability ou porta de componente nao estiver confirmada, retorne clarification/diagnostic em vez de alucinar o plano.\"],\"example\":{\"uiCompositionPlan\":{\"version\":\"1.0\",\"kind\":\"praxis.ui-composition-plan\",\"layoutPreset\":\"master-detail-dashboard\",\"state\":{\"values\":{\"selectedDepartmentId\":null,\"selectedDepartmentName\":null}},\"widgets\":[{\"key\":\"department-master\",\"componentId\":\"praxis-list\",\"role\":\"master\",\"inputs\":{\"config\":{\"dataSource\":{\"resourcePath\":\"/api/human-resources/departamentos\"}}}},{\"key\":\"department-employees\",\"componentId\":\"praxis-table\",\"role\":\"detail\",\"inputs\":{\"resourcePath\":\"/api/human-resources/funcionarios\",\"tableId\":\"department-employees\"}},{\"key\":\"department-payroll\",\"componentId\":\"praxis-chart\",\"role\":\"detail\",\"inputs\":{\"config\":{\"chartId\":\"department-payroll\",\"resourcePath\":\"/api/human-resources/vw-analytics-folha-pagamento\"}}},{\"key\":\"department-summary\",\"componentId\":\"praxis-rich-content\",\"role\":\"detail\",\"inputs\":{\"document\":{\"kind\":\"praxis.rich-content.document\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"text\",\"text\":\"Selecione um departamento para revisar funcionarios, folha e observacoes.\"}]}}}],\"bindings\":[{\"id\":\"department-master.itemSelect->state.selectedDepartmentId\",\"from\":{\"kind\":\"component-port\",\"widget\":\"department-master\",\"port\":\"itemSelect\",\"direction\":\"output\"},\"to\":{\"kind\":\"state\",\"path\":\"selectedDepartmentId\"},\"intent\":\"state-write\",\"transform\":{\"kind\":\"pick-path\",\"id\":\"pick-department-id\",\"path\":\"payload.item.id\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"state\"]}},{\"id\":\"department-master.itemSelect->state.selectedDepartmentName\",\"from\":{\"kind\":\"component-port\",\"widget\":\"department-master\",\"port\":\"itemSelect\",\"direction\":\"output\"},\"to\":{\"kind\":\"state\",\"path\":\"selectedDepartmentName\"},\"intent\":\"state-write\",\"transform\":{\"kind\":\"pick-path\",\"id\":\"pick-department-name\",\"path\":\"payload.item.nome\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"state\"]}},{\"id\":\"department-master.itemSelect->global-action.department-selection-audit\",\"from\":{\"kind\":\"component-port\",\"widget\":\"department-master\",\"port\":\"itemSelect\",\"direction\":\"output\"},\"to\":{\"kind\":\"global-action\",\"actionId\":\"department.selection.audit\",\"payloadExpr\":\"payload.item\",\"meta\":{\"label\":\"Audit department selection\"}},\"intent\":\"command-dispatch\",\"policy\":{\"distinct\":true,\"distinctBy\":\"payload.item.id\",\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"global-action\"]}},{\"id\":\"state.selectedDepartmentId->department-employees.queryContext\",\"from\":{\"kind\":\"state\",\"path\":\"selectedDepartmentId\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-employees\",\"port\":\"queryContext\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!=\":[{\"var\":\"state.selectedDepartmentId\"},null]},\"transform\":{\"kind\":\"query-context\",\"id\":\"department-filter\",\"field\":\"departamentoId\"},\"policy\":{\"distinct\":true,\"distinctBy\":\"value\",\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"table-filter\"]}},{\"id\":\"state.selectedDepartmentId->department-payroll.queryContext\",\"from\":{\"kind\":\"state\",\"path\":\"selectedDepartmentId\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-payroll\",\"port\":\"queryContext\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!=\":[{\"var\":\"state.selectedDepartmentId\"},null]},\"transform\":{\"kind\":\"query-context\",\"id\":\"department-payroll-filter\",\"field\":\"departamentoId\"},\"policy\":{\"distinct\":true,\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"chart-filter\"]}},{\"id\":\"state.selectedDepartmentName->department-summary.document\",\"from\":{\"kind\":\"state\",\"path\":\"selectedDepartmentName\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-summary\",\"port\":\"document\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!!\":[{\"var\":\"state.selectedDepartmentName\"}]},\"transform\":{\"kind\":\"template\",\"id\":\"department-summary-document\",\"template\":{\"kind\":\"praxis.rich-content.document\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"text\",\"text\":{\"concat\":[\"Departamento selecionado: \",{\"var\":\"value\"}]}}]}},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"rich-content\"]}}]}},\"compiledOutput\":{\"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.\",\"forbiddenLegacyPaths\":[\"page.options\",\"page.widgets[].layout\",\"page.connections\",\"connections\"]}}",
3817
+ "content": "{\"_comment\":\"Contrato operacional para orientar LLM/backend a emitir UiCompositionPlan antes do WidgetPageDefinition final.\",\"templateMeta\":{\"registryKey\":\"praxis-page-builder\",\"variantId\":\"ui-composition-plan\",\"status\":\"golden-fixture\",\"useWhen\":\"Agentic page creation or modification needs multiple Praxis widgets, state and bindings before compiling the persisted page JSON.\",\"examplePrompts\":[\"Crie uma tela master detail de departamentos com funcionarios, folha e resumo\",\"Monte um dashboard com lista mestre, tabela detalhe, grafico e texto dinamico\"]},\"outputEnvelope\":{\"uiCompositionPlan\":{\"version\":\"1.0\",\"kind\":\"praxis.ui-composition-plan\",\"layoutPreset\":\"{{layoutPreset}}\",\"state\":{\"values\":{\"{{stateKey}}\":null}},\"widgets\":[{\"key\":\"{{stableWidgetKey}}\",\"componentId\":\"{{registeredComponentId}}\",\"role\":\"{{semanticRole}}\",\"bindingOrder\":[\"{{inputName}}\"],\"inputs\":{\"{{inputName}}\":\"{{canonicalInputValue}}\"}}],\"selectionSyncs\":[{\"id\":\"{{stableSelectionSyncId}}\",\"intent\":\"selection-sync\",\"sources\":[{\"kind\":\"component-port\",\"widget\":\"{{sourceWidgetKey}}\",\"port\":\"{{selectionOutputPort}}\",\"direction\":\"output\"}],\"target\":{\"kind\":\"state\",\"path\":\"{{selectionStatePath}}\",\"layer\":\"values\"},\"mapping\":{\"{{selectionField}}\":\"{{selectionPayloadPath}}\"}}],\"contextScopes\":[{\"id\":\"{{stableContextScopeId}}\",\"context\":{\"parentResourcePath\":{\"kind\":\"constant\",\"value\":\"{{parentResourcePath}}\"},\"parentResourceId\":{\"kind\":\"state\",\"path\":\"{{parentResourceIdStatePath}}\",\"layer\":\"values\"}},\"targets\":[{\"widget\":\"{{contextOwnerWidgetKey}}\",\"nestedPath\":[{\"kind\":\"{{containerSegmentKind}}\",\"id\":\"{{containerSegmentId}}\"},{\"kind\":\"widget\",\"key\":\"{{nestedWidgetKey}}\"}]}]}],\"bindings\":[{\"id\":\"{{stableBindingId}}\",\"from\":{\"kind\":\"component-port\",\"widget\":\"{{sourceWidgetKey}}\",\"port\":\"{{outputPort}}\",\"direction\":\"output\"},\"to\":{\"kind\":\"state\",\"path\":\"{{statePath}}\"},\"intent\":\"state-write\",\"transform\":{\"kind\":\"pick-path\",\"id\":\"{{transformId}}\",\"path\":\"{{payloadPath}}\"},\"metadata\":{\"source\":\"ui-composition-plan\"}}]},\"compiledFormPatch\":{\"version\":\"1.1\",\"patch\":{}}},\"validationRules\":[\"uiCompositionPlan.version deve ser 1.0.\",\"uiCompositionPlan.kind deve ser praxis.ui-composition-plan.\",\"widgets[].key deve ser estavel e unico.\",\"widgets[].componentId deve existir no catalogo de componentes registrado do Page Builder.\",\"bindings[].from/to com kind component-port devem referenciar widgets existentes no proprio plano.\",\"bindings[].from/to com kind state devem usar paths declarados ou justificaveis em state.values/state.derived.\",\"bindings[].to com kind global-action deve declarar actionId e compila para page.composition.links[].to.ref.[actionId].\",\"Use intent command-dispatch para bindings cujo destino e global-action.\",\"selectionSyncs[] reduz autoria repetitiva e sempre compila cada source/mapping em page.composition.links explicitos com intent selection-sync.\",\"contextScopes[] materializa constantes em inputs e estado em links state-read explicitos; nao existe heranca de contexto ambiente no runtime persistido.\",\"Use bindings como fonte declarativa. Nao emita connections legado nem page.composition.links concorrente no mesmo plano.\",\"Use pick-path para extrair payload/evento, query-context para filtros de recurso, template para gerar inputs estruturados e constant para valores fixos.\",\"Se API, metadata, surface, action, capability ou porta de componente nao estiver confirmada, retorne clarification/diagnostic em vez de alucinar o plano.\"],\"example\":{\"uiCompositionPlan\":{\"version\":\"1.0\",\"kind\":\"praxis.ui-composition-plan\",\"layoutPreset\":\"master-detail-dashboard\",\"state\":{\"values\":{\"selection\":{\"departmentId\":null,\"departmentName\":null}}},\"widgets\":[{\"key\":\"department-master\",\"componentId\":\"praxis-list\",\"role\":\"master\",\"inputs\":{\"config\":{\"dataSource\":{\"resourcePath\":\"/api/human-resources/departamentos\"}}}},{\"key\":\"department-employees\",\"componentId\":\"praxis-table\",\"role\":\"detail\",\"inputs\":{\"resourcePath\":\"/api/human-resources/funcionarios\",\"tableId\":\"department-employees\"}},{\"key\":\"department-payroll\",\"componentId\":\"praxis-chart\",\"role\":\"detail\",\"inputs\":{\"config\":{\"chartId\":\"department-payroll\",\"resourcePath\":\"/api/human-resources/vw-analytics-folha-pagamento\"}}},{\"key\":\"department-summary\",\"componentId\":\"praxis-rich-content\",\"role\":\"detail\",\"inputs\":{\"document\":{\"kind\":\"praxis.rich-content.document\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"text\",\"text\":\"Selecione um departamento para revisar funcionarios, folha e observacoes.\"}]}}}],\"selectionSyncs\":[{\"id\":\"department-selection\",\"intent\":\"selection-sync\",\"sources\":[{\"kind\":\"component-port\",\"widget\":\"department-master\",\"port\":\"itemSelect\",\"direction\":\"output\"}],\"target\":{\"kind\":\"state\",\"path\":\"selection\",\"layer\":\"values\"},\"mapping\":{\"departmentId\":\"payload.item.id\",\"departmentName\":\"payload.item.nome\"},\"policy\":{\"distinct\":true,\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"selection\"]}}],\"bindings\":[{\"id\":\"department-master.itemSelect->global-action.department-selection-audit\",\"from\":{\"kind\":\"component-port\",\"widget\":\"department-master\",\"port\":\"itemSelect\",\"direction\":\"output\"},\"to\":{\"kind\":\"global-action\",\"actionId\":\"department.selection.audit\",\"payloadExpr\":\"payload.item\",\"meta\":{\"label\":\"Audit department selection\"}},\"intent\":\"command-dispatch\",\"policy\":{\"distinct\":true,\"distinctBy\":\"payload.item.id\",\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"global-action\"]}},{\"id\":\"state.selection.departmentId->department-employees.queryContext\",\"from\":{\"kind\":\"state\",\"path\":\"selection.departmentId\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-employees\",\"port\":\"queryContext\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!=\":[{\"var\":\"state.selection.departmentId\"},null]},\"transform\":{\"kind\":\"query-context\",\"id\":\"department-filter\",\"field\":\"departamentoId\"},\"policy\":{\"distinct\":true,\"distinctBy\":\"value\",\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"table-filter\"]}},{\"id\":\"state.selection.departmentId->department-payroll.queryContext\",\"from\":{\"kind\":\"state\",\"path\":\"selection.departmentId\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-payroll\",\"port\":\"queryContext\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!=\":[{\"var\":\"state.selection.departmentId\"},null]},\"transform\":{\"kind\":\"query-context\",\"id\":\"department-payroll-filter\",\"field\":\"departamentoId\"},\"policy\":{\"distinct\":true,\"missingValuePolicy\":\"skip\"},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"chart-filter\"]}},{\"id\":\"state.selection.departmentName->department-summary.document\",\"from\":{\"kind\":\"state\",\"path\":\"selection.departmentName\"},\"to\":{\"kind\":\"component-port\",\"widget\":\"department-summary\",\"port\":\"document\",\"direction\":\"input\"},\"intent\":\"state-read\",\"condition\":{\"!!\":[{\"var\":\"state.selection.departmentName\"}]},\"transform\":{\"kind\":\"template\",\"id\":\"department-summary-document\",\"template\":{\"kind\":\"praxis.rich-content.document\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"text\",\"text\":{\"concat\":[\"Departamento selecionado: \",{\"var\":\"value\"}]}}]}},\"metadata\":{\"source\":\"ui-composition-plan\",\"tags\":[\"master-detail\",\"rich-content\"]}}]}},\"compiledOutput\":{\"summary\":\"O compilador expande selectionSyncs e bindings em WidgetPageDefinition com page.widgets[].definition.id, page.widgets[].definition.inputs e page.composition.links version 1.0.0. O JSON persistido nao deve conter o plano intermediario nem connections legado.\",\"forbiddenLegacyPaths\":[\"page.options\",\"page.widgets[].layout\",\"page.connections\",\"connections\"]}}",
3812
3818
  "sourcePointer": "examples/ai-recipes/praxis-page-builder.ui-composition-plan.json",
3813
- "contentHash": "2daf850e63ae2f581e944afd15eded19c4978a1824f7beb9a37fa6f8af7beae3",
3819
+ "contentHash": "30f2d6b6b0b8fd552d4079e7ce6caf68d0d2c47151a9f604f5573e4ed0396252",
3814
3820
  "sourceKind": "component_definition",
3815
3821
  "sourceId": "praxis-page-builder",
3816
3822
  "corpusVersion": "1.0.0"
@@ -7,7 +7,7 @@ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
7
7
  import * as i2$1 from '@angular/material/icon';
8
8
  import { MatIconModule } from '@angular/material/icon';
9
9
  import * as i2$2 from '@praxisui/core';
10
- import { PraxisIconDirective, BUILTIN_SHELL_PRESETS, PraxisIconButtonComponent, providePraxisI18n, PraxisI18nService, GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, PRAXIS_GLOBAL_ACTION_CATALOG, SurfaceOpenActionEditorComponent, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, SETTINGS_PANEL_DATA as SETTINGS_PANEL_DATA$1, deepMerge, generateId, ComponentMetadataRegistry, ObservabilityDashboardService, PraxisRuntimeComponentObservationRegistryService, domainKnowledgeTimelineToRichContentDocument, DomainRuleService, DomainKnowledgeService, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
10
+ import { PraxisIconDirective, BUILTIN_SHELL_PRESETS, PraxisIconButtonComponent, providePraxisI18n, PraxisI18nService, GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, PRAXIS_GLOBAL_ACTION_CATALOG, SurfaceOpenActionEditorComponent, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, SETTINGS_PANEL_DATA as SETTINGS_PANEL_DATA$1, NestedWidgetConfigAccessor, deepMerge, generateId, ComponentMetadataRegistry, ObservabilityDashboardService, PraxisRuntimeComponentObservationRegistryService, domainKnowledgeTimelineToRichContentDocument, DomainRuleService, DomainKnowledgeService, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
11
11
  import * as i3 from '@angular/material/tooltip';
12
12
  import { MatTooltipModule } from '@angular/material/tooltip';
13
13
  import * as i3$1 from '@angular/material/form-field';
@@ -13765,9 +13765,9 @@ const PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST = {
13765
13765
  target: { kind: 'agenticPreview', resolver: 'agentic-preview-result', ambiguityPolicy: 'fail', required: true },
13766
13766
  inputSchema: { type: 'object', required: ['uiCompositionPlan'], properties: { uiCompositionPlan: { type: 'object' } } },
13767
13767
  effects: [{ kind: 'compile-domain-patch', handler: 'page-builder-ui-composition-plan-compile', handlerContract: {
13768
- reads: ['UiCompositionPlan', 'compileUiCompositionPlan', 'PAGE_BUILDER_WIDGET_AI_CATALOGS', 'ComponentDocMeta.configEditor'],
13768
+ reads: ['UiCompositionPlan', 'UiCompositionPlan.selectionSyncs', 'UiCompositionPlan.contextScopes', 'compileUiCompositionPlan', 'PAGE_BUILDER_WIDGET_AI_CATALOGS', 'ComponentDocMeta.configEditor'],
13769
13769
  writes: ['compiledFormPatch.patch.page'],
13770
- identityKeys: ['uiCompositionPlan.id', 'widgetKey', 'uiCompositionPlan.bindings[].id'],
13770
+ identityKeys: ['uiCompositionPlan.id', 'widgetKey', 'uiCompositionPlan.bindings[].id', 'uiCompositionPlan.selectionSyncs[].id', 'uiCompositionPlan.contextScopes[].id'],
13771
13771
  failureModes: ['ui-composition-plan-invalid', 'widget-catalog-missing', 'compiled-page-invalid', 'child-config-editor-missing'],
13772
13772
  description: 'Compiles the agentic intermediate UiCompositionPlan into a renderable WidgetPageDefinition patch.page.',
13773
13773
  } }],
@@ -13904,6 +13904,8 @@ const PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST = {
13904
13904
  roundTripRequirements: [
13905
13905
  'WidgetPageDefinition is the canonical persisted runtime page shape for page-builder.',
13906
13906
  'UiCompositionPlan is an intermediate agentic plan and must compile before local preview/apply.',
13907
+ 'UiCompositionPlan.selectionSyncs is an authoring shorthand that compiles into explicit canonical page.composition.links and is never persisted in WidgetPageDefinition.',
13908
+ 'UiCompositionPlan.contextScopes compiles constant context into explicit widget inputs and state context into explicit page.composition.links; runtime inheritance is never ambient.',
13907
13909
  'Widget keys and composition link ids are stable identities; array indexes are never canonical identities.',
13908
13910
  'Persisted wiring uses page.composition.links and must not write legacy connections.',
13909
13911
  'Nested component ports use component-port refs with nestedPath ending in a stable widget key.',
@@ -14044,6 +14046,8 @@ function compileUiCompositionPlan(plan) {
14044
14046
  diagnostics,
14045
14047
  };
14046
14048
  }
14049
+ const bindings = expandedBindings(plan);
14050
+ const widgets = materializeContextScopeConstants(plan, plan.widgets.map((widget) => toWidgetInstance(widget, bindings)));
14047
14051
  return {
14048
14052
  valid: true,
14049
14053
  page: {
@@ -14055,10 +14059,10 @@ function compileUiCompositionPlan(plan) {
14055
14059
  slotAssignments: clone(plan.slotAssignments),
14056
14060
  state: clone(plan.state),
14057
14061
  themePreset: plan.themePreset,
14058
- widgets: plan.widgets.map((widget) => toWidgetInstance(widget, plan.bindings ?? [])),
14062
+ widgets,
14059
14063
  composition: {
14060
14064
  version: '1.0.0',
14061
- links: (plan.bindings ?? []).map(toCompositionLink),
14065
+ links: bindings.map(toCompositionLink),
14062
14066
  },
14063
14067
  },
14064
14068
  diagnostics: [],
@@ -14199,12 +14203,176 @@ function validateUiCompositionPlan(plan) {
14199
14203
  });
14200
14204
  }
14201
14205
  }
14206
+ for (const [index, selectionSync] of (plan.selectionSyncs ?? []).entries()) {
14207
+ validateSelectionSync(selectionSync, widgetKeys, diagnostics, `selectionSyncs.${index}`);
14208
+ }
14209
+ for (const [index, contextScope] of (plan.contextScopes ?? []).entries()) {
14210
+ validateContextScope(contextScope, plan, widgetKeys, diagnostics, `contextScopes.${index}`);
14211
+ }
14202
14212
  validateCanvas(plan.canvas, widgetKeys, diagnostics);
14203
14213
  validateGrouping(plan.grouping, widgetKeys, diagnostics);
14204
14214
  validateDeviceLayouts(plan.deviceLayouts, widgetKeys, diagnostics);
14205
14215
  validateSlotAssignments(plan.slotAssignments, widgetKeys, diagnostics);
14206
14216
  return diagnostics;
14207
14217
  }
14218
+ function validateSelectionSync(selectionSync, widgetKeys, diagnostics, path) {
14219
+ if (!selectionSync || typeof selectionSync !== 'object') {
14220
+ diagnostics.push({
14221
+ code: 'selection-sync-required',
14222
+ message: 'Selection sync must be an object.',
14223
+ path,
14224
+ });
14225
+ return;
14226
+ }
14227
+ if (!selectionSync.id?.trim()) {
14228
+ diagnostics.push({
14229
+ code: 'selection-sync-id-required',
14230
+ message: 'Every selection sync must declare a stable id.',
14231
+ path: `${path}.id`,
14232
+ });
14233
+ }
14234
+ if (selectionSync.intent !== 'selection-sync') {
14235
+ diagnostics.push({
14236
+ code: 'selection-sync-intent-invalid',
14237
+ message: 'Selection sync intent must be "selection-sync".',
14238
+ path: `${path}.intent`,
14239
+ });
14240
+ }
14241
+ if (!selectionSync.sources?.length) {
14242
+ diagnostics.push({
14243
+ code: 'selection-sync-source-required',
14244
+ message: 'Selection sync must declare at least one component output source.',
14245
+ path: `${path}.sources`,
14246
+ });
14247
+ }
14248
+ for (const [sourceIndex, source] of (selectionSync.sources ?? []).entries()) {
14249
+ validateEndpoint(source, widgetKeys, diagnostics, `${path}.sources.${sourceIndex}`, false);
14250
+ if (source?.kind === 'component-port' && source.direction !== 'output') {
14251
+ diagnostics.push({
14252
+ code: 'selection-sync-source-direction-invalid',
14253
+ message: 'Selection sync sources must be component output ports.',
14254
+ path: `${path}.sources.${sourceIndex}.direction`,
14255
+ });
14256
+ }
14257
+ }
14258
+ if (selectionSync.target?.kind !== 'state') {
14259
+ diagnostics.push({
14260
+ code: 'selection-sync-target-state-required',
14261
+ message: 'Selection sync target must be a page state endpoint.',
14262
+ path: `${path}.target.kind`,
14263
+ });
14264
+ }
14265
+ else {
14266
+ validateEndpoint(selectionSync.target, widgetKeys, diagnostics, `${path}.target`, false);
14267
+ }
14268
+ const mappings = Object.entries(selectionSync.mapping ?? {});
14269
+ if (!mappings.length) {
14270
+ diagnostics.push({
14271
+ code: 'selection-sync-mapping-required',
14272
+ message: 'Selection sync must declare at least one state mapping.',
14273
+ path: `${path}.mapping`,
14274
+ });
14275
+ }
14276
+ for (const [targetKey, mapping] of mappings) {
14277
+ if (!targetKey.trim()) {
14278
+ diagnostics.push({
14279
+ code: 'selection-sync-target-key-required',
14280
+ message: 'Selection sync mapping keys must be non-empty.',
14281
+ path: `${path}.mapping`,
14282
+ });
14283
+ }
14284
+ const sourcePath = typeof mapping === 'string' ? mapping : mapping?.path;
14285
+ if (!sourcePath?.trim()) {
14286
+ diagnostics.push({
14287
+ code: 'selection-sync-source-path-required',
14288
+ message: `Selection sync mapping "${targetKey}" must declare a source path.`,
14289
+ path: `${path}.mapping.${targetKey}`,
14290
+ });
14291
+ }
14292
+ }
14293
+ }
14294
+ function validateContextScope(contextScope, plan, widgetKeys, diagnostics, path) {
14295
+ if (!contextScope || typeof contextScope !== 'object') {
14296
+ diagnostics.push({ code: 'context-scope-required', message: 'Context scope must be an object.', path });
14297
+ return;
14298
+ }
14299
+ if (!contextScope.id?.trim()) {
14300
+ diagnostics.push({
14301
+ code: 'context-scope-id-required',
14302
+ message: 'Every context scope must declare a stable id.',
14303
+ path: `${path}.id`,
14304
+ });
14305
+ }
14306
+ const contextEntries = Object.entries(contextScope.context ?? {});
14307
+ if (!contextEntries.length) {
14308
+ diagnostics.push({
14309
+ code: 'context-scope-context-required',
14310
+ message: 'Context scope must declare at least one context value.',
14311
+ path: `${path}.context`,
14312
+ });
14313
+ }
14314
+ for (const [contextKey, contextValue] of contextEntries) {
14315
+ if (!contextKey.trim()) {
14316
+ diagnostics.push({
14317
+ code: 'context-scope-key-required',
14318
+ message: 'Context scope keys must be non-empty.',
14319
+ path: `${path}.context`,
14320
+ });
14321
+ }
14322
+ if (contextValue?.kind === 'state' && !contextValue.path?.trim()) {
14323
+ diagnostics.push({
14324
+ code: 'context-scope-state-path-required',
14325
+ message: `Context value "${contextKey}" must declare a state path.`,
14326
+ path: `${path}.context.${contextKey}.path`,
14327
+ });
14328
+ }
14329
+ else if (contextValue?.kind !== 'state' && contextValue?.kind !== 'constant') {
14330
+ diagnostics.push({
14331
+ code: 'context-scope-value-kind-invalid',
14332
+ message: `Context value "${contextKey}" must be constant or state.`,
14333
+ path: `${path}.context.${contextKey}.kind`,
14334
+ });
14335
+ }
14336
+ }
14337
+ if (!contextScope.targets?.length) {
14338
+ diagnostics.push({
14339
+ code: 'context-scope-target-required',
14340
+ message: 'Context scope must declare at least one component target.',
14341
+ path: `${path}.targets`,
14342
+ });
14343
+ }
14344
+ const accessor = new NestedWidgetConfigAccessor();
14345
+ const owners = new Map((plan.widgets ?? []).map((widget) => [widget.key, toWidgetInstance(widget, [])]));
14346
+ for (const [targetIndex, target] of (contextScope.targets ?? []).entries()) {
14347
+ const targetPath = `${path}.targets.${targetIndex}`;
14348
+ if (!widgetKeys.has(target.widget)) {
14349
+ diagnostics.push({
14350
+ code: 'context-scope-target-widget-not-found',
14351
+ message: `Context scope target references unknown widget "${target.widget}".`,
14352
+ path: `${targetPath}.widget`,
14353
+ });
14354
+ continue;
14355
+ }
14356
+ validateNestedPath(target.nestedPath, diagnostics, `${targetPath}.nestedPath`);
14357
+ const owner = owners.get(target.widget);
14358
+ if (target.nestedPath?.length && owner && !accessor.resolveNestedWidget(owner, target.nestedPath)) {
14359
+ diagnostics.push({
14360
+ code: 'context-scope-nested-target-not-found',
14361
+ message: `Context scope target does not resolve inside widget "${target.widget}".`,
14362
+ path: `${targetPath}.nestedPath`,
14363
+ });
14364
+ }
14365
+ for (const inheritedKey of target.inherit ?? []) {
14366
+ if (!Object.prototype.hasOwnProperty.call(contextScope.context ?? {}, inheritedKey)) {
14367
+ diagnostics.push({
14368
+ code: 'context-scope-inherited-key-not-found',
14369
+ message: `Context scope target inherits unknown key "${inheritedKey}".`,
14370
+ path: `${targetPath}.inherit`,
14371
+ });
14372
+ }
14373
+ }
14374
+ }
14375
+ }
14208
14376
  function validateCanvas(canvas, widgetKeys, diagnostics) {
14209
14377
  if (!canvas)
14210
14378
  return;
@@ -14401,6 +14569,111 @@ function validateNestedPath(nestedPath, diagnostics, path) {
14401
14569
  });
14402
14570
  }
14403
14571
  }
14572
+ function expandedBindings(plan) {
14573
+ return [
14574
+ ...(plan.bindings ?? []).map((binding) => clone(binding)),
14575
+ ...(plan.selectionSyncs ?? []).flatMap(expandSelectionSync),
14576
+ ...(plan.contextScopes ?? []).flatMap(expandContextScopeBindings),
14577
+ ];
14578
+ }
14579
+ function expandSelectionSync(selectionSync) {
14580
+ const basePath = selectionSync.target.path.replace(/\.+$/, '');
14581
+ return selectionSync.sources.flatMap((source) => Object.entries(selectionSync.mapping).map(([targetKey, mapping]) => {
14582
+ const normalizedMapping = typeof mapping === 'string' ? { path: mapping } : mapping;
14583
+ const targetPath = basePath ? `${basePath}.${targetKey}` : targetKey;
14584
+ return {
14585
+ id: `${selectionSync.id}:${source.widget}.${source.port}->state.${targetPath}`,
14586
+ from: clone(source),
14587
+ to: {
14588
+ kind: 'state',
14589
+ path: targetPath,
14590
+ layer: selectionSync.target.layer,
14591
+ },
14592
+ intent: 'selection-sync',
14593
+ condition: clone(normalizedMapping.condition),
14594
+ transform: {
14595
+ kind: 'pick-path',
14596
+ id: `${selectionSync.id}:${source.widget}.${source.port}:pick-${targetKey}`,
14597
+ path: normalizedMapping.path,
14598
+ inputSource: normalizedMapping.inputSource,
14599
+ },
14600
+ policy: clone(selectionSync.policy),
14601
+ metadata: clone(selectionSync.metadata),
14602
+ };
14603
+ }));
14604
+ }
14605
+ function expandContextScopeBindings(contextScope) {
14606
+ return contextScope.targets.flatMap((target) => {
14607
+ const inheritedKeys = target.inherit?.length
14608
+ ? target.inherit
14609
+ : Object.keys(contextScope.context);
14610
+ return inheritedKeys.flatMap((contextKey) => {
14611
+ const contextValue = contextScope.context[contextKey];
14612
+ if (!contextValue || contextValue.kind !== 'state') {
14613
+ return [];
14614
+ }
14615
+ return [{
14616
+ id: `${contextScope.id}:state.${contextValue.path}->${target.widget}.${contextKey}${nestedTargetIdentity(target.nestedPath)}`,
14617
+ from: {
14618
+ kind: 'state',
14619
+ path: contextValue.path,
14620
+ layer: contextValue.layer,
14621
+ },
14622
+ to: {
14623
+ kind: 'component-port',
14624
+ widget: target.widget,
14625
+ port: contextKey,
14626
+ direction: 'input',
14627
+ ...(target.nestedPath?.length ? { nestedPath: clone(target.nestedPath) } : {}),
14628
+ },
14629
+ intent: 'state-read',
14630
+ condition: clone(contextValue.condition),
14631
+ policy: clone(contextScope.policy),
14632
+ metadata: clone(contextScope.metadata),
14633
+ }];
14634
+ });
14635
+ });
14636
+ }
14637
+ function materializeContextScopeConstants(plan, sourceWidgets) {
14638
+ const accessor = new NestedWidgetConfigAccessor();
14639
+ const widgets = sourceWidgets.map((widget) => clone(widget));
14640
+ for (const contextScope of plan.contextScopes ?? []) {
14641
+ for (const target of contextScope.targets) {
14642
+ const widgetIndex = widgets.findIndex((widget) => widget.key === target.widget);
14643
+ if (widgetIndex < 0)
14644
+ continue;
14645
+ const inheritedKeys = target.inherit?.length
14646
+ ? target.inherit
14647
+ : Object.keys(contextScope.context);
14648
+ for (const contextKey of inheritedKeys) {
14649
+ const contextValue = contextScope.context[contextKey];
14650
+ if (!contextValue || contextValue.kind !== 'constant')
14651
+ continue;
14652
+ if (target.nestedPath?.length) {
14653
+ const result = accessor.setNestedWidgetInput(widgets[widgetIndex], target.nestedPath, contextKey, contextValue.value);
14654
+ widgets[widgetIndex] = result.widget;
14655
+ }
14656
+ else {
14657
+ widgets[widgetIndex] = {
14658
+ ...widgets[widgetIndex],
14659
+ definition: {
14660
+ ...widgets[widgetIndex].definition,
14661
+ inputs: {
14662
+ ...(widgets[widgetIndex].definition.inputs ?? {}),
14663
+ [contextKey]: clone(contextValue.value),
14664
+ },
14665
+ },
14666
+ };
14667
+ }
14668
+ }
14669
+ }
14670
+ }
14671
+ return widgets;
14672
+ }
14673
+ function nestedTargetIdentity(nestedPath) {
14674
+ const child = nestedPath?.[nestedPath.length - 1];
14675
+ return child?.kind === 'widget' && child.key ? `#${child.key}` : '';
14676
+ }
14404
14677
  function toWidgetInstance(widget, bindings) {
14405
14678
  const outputs = linkedTopLevelOutputs(widget.key, widget.outputs, bindings);
14406
14679
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/page-builder",
3
- "version": "9.0.4-rc.48",
3
+ "version": "9.0.4-rc.49",
4
4
  "description": "Page and widget builder utilities for Praxis UI (grid, dynamic widgets, editors).",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -8,9 +8,9 @@
8
8
  "@angular/forms": "^21.0.0",
9
9
  "@angular/cdk": "^21.0.0",
10
10
  "@angular/material": "^21.0.0",
11
- "@praxisui/ai": "^9.0.4-rc.48",
12
- "@praxisui/core": "^9.0.4-rc.48",
13
- "@praxisui/settings-panel": "^9.0.4-rc.48",
11
+ "@praxisui/ai": "^9.0.4-rc.49",
12
+ "@praxisui/core": "^9.0.4-rc.49",
13
+ "@praxisui/settings-panel": "^9.0.4-rc.49",
14
14
  "rxjs": "~7.8.0"
15
15
  },
16
16
  "dependencies": {
@@ -1548,6 +1548,51 @@ interface UiCompositionPlanBinding {
1548
1548
  policy?: CompositionLink['policy'];
1549
1549
  metadata?: Record<string, unknown>;
1550
1550
  }
1551
+ type UiCompositionPlanSelectionSyncMapping = string | {
1552
+ path: string;
1553
+ inputSource?: UiCompositionPlanInputSource;
1554
+ condition?: unknown;
1555
+ };
1556
+ /**
1557
+ * Semantic authoring shorthand for projecting the same selection emitted by one
1558
+ * or more component outputs into page state. The compiler expands this shape
1559
+ * into explicit canonical composition links before preview or persistence.
1560
+ */
1561
+ interface UiCompositionPlanSelectionSync {
1562
+ id: string;
1563
+ intent: 'selection-sync';
1564
+ sources: UiCompositionPlanComponentPortEndpoint[];
1565
+ target: UiCompositionPlanStateEndpoint;
1566
+ mapping: Record<string, UiCompositionPlanSelectionSyncMapping>;
1567
+ policy?: CompositionLink['policy'];
1568
+ metadata?: Record<string, unknown>;
1569
+ }
1570
+ type UiCompositionPlanContextValue = {
1571
+ kind: 'constant';
1572
+ value: unknown;
1573
+ } | {
1574
+ kind: 'state';
1575
+ path: string;
1576
+ layer?: 'values' | 'derived' | 'transient';
1577
+ condition?: unknown;
1578
+ };
1579
+ interface UiCompositionPlanContextScopeTarget {
1580
+ widget: string;
1581
+ nestedPath?: ComponentPortPathSegment[];
1582
+ inherit?: string[];
1583
+ }
1584
+ /**
1585
+ * Groups reusable parent/resource context for one or more component targets.
1586
+ * Constants become explicit widget inputs and state values become explicit
1587
+ * canonical links during compilation; no hidden runtime inheritance remains.
1588
+ */
1589
+ interface UiCompositionPlanContextScope {
1590
+ id: string;
1591
+ context: Record<string, UiCompositionPlanContextValue>;
1592
+ targets: UiCompositionPlanContextScopeTarget[];
1593
+ policy?: CompositionLink['policy'];
1594
+ metadata?: Record<string, unknown>;
1595
+ }
1551
1596
  interface UiCompositionPlan {
1552
1597
  version: '1.0';
1553
1598
  kind: 'praxis.ui-composition-plan';
@@ -1560,6 +1605,8 @@ interface UiCompositionPlan {
1560
1605
  state?: WidgetPageStateInput;
1561
1606
  themePreset?: string;
1562
1607
  widgets: UiCompositionPlanWidget[];
1608
+ selectionSyncs?: UiCompositionPlanSelectionSync[];
1609
+ contextScopes?: UiCompositionPlanContextScope[];
1563
1610
  bindings?: UiCompositionPlanBinding[];
1564
1611
  }
1565
1612
  interface UiCompositionPlanDiagnostic {
@@ -2087,4 +2134,4 @@ declare const PRAXIS_PAGE_BUILDER_COMPONENT_METADATA: ComponentDocMeta;
2087
2134
  declare function providePraxisPageBuilderMetadata(): Provider;
2088
2135
 
2089
2136
  export { ComponentPaletteDialogComponent, ConfirmDialogComponent, ConnectionEditorComponent, DynamicPageBuilderComponent, DynamicPageConfigEditorComponent, FloatingToolbarComponent, PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS, PAGE_BUILDER_AI_CAPABILITIES, PAGE_BUILDER_COMPONENT_CONTEXT_PACK, PAGE_BUILDER_WIDGET_AI_CATALOGS, PLACEHOLDER, PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST, PRAXIS_PAGE_BUILDER_COMPONENT_METADATA, PageBuilderAgenticAuthoringService, PageConfigEditorComponent, TileToolbarComponent, WidgetShellEditorComponent, clearWidgetAiCatalogs, compileUiCompositionPlan, getPageAiCatalog, getWidgetAiCapabilities, providePageBuilderWidgetAiCatalogs, providePraxisPageBuilderMetadata, registerWidgetAiCatalog, registerWidgetAiCatalogs, validateUiCompositionPlan };
2090
- export type { Capability, CapabilityCatalog, CapabilityCategory, ComponentPaletteData, ComponentPaletteSelection, ConfirmDialogData, PageBuilderAgenticAuthoringAttachmentSummary, PageBuilderAgenticAuthoringCandidate, PageBuilderAgenticAuthoringComponentCapabilitiesResult, PageBuilderAgenticAuthoringComponentCapability, PageBuilderAgenticAuthoringComponentCapabilityCatalog, PageBuilderAgenticAuthoringComponentCapabilityExample, PageBuilderAgenticAuthoringComponentFieldAlias, PageBuilderAgenticAuthoringConversationMessage, PageBuilderAgenticAuthoringGateResult, PageBuilderAgenticAuthoringIntentResolutionRequest, PageBuilderAgenticAuthoringIntentResolutionResult, PageBuilderAgenticAuthoringOptions, PageBuilderAgenticAuthoringPendingClarification, PageBuilderAgenticAuthoringPromptRequest, PageBuilderAgenticAuthoringProvider, PageBuilderAgenticAuthoringQuickReply, PageBuilderAgenticAuthoringResourceCandidatesRequest, PageBuilderAgenticAuthoringResourceCandidatesResult, PageBuilderAgenticAuthoringSharedRuleHandoff, PageBuilderAgenticAuthoringTarget, PageBuilderAgenticAuthoringTurnStreamConnectionError, PageBuilderAgenticAuthoringTurnStreamEvent, PageBuilderAgenticAuthoringTurnStreamRequest, PageBuilderAgenticAuthoringTurnStreamStartResponse, PageBuilderApplyRequest, PageBuilderApplyResult, PageBuilderCompiledFormPatch, PageBuilderMinimalFormPlanResult, PageBuilderPreviewDiagnostics, PageBuilderPreviewResult, PageBuilderProjectKnowledgeAudit, UiCompositionPlan, UiCompositionPlanBinding, UiCompositionPlanCompileResult, UiCompositionPlanComponentPortEndpoint, UiCompositionPlanDiagnostic, UiCompositionPlanEndpoint, UiCompositionPlanGlobalActionEndpoint, UiCompositionPlanInputSource, UiCompositionPlanSourceEndpoint, UiCompositionPlanStateEndpoint, UiCompositionPlanTargetEndpoint, UiCompositionPlanTransform, UiCompositionPlanWidget, ValueKind };
2137
+ export type { Capability, CapabilityCatalog, CapabilityCategory, ComponentPaletteData, ComponentPaletteSelection, ConfirmDialogData, PageBuilderAgenticAuthoringAttachmentSummary, PageBuilderAgenticAuthoringCandidate, PageBuilderAgenticAuthoringComponentCapabilitiesResult, PageBuilderAgenticAuthoringComponentCapability, PageBuilderAgenticAuthoringComponentCapabilityCatalog, PageBuilderAgenticAuthoringComponentCapabilityExample, PageBuilderAgenticAuthoringComponentFieldAlias, PageBuilderAgenticAuthoringConversationMessage, PageBuilderAgenticAuthoringGateResult, PageBuilderAgenticAuthoringIntentResolutionRequest, PageBuilderAgenticAuthoringIntentResolutionResult, PageBuilderAgenticAuthoringOptions, PageBuilderAgenticAuthoringPendingClarification, PageBuilderAgenticAuthoringPromptRequest, PageBuilderAgenticAuthoringProvider, PageBuilderAgenticAuthoringQuickReply, PageBuilderAgenticAuthoringResourceCandidatesRequest, PageBuilderAgenticAuthoringResourceCandidatesResult, PageBuilderAgenticAuthoringSharedRuleHandoff, PageBuilderAgenticAuthoringTarget, PageBuilderAgenticAuthoringTurnStreamConnectionError, PageBuilderAgenticAuthoringTurnStreamEvent, PageBuilderAgenticAuthoringTurnStreamRequest, PageBuilderAgenticAuthoringTurnStreamStartResponse, PageBuilderApplyRequest, PageBuilderApplyResult, PageBuilderCompiledFormPatch, PageBuilderMinimalFormPlanResult, PageBuilderPreviewDiagnostics, PageBuilderPreviewResult, PageBuilderProjectKnowledgeAudit, UiCompositionPlan, UiCompositionPlanBinding, UiCompositionPlanCompileResult, UiCompositionPlanComponentPortEndpoint, UiCompositionPlanContextScope, UiCompositionPlanContextScopeTarget, UiCompositionPlanContextValue, UiCompositionPlanDiagnostic, UiCompositionPlanEndpoint, UiCompositionPlanGlobalActionEndpoint, UiCompositionPlanInputSource, UiCompositionPlanSelectionSync, UiCompositionPlanSelectionSyncMapping, UiCompositionPlanSourceEndpoint, UiCompositionPlanStateEndpoint, UiCompositionPlanTargetEndpoint, UiCompositionPlanTransform, UiCompositionPlanWidget, ValueKind };