@bolloon/bolloon-agent 0.4.14 → 0.4.16

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.
Files changed (213) hide show
  1. package/README.md +127 -127
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon-daemon.sh +207 -0
  4. package/bin/bolloon.cjs +0 -0
  5. package/dist/agents/constraint-layer.js +19 -19
  6. package/dist/agents/judgment-protocol.js +14 -14
  7. package/dist/agents/pi-sdk-types.js +12 -12
  8. package/dist/agents/pi-sdk.js +101 -101
  9. package/dist/agents/skill-organizer.js +19 -19
  10. package/dist/agents/workflow-pivot-loop.js +2 -2
  11. package/dist/agents/x402/x402Pay.js +4 -0
  12. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  13. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  14. package/dist/bollharness-integration/context-router.js +292 -292
  15. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  16. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  17. package/dist/bollharness-integration/skill-adapter.js +21 -21
  18. package/dist/bootstrap/chat-archiver.js +14 -14
  19. package/dist/bootstrap/context-os.js +24 -24
  20. package/dist/bootstrap/memory-compressor.js +13 -13
  21. package/dist/cli-entry.js +36 -36
  22. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +63 -0
  23. package/dist/constraint-runtime/reference_data/commands_snapshot.json +1037 -0
  24. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +8 -0
  25. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +8 -0
  26. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +32 -0
  27. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +13 -0
  28. package/dist/constraint-runtime/reference_data/subsystems/cli.json +26 -0
  29. package/dist/constraint-runtime/reference_data/subsystems/components.json +32 -0
  30. package/dist/constraint-runtime/reference_data/subsystems/constants.json +28 -0
  31. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +8 -0
  32. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +15 -0
  33. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +32 -0
  34. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +21 -0
  35. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +15 -0
  36. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +18 -0
  37. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +8 -0
  38. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +11 -0
  39. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +8 -0
  40. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +9 -0
  41. package/dist/constraint-runtime/reference_data/subsystems/remote.json +11 -0
  42. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +8 -0
  43. package/dist/constraint-runtime/reference_data/subsystems/screens.json +10 -0
  44. package/dist/constraint-runtime/reference_data/subsystems/server.json +10 -0
  45. package/dist/constraint-runtime/reference_data/subsystems/services.json +32 -0
  46. package/dist/constraint-runtime/reference_data/subsystems/skills.json +27 -0
  47. package/dist/constraint-runtime/reference_data/subsystems/state.json +13 -0
  48. package/dist/constraint-runtime/reference_data/subsystems/types.json +18 -0
  49. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +9 -0
  50. package/dist/constraint-runtime/reference_data/subsystems/utils.json +32 -0
  51. package/dist/constraint-runtime/reference_data/subsystems/vim.json +12 -0
  52. package/dist/constraint-runtime/reference_data/subsystems/voice.json +8 -0
  53. package/dist/constraint-runtime/reference_data/tools_snapshot.json +922 -0
  54. package/dist/context-compaction/auto-compact.js +7 -7
  55. package/dist/electron/config.js.map +1 -0
  56. package/dist/electron/dialogs.js.map +1 -0
  57. package/dist/electron/first-run.js +54 -54
  58. package/dist/electron/first-run.js.map +1 -0
  59. package/dist/electron/ipc.js.map +1 -0
  60. package/dist/electron/logger.js.map +1 -0
  61. package/dist/electron/main.js.map +1 -0
  62. package/dist/electron/menu.js.map +1 -0
  63. package/dist/electron/paths.js.map +1 -0
  64. package/dist/electron/server.js.map +1 -0
  65. package/dist/electron/tray.js.map +1 -0
  66. package/dist/electron/window.js.map +1 -0
  67. package/dist/electron-build/electron/first-run.js +54 -54
  68. package/dist/electron-preload.js.map +1 -1
  69. package/dist/electron.js.map +1 -1
  70. package/dist/index.js +112 -112
  71. package/dist/llm/llm-judgment-client.js +102 -102
  72. package/dist/llm/pi-ai.js +48 -48
  73. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  74. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  75. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  76. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  77. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  78. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  79. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  80. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  81. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  82. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  83. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  84. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  85. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  86. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  87. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  88. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  89. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  90. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  91. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  92. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  93. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  94. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  95. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  96. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  97. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  98. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  99. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  100. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  101. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  102. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  103. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  104. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  105. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  106. package/dist/llm/tool-manifest/bash.js +3 -3
  107. package/dist/llm/tool-manifest/create_file.js +4 -4
  108. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  109. package/dist/llm/tool-manifest/image_search.js +2 -2
  110. package/dist/llm/tool-manifest/index.js +59 -0
  111. package/dist/llm/tool-manifest/mcp.js +2 -2
  112. package/dist/llm/tool-manifest/message_compose.js +3 -3
  113. package/dist/llm/tool-manifest/places.js +2 -2
  114. package/dist/llm/tool-manifest/present_files.js +1 -1
  115. package/dist/llm/tool-manifest/recipe.js +2 -2
  116. package/dist/llm/tool-manifest/str_replace.js +5 -5
  117. package/dist/llm/tool-manifest/view.js +3 -3
  118. package/dist/llm/tool-manifest/weather.js +4 -4
  119. package/dist/llm/tool-manifest/web.js +4 -4
  120. package/dist/network/p2p.js +78 -4
  121. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  122. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  123. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  124. package/dist/pi-ecosystem-judgment/index.js +1 -1
  125. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  126. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  127. package/dist/security/context-router-tool.js +15 -15
  128. package/dist/utils/auto-update.js.map +1 -0
  129. package/dist/web/a2ui-client.js +1594 -223
  130. package/dist/web/api-config.html +779 -779
  131. package/dist/web/client-hearth.js +10 -10
  132. package/dist/web/client.js.map +7 -0
  133. package/dist/web/components/wallet-viem.mjs +118 -118
  134. package/dist/web/index.html +502 -502
  135. package/dist/web/manifest.json +20 -20
  136. package/dist/web/mobile-agent.js +397 -0
  137. package/dist/web/mobile-core.js +86235 -0
  138. package/dist/web/mobile-data.js +346 -0
  139. package/dist/web/mobile-http-api.js +71 -0
  140. package/dist/web/mobile-p2p.js +250 -0
  141. package/dist/web/mobile-payments.js +80 -0
  142. package/dist/web/mobile-wallet.js +226 -0
  143. package/dist/web/mobile.css +483 -6
  144. package/dist/web/mobile.html +99 -50
  145. package/dist/web/mobile.js +1040 -187
  146. package/dist/web/server.js +13 -13
  147. package/dist/web/style.css +4946 -4946
  148. package/package.json +186 -198
  149. package/scripts/build-cli.js +215 -215
  150. package/scripts/build-web.ts +162 -149
  151. package/scripts/postinstall.js +152 -152
  152. package/bin/bolloon.js +0 -157
  153. package/dist/agents/python-exec.js +0 -115
  154. package/dist/pi-ecosystem-colony/index.js +0 -365
  155. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  156. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  157. package/dist/social/ant-colony/index.js +0 -6
  158. package/dist/social/ant-colony/types.js +0 -24
  159. package/dist/storage/trajectory.js +0 -101
  160. package/dist/test/ai-judgment-test.js +0 -80
  161. package/dist/test/bollharness-integration.test.js +0 -318
  162. package/dist/test/channel-agent-multi-dialogue.js +0 -205
  163. package/dist/test/channel-heartbeat-agent-test.js +0 -201
  164. package/dist/test/constraint-layer.test.js +0 -164
  165. package/dist/test/diap-identity-test.js +0 -172
  166. package/dist/test/diap-quick-test.js +0 -62
  167. package/dist/test/global-shared-context.test.js +0 -315
  168. package/dist/test/harness-judgment-injection.test.js +0 -246
  169. package/dist/test/harness-workflow-integrator-test.js +0 -228
  170. package/dist/test/human-value-store.test.js +0 -243
  171. package/dist/test/hybrid-integration-test.js +0 -118
  172. package/dist/test/hybrid-messenger-verify.js +0 -55
  173. package/dist/test/iroh-bistream-debug.js +0 -38
  174. package/dist/test/iroh-communication.test.js +0 -66
  175. package/dist/test/iroh-debug-test.js +0 -57
  176. package/dist/test/iroh-diap-test.js +0 -71
  177. package/dist/test/iroh-direct-connect.js +0 -55
  178. package/dist/test/iroh-e2e-fixed.js +0 -89
  179. package/dist/test/iroh-e2e-same-process.js +0 -63
  180. package/dist/test/iroh-e2e.js +0 -66
  181. package/dist/test/iroh-final-e2e.js +0 -72
  182. package/dist/test/iroh-relay-test.js +0 -37
  183. package/dist/test/iroh-simple-test.js +0 -41
  184. package/dist/test/iroh-transport-verify.js +0 -54
  185. package/dist/test/iroh-transport.test.js +0 -37
  186. package/dist/test/iroh-two-nodes.js +0 -70
  187. package/dist/test/iroh-verify.js +0 -44
  188. package/dist/test/judgment-decision.test.js +0 -219
  189. package/dist/test/llm-judgment-integration.test.js +0 -220
  190. package/dist/test/p2p-agent-complex-dialogue.js +0 -385
  191. package/dist/test/p2p-agent-dialogue.js +0 -341
  192. package/dist/test/p2p-agent-full-bidirectional.js +0 -510
  193. package/dist/test/p2p-agent-harness-flow.js +0 -437
  194. package/dist/test/p2p-agent-harness-single.js +0 -143
  195. package/dist/test/p2p-ai-dialogue-test.js +0 -318
  196. package/dist/test/p2p-cid-connect-test.js +0 -195
  197. package/dist/test/p2p-connect-receiver.js +0 -69
  198. package/dist/test/p2p-doc-transfer.js +0 -110
  199. package/dist/test/p2p-identity-page-test.js +0 -77
  200. package/dist/test/p2p-iroh-test.js +0 -171
  201. package/dist/test/p2p-minimal-test.js +0 -241
  202. package/dist/test/p2p-node-1.js +0 -148
  203. package/dist/test/p2p-node-2.js +0 -148
  204. package/dist/test/p2p-server.js +0 -281
  205. package/dist/test/p2p-two-nodes-test.js +0 -438
  206. package/dist/test/pi-sdk.test.js +0 -44
  207. package/dist/test/set-persona.js +0 -40
  208. package/dist/test/simple.test.js +0 -9
  209. package/dist/test/storage-integration.test.js +0 -150
  210. package/dist/test/subagent-manager.test.js +0 -276
  211. package/dist/test/test-gate-flow.test.js +0 -81
  212. package/dist/test/workflow-engine.test.js +0 -87
  213. package/dist/test/workflow-pivot-loop.test.js +0 -246
@@ -4103,7 +4103,7 @@
4103
4103
  function is(x2, y2) {
4104
4104
  return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2;
4105
4105
  }
4106
- function shallowEqual(objA, objB) {
4106
+ function shallowEqual2(objA, objB) {
4107
4107
  if (objectIs(objA, objB)) return true;
4108
4108
  if ("object" !== typeof objA || null === objA || "object" !== typeof objB || null === objB)
4109
4109
  return false;
@@ -4171,7 +4171,7 @@
4171
4171
  anchorOffset: doc.anchorOffset,
4172
4172
  focusNode: doc.focusNode,
4173
4173
  focusOffset: doc.focusOffset
4174
- }), lastSelection && shallowEqual(lastSelection, doc) || (lastSelection = doc, doc = accumulateTwoPhaseListeners(activeElementInst, "onSelect"), 0 < doc.length && (nativeEvent = new SyntheticEvent(
4174
+ }), lastSelection && shallowEqual2(lastSelection, doc) || (lastSelection = doc, doc = accumulateTwoPhaseListeners(activeElementInst, "onSelect"), 0 < doc.length && (nativeEvent = new SyntheticEvent(
4175
4175
  "onSelect",
4176
4176
  "select",
4177
4177
  null,
@@ -8199,7 +8199,7 @@
8199
8199
  );
8200
8200
  return oldProps;
8201
8201
  }
8202
- return ctor.prototype && ctor.prototype.isPureReactComponent ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) : true;
8202
+ return ctor.prototype && ctor.prototype.isPureReactComponent ? !shallowEqual2(oldProps, newProps) || !shallowEqual2(oldState, newState) : true;
8203
8203
  }
8204
8204
  function callComponentWillReceiveProps(workInProgress2, instance, newProps, nextContext) {
8205
8205
  var oldState = instance.state;
@@ -8505,7 +8505,7 @@
8505
8505
  if (!checkScheduledUpdateOrContext(current2, renderLanes2)) {
8506
8506
  var prevProps = type.memoizedProps;
8507
8507
  Component = Component.compare;
8508
- Component = null !== Component ? Component : shallowEqual;
8508
+ Component = null !== Component ? Component : shallowEqual2;
8509
8509
  if (Component(prevProps, nextProps) && current2.ref === workInProgress2.ref)
8510
8510
  return bailoutOnAlreadyFinishedWork(
8511
8511
  current2,
@@ -8522,7 +8522,7 @@
8522
8522
  function updateSimpleMemoComponent(current2, workInProgress2, Component, nextProps, renderLanes2) {
8523
8523
  if (null !== current2) {
8524
8524
  var prevProps = current2.memoizedProps;
8525
- if (shallowEqual(prevProps, nextProps) && current2.ref === workInProgress2.ref && workInProgress2.type === current2.type)
8525
+ if (shallowEqual2(prevProps, nextProps) && current2.ref === workInProgress2.ref && workInProgress2.type === current2.type)
8526
8526
  if (didReceiveUpdate = false, workInProgress2.pendingProps = nextProps = prevProps, checkScheduledUpdateOrContext(current2, renderLanes2))
8527
8527
  0 !== (current2.flags & 131072) && (didReceiveUpdate = true);
8528
8528
  else
@@ -25808,6 +25808,365 @@
25808
25808
  }
25809
25809
  };
25810
25810
 
25811
+ // node_modules/@a2ui/web_core/src/v0_9/schema/common-types.js
25812
+ var DataBindingSchema = external_exports.object({
25813
+ "path": external_exports.string().describe("A JSON Pointer path to a value in the data model.")
25814
+ }).describe("REF:common_types.json#/$defs/DataBinding|A JSON Pointer path to a value in the data model.");
25815
+ var FunctionCallSchema = external_exports.object({
25816
+ "call": external_exports.string().describe("The name of the function to call."),
25817
+ "args": external_exports.record(external_exports.any()).describe("Arguments passed to the function."),
25818
+ "returnType": external_exports.enum(["string", "number", "boolean", "array", "object", "any", "void"]).default("boolean")
25819
+ }).describe("REF:common_types.json#/$defs/FunctionCall|Invokes a named function on the client.");
25820
+ var DynamicBooleanSchema = external_exports.union([external_exports.boolean(), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicBoolean|A boolean value that can be a literal, a path, or a function call returning a boolean.");
25821
+ var DynamicStringSchema = external_exports.union([
25822
+ external_exports.string(),
25823
+ DataBindingSchema,
25824
+ // FunctionCall returning string (simplified schema for Zod, stricter in JSON Schema)
25825
+ FunctionCallSchema
25826
+ ]).describe("REF:common_types.json#/$defs/DynamicString|Represents a string");
25827
+ var DynamicNumberSchema = external_exports.union([external_exports.number(), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicNumber|Represents a value that can be either a literal number, a path to a number in the data model, or a function call returning a number.");
25828
+ var DynamicStringListSchema = external_exports.union([external_exports.array(external_exports.string()), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicStringList|Represents a value that can be either a literal array of strings, a path to a string array in the data model, or a function call returning a string array.");
25829
+ var DynamicValueSchema = external_exports.union([
25830
+ external_exports.string(),
25831
+ external_exports.number(),
25832
+ external_exports.boolean(),
25833
+ external_exports.array(external_exports.any()),
25834
+ DataBindingSchema,
25835
+ FunctionCallSchema
25836
+ ]).describe("REF:common_types.json#/$defs/DynamicValue|A value that can be a literal, a path, or a function call returning any type.");
25837
+ var ComponentIdSchema = markChildRef(external_exports.string().describe("REF:common_types.json#/$defs/ComponentId|The unique identifier for a component."), "component-id");
25838
+ function markChildRef(schema, ref) {
25839
+ schema._def.a2uiChildRef = ref;
25840
+ return schema;
25841
+ }
25842
+ function childRefKindOf(schema) {
25843
+ return schema._def.a2uiChildRef;
25844
+ }
25845
+ function componentId(options = {}) {
25846
+ if (options.description === void 0) {
25847
+ return ComponentIdSchema;
25848
+ }
25849
+ return ComponentIdSchema.describe(`REF:common_types.json#/$defs/ComponentId|${options.description}`);
25850
+ }
25851
+ function childList(options = {}) {
25852
+ if (options.description === void 0) {
25853
+ return ChildListSchema;
25854
+ }
25855
+ return ChildListSchema.describe(`REF:common_types.json#/$defs/ChildList|${options.description}`);
25856
+ }
25857
+ var ChildListSchema = markChildRef(external_exports.union([
25858
+ external_exports.array(ComponentIdSchema).describe("A static list of child component IDs."),
25859
+ external_exports.object({
25860
+ "componentId": ComponentIdSchema,
25861
+ "path": external_exports.string().describe("The path to the list of component property objects in the data model.")
25862
+ }).describe("A template for generating a dynamic list of children.")
25863
+ ]).describe("REF:common_types.json#/$defs/ChildList"), "child-list");
25864
+ var ActionSchema = external_exports.union([
25865
+ external_exports.object({
25866
+ "event": external_exports.object({
25867
+ "name": external_exports.string(),
25868
+ "context": external_exports.record(DynamicValueSchema).optional()
25869
+ })
25870
+ }).describe("Triggers a server-side event."),
25871
+ external_exports.object({
25872
+ "functionCall": FunctionCallSchema
25873
+ }).describe("Executes a local client-side function.")
25874
+ ]).describe("REF:common_types.json#/$defs/Action");
25875
+ var CheckRuleSchema = external_exports.object({
25876
+ "condition": DynamicBooleanSchema,
25877
+ "message": external_exports.string().describe("The error message to display if the check fails.")
25878
+ }).describe("REF:common_types.json#/$defs/CheckRule|A check rule consisting of a condition and an error message.");
25879
+ var CheckableSchema = external_exports.object({
25880
+ "checks": external_exports.array(CheckRuleSchema).optional().describe("A list of checks to perform."),
25881
+ "isValid": external_exports.boolean().optional().describe("Whether the checks currently pass."),
25882
+ "validationErrors": external_exports.array(external_exports.string()).optional().describe("Current validation error messages.")
25883
+ }).describe("REF:common_types.json#/$defs/Checkable|Properties for components that support client-side checks.");
25884
+ var AccessibilityAttributesSchema = external_exports.object({
25885
+ "label": DynamicStringSchema.optional().describe("REF:common_types.json#/$defs/DynamicString|A short string used by assistive technologies to convey the purpose of an element."),
25886
+ "description": DynamicStringSchema.optional().describe("REF:common_types.json#/$defs/DynamicString|Additional information provided by assistive technologies about an element.")
25887
+ }).describe("REF:common_types.json#/$defs/AccessibilityAttributes|Attributes to enhance accessibility.");
25888
+ var AnyComponentSchema = external_exports.object({
25889
+ "component": external_exports.string().describe("The type name of the component."),
25890
+ "id": ComponentIdSchema.optional(),
25891
+ "weight": external_exports.number().optional()
25892
+ }).passthrough().describe("A generic A2UI component definition.");
25893
+
25894
+ // node_modules/@a2ui/web_core/src/v0_9/catalog/schema_loader.js
25895
+ var COMMON_TYPE_SCHEMAS = {
25896
+ DynamicString: DynamicStringSchema,
25897
+ DynamicNumber: DynamicNumberSchema,
25898
+ DynamicBoolean: DynamicBooleanSchema,
25899
+ DynamicStringList: DynamicStringListSchema,
25900
+ DynamicValue: DynamicValueSchema,
25901
+ ComponentId: ComponentIdSchema,
25902
+ ChildList: ChildListSchema,
25903
+ Action: ActionSchema,
25904
+ CheckRule: CheckRuleSchema,
25905
+ Checkable: CheckableSchema,
25906
+ AccessibilityAttributes: AccessibilityAttributesSchema
25907
+ };
25908
+ function resolveJsonPointer(rootDoc, pointer) {
25909
+ if (!pointer.startsWith("#/"))
25910
+ return void 0;
25911
+ const segments = pointer.slice(2).split("/").map((s2) => s2.replace(/~1/g, "/").replace(/~0/g, "~"));
25912
+ let curr = rootDoc;
25913
+ for (const seg of segments) {
25914
+ if (curr && typeof curr === "object" && seg in curr) {
25915
+ curr = curr[seg];
25916
+ } else {
25917
+ return void 0;
25918
+ }
25919
+ }
25920
+ return typeof curr === "object" && curr !== null ? curr : void 0;
25921
+ }
25922
+ function resolveProtocolRef(ref) {
25923
+ const defName = ref.split(/#\/(?:\$defs|definitions)\//)[1];
25924
+ return defName ? COMMON_TYPE_SCHEMAS[defName] : void 0;
25925
+ }
25926
+ function convertEnumToZod(values) {
25927
+ if (values.length === 0) {
25928
+ return external_exports.unknown();
25929
+ }
25930
+ if (values.every((v2) => typeof v2 === "string")) {
25931
+ return external_exports.enum(values);
25932
+ }
25933
+ if (values.length === 1) {
25934
+ return external_exports.literal(values[0]);
25935
+ }
25936
+ return external_exports.union(values.map((v2) => external_exports.literal(v2)));
25937
+ }
25938
+ function convertPropertyToZod(propSchema, rootDoc, visitedPointers = /* @__PURE__ */ new Set()) {
25939
+ if (!propSchema || typeof propSchema !== "object") {
25940
+ return external_exports.unknown();
25941
+ }
25942
+ if (propSchema.$ref && typeof propSchema.$ref === "string") {
25943
+ const ref = propSchema.$ref;
25944
+ const resolvedProtocol = resolveProtocolRef(ref);
25945
+ if (resolvedProtocol) {
25946
+ const defName = ref.split(/#\/(?:\$defs|definitions)\//)[1];
25947
+ const desc = propSchema.description ? `REF:common_types.json#/$defs/${defName}|${propSchema.description}` : resolvedProtocol.description;
25948
+ return desc ? resolvedProtocol.describe(desc) : resolvedProtocol;
25949
+ }
25950
+ if (rootDoc && ref.startsWith("#/") && !visitedPointers.has(ref)) {
25951
+ visitedPointers.add(ref);
25952
+ const localTarget = resolveJsonPointer(rootDoc, ref);
25953
+ if (localTarget) {
25954
+ let zodType = convertPropertyToZod(localTarget, rootDoc, visitedPointers);
25955
+ if (propSchema.description) {
25956
+ zodType = zodType.describe(propSchema.description);
25957
+ }
25958
+ return zodType;
25959
+ }
25960
+ }
25961
+ }
25962
+ if (Array.isArray(propSchema.oneOf) || Array.isArray(propSchema.anyOf)) {
25963
+ const branches = propSchema.oneOf || propSchema.anyOf;
25964
+ const enumBranch = branches.find((b2) => Array.isArray(b2.enum));
25965
+ const hasBinding = branches.some((b2) => typeof b2.$ref === "string" && b2.$ref.includes("DataBinding"));
25966
+ if (enumBranch) {
25967
+ let enumZod = convertEnumToZod(enumBranch.enum);
25968
+ if (propSchema.default !== void 0) {
25969
+ enumZod = enumZod.default(propSchema.default);
25970
+ }
25971
+ const desc = propSchema.description || (hasBinding ? "REF:common_types.json#/$defs/DynamicString" : void 0);
25972
+ if (desc) {
25973
+ enumZod = enumZod.describe(desc);
25974
+ }
25975
+ return enumZod;
25976
+ }
25977
+ }
25978
+ if (Array.isArray(propSchema.enum) && propSchema.enum.length > 0) {
25979
+ let enumZod = convertEnumToZod(propSchema.enum);
25980
+ if (propSchema.default !== void 0) {
25981
+ enumZod = enumZod.default(propSchema.default);
25982
+ }
25983
+ if (propSchema.description) {
25984
+ enumZod = enumZod.describe(propSchema.description);
25985
+ }
25986
+ return enumZod;
25987
+ }
25988
+ if (propSchema.type === "array") {
25989
+ const itemSchema = propSchema.items ? convertPropertyToZod(propSchema.items, rootDoc, visitedPointers) : external_exports.any();
25990
+ let arr = external_exports.array(itemSchema);
25991
+ if (propSchema.description)
25992
+ arr = arr.describe(propSchema.description);
25993
+ return arr;
25994
+ }
25995
+ switch (propSchema.type) {
25996
+ case "string": {
25997
+ let s2 = external_exports.string();
25998
+ if (propSchema.default !== void 0)
25999
+ s2 = s2.default(propSchema.default);
26000
+ if (propSchema.description)
26001
+ s2 = s2.describe(propSchema.description);
26002
+ return s2;
26003
+ }
26004
+ case "integer": {
26005
+ let n2 = external_exports.number().int();
26006
+ if (propSchema.default !== void 0)
26007
+ n2 = n2.default(propSchema.default);
26008
+ if (propSchema.description)
26009
+ n2 = n2.describe(propSchema.description);
26010
+ return n2;
26011
+ }
26012
+ case "number": {
26013
+ let n2 = external_exports.number();
26014
+ if (propSchema.default !== void 0)
26015
+ n2 = n2.default(propSchema.default);
26016
+ if (propSchema.description)
26017
+ n2 = n2.describe(propSchema.description);
26018
+ return n2;
26019
+ }
26020
+ case "boolean": {
26021
+ let b2 = external_exports.boolean();
26022
+ if (propSchema.default !== void 0)
26023
+ b2 = b2.default(propSchema.default);
26024
+ if (propSchema.description)
26025
+ b2 = b2.describe(propSchema.description);
26026
+ return b2;
26027
+ }
26028
+ case "object": {
26029
+ let obj = external_exports.record(external_exports.any());
26030
+ if (propSchema.description)
26031
+ obj = obj.describe(propSchema.description);
26032
+ return obj;
26033
+ }
26034
+ default: {
26035
+ let anyZ = external_exports.any();
26036
+ if (propSchema.description)
26037
+ anyZ = anyZ.describe(propSchema.description);
26038
+ return anyZ;
26039
+ }
26040
+ }
26041
+ }
26042
+ function convertPropertiesToShape(properties, requiredSet, omitEnvelopeFields = false, rootDoc) {
26043
+ const shape = {};
26044
+ for (const [propName, propSchema] of Object.entries(properties)) {
26045
+ if (omitEnvelopeFields && (propName === "component" || propName === "id")) {
26046
+ continue;
26047
+ }
26048
+ const zodField = convertPropertyToZod(propSchema, rootDoc);
26049
+ shape[propName] = requiredSet.has(propName) ? zodField : zodField.optional();
26050
+ }
26051
+ return shape;
26052
+ }
26053
+ function collectComponentSubSchemas(schema, rootDoc, visitedPointers = /* @__PURE__ */ new Set()) {
26054
+ const result = [];
26055
+ if (!schema || typeof schema !== "object")
26056
+ return result;
26057
+ if (Array.isArray(schema.allOf)) {
26058
+ for (const sub of schema.allOf) {
26059
+ if (!sub || typeof sub !== "object")
26060
+ continue;
26061
+ if (typeof sub.$ref === "string") {
26062
+ const ref = sub.$ref;
26063
+ if (ref.includes("common_types.json") && ref.includes("ComponentCommon")) {
26064
+ result.push({
26065
+ properties: {
26066
+ accessibility: AccessibilityAttributesSchema.optional()
26067
+ }
26068
+ });
26069
+ } else if (ref.startsWith("#/")) {
26070
+ if (!visitedPointers.has(ref)) {
26071
+ visitedPointers.add(ref);
26072
+ const target = resolveJsonPointer(rootDoc, ref);
26073
+ if (target) {
26074
+ result.push(...collectComponentSubSchemas(target, rootDoc, visitedPointers));
26075
+ }
26076
+ }
26077
+ }
26078
+ } else {
26079
+ result.push(...collectComponentSubSchemas(sub, rootDoc, visitedPointers));
26080
+ }
26081
+ }
26082
+ }
26083
+ if (schema.properties) {
26084
+ result.push(schema);
26085
+ }
26086
+ return result;
26087
+ }
26088
+ function convertComponentJsonSchemaToZod(rawSchema, rootDoc) {
26089
+ const shape = {};
26090
+ const schemasToMerge = collectComponentSubSchemas(rawSchema, rootDoc);
26091
+ const requiredSet = /* @__PURE__ */ new Set();
26092
+ for (const s2 of schemasToMerge) {
26093
+ if (Array.isArray(s2.required)) {
26094
+ s2.required.forEach((r2) => requiredSet.add(r2));
26095
+ }
26096
+ }
26097
+ for (const s2 of schemasToMerge) {
26098
+ const propShape = convertPropertiesToShape(s2.properties || {}, requiredSet, true, rootDoc);
26099
+ Object.assign(shape, propShape);
26100
+ }
26101
+ return external_exports.object(shape).strict();
26102
+ }
26103
+ function convertFunctionArgsJsonSchemaToZod(rawSchema, rootDoc) {
26104
+ const requiredSet = new Set(Array.isArray(rawSchema.required) ? rawSchema.required : []);
26105
+ const shape = convertPropertiesToShape(rawSchema.properties || {}, requiredSet, false, rootDoc);
26106
+ return external_exports.object(shape).strict();
26107
+ }
26108
+ function parseFunctionDefinitions(rawFunctions, rootDoc) {
26109
+ const result = [];
26110
+ if (!rawFunctions)
26111
+ return result;
26112
+ if (Array.isArray(rawFunctions)) {
26113
+ for (const fn of rawFunctions) {
26114
+ if (fn && typeof fn.name === "string") {
26115
+ const paramSchema = fn.parameters && typeof fn.parameters === "object" ? convertFunctionArgsJsonSchemaToZod(fn.parameters, rootDoc) : external_exports.record(external_exports.any());
26116
+ result.push({
26117
+ name: fn.name,
26118
+ description: fn.description,
26119
+ returnType: fn.returnType ?? "any",
26120
+ schema: paramSchema
26121
+ });
26122
+ }
26123
+ }
26124
+ return result;
26125
+ }
26126
+ if (typeof rawFunctions === "object") {
26127
+ for (const [name, defn] of Object.entries(rawFunctions)) {
26128
+ const d2 = defn;
26129
+ const argsSchema = d2.properties?.args ?? d2.args ?? d2.parameters;
26130
+ const paramSchema = argsSchema && typeof argsSchema === "object" ? convertFunctionArgsJsonSchemaToZod(argsSchema, rootDoc) : external_exports.record(external_exports.any());
26131
+ result.push({
26132
+ name,
26133
+ description: d2.description,
26134
+ returnType: d2.returnType ?? d2.properties?.returnType?.const ?? "any",
26135
+ schema: paramSchema
26136
+ });
26137
+ }
26138
+ }
26139
+ return result;
26140
+ }
26141
+ function loadCatalogFromSchema(catalogSchema) {
26142
+ const catalogId = catalogSchema.catalogId ?? catalogSchema.$id ?? catalogSchema.id;
26143
+ if (!catalogId || typeof catalogId !== "string") {
26144
+ throw new Error("Catalog ID must be specified via catalog metadata ('catalogId' or '$id').");
26145
+ }
26146
+ const permittedNames = /* @__PURE__ */ new Set();
26147
+ const oneOf = catalogSchema.$defs?.anyComponent?.oneOf;
26148
+ if (Array.isArray(oneOf)) {
26149
+ for (const item of oneOf) {
26150
+ if (typeof item?.$ref === "string" && item.$ref.startsWith("#/components/")) {
26151
+ permittedNames.add(item.$ref.split("/").pop());
26152
+ }
26153
+ }
26154
+ }
26155
+ const components = [];
26156
+ const componentsMap = catalogSchema.components ?? {};
26157
+ for (const [name, rawCompSchema] of Object.entries(componentsMap)) {
26158
+ if (permittedNames.size === 0 || permittedNames.has(name)) {
26159
+ const zodSchema = convertComponentJsonSchemaToZod(rawCompSchema, catalogSchema);
26160
+ components.push({
26161
+ name,
26162
+ schema: zodSchema
26163
+ });
26164
+ }
26165
+ }
26166
+ const functions = parseFunctionDefinitions(catalogSchema.functions, catalogSchema);
26167
+ return new Catalog(catalogId, components, functions);
26168
+ }
26169
+
25811
26170
  // node_modules/@a2ui/web_core/src/v0_9/catalog/types.js
25812
26171
  function createFunctionImplementation(api, execute) {
25813
26172
  return {
@@ -25836,9 +26195,13 @@
25836
26195
  if (!fn) {
25837
26196
  throw new A2uiExpressionError(`Function not found in catalog '${this.id}': ${name}`, name);
25838
26197
  }
26198
+ const execute = fn.execute;
26199
+ if (typeof execute !== "function") {
26200
+ throw new A2uiExpressionError(`Function '${name}' in catalog '${this.id}' is schema-only and has no implementation.`, name);
26201
+ }
25839
26202
  try {
25840
26203
  const safeArgs = fn.schema.parse(rawArgs);
25841
- return fn.execute(safeArgs, ctx, abortSignal);
26204
+ return execute.call(fn, safeArgs, ctx, abortSignal);
25842
26205
  } catch (e2) {
25843
26206
  if (e2?.name === "ZodError" || e2 instanceof external_exports.ZodError) {
25844
26207
  throw new A2uiExpressionError(`Validation failed for function '${name}': ${e2.message}`, name, e2.errors ?? e2.issues);
@@ -25847,6 +26210,14 @@
25847
26210
  }
25848
26211
  };
25849
26212
  }
26213
+ /**
26214
+ * Constructs a fully-typed schema-only Catalog directly from raw A2UI catalog schema.
26215
+ *
26216
+ * @param catalogSchema Raw catalog schema or client capabilities payload object.
26217
+ */
26218
+ static fromSchema(catalogSchema) {
26219
+ return loadCatalogFromSchema(catalogSchema);
26220
+ }
25850
26221
  };
25851
26222
 
25852
26223
  // node_modules/@a2ui/web_core/src/v0_9/common/events.js
@@ -28164,6 +28535,24 @@
28164
28535
  };
28165
28536
 
28166
28537
  // node_modules/@a2ui/web_core/src/v0_9/processing/message-processor.js
28538
+ function formatZodIssue(err) {
28539
+ const path = err.path.join(".") || "root";
28540
+ if ("keys" in err && Array.isArray(err.keys) && err.keys.length > 0) {
28541
+ const keysStr = err.keys.map((k) => `'${k}'`).join(", ");
28542
+ return `${path}: Unrecognized key(s) in object: ${keysStr}`;
28543
+ }
28544
+ if (err.code === "invalid_enum_value" && Array.isArray(err.options)) {
28545
+ const optionsStr = err.options.join(" | ");
28546
+ return `${path}: Invalid enum value. Expected ${optionsStr}, received '${err.received}'`;
28547
+ }
28548
+ if (err.message && !err.message.includes("Expected undefined, received undefined")) {
28549
+ return `${path}: ${err.message}`;
28550
+ }
28551
+ if ("expected" in err && err.expected !== void 0 && err.received !== void 0) {
28552
+ return path + ": Expected " + err.expected + ", received " + err.received;
28553
+ }
28554
+ return `${path}: Validation error (${err.code || "invalid"})`;
28555
+ }
28167
28556
  var MessageProcessor = class {
28168
28557
  /**
28169
28558
  * Creates a new message processor.
@@ -28378,8 +28767,12 @@
28378
28767
  if (componentApi) {
28379
28768
  const validationResult = componentApi.schema.safeParse(properties);
28380
28769
  if (!validationResult.success) {
28381
- const formattedErrors = validationResult.error.errors.map((err) => `${err.path.join(".") || "root"}: ${err.message}`).join(", ");
28382
- throw new A2uiValidationError(`Validation failed for component '${componentType}' (${id}): ${formattedErrors}`);
28770
+ const formattedErrors = validationResult.error.errors.map(formatZodIssue).join(", ");
28771
+ console.error("[A2UI Validation Error] Component '" + componentType + "' (" + id + "):", {
28772
+ propertyKeys: Object.keys(properties),
28773
+ issues: validationResult.error.issues
28774
+ });
28775
+ throw new A2uiValidationError(`Validation failed for component '${componentType}' (${id}): ${formattedErrors}`, validationResult.error.issues);
28383
28776
  }
28384
28777
  }
28385
28778
  }
@@ -28461,6 +28854,19 @@
28461
28854
  const absolutePath = this.resolvePath(path);
28462
28855
  this.dataModel.set(absolutePath, value);
28463
28856
  }
28857
+ /**
28858
+ * Checks whether a value (typically an array element) contains any dynamic parts
28859
+ * (path bindings or function calls) that require resolution.
28860
+ */
28861
+ static containsDynamicValue(value) {
28862
+ if (value === null || typeof value !== "object") {
28863
+ return false;
28864
+ }
28865
+ if (Array.isArray(value)) {
28866
+ return value.some((item) => _DataContext.containsDynamicValue(item));
28867
+ }
28868
+ return "path" in value || "call" in value;
28869
+ }
28464
28870
  /**
28465
28871
  * Synchronously evaluates a `DynamicValue` (a literal, a path binding, or a function call)
28466
28872
  * into its concrete runtime value.
@@ -28473,9 +28879,15 @@
28473
28879
  * @returns The synchronously resolved value.
28474
28880
  */
28475
28881
  resolveDynamicValue(value) {
28476
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
28882
+ if (value === null || typeof value !== "object") {
28477
28883
  return value;
28478
28884
  }
28885
+ if (Array.isArray(value)) {
28886
+ if (!_DataContext.containsDynamicValue(value)) {
28887
+ return value;
28888
+ }
28889
+ return value.map((item) => this.resolveDynamicValue(item));
28890
+ }
28479
28891
  if ("path" in value) {
28480
28892
  const absolutePath = this.resolvePath(value.path);
28481
28893
  return this.dataModel.get(absolutePath);
@@ -28540,9 +28952,22 @@
28540
28952
  * @returns A Preact Signal containing the reactive result of the evaluation.
28541
28953
  */
28542
28954
  resolveSignal(value) {
28543
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
28955
+ if (typeof value !== "object" || value === null) {
28544
28956
  return signal(value);
28545
28957
  }
28958
+ if (Array.isArray(value)) {
28959
+ if (!_DataContext.containsDynamicValue(value)) {
28960
+ return signal(value);
28961
+ }
28962
+ const itemSignals = value.map((item) => this.resolveSignal(item));
28963
+ const resultSig = computed(() => itemSignals.map((s2) => getValue(s2)));
28964
+ resultSig.unsubscribe = () => {
28965
+ for (const s2 of itemSignals) {
28966
+ s2.unsubscribe?.();
28967
+ }
28968
+ };
28969
+ return resultSig;
28970
+ }
28546
28971
  if ("path" in value) {
28547
28972
  const absolutePath = this.resolvePath(value.path);
28548
28973
  return this.dataModel.getSignal(absolutePath);
@@ -28710,10 +29135,10 @@
28710
29135
  * @param componentId The ID of the component.
28711
29136
  * @param dataModelBasePath The base path for data model access (default: '/').
28712
29137
  */
28713
- constructor(surface, componentId, dataModelBasePath = "/") {
28714
- const model = surface.componentsModel.get(componentId);
29138
+ constructor(surface, componentId2, dataModelBasePath = "/") {
29139
+ const model = surface.componentsModel.get(componentId2);
28715
29140
  if (!model) {
28716
- throw new A2uiStateError(`Component not found: ${componentId}`);
29141
+ throw new A2uiStateError(`Component not found: ${componentId2}`);
28717
29142
  }
28718
29143
  this.componentModel = model;
28719
29144
  this.surfaceComponents = surface.componentsModel;
@@ -28735,14 +29160,33 @@
28735
29160
  function scrapeSchemaBehavior(schema) {
28736
29161
  return getFieldBehavior(schema);
28737
29162
  }
29163
+ var ACTION_REF = "REF:common_types.json#/$defs/Action";
29164
+ var DATA_BINDING_REF = "REF:common_types.json#/$defs/DataBinding";
29165
+ var DYNAMIC_REF_PREFIX = "#/$defs/Dynamic";
28738
29166
  function getFieldBehavior(type, propertyName) {
28739
29167
  let current = type;
29168
+ let description = current._def?.description || "";
28740
29169
  while (current._def.typeName === "ZodOptional" || current._def.typeName === "ZodNullable" || current._def.typeName === "ZodDefault") {
29170
+ if (!description && current._def.description) {
29171
+ description = current._def.description;
29172
+ }
28741
29173
  current = current._def.innerType;
28742
29174
  }
29175
+ if (!description && current._def.description) {
29176
+ description = current._def.description;
29177
+ }
28743
29178
  if (propertyName === "checks") {
28744
29179
  return { type: "CHECKABLE" };
28745
29180
  }
29181
+ if (description.startsWith(ACTION_REF)) {
29182
+ return { type: "ACTION" };
29183
+ }
29184
+ if (childRefKindOf(current) === "child-list" || description.includes("#/$defs/ChildList")) {
29185
+ return { type: "STRUCTURAL" };
29186
+ }
29187
+ if ((description.startsWith(DATA_BINDING_REF) || description.includes(DYNAMIC_REF_PREFIX)) && current._def.typeName !== "ZodObject" && current._def.typeName !== "ZodArray") {
29188
+ return { type: "DYNAMIC" };
29189
+ }
28746
29190
  if (current._def.typeName === "ZodUnion") {
28747
29191
  const options = current._def.options;
28748
29192
  const isAction = options.some((o2) => o2._def.typeName === "ZodObject" && o2._def.shape().event);
@@ -28778,6 +29222,7 @@
28778
29222
  this.propsListeners = [];
28779
29223
  this.currentProps = {};
28780
29224
  this.isConnected = false;
29225
+ this.actionClosures = /* @__PURE__ */ new Map();
28781
29226
  this.context = context;
28782
29227
  this.behaviorTree = scrapeSchemaBehavior(schema);
28783
29228
  if (this.behaviorTree.type !== "OBJECT") {
@@ -28808,13 +29253,56 @@
28808
29253
  this.currentProps = { ...this.currentProps, ...resolved };
28809
29254
  this.notify();
28810
29255
  }
28811
- resolveAndBind(value, behavior, path, isSync) {
28812
- if (value === void 0 || value === null)
28813
- return value;
28814
- switch (behavior.type) {
28815
- case "DYNAMIC": {
28816
- const bound = this.context.dataContext.subscribeDynamicValue(value, (newVal) => {
28817
- this.updateDeepValue(path, newVal);
29256
+ bindDynamicValue(value, path, isSync) {
29257
+ const bound = this.context.dataContext.subscribeDynamicValue(value, (newVal) => {
29258
+ this.updateDeepValue(path, newVal);
29259
+ this.notify();
29260
+ });
29261
+ if (!isSync) {
29262
+ this.dataListeners.push(() => bound.unsubscribe());
29263
+ } else {
29264
+ bound.unsubscribe();
29265
+ }
29266
+ return bound.value;
29267
+ }
29268
+ bindAction(value, path) {
29269
+ const cacheKey = path.join("/");
29270
+ const cached = this.actionClosures.get(cacheKey);
29271
+ if (cached && jsonEquals(cached.raw, value)) {
29272
+ return cached.closure;
29273
+ }
29274
+ const closure = () => {
29275
+ const resolveDeepSync = (val) => {
29276
+ if (typeof val !== "object" || val === null)
29277
+ return val;
29278
+ if ("path" in val || "call" in val) {
29279
+ return this.context.dataContext.resolveDynamicValue(val);
29280
+ }
29281
+ if (Array.isArray(val))
29282
+ return val.map(resolveDeepSync);
29283
+ const res = {};
29284
+ for (const [k, v2] of Object.entries(val))
29285
+ res[k] = resolveDeepSync(v2);
29286
+ return res;
29287
+ };
29288
+ this.context.dispatchAction(resolveDeepSync(value));
29289
+ };
29290
+ this.actionClosures.set(cacheKey, { raw: value, closure });
29291
+ return closure;
29292
+ }
29293
+ bindStructuralTemplate(value, path, isSync) {
29294
+ if (value && typeof value === "object" && !Array.isArray(value)) {
29295
+ const templatePath = value.path;
29296
+ const templateComponentId = value.componentId;
29297
+ if (templatePath && templateComponentId) {
29298
+ const bound = this.context.dataContext.subscribeDynamicValue({ path: templatePath }, (newVal) => {
29299
+ const arr = Array.isArray(newVal) ? newVal : [];
29300
+ const listContext2 = this.context.dataContext.nested(templatePath);
29301
+ const resolvedChildren = arr.map((_2, i2) => ({
29302
+ id: templateComponentId,
29303
+ basePath: listContext2.nested(String(i2)).path
29304
+ }));
29305
+ this.updateDeepValue(path, resolvedChildren);
28818
29306
  this.notify();
28819
29307
  });
28820
29308
  if (!isSync) {
@@ -28822,50 +29310,28 @@
28822
29310
  } else {
28823
29311
  bound.unsubscribe();
28824
29312
  }
28825
- return bound.value;
29313
+ const currentArr = Array.isArray(bound.value) ? bound.value : [];
29314
+ const listContext = this.context.dataContext.nested(templatePath);
29315
+ return currentArr.map((_2, i2) => ({
29316
+ id: templateComponentId,
29317
+ basePath: listContext.nested(String(i2)).path
29318
+ }));
29319
+ }
29320
+ }
29321
+ return value;
29322
+ }
29323
+ resolveAndBind(value, behavior, path, isSync) {
29324
+ if (value === void 0 || value === null)
29325
+ return value;
29326
+ switch (behavior.type) {
29327
+ case "DYNAMIC": {
29328
+ return this.bindDynamicValue(value, path, isSync);
28826
29329
  }
28827
29330
  case "ACTION": {
28828
- return () => {
28829
- const resolveDeepSync = (val) => {
28830
- if (typeof val !== "object" || val === null)
28831
- return val;
28832
- if ("path" in val || "call" in val)
28833
- return this.context.dataContext.resolveDynamicValue(val);
28834
- if (Array.isArray(val))
28835
- return val.map(resolveDeepSync);
28836
- const res = {};
28837
- for (const [k, v2] of Object.entries(val))
28838
- res[k] = resolveDeepSync(v2);
28839
- return res;
28840
- };
28841
- this.context.dispatchAction(resolveDeepSync(value));
28842
- };
29331
+ return this.bindAction(value, path);
28843
29332
  }
28844
29333
  case "STRUCTURAL": {
28845
- if (value && typeof value === "object" && value.path && value.componentId) {
28846
- const bound = this.context.dataContext.subscribeDynamicValue({ path: value.path }, (newVal) => {
28847
- const arr = Array.isArray(newVal) ? newVal : [];
28848
- const listContext2 = this.context.dataContext.nested(value.path);
28849
- const resolvedChildren = arr.map((_2, i2) => ({
28850
- id: value.componentId,
28851
- basePath: listContext2.nested(String(i2)).path
28852
- }));
28853
- this.updateDeepValue(path, resolvedChildren);
28854
- this.notify();
28855
- });
28856
- if (!isSync) {
28857
- this.dataListeners.push(() => bound.unsubscribe());
28858
- } else {
28859
- bound.unsubscribe();
28860
- }
28861
- const currentArr = Array.isArray(bound.value) ? bound.value : [];
28862
- const listContext = this.context.dataContext.nested(value.path);
28863
- return currentArr.map((_2, i2) => ({
28864
- id: value.componentId,
28865
- basePath: listContext.nested(String(i2)).path
28866
- }));
28867
- }
28868
- return value;
29334
+ return this.bindStructuralTemplate(value, path, isSync);
28869
29335
  }
28870
29336
  case "CHECKABLE": {
28871
29337
  const rules = Array.isArray(value) ? value : [];
@@ -28900,8 +29366,9 @@
28900
29366
  this.updateDeepValue([...parentPath, "validationErrors"], initialErrors);
28901
29367
  return value;
28902
29368
  }
28903
- case "STATIC":
29369
+ case "STATIC": {
28904
29370
  return value;
29371
+ }
28905
29372
  case "ARRAY": {
28906
29373
  if (!Array.isArray(value))
28907
29374
  return value;
@@ -28980,77 +29447,817 @@
28980
29447
  return this.currentProps;
28981
29448
  }
28982
29449
  };
28983
-
28984
- // node_modules/@a2ui/web_core/src/v0_9/schema/common-types.js
28985
- var DataBindingSchema = external_exports.object({
28986
- "path": external_exports.string().describe("A JSON Pointer path to a value in the data model.")
28987
- }).describe("REF:common_types.json#/$defs/DataBinding|A JSON Pointer path to a value in the data model.");
28988
- var FunctionCallSchema = external_exports.object({
28989
- "call": external_exports.string().describe("The name of the function to call."),
28990
- "args": external_exports.record(external_exports.any()).describe("Arguments passed to the function."),
28991
- "returnType": external_exports.enum(["string", "number", "boolean", "array", "object", "any", "void"]).default("boolean")
28992
- }).describe("REF:common_types.json#/$defs/FunctionCall|Invokes a named function on the client.");
28993
- var DynamicBooleanSchema = external_exports.union([external_exports.boolean(), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicBoolean|A boolean value that can be a literal, a path, or a function call returning a boolean.");
28994
- var DynamicStringSchema = external_exports.union([
28995
- external_exports.string(),
28996
- DataBindingSchema,
28997
- // FunctionCall returning string (simplified schema for Zod, stricter in JSON Schema)
28998
- FunctionCallSchema
28999
- ]).describe("REF:common_types.json#/$defs/DynamicString|Represents a string");
29000
- var DynamicNumberSchema = external_exports.union([external_exports.number(), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicNumber|Represents a value that can be either a literal number, a path to a number in the data model, or a function call returning a number.");
29001
- var DynamicStringListSchema = external_exports.union([external_exports.array(external_exports.string()), DataBindingSchema, FunctionCallSchema]).describe("REF:common_types.json#/$defs/DynamicStringList|Represents a value that can be either a literal array of strings, a path to a string array in the data model, or a function call returning a string array.");
29002
- var DynamicValueSchema = external_exports.union([
29003
- external_exports.string(),
29004
- external_exports.number(),
29005
- external_exports.boolean(),
29006
- external_exports.array(external_exports.any()),
29007
- DataBindingSchema,
29008
- FunctionCallSchema
29009
- ]).describe("REF:common_types.json#/$defs/DynamicValue|A value that can be a literal, a path, or a function call returning any type.");
29010
- var ComponentIdSchema = external_exports.string().describe("REF:common_types.json#/$defs/ComponentId|The unique identifier for a component.");
29011
- var ChildListSchema = external_exports.union([
29012
- external_exports.array(ComponentIdSchema).describe("A static list of child component IDs."),
29013
- external_exports.object({
29014
- "componentId": ComponentIdSchema,
29015
- "path": external_exports.string().describe("The path to the list of component property objects in the data model.")
29016
- }).describe("A template for generating a dynamic list of children.")
29017
- ]).describe("REF:common_types.json#/$defs/ChildList");
29018
- var ActionSchema = external_exports.union([
29019
- external_exports.object({
29020
- "event": external_exports.object({
29021
- "name": external_exports.string(),
29022
- "context": external_exports.record(DynamicValueSchema).optional()
29023
- })
29024
- }).describe("Triggers a server-side event."),
29025
- external_exports.object({
29026
- "functionCall": FunctionCallSchema
29027
- }).describe("Executes a local client-side function.")
29028
- ]).describe("REF:common_types.json#/$defs/Action");
29029
- var CheckRuleSchema = external_exports.object({
29030
- "condition": DynamicBooleanSchema,
29031
- "message": external_exports.string().describe("The error message to display if the check fails.")
29032
- }).describe("REF:common_types.json#/$defs/CheckRule|A check rule consisting of a condition and an error message.");
29033
- var CheckableSchema = external_exports.object({
29034
- "checks": external_exports.array(CheckRuleSchema).optional().describe("A list of checks to perform."),
29035
- "isValid": external_exports.boolean().optional().describe("Whether the checks currently pass."),
29036
- "validationErrors": external_exports.array(external_exports.string()).optional().describe("Current validation error messages.")
29037
- }).describe("REF:common_types.json#/$defs/Checkable|Properties for components that support client-side checks.");
29038
- var AccessibilityAttributesSchema = external_exports.object({
29039
- "label": DynamicStringSchema.optional().describe("REF:common_types.json#/$defs/DynamicString|A short string used by assistive technologies to convey the purpose of an element."),
29040
- "description": DynamicStringSchema.optional().describe("REF:common_types.json#/$defs/DynamicString|Additional information provided by assistive technologies about an element.")
29041
- }).describe("REF:common_types.json#/$defs/AccessibilityAttributes|Attributes to enhance accessibility.");
29042
- var AnyComponentSchema = external_exports.object({
29043
- "component": external_exports.string().describe("The type name of the component."),
29044
- "id": ComponentIdSchema.optional(),
29045
- "weight": external_exports.number().optional()
29046
- }).passthrough().describe("A generic A2UI component definition.");
29047
-
29048
- // node_modules/@a2ui/web_core/src/v0_9/basic_catalog/expressions/expression_parser.js
29049
- var ExpressionParser = class _ExpressionParser {
29050
- static {
29051
- this.MAX_DEPTH = 10;
29450
+ function jsonEquals(a2, b2) {
29451
+ if (Object.is(a2, b2))
29452
+ return true;
29453
+ if (typeof a2 !== "object" || typeof b2 !== "object" || a2 === null || b2 === null) {
29454
+ return false;
29052
29455
  }
29053
- /**
29456
+ if (Array.isArray(a2) || Array.isArray(b2)) {
29457
+ if (!Array.isArray(a2) || !Array.isArray(b2) || a2.length !== b2.length) {
29458
+ return false;
29459
+ }
29460
+ return a2.every((item, index) => jsonEquals(item, b2[index]));
29461
+ }
29462
+ const aKeys = Object.keys(a2);
29463
+ const bKeys = Object.keys(b2);
29464
+ if (aKeys.length !== bKeys.length)
29465
+ return false;
29466
+ return aKeys.every((key) => Object.prototype.hasOwnProperty.call(b2, key) && jsonEquals(a2[key], b2[key]));
29467
+ }
29468
+
29469
+ // node_modules/@a2ui/web_core/src/v0_9/nodes/resolved-binding.js
29470
+ var ResolvedBinding = class {
29471
+ constructor(value) {
29472
+ this.value = value;
29473
+ }
29474
+ };
29475
+ var WritableBinding = class extends ResolvedBinding {
29476
+ constructor(value, set, path) {
29477
+ super(value);
29478
+ this.set = set;
29479
+ this.path = path;
29480
+ }
29481
+ };
29482
+ function isWritable(binding) {
29483
+ return binding instanceof WritableBinding;
29484
+ }
29485
+ function sameBinding(a2, b2) {
29486
+ if (isWritable(a2) !== isWritable(b2)) {
29487
+ return false;
29488
+ }
29489
+ if (isWritable(a2) && isWritable(b2) && a2.path !== b2.path) {
29490
+ return false;
29491
+ }
29492
+ return valueEquals(a2.value, b2.value);
29493
+ }
29494
+ function valueEquals(a2, b2) {
29495
+ if (Object.is(a2, b2)) {
29496
+ return true;
29497
+ }
29498
+ if (Array.isArray(a2) && Array.isArray(b2)) {
29499
+ return a2.length === b2.length && a2.every((item, i2) => valueEquals(item, b2[i2]));
29500
+ }
29501
+ if (isPlainObject(a2) && isPlainObject(b2)) {
29502
+ const aKeys = Object.keys(a2);
29503
+ const bKeys = Object.keys(b2);
29504
+ return aKeys.length === bKeys.length && aKeys.every((key) => key in b2 && valueEquals(a2[key], b2[key]));
29505
+ }
29506
+ return false;
29507
+ }
29508
+ function isPlainObject(value) {
29509
+ if (typeof value !== "object" || value === null) {
29510
+ return false;
29511
+ }
29512
+ const proto = Object.getPrototypeOf(value);
29513
+ return proto === Object.prototype || proto === null;
29514
+ }
29515
+
29516
+ // node_modules/@a2ui/web_core/src/v0_9/nodes/component-node.js
29517
+ var PLACEHOLDER_TYPE = "Placeholder";
29518
+ function isComponentNode(value) {
29519
+ return value instanceof MutableComponentNode;
29520
+ }
29521
+ var MutableComponentNode = class {
29522
+ constructor(instanceId, componentId2, type, dataPath, initialProps, impl, state = "resolved") {
29523
+ this._onDestroyed = new EventEmitter();
29524
+ this.onDestroyed = this._onDestroyed;
29525
+ this.cleanups = [];
29526
+ this._disposed = false;
29527
+ this.instanceId = instanceId;
29528
+ this.componentId = componentId2;
29529
+ this.type = type;
29530
+ this.dataPath = dataPath;
29531
+ this.props = signal(initialProps);
29532
+ this.impl = impl;
29533
+ this.state = state;
29534
+ }
29535
+ get disposed() {
29536
+ return this._disposed;
29537
+ }
29538
+ get isPlaceholder() {
29539
+ return this.state !== "resolved";
29540
+ }
29541
+ addCleanup(cleanup) {
29542
+ this.cleanups.push(cleanup);
29543
+ }
29544
+ toJSON() {
29545
+ if (this.isPlaceholder) {
29546
+ return { id: this.componentId, type: this.type, state: this.state };
29547
+ }
29548
+ const serialized = {
29549
+ id: this.componentId,
29550
+ type: this.type
29551
+ };
29552
+ const props = peekValue(this.props);
29553
+ for (const [key, value] of Object.entries(props)) {
29554
+ serialized[key] = serializeValue(value);
29555
+ }
29556
+ return serialized;
29557
+ }
29558
+ /**
29559
+ * Replaces the resolved props, emitting only if a shallow comparison shows
29560
+ * a change. Callers must keep unchanged values reference-identical; the
29561
+ * shallow comparison is exact only under that invariant.
29562
+ */
29563
+ setProps(next) {
29564
+ if (this._disposed) {
29565
+ return;
29566
+ }
29567
+ const previous = peekValue(this.props);
29568
+ if (!shallowEqual(previous, next)) {
29569
+ setValue(this.props, next);
29570
+ }
29571
+ }
29572
+ /**
29573
+ * Tears down this node: runs registered cleanups, then fires `onDestroyed`.
29574
+ * Idempotent.
29575
+ */
29576
+ dispose() {
29577
+ if (this._disposed) {
29578
+ return;
29579
+ }
29580
+ this._disposed = true;
29581
+ for (const cleanup of this.cleanups) {
29582
+ try {
29583
+ cleanup();
29584
+ } catch (e2) {
29585
+ console.error(`ComponentNode cleanup error (${this.instanceId}):`, e2);
29586
+ }
29587
+ }
29588
+ this.cleanups = [];
29589
+ this._onDestroyed.emit();
29590
+ this._onDestroyed.dispose();
29591
+ }
29592
+ };
29593
+ function serializeValue(value) {
29594
+ if (isComponentNode(value)) {
29595
+ return value.toJSON();
29596
+ }
29597
+ if (value instanceof ResolvedBinding) {
29598
+ return serializeValue(value.value);
29599
+ }
29600
+ if (typeof value === "function") {
29601
+ return "<Action>";
29602
+ }
29603
+ if (Array.isArray(value)) {
29604
+ return value.map(serializeValue);
29605
+ }
29606
+ if (value && typeof value === "object") {
29607
+ const result = {};
29608
+ for (const [key, inner] of Object.entries(value)) {
29609
+ result[key] = serializeValue(inner);
29610
+ }
29611
+ return result;
29612
+ }
29613
+ return value;
29614
+ }
29615
+ function shallowEqual(a2, b2) {
29616
+ if (Object.is(a2, b2)) {
29617
+ return true;
29618
+ }
29619
+ const aKeys = Object.keys(a2);
29620
+ const bKeys = Object.keys(b2);
29621
+ if (aKeys.length !== bKeys.length) {
29622
+ return false;
29623
+ }
29624
+ for (const key of aKeys) {
29625
+ if (!Object.is(a2[key], b2[key])) {
29626
+ return false;
29627
+ }
29628
+ }
29629
+ return true;
29630
+ }
29631
+
29632
+ // node_modules/@a2ui/web_core/src/v0_9/nodes/ref-fields.js
29633
+ var COMPONENT_ID_REF = "REF:common_types.json#/$defs/ComponentId";
29634
+ var CHILD_LIST_REF = "REF:common_types.json#/$defs/ChildList";
29635
+ var EMPTY_REF_FIELDS = /* @__PURE__ */ new Map();
29636
+ var refFieldsCache = /* @__PURE__ */ new WeakMap();
29637
+ function extractRefFields(schema) {
29638
+ const cached = refFieldsCache.get(schema);
29639
+ if (cached) {
29640
+ return cached;
29641
+ }
29642
+ const unwrapped = unwrap(schema);
29643
+ if (unwrapped.schema._def.typeName !== "ZodObject") {
29644
+ refFieldsCache.set(schema, EMPTY_REF_FIELDS);
29645
+ return EMPTY_REF_FIELDS;
29646
+ }
29647
+ const fields = /* @__PURE__ */ new Map();
29648
+ const shape = unwrapped.schema.shape;
29649
+ for (const [key, value] of Object.entries(shape)) {
29650
+ const field = unwrap(value);
29651
+ if (marksChildList(field) || isChildListUnion(field.schema)) {
29652
+ fields.set(key, { kind: "list" });
29653
+ continue;
29654
+ }
29655
+ if (marksComponentId(field)) {
29656
+ fields.set(key, { kind: "single" });
29657
+ continue;
29658
+ }
29659
+ if (field.schema._def.typeName === "ZodArray") {
29660
+ const element = unwrap(field.schema._def.type);
29661
+ if (marksComponentId(element)) {
29662
+ fields.set(key, { kind: "list" });
29663
+ continue;
29664
+ }
29665
+ if (element.schema._def.typeName === "ZodObject") {
29666
+ const subKeys = /* @__PURE__ */ new Set();
29667
+ const elementShape = element.schema.shape;
29668
+ for (const [subKey, subValue] of Object.entries(elementShape)) {
29669
+ if (marksComponentId(unwrap(subValue))) {
29670
+ subKeys.add(subKey);
29671
+ }
29672
+ }
29673
+ if (subKeys.size > 0) {
29674
+ fields.set(key, { kind: "nested", keys: subKeys });
29675
+ }
29676
+ }
29677
+ }
29678
+ }
29679
+ const result = fields;
29680
+ refFieldsCache.set(schema, result);
29681
+ return result;
29682
+ }
29683
+ function unwrap(schema) {
29684
+ const descriptions = [];
29685
+ const refs = /* @__PURE__ */ new Set();
29686
+ let current = schema;
29687
+ for (; ; ) {
29688
+ if (current.description) {
29689
+ descriptions.push(current.description);
29690
+ }
29691
+ const ref = childRefKindOf(current);
29692
+ if (ref) {
29693
+ refs.add(ref);
29694
+ }
29695
+ const typeName = current._def.typeName;
29696
+ if (typeName === "ZodOptional" || typeName === "ZodNullable" || typeName === "ZodDefault") {
29697
+ current = current._def.innerType;
29698
+ } else if (typeName === "ZodEffects") {
29699
+ current = current._def.schema;
29700
+ } else {
29701
+ return { schema: current, descriptions, refs };
29702
+ }
29703
+ }
29704
+ }
29705
+ function marksComponentId(field) {
29706
+ return field.refs.has("component-id") || hasPointer(field.descriptions, COMPONENT_ID_REF);
29707
+ }
29708
+ function marksChildList(field) {
29709
+ return field.refs.has("child-list") || hasPointer(field.descriptions, CHILD_LIST_REF);
29710
+ }
29711
+ function hasPointer(descriptions, pointer) {
29712
+ return descriptions.some((d2) => d2.startsWith(pointer));
29713
+ }
29714
+ function isChildListUnion(schema) {
29715
+ if (schema._def.typeName !== "ZodUnion") {
29716
+ return false;
29717
+ }
29718
+ const options = schema._def.options;
29719
+ return options.some((o2) => {
29720
+ if (o2._def.typeName !== "ZodObject") {
29721
+ return false;
29722
+ }
29723
+ const shape = o2.shape;
29724
+ return shape.componentId && shape.path;
29725
+ });
29726
+ }
29727
+
29728
+ // node_modules/@a2ui/web_core/src/v0_9/nodes/node-resolver.js
29729
+ var ROOT_COMPONENT_ID = "root";
29730
+ var ROOT_DATA_PATH = "/";
29731
+ var ROOT_EDGE_KEY = ">root>root@/";
29732
+ var EMPTY_REF_FIELDS2 = /* @__PURE__ */ new Map();
29733
+ var NodeResolver = class {
29734
+ constructor(surface, catalog) {
29735
+ this.records = /* @__PURE__ */ new Map();
29736
+ this.nodesByEdge = /* @__PURE__ */ new Map();
29737
+ this.nodesByComponentId = /* @__PURE__ */ new Map();
29738
+ this.pendingParents = /* @__PURE__ */ new Map();
29739
+ this.dispatchedErrors = /* @__PURE__ */ new Map();
29740
+ this.modelSubs = [];
29741
+ this._disposed = false;
29742
+ if (catalog !== surface.catalog) {
29743
+ throw new A2uiStateError("NodeResolver requires the same catalog instance its surface was constructed with.");
29744
+ }
29745
+ this.surface = surface;
29746
+ this.catalog = catalog;
29747
+ this.rootNode = signal(void 0);
29748
+ this.modelSubs.push(surface.componentsModel.onCreated.subscribe((component) => this.onComponentCreated(component)));
29749
+ this.modelSubs.push(surface.componentsModel.onDeleted.subscribe((id) => this.onComponentDeleted(id)));
29750
+ if (surface.componentsModel.get(ROOT_COMPONENT_ID)) {
29751
+ this.buildRoot();
29752
+ }
29753
+ }
29754
+ /**
29755
+ * Dispatches once per (code, component, path) for as long as the condition
29756
+ * persists: the record is cleared when the component is deleted, when a
29757
+ * node for the pair resolves, or when a cyclic stand-in's edge goes away,
29758
+ * so a condition that is fixed and later reintroduced reports again.
29759
+ */
29760
+ dispatchOnce(code, componentId2, dataPath, message2) {
29761
+ let byPath = this.dispatchedErrors.get(componentId2);
29762
+ if (!byPath) {
29763
+ byPath = /* @__PURE__ */ new Map();
29764
+ this.dispatchedErrors.set(componentId2, byPath);
29765
+ }
29766
+ let codes = byPath.get(dataPath);
29767
+ if (!codes) {
29768
+ codes = /* @__PURE__ */ new Set();
29769
+ byPath.set(dataPath, codes);
29770
+ }
29771
+ if (codes.has(code)) {
29772
+ return;
29773
+ }
29774
+ codes.add(code);
29775
+ this.surface.dispatchError({ code, message: message2 });
29776
+ }
29777
+ clearDispatched(componentId2, dataPath) {
29778
+ const byPath = this.dispatchedErrors.get(componentId2);
29779
+ if (byPath?.delete(dataPath) && byPath.size === 0) {
29780
+ this.dispatchedErrors.delete(componentId2);
29781
+ }
29782
+ }
29783
+ /** Number of live nodes (including placeholders). Exposed for tests and devtools. */
29784
+ get activeNodeCount() {
29785
+ return this.records.size;
29786
+ }
29787
+ get disposed() {
29788
+ return this._disposed;
29789
+ }
29790
+ /** Tears down the whole tree and stops tracking the surface. Idempotent. */
29791
+ dispose() {
29792
+ if (this._disposed) {
29793
+ return;
29794
+ }
29795
+ this._disposed = true;
29796
+ for (const sub of this.modelSubs) {
29797
+ sub.unsubscribe();
29798
+ }
29799
+ this.modelSubs.length = 0;
29800
+ for (const node of [...this.records.keys()]) {
29801
+ this.disposeNode(node);
29802
+ }
29803
+ this.pendingParents.clear();
29804
+ this.dispatchedErrors.clear();
29805
+ this.rootRecord = void 0;
29806
+ setValue(this.rootNode, void 0);
29807
+ }
29808
+ /** No-op while a root record exists; root deletion clears it so a re-sent root rebuilds. */
29809
+ buildRoot() {
29810
+ if (this.rootRecord) {
29811
+ return;
29812
+ }
29813
+ const node = this.createNode(ROOT_COMPONENT_ID, ROOT_DATA_PATH, ROOT_EDGE_KEY, void 0);
29814
+ this.rootRecord = this.records.get(node);
29815
+ setValue(this.rootNode, node);
29816
+ }
29817
+ onComponentCreated(component) {
29818
+ if (this._disposed) {
29819
+ return;
29820
+ }
29821
+ if (component.id === ROOT_COMPONENT_ID) {
29822
+ const current = this.surface.componentsModel.get(ROOT_COMPONENT_ID);
29823
+ if (this.rootRecord && this.rootRecord.componentModel !== current) {
29824
+ this.disposeNode(this.rootRecord.node);
29825
+ this.rootRecord = void 0;
29826
+ if (!current) {
29827
+ setValue(this.rootNode, void 0);
29828
+ }
29829
+ }
29830
+ if (current) {
29831
+ this.buildRoot();
29832
+ }
29833
+ }
29834
+ const waiting = this.pendingParents.get(component.id);
29835
+ if (waiting) {
29836
+ this.pendingParents.delete(component.id);
29837
+ for (const parent of waiting) {
29838
+ const record = this.records.get(parent);
29839
+ if (record && !parent.disposed) {
29840
+ this.materialize(record);
29841
+ }
29842
+ }
29843
+ }
29844
+ }
29845
+ onComponentDeleted(id) {
29846
+ if (this._disposed) {
29847
+ return;
29848
+ }
29849
+ this.dispatchedErrors.delete(id);
29850
+ const model = this.surface.componentsModel.get(id);
29851
+ const affected = this.nodesByComponentId.get(id);
29852
+ if (!affected) {
29853
+ return;
29854
+ }
29855
+ const parentsToRefresh = /* @__PURE__ */ new Set();
29856
+ let rootAffected = false;
29857
+ for (const node of [...affected]) {
29858
+ const record = this.records.get(node);
29859
+ if (!record) {
29860
+ continue;
29861
+ }
29862
+ if (record.parent) {
29863
+ parentsToRefresh.add(record.parent);
29864
+ } else {
29865
+ rootAffected = true;
29866
+ }
29867
+ }
29868
+ if (rootAffected && this.rootRecord) {
29869
+ if (!model) {
29870
+ this.disposeNode(this.rootRecord.node);
29871
+ this.rootRecord = void 0;
29872
+ setValue(this.rootNode, void 0);
29873
+ } else if (this.rootRecord.componentModel !== model) {
29874
+ this.disposeNode(this.rootRecord.node);
29875
+ this.rootRecord = void 0;
29876
+ this.buildRoot();
29877
+ }
29878
+ }
29879
+ for (const parent of parentsToRefresh) {
29880
+ const record = this.records.get(parent);
29881
+ if (record && !parent.disposed) {
29882
+ this.materialize(record);
29883
+ }
29884
+ }
29885
+ }
29886
+ /**
29887
+ * Creates a node for one (componentId, dataPath) edge. A missing component
29888
+ * definition yields a placeholder node and registers the parent for a
29889
+ * refresh when the definition arrives.
29890
+ */
29891
+ createNode(componentId2, dataPath, edgeKey, parent, occurrence = 1) {
29892
+ const model = this.surface.componentsModel.get(componentId2);
29893
+ if (!model) {
29894
+ const record2 = this.registerNode(new MutableComponentNode(instanceIdFor(componentId2, dataPath, occurrence), componentId2, PLACEHOLDER_TYPE, dataPath, {}, void 0, "pending"), { edgeKey, parent, occurrence, refFields: EMPTY_REF_FIELDS2 });
29895
+ if (parent) {
29896
+ this.registerPendingParent(componentId2, parent);
29897
+ }
29898
+ return record2.node;
29899
+ }
29900
+ const api = this.catalog.components.get(model.type);
29901
+ if (!api) {
29902
+ this.dispatchOnce("UNKNOWN_COMPONENT_TYPE", componentId2, dataPath, `Component '${componentId2}' has type '${model.type}', which is not in catalog '${this.catalog.id}'.`);
29903
+ return this.registerNode(new MutableComponentNode(instanceIdFor(componentId2, dataPath, occurrence), componentId2, model.type, dataPath, {}, void 0, "unknown-type"), { edgeKey, parent, occurrence, refFields: EMPTY_REF_FIELDS2, componentModel: model }).node;
29904
+ }
29905
+ this.clearDispatched(componentId2, dataPath);
29906
+ const context = new ComponentContext(this.surface, componentId2, dataPath);
29907
+ const binder = new GenericBinder(context, api.schema);
29908
+ const record = this.registerNode(new MutableComponentNode(instanceIdFor(componentId2, dataPath, occurrence), componentId2, model.type, dataPath, {}, api), {
29909
+ edgeKey,
29910
+ parent,
29911
+ occurrence,
29912
+ refFields: extractRefFields(api.schema),
29913
+ behavior: scrapeSchemaBehavior(api.schema),
29914
+ context,
29915
+ componentModel: model,
29916
+ binder
29917
+ });
29918
+ record.binderSub = binder.subscribe((raw) => {
29919
+ record.lastBinderProps = raw;
29920
+ this.materialize(record);
29921
+ });
29922
+ record.lastBinderProps = binder.snapshot;
29923
+ this.materialize(record);
29924
+ return record.node;
29925
+ }
29926
+ registerNode(node, partial) {
29927
+ const record = {
29928
+ node,
29929
+ edgeKey: partial.edgeKey,
29930
+ parent: partial.parent,
29931
+ occurrence: partial.occurrence,
29932
+ refFields: partial.refFields,
29933
+ behavior: partial.behavior,
29934
+ context: partial.context,
29935
+ componentModel: partial.componentModel,
29936
+ binder: partial.binder,
29937
+ childEdges: /* @__PURE__ */ new Map()
29938
+ };
29939
+ this.records.set(node, record);
29940
+ this.nodesByEdge.set(partial.edgeKey, node);
29941
+ let byId = this.nodesByComponentId.get(node.componentId);
29942
+ if (!byId) {
29943
+ byId = /* @__PURE__ */ new Set();
29944
+ this.nodesByComponentId.set(node.componentId, byId);
29945
+ }
29946
+ byId.add(node);
29947
+ return record;
29948
+ }
29949
+ /**
29950
+ * Returns the node for a child edge, reusing the cached node when the edge
29951
+ * is unchanged and replacing it (placeholder upgrade or downgrade, id
29952
+ * change, type change) when it is not.
29953
+ */
29954
+ childNode(componentId2, dataPath, edgeKey, parent, occurrence = 1) {
29955
+ const existing = this.nodesByEdge.get(edgeKey);
29956
+ if (this.isCyclic(componentId2, dataPath, parent)) {
29957
+ if (existing && !existing.disposed && existing.isPlaceholder && this.records.get(existing)?.occurrence === occurrence) {
29958
+ return existing;
29959
+ }
29960
+ if (existing && !existing.disposed) {
29961
+ this.disposeNode(existing);
29962
+ }
29963
+ this.dispatchOnce("CYCLIC_REFERENCE", componentId2, dataPath, `Component '${componentId2}' at '${dataPath}' is referenced by one of its own descendants; rendering a placeholder instead.`);
29964
+ return this.registerNode(new MutableComponentNode(instanceIdFor(componentId2, dataPath, occurrence), componentId2, PLACEHOLDER_TYPE, dataPath, {}, void 0, "cyclic"), { edgeKey, parent, occurrence, refFields: EMPTY_REF_FIELDS2 }).node;
29965
+ }
29966
+ if (existing && !existing.disposed) {
29967
+ const model = this.surface.componentsModel.get(componentId2);
29968
+ const api = model ? this.catalog.components.get(model.type) : void 0;
29969
+ const existingRecord = this.records.get(existing);
29970
+ const upToDate = existing.componentId === componentId2 && existing.dataPath === dataPath && existingRecord?.occurrence === occurrence && (existing.isPlaceholder ? model === void 0 && existing.state === "pending" || model !== void 0 && api === void 0 && existing.state === "unknown-type" && existingRecord?.componentModel === model : model !== void 0 && existing.type === model.type && existingRecord?.componentModel === model);
29971
+ if (upToDate) {
29972
+ if (existing.state === "pending") {
29973
+ this.registerPendingParent(componentId2, parent);
29974
+ }
29975
+ return existing;
29976
+ }
29977
+ this.disposeNode(existing);
29978
+ }
29979
+ return this.createNode(componentId2, dataPath, edgeKey, parent, occurrence);
29980
+ }
29981
+ /** Registers a parent to be refreshed when `componentId` arrives. */
29982
+ registerPendingParent(componentId2, parent) {
29983
+ let waiting = this.pendingParents.get(componentId2);
29984
+ if (!waiting) {
29985
+ waiting = /* @__PURE__ */ new Set();
29986
+ this.pendingParents.set(componentId2, waiting);
29987
+ }
29988
+ waiting.add(parent);
29989
+ }
29990
+ /** True when (componentId, dataPath) already appears in the parent chain. */
29991
+ isCyclic(componentId2, dataPath, parent) {
29992
+ for (let node = parent; node; node = this.records.get(node)?.parent) {
29993
+ if (node.componentId === componentId2 && node.dataPath === dataPath) {
29994
+ return true;
29995
+ }
29996
+ }
29997
+ return false;
29998
+ }
29999
+ /**
30000
+ * Rebuilds a node's resolved props from its binder output: child reference
30001
+ * properties become live `ComponentNode`s, children this parent no longer
30002
+ * references are disposed, and unchanged values keep reference identity so
30003
+ * the shallow comparison in `MutableComponentNode.setProps` stays exact.
30004
+ */
30005
+ materialize(record) {
30006
+ if (record.node.disposed) {
30007
+ return;
30008
+ }
30009
+ const raw = record.lastBinderProps ?? record.binder?.snapshot ?? {};
30010
+ const next = { ...raw };
30011
+ const newEdges = /* @__PURE__ */ new Map();
30012
+ const modelProps = record.componentModel?.properties;
30013
+ if (modelProps) {
30014
+ for (const key of record.refFields.keys()) {
30015
+ if (key in next && !(key in modelProps)) {
30016
+ delete next[key];
30017
+ }
30018
+ }
30019
+ }
30020
+ const occurrences = /* @__PURE__ */ new Map();
30021
+ const resolveChild = (slot, componentId2, dataPath) => {
30022
+ const occurrenceKey = `${escapeIdPart(componentId2)}@${escapeIdPart(dataPath)}`;
30023
+ const occurrence = (occurrences.get(occurrenceKey) ?? 0) + 1;
30024
+ occurrences.set(occurrenceKey, occurrence);
30025
+ const edgeKey = `${record.edgeKey}>${slot}>${occurrenceKey}`;
30026
+ const child = this.childNode(componentId2, dataPath, edgeKey, record.node, occurrence);
30027
+ newEdges.set(edgeKey, child);
30028
+ return child;
30029
+ };
30030
+ for (const [key, ref] of record.refFields) {
30031
+ switch (ref.kind) {
30032
+ case "single": {
30033
+ const value = next[key];
30034
+ if (typeof value === "string" && value) {
30035
+ next[key] = resolveChild(escapeIdPart(key), value, record.node.dataPath);
30036
+ }
30037
+ break;
30038
+ }
30039
+ case "list": {
30040
+ const value = next[key];
30041
+ if (!Array.isArray(value)) {
30042
+ break;
30043
+ }
30044
+ next[key] = value.map((item, index) => {
30045
+ if (typeof item === "string" && item) {
30046
+ return resolveChild(`${escapeIdPart(key)}[${index}]`, item, record.node.dataPath);
30047
+ }
30048
+ if (item && typeof item === "object" && !Array.isArray(item)) {
30049
+ const entry = item;
30050
+ if (typeof entry.id === "string" && typeof entry.basePath === "string") {
30051
+ return resolveChild(`${escapeIdPart(key)}[${index}]`, entry.id, entry.basePath);
30052
+ }
30053
+ if (typeof entry.componentId === "string" && entry.componentId) {
30054
+ return resolveChild(`${escapeIdPart(key)}[${index}]`, entry.componentId, record.node.dataPath);
30055
+ }
30056
+ }
30057
+ return item;
30058
+ });
30059
+ break;
30060
+ }
30061
+ case "nested": {
30062
+ const value = next[key];
30063
+ if (!Array.isArray(value)) {
30064
+ break;
30065
+ }
30066
+ next[key] = value.map((item, index) => {
30067
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
30068
+ return item;
30069
+ }
30070
+ const entry = { ...item };
30071
+ let resolvedAny = false;
30072
+ for (const subKey of ref.keys) {
30073
+ const childId = entry[subKey];
30074
+ if (typeof childId === "string" && childId) {
30075
+ entry[subKey] = resolveChild(`${escapeIdPart(key)}[${index}].${escapeIdPart(subKey)}`, childId, record.node.dataPath);
30076
+ resolvedAny = true;
30077
+ }
30078
+ }
30079
+ return resolvedAny ? entry : item;
30080
+ });
30081
+ break;
30082
+ }
30083
+ }
30084
+ }
30085
+ for (const [edgeKey, child] of record.childEdges) {
30086
+ if (!newEdges.has(edgeKey)) {
30087
+ this.disposeNode(child);
30088
+ if (child.isPlaceholder) {
30089
+ const stillWaiting = [...newEdges.values()].some((other) => other.isPlaceholder && other.componentId === child.componentId);
30090
+ if (!stillWaiting) {
30091
+ const waiting = this.pendingParents.get(child.componentId);
30092
+ if (waiting) {
30093
+ waiting.delete(record.node);
30094
+ if (waiting.size === 0) {
30095
+ this.pendingParents.delete(child.componentId);
30096
+ }
30097
+ }
30098
+ }
30099
+ }
30100
+ }
30101
+ }
30102
+ record.childEdges = newEdges;
30103
+ const wrapped = record.behavior && record.context ? wrapDynamicValues(next, record.behavior, modelProps ?? {}, record.context.dataContext) : next;
30104
+ const previous = peekValue(record.node.props);
30105
+ for (const key of Object.keys(wrapped)) {
30106
+ wrapped[key] = stabilize(previous[key], wrapped[key]);
30107
+ }
30108
+ record.node.setProps(wrapped);
30109
+ }
30110
+ /** Disposes a node and, through parent-scoped ownership, its subtree. */
30111
+ disposeNode(node) {
30112
+ if (node.disposed) {
30113
+ return;
30114
+ }
30115
+ const record = this.records.get(node);
30116
+ if (record) {
30117
+ for (const child of record.childEdges.values()) {
30118
+ this.disposeNode(child);
30119
+ }
30120
+ record.childEdges.clear();
30121
+ record.binderSub?.unsubscribe();
30122
+ record.binderSub = void 0;
30123
+ if (this.nodesByEdge.get(record.edgeKey) === node) {
30124
+ this.nodesByEdge.delete(record.edgeKey);
30125
+ }
30126
+ this.records.delete(node);
30127
+ }
30128
+ const byId = this.nodesByComponentId.get(node.componentId);
30129
+ if (byId) {
30130
+ byId.delete(node);
30131
+ if (byId.size === 0) {
30132
+ this.nodesByComponentId.delete(node.componentId);
30133
+ }
30134
+ }
30135
+ for (const [componentId2, waiting] of this.pendingParents) {
30136
+ waiting.delete(node);
30137
+ if (waiting.size === 0) {
30138
+ this.pendingParents.delete(componentId2);
30139
+ }
30140
+ }
30141
+ if (node.state === "cyclic") {
30142
+ this.clearDispatched(node.componentId, node.dataPath);
30143
+ }
30144
+ node.dispose();
30145
+ }
30146
+ };
30147
+ var ID_PART_ESCAPES = {
30148
+ "~": "~0",
30149
+ "#": "~1",
30150
+ "[": "~2",
30151
+ "]": "~3",
30152
+ ">": "~4",
30153
+ "@": "~5"
30154
+ };
30155
+ function escapeIdPart(part) {
30156
+ return part.replace(/[~#[\]>@]/g, (match2) => ID_PART_ESCAPES[match2]);
30157
+ }
30158
+ function instanceIdFor(componentId2, dataPath, occurrence) {
30159
+ const trimmed = dataPath.replace(/\/+$/, "") || ROOT_DATA_PATH;
30160
+ const base = dataPath === ROOT_DATA_PATH ? escapeIdPart(componentId2) : `${escapeIdPart(componentId2)}-[${escapeIdPart(trimmed)}]`;
30161
+ return occurrence > 1 ? `${base}#${occurrence}` : base;
30162
+ }
30163
+ function wrapDynamicValues(value, behavior, raw, dataContext) {
30164
+ switch (behavior.type) {
30165
+ case "DYNAMIC": {
30166
+ const path = raw && typeof raw === "object" && !Array.isArray(raw) && typeof raw.path === "string" ? raw.path : void 0;
30167
+ if (path === void 0) {
30168
+ return new ResolvedBinding(value);
30169
+ }
30170
+ return new WritableBinding(value, (newValue) => dataContext.set(path, newValue), path);
30171
+ }
30172
+ case "ARRAY": {
30173
+ if (!Array.isArray(value)) {
30174
+ return value;
30175
+ }
30176
+ const rawItems = Array.isArray(raw) ? raw : [];
30177
+ return value.map((item, index) => wrapDynamicValues(item, behavior.element, rawItems[index], dataContext));
30178
+ }
30179
+ case "OBJECT": {
30180
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
30181
+ return value;
30182
+ }
30183
+ const setterNames = /* @__PURE__ */ new Set();
30184
+ for (const [key, childBehavior] of Object.entries(behavior.shape)) {
30185
+ if (childBehavior.type === "DYNAMIC") {
30186
+ setterNames.add(`set${key.charAt(0).toUpperCase()}${key.slice(1)}`);
30187
+ }
30188
+ }
30189
+ const rawRecord = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
30190
+ const out = {};
30191
+ for (const [key, item] of Object.entries(value)) {
30192
+ if (setterNames.has(key)) {
30193
+ continue;
30194
+ }
30195
+ out[key] = wrapDynamicValues(item, behavior.shape[key] ?? { type: "STATIC" }, rawRecord[key], dataContext);
30196
+ }
30197
+ for (const [key, childBehavior] of Object.entries(behavior.shape)) {
30198
+ if (childBehavior.type === "DYNAMIC" && !(key in out)) {
30199
+ out[key] = new ResolvedBinding(void 0);
30200
+ }
30201
+ }
30202
+ return out;
30203
+ }
30204
+ default:
30205
+ return value;
30206
+ }
30207
+ }
30208
+ function stabilize(prev, next) {
30209
+ if (Object.is(prev, next)) {
30210
+ return next;
30211
+ }
30212
+ if (prev instanceof ResolvedBinding && next instanceof ResolvedBinding) {
30213
+ return sameBinding(prev, next) ? prev : next;
30214
+ }
30215
+ if (isComponentNode(prev) || isComponentNode(next)) {
30216
+ return next;
30217
+ }
30218
+ if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
30219
+ let allSame = true;
30220
+ const out = next.map((item, i2) => {
30221
+ const stabilized = stabilize(prev[i2], item);
30222
+ if (!Object.is(stabilized, prev[i2])) {
30223
+ allSame = false;
30224
+ }
30225
+ return stabilized;
30226
+ });
30227
+ return allSame ? prev : out;
30228
+ }
30229
+ if (isPlainObject2(prev) && isPlainObject2(next)) {
30230
+ const prevKeys = Object.keys(prev);
30231
+ const nextKeys = Object.keys(next);
30232
+ if (prevKeys.length === nextKeys.length) {
30233
+ let allSame = true;
30234
+ const out = {};
30235
+ for (const key of nextKeys) {
30236
+ const stabilized = stabilize(prev[key], next[key]);
30237
+ out[key] = stabilized;
30238
+ if (!(key in prev) || !Object.is(stabilized, prev[key])) {
30239
+ allSame = false;
30240
+ }
30241
+ }
30242
+ return allSame ? prev : out;
30243
+ }
30244
+ }
30245
+ return next;
30246
+ }
30247
+ function isPlainObject2(value) {
30248
+ if (!value || typeof value !== "object" || Array.isArray(value) || isComponentNode(value)) {
30249
+ return false;
30250
+ }
30251
+ const proto = Object.getPrototypeOf(value);
30252
+ return proto === Object.prototype || proto === null;
30253
+ }
30254
+
30255
+ // node_modules/@a2ui/web_core/src/v0_9/basic_catalog/expressions/expression_parser.js
30256
+ var ExpressionParser = class _ExpressionParser {
30257
+ static {
30258
+ this.MAX_DEPTH = 10;
30259
+ }
30260
+ /**
29054
30261
  * Parses an input string into an array of DynamicValues.
29055
30262
  * If the input contains no interpolation, it returns the raw string as a single literal.
29056
30263
  */
@@ -31442,7 +32649,9 @@
31442
32649
  name: "Row",
31443
32650
  schema: external_exports.object({
31444
32651
  ...CommonProps,
31445
- "children": ChildListSchema.describe("Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID."),
32652
+ "children": childList({
32653
+ description: "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID."
32654
+ }),
31446
32655
  "justify": external_exports.enum(["center", "end", "spaceAround", "spaceBetween", "spaceEvenly", "start", "stretch"]).default("start").describe("Defines the arrangement of children along the main axis (horizontally). Use 'spaceBetween' to push items to the edges, or 'start'/'end'/'center' to pack them together.").optional(),
31447
32656
  "align": external_exports.enum(["start", "center", "end", "stretch"]).default("stretch").describe("Defines the alignment of children along the cross axis (vertically). This is similar to the CSS 'align-items' property, but uses camelCase values (e.g., 'start').").optional()
31448
32657
  }).strict().describe("A layout component that arranges its children horizontally. To create a grid layout, nest Columns within this Row.")
@@ -31451,7 +32660,9 @@
31451
32660
  name: "Column",
31452
32661
  schema: external_exports.object({
31453
32662
  ...CommonProps,
31454
- "children": ChildListSchema.describe("Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID."),
32663
+ "children": childList({
32664
+ description: "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID."
32665
+ }),
31455
32666
  "justify": external_exports.enum(["start", "center", "end", "spaceBetween", "spaceAround", "spaceEvenly", "stretch"]).default("start").describe("Defines the arrangement of children along the main axis (vertically). Use 'spaceBetween' to push items to the edges (e.g. header at top, footer at bottom), or 'start'/'end'/'center' to pack them together.").optional(),
31456
32667
  "align": external_exports.enum(["center", "end", "start", "stretch"]).default("stretch").describe("Defines the alignment of children along the cross axis (horizontally). This is similar to the CSS 'align-items' property.").optional()
31457
32668
  }).strict().describe("A layout component that arranges its children vertically. To create a grid layout, nest Rows within this Column.")
@@ -31460,7 +32671,9 @@
31460
32671
  name: "List",
31461
32672
  schema: external_exports.object({
31462
32673
  ...CommonProps,
31463
- "children": ChildListSchema.describe("Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list."),
32674
+ "children": childList({
32675
+ description: "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list."
32676
+ }),
31464
32677
  "direction": external_exports.enum(["vertical", "horizontal"]).default("vertical").describe("The direction in which the list items are laid out.").optional(),
31465
32678
  "align": external_exports.enum(["start", "center", "end", "stretch"]).default("stretch").describe("Defines the alignment of children along the cross axis.").optional(),
31466
32679
  "listStyle": external_exports.enum(["ordered", "unordered", "none"]).describe("The style of the list (ordered, unordered, or none).").optional()
@@ -31470,7 +32683,9 @@
31470
32683
  name: "Card",
31471
32684
  schema: external_exports.object({
31472
32685
  ...CommonProps,
31473
- "child": ComponentIdSchema.describe("The ID of the single child component to be rendered inside the card. To display multiple elements, you MUST wrap them in a layout component (like Column or Row) and pass that container's ID here. Do NOT pass multiple IDs or a non-existent ID. Do NOT define the child component inline.")
32686
+ "child": componentId({
32687
+ description: "The ID of the single child component to be rendered inside the card. To display multiple elements, you MUST wrap them in a layout component (like Column or Row) and pass that container's ID here. Do NOT pass multiple IDs or a non-existent ID. Do NOT define the child component inline."
32688
+ })
31474
32689
  }).strict()
31475
32690
  };
31476
32691
  var TabsApi = {
@@ -31479,7 +32694,9 @@
31479
32694
  ...CommonProps,
31480
32695
  "tabs": external_exports.array(external_exports.object({
31481
32696
  "title": DynamicStringSchema.describe("The tab title."),
31482
- "child": ComponentIdSchema.describe("The ID of the child component. Do NOT define the component inline.")
32697
+ "child": componentId({
32698
+ description: "The ID of the child component. Do NOT define the component inline."
32699
+ })
31483
32700
  }).strict()).min(1).describe("An array of objects, where each object defines a tab with a title and a child component.")
31484
32701
  }).strict()
31485
32702
  };
@@ -31487,8 +32704,12 @@
31487
32704
  name: "Modal",
31488
32705
  schema: external_exports.object({
31489
32706
  ...CommonProps,
31490
- "trigger": ComponentIdSchema.describe("The ID of the component that opens the modal when interacted with (e.g., a button). Do NOT define the component inline."),
31491
- "content": ComponentIdSchema.describe("The ID of the component to be displayed inside the modal. Do NOT define the component inline.")
32707
+ "trigger": componentId({
32708
+ description: "The ID of the component that opens the modal when interacted with (e.g., a button). Do NOT define the component inline."
32709
+ }),
32710
+ "content": componentId({
32711
+ description: "The ID of the component to be displayed inside the modal. Do NOT define the component inline."
32712
+ })
31492
32713
  }).strict()
31493
32714
  };
31494
32715
  var DividerApi = {
@@ -31502,7 +32723,9 @@
31502
32723
  name: "Button",
31503
32724
  schema: external_exports.object({
31504
32725
  ...CommonProps,
31505
- "child": ComponentIdSchema.describe("The ID of the child component. Use a 'Text' component for a labeled button. Only use an 'Icon' if the requirements explicitly ask for an icon-only button. Do NOT define the child component inline."),
32726
+ "child": componentId({
32727
+ description: "The ID of the child component. Use a 'Text' component for a labeled button. Only use an 'Icon' if the requirements explicitly ask for an icon-only button. Do NOT define the child component inline."
32728
+ }),
31506
32729
  "variant": external_exports.enum(["default", "primary", "borderless"]).default("default").describe("A hint for the button style. If omitted, a default button style is used. 'primary' indicates this is the main call-to-action button. 'borderless' means the button has no visual border or background, making its child content appear like a clickable link.").optional(),
31507
32730
  "action": ActionSchema.optional(),
31508
32731
  ...CheckableSchema.shape
@@ -31671,104 +32894,243 @@
31671
32894
  // node_modules/@a2ui/react/v0_9/index.js
31672
32895
  var import_react = __toESM(require_react(), 1);
31673
32896
  var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
31674
- var ResolvedChild = (0, import_react.memo)(
32897
+ var NodeSurfaceContext = (0, import_react.createContext)(
32898
+ null
32899
+ );
32900
+ var LoadingPlaceholder = ({ componentId: componentId2 }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "gray", padding: "4px" }, children: [
32901
+ "[Loading ",
32902
+ componentId2,
32903
+ "...]"
32904
+ ] });
32905
+ var reportedUnresolved = /* @__PURE__ */ new WeakMap();
32906
+ var UnresolvedChildReference = ({ surface, id, requestedPath, detail }) => {
32907
+ const message2 = `Unresolved child reference '${id}' at '${requestedPath}': ${detail}`;
32908
+ (0, import_react.useEffect)(() => {
32909
+ if (!surface) {
32910
+ return;
32911
+ }
32912
+ let seen = reportedUnresolved.get(surface);
32913
+ if (!seen) {
32914
+ seen = /* @__PURE__ */ new Set();
32915
+ reportedUnresolved.set(surface, seen);
32916
+ }
32917
+ const key = JSON.stringify([id, requestedPath]);
32918
+ if (!seen.has(key)) {
32919
+ seen.add(key);
32920
+ void surface.dispatchError({ code: "UNRESOLVED_CHILD_REFERENCE", message: message2 });
32921
+ }
32922
+ }, [surface, id, requestedPath, message2]);
32923
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "red" }, children: message2 });
32924
+ };
32925
+ function useSignalValue(signal2) {
32926
+ const subscribe = (0, import_react.useCallback)(
32927
+ (onChange) => effect(() => {
32928
+ getValue(signal2);
32929
+ onChange();
32930
+ }),
32931
+ [signal2]
32932
+ );
32933
+ const getSnapshot = (0, import_react.useCallback)(() => peekValue(signal2), [signal2]);
32934
+ return (0, import_react.useSyncExternalStore)(subscribe, getSnapshot);
32935
+ }
32936
+ function newChildIndex() {
32937
+ return { byToken: /* @__PURE__ */ new Map(), byId: /* @__PURE__ */ new Map() };
32938
+ }
32939
+ function setChild(map, id, child, firstWins) {
32940
+ let byPath = map.get(id);
32941
+ if (!byPath) {
32942
+ byPath = /* @__PURE__ */ new Map();
32943
+ map.set(id, byPath);
32944
+ }
32945
+ if (!firstWins || !byPath.has(child.dataPath)) {
32946
+ byPath.set(child.dataPath, child);
32947
+ }
32948
+ }
32949
+ function registerChild(index, child) {
32950
+ setChild(index.byToken, child.instanceId, child, false);
32951
+ setChild(index.byId, child.componentId, child, true);
32952
+ return child.instanceId;
32953
+ }
32954
+ function toViewValue(parent, value, index) {
32955
+ if (isComponentNode(value)) {
32956
+ const token = registerChild(index, value);
32957
+ if (value.dataPath !== parent.dataPath) {
32958
+ return { id: token, basePath: value.dataPath };
32959
+ }
32960
+ return token;
32961
+ }
32962
+ if (value instanceof ResolvedBinding) {
32963
+ return toViewValue(parent, value.value, index);
32964
+ }
32965
+ if (Array.isArray(value)) {
32966
+ return value.map((item) => toViewValue(parent, item, index));
32967
+ }
32968
+ if (isPlainObject3(value)) {
32969
+ return toViewProps(parent, value, index);
32970
+ }
32971
+ return value;
32972
+ }
32973
+ function isPlainObject3(value) {
32974
+ if (!value || typeof value !== "object") {
32975
+ return false;
32976
+ }
32977
+ const proto = Object.getPrototypeOf(value);
32978
+ return proto === Object.prototype || proto === null;
32979
+ }
32980
+ function toViewProps(parent, props, index) {
32981
+ const result = {};
32982
+ for (const [key, inner] of Object.entries(props)) {
32983
+ if (inner instanceof ResolvedBinding) {
32984
+ result[key] = toViewValue(parent, inner.value, index);
32985
+ result[`set${key.charAt(0).toUpperCase()}${key.slice(1)}`] = isWritable(inner) ? inner.set : () => {
32986
+ };
32987
+ } else {
32988
+ result[key] = toViewValue(parent, inner, index);
32989
+ }
32990
+ }
32991
+ return result;
32992
+ }
32993
+ function useNodeView(node, buildChild) {
32994
+ const surface = (0, import_react.useContext)(NodeSurfaceContext);
32995
+ const resolved = useSignalValue(node.props);
32996
+ const { viewProps, childIndex } = (0, import_react.useMemo)(() => {
32997
+ const index = newChildIndex();
32998
+ return { viewProps: toViewProps(node, resolved, index), childIndex: index };
32999
+ }, [node, resolved]);
33000
+ const context = (0, import_react.useMemo)(
33001
+ () => surface && surface.componentsModel.get(node.componentId) ? new ComponentContext(surface, node.componentId, node.dataPath) : void 0,
33002
+ [surface, node]
33003
+ );
33004
+ const resolveThrough = (0, import_react.useCallback)(
33005
+ (map, id, basePath) => {
33006
+ const requested = basePath ?? node.dataPath;
33007
+ const byPath = map.get(id);
33008
+ const childNode = byPath?.get(requested);
33009
+ if (childNode) {
33010
+ return buildChild(childNode, basePath);
33011
+ }
33012
+ const elsewhere = byPath ? [...byPath.keys()] : [];
33013
+ if (elsewhere.length > 0) {
33014
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
33015
+ UnresolvedChildReference,
33016
+ {
33017
+ surface,
33018
+ id,
33019
+ requestedPath: requested,
33020
+ detail: `instances exist at ${elsewhere.join(", ")}. Instances are created only at the data paths the payload implies; buildChild selects among them.`
33021
+ },
33022
+ JSON.stringify([id, requested])
33023
+ );
33024
+ }
33025
+ return buildChild(id, basePath);
33026
+ },
33027
+ [buildChild, node, surface]
33028
+ );
33029
+ const viewBuildChild = (0, import_react.useCallback)(
33030
+ (id, basePath) => resolveThrough(childIndex.byToken, id, basePath),
33031
+ [resolveThrough, childIndex]
33032
+ );
33033
+ const rawBuildChild = (0, import_react.useCallback)(
33034
+ (id, basePath) => resolveThrough(childIndex.byId, id, basePath),
33035
+ [resolveThrough, childIndex]
33036
+ );
33037
+ if (!surface) {
33038
+ throw new Error("A2UI component views render only inside A2uiSurface.");
33039
+ }
33040
+ return { viewProps, context, viewBuildChild, rawBuildChild };
33041
+ }
33042
+ var RenderFallback = ({ node, impl, buildChild }) => {
33043
+ const { context, rawBuildChild } = useNodeView(node, buildChild);
33044
+ const Render = impl.render;
33045
+ if (!context) {
33046
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPlaceholder, { componentId: node.componentId });
33047
+ }
33048
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Render, { context, buildChild: rawBuildChild });
33049
+ };
33050
+ var NodeView = (0, import_react.memo)(
31675
33051
  ({
31676
33052
  surface,
31677
- id,
31678
- basePath,
31679
- compImpl,
31680
- componentModel
33053
+ node
31681
33054
  }) => {
31682
- const ComponentToRender = compImpl.render;
31683
- const context = (0, import_react.useMemo)(
31684
- () => new ComponentContext(surface, id, basePath),
31685
- // componentModel is used as a trigger for recreation even if not in the body
31686
- // eslint-disable-next-line react-hooks/exhaustive-deps
31687
- [surface, id, basePath, componentModel]
31688
- );
31689
33055
  const buildChild = (0, import_react.useCallback)(
31690
- (childId, specificPath) => {
31691
- const path = specificPath || context.dataContext.path;
33056
+ (child, basePath) => {
33057
+ if (isComponentNode(child)) {
33058
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NodeView, { surface, node: child }, child.instanceId);
33059
+ }
33060
+ const requested = basePath ?? node.dataPath;
33061
+ const detail = surface.componentsModel.get(child) ? "the component exists, but the catalog schema does not mark the referencing property as a component id. Use componentId() or childList() from @a2ui/web_core." : "no component with this id exists on the surface.";
31692
33062
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
31693
- DeferredChild,
33063
+ UnresolvedChildReference,
31694
33064
  {
31695
33065
  surface,
31696
- id: childId,
31697
- basePath: path
33066
+ id: child,
33067
+ requestedPath: requested,
33068
+ detail
31698
33069
  },
31699
- `${childId}-${path}`
33070
+ JSON.stringify([child, requested])
31700
33071
  );
31701
33072
  },
31702
- [surface, context.dataContext.path]
33073
+ [surface, node]
31703
33074
  );
31704
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComponentToRender, { context, buildChild });
33075
+ if (node.state === "unknown-type") {
33076
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "red" }, children: [
33077
+ "Unknown component type: ",
33078
+ node.type
33079
+ ] });
33080
+ }
33081
+ if (node.isPlaceholder) {
33082
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPlaceholder, { componentId: node.componentId });
33083
+ }
33084
+ const impl = node.impl;
33085
+ if (!impl) {
33086
+ return null;
33087
+ }
33088
+ const View = impl.view;
33089
+ if (!View) {
33090
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RenderFallback, { node, impl, buildChild });
33091
+ }
33092
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, { node, buildChild });
31705
33093
  }
31706
33094
  );
31707
- ResolvedChild.displayName = "ResolvedChild";
31708
- var DeferredChild = (0, import_react.memo)(({ surface, id, basePath }) => {
31709
- const store = (0, import_react.useMemo)(() => {
31710
- let version = 0;
31711
- return {
31712
- subscribe: (cb) => {
31713
- const unsub1 = surface.componentsModel.onCreated.subscribe((comp) => {
31714
- if (comp.id === id) {
31715
- version++;
31716
- cb();
31717
- }
31718
- });
31719
- const unsub2 = surface.componentsModel.onDeleted.subscribe((delId) => {
31720
- if (delId === id) {
31721
- version++;
31722
- cb();
31723
- }
31724
- });
31725
- return () => {
31726
- unsub1.unsubscribe();
31727
- unsub2.unsubscribe();
31728
- };
31729
- },
31730
- getSnapshot: () => {
31731
- const comp = surface.componentsModel.get(id);
31732
- return comp ? `${comp.type}-${version}` : `missing-${version}`;
31733
- }
31734
- };
31735
- }, [surface, id]);
31736
- (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot);
31737
- const componentModel = surface.componentsModel.get(id);
31738
- if (!componentModel) {
31739
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "gray", padding: "4px" }, children: [
31740
- "[Loading ",
31741
- id,
31742
- "...]"
31743
- ] });
31744
- }
31745
- const compImpl = surface.catalog.components.get(componentModel.type);
31746
- if (!compImpl) {
31747
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "red" }, children: [
31748
- "Unknown component: ",
31749
- componentModel.type
31750
- ] });
31751
- }
31752
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
31753
- ResolvedChild,
31754
- {
31755
- surface,
31756
- id,
31757
- basePath,
31758
- componentModel,
31759
- compImpl
31760
- }
33095
+ NodeView.displayName = "NodeView";
33096
+ var A2uiSurface = ({ surface }) => {
33097
+ const box = (0, import_react.useMemo)(
33098
+ () => ({ resolver: void 0 }),
33099
+ // eslint-disable-next-line react-hooks/exhaustive-deps
33100
+ [surface]
31761
33101
  );
31762
- });
31763
- DeferredChild.displayName = "DeferredChild";
31764
- var A2uiSurface = ({
31765
- surface
31766
- }) => {
31767
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeferredChild, { surface, id: "root", basePath: "/" });
33102
+ const subscribe = (0, import_react.useCallback)(
33103
+ (onChange) => {
33104
+ const resolver = new NodeResolver(surface, surface.catalog);
33105
+ box.resolver = resolver;
33106
+ const stopEffect = effect(() => {
33107
+ getValue(resolver.rootNode);
33108
+ onChange();
33109
+ });
33110
+ return () => {
33111
+ stopEffect();
33112
+ resolver.dispose();
33113
+ if (box.resolver === resolver) {
33114
+ box.resolver = void 0;
33115
+ }
33116
+ };
33117
+ },
33118
+ [surface, box]
33119
+ );
33120
+ const getSnapshot = (0, import_react.useCallback)(
33121
+ () => box.resolver ? peekValue(box.resolver.rootNode) : void 0,
33122
+ [box]
33123
+ );
33124
+ const root = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot);
33125
+ if (!root) {
33126
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPlaceholder, { componentId: "root" });
33127
+ }
33128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NodeSurfaceContext.Provider, { value: surface, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NodeView, { surface, node: root }) });
31768
33129
  };
31769
33130
  function createComponentImplementation(api, RenderComponent) {
31770
33131
  const MemoizedRender = (0, import_react.memo)(RenderComponent, (prev, next) => {
31771
33132
  if (prev.props !== next.props) return false;
33133
+ if (prev.buildChild !== next.buildChild) return false;
31772
33134
  if (prev.context.componentModel.id !== next.context.componentModel.id) return false;
31773
33135
  if (prev.context.dataContext.path !== next.context.dataContext.path) return false;
31774
33136
  return true;
@@ -31796,10 +33158,19 @@
31796
33158
  }, [binding]);
31797
33159
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MemoizedRender, { props: props || {}, buildChild, context });
31798
33160
  };
33161
+ const NodeView2 = ({ node, buildChild }) => {
33162
+ const { viewProps, context, viewBuildChild } = useNodeView(node, buildChild);
33163
+ if (!context) {
33164
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPlaceholder, { componentId: node.componentId });
33165
+ }
33166
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MemoizedRender, { props: viewProps, buildChild: viewBuildChild, context });
33167
+ };
33168
+ NodeView2.displayName = `${api.name}.view`;
31799
33169
  return {
31800
33170
  name: api.name,
31801
33171
  schema: api.schema,
31802
- render: ReactWrapper
33172
+ render: ReactWrapper,
33173
+ view: NodeView2
31803
33174
  };
31804
33175
  }
31805
33176
  var useBasicCatalogStyles = () => {
@@ -32043,9 +33414,9 @@
32043
33414
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("audio", { src: props.url, controls: true })
32044
33415
  ] });
32045
33416
  });
32046
- var ChildList = ({ childList, buildChild }) => {
32047
- if (!Array.isArray(childList)) return null;
32048
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: childList.map((childRef, index) => {
33417
+ var ChildList = ({ childList: childList2, buildChild }) => {
33418
+ if (!Array.isArray(childList2)) return null;
33419
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: childList2.map((childRef, index) => {
32049
33420
  if (typeof childRef === "string") {
32050
33421
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.default.Fragment, { children: buildChild(childRef) }, `${childRef}-${index}`);
32051
33422
  }