@symerian/symi 3.5.14 → 3.5.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 (165) hide show
  1. package/dist/{agent-Cq8f1rHB.js → agent-RWZSPbLw.js} +1 -1
  2. package/dist/{agent-CSOQs4VQ.js → agent-Za31LZ2H.js} +1 -1
  3. package/dist/{agents-BiKiy1SO.js → agents-CulBOE6L.js} +3 -3
  4. package/dist/{audit-DJURK8ly.js → audit-B1fVD2bA.js} +2 -2
  5. package/dist/{audit-BPhWpe_6.js → audit-BQnxE5w6.js} +2 -2
  6. package/dist/{auth-choice-9XyVfAyH.js → auth-choice-B8n3tJtT.js} +2 -2
  7. package/dist/{auth-choice-BYOypIGE.js → auth-choice-C8ElO44A.js} +2 -2
  8. package/dist/{banner-BDexjPFs.js → banner-B91SPus6.js} +1 -1
  9. package/dist/{browser-cli-BxDx4t2-.js → browser-cli-BvOz7txM.js} +3 -3
  10. package/dist/{browser-cli-BT0akXlr.js → browser-cli-CXDzGAN7.js} +3 -3
  11. package/dist/build-info.json +3 -3
  12. package/dist/bundled/boot-md/handler.js +4 -4
  13. package/dist/bundled/session-memory/handler.js +4 -4
  14. package/dist/{call-mzNPQq1S.js → call-A18kwyah.js} +2 -1
  15. package/dist/{call-BC1HAVqW.js → call-PpGwcPn-.js} +2 -1
  16. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  17. package/dist/{channel-options-Cy9aQzx9.js → channel-options-1G5HGFpn.js} +1 -1
  18. package/dist/{channel-options-BjgoCETm.js → channel-options-CsyyC4uc.js} +1 -1
  19. package/dist/{channels-cli-DokpJOeN.js → channels-cli-R3TK9Jwf.js} +9 -9
  20. package/dist/{channels-cli-R0UMOKTA.js → channels-cli-aF7d6Af9.js} +9 -9
  21. package/dist/{chrome-CmQwGAuL.js → chrome-OTJg3QKn.js} +7 -7
  22. package/dist/{cli-ay-COtm8.js → cli-Bguq-s8o.js} +6 -6
  23. package/dist/{cli-BnLVnWOZ.js → cli-CFaH6TRI.js} +6 -6
  24. package/dist/{client-BcvL_D-H.js → client-CdiymIXS.js} +32 -1
  25. package/dist/{client-BfnNfATE.js → client-DDqXo-cF.js} +32 -1
  26. package/dist/{command-registry-CjxdlqkY.js → command-registry-2hfSOaGL.js} +11 -11
  27. package/dist/{completion-cli-kGAGMr-I.js → completion-cli-BEO2AB41.js} +1 -1
  28. package/dist/{completion-cli-D2pLg5yF.js → completion-cli-TYU7Y_XZ.js} +2 -2
  29. package/dist/{config-cli-D12Nouyy.js → config-cli-Cvylxp-R.js} +1 -1
  30. package/dist/{config-cli-BAognmPE.js → config-cli-D6vpEtzB.js} +1 -1
  31. package/dist/{configure-CJp0NIbm.js → configure-BMRfSJ5h.js} +6 -6
  32. package/dist/{configure-B8-2sqW3.js → configure-DRDyxmMR.js} +6 -6
  33. package/dist/control-ui/css/style.css +80 -0
  34. package/dist/control-ui/index.html +1 -0
  35. package/dist/control-ui/js/gateway.js +10 -0
  36. package/dist/control-ui/js/symframe.js +353 -0
  37. package/dist/{cron-cli-DoXlzwQ0.js → cron-cli-DVEdIAaa.js} +3 -3
  38. package/dist/{cron-cli-BJzi2QtY.js → cron-cli-DlxcZT7g.js} +3 -3
  39. package/dist/{daemon-cli-CRGNFCN7.js → daemon-cli-6ZV3jmTp.js} +2 -2
  40. package/dist/{daemon-cli-DXHRewv8.js → daemon-cli-DqJhEk3T.js} +2 -2
  41. package/dist/daemon-cli.js +32 -0
  42. package/dist/{deliver-B04yNX82.js → deliver-BiWlR84Y.js} +4 -4
  43. package/dist/{devices-cli-DAG-TaOo.js → devices-cli-C4rLpzkl.js} +2 -2
  44. package/dist/{devices-cli-YdVaVQkF.js → devices-cli-C6EdHL_5.js} +2 -2
  45. package/dist/{doctor-completion-CmKOsLDy.js → doctor-completion-CvaSyxyp.js} +1 -1
  46. package/dist/{doctor-completion-Ca692KiP.js → doctor-completion-DgNgQFQQ.js} +1 -1
  47. package/dist/entry.js +1 -1
  48. package/dist/{exec-approvals-cli-Cnie7kMb.js → exec-approvals-cli-Ca54uWdL.js} +4 -4
  49. package/dist/{exec-approvals-cli-BuHNELGd.js → exec-approvals-cli-bu1S7v6i.js} +4 -4
  50. package/dist/extensionAPI.js +2 -2
  51. package/dist/{gateway-cli-zh8P3vbG.js → gateway-cli-BNhURE6O.js} +16 -16
  52. package/dist/{gateway-cli-CvzoUDQs.js → gateway-cli-DCTPCoQx.js} +16 -16
  53. package/dist/{gateway-rpc-st8ffJBC.js → gateway-rpc-DMSsr0Xn.js} +1 -1
  54. package/dist/{gateway-rpc-CIHuIeji.js → gateway-rpc-vivTzTCq.js} +1 -1
  55. package/dist/{glass-ui-ws-QqYp-Uof.js → glass-ui-ws-Bzs3ALoN.js} +13 -13
  56. package/dist/{glass-ui-ws-DCXg7AbP.js → glass-ui-ws-C88aJslb.js} +13 -13
  57. package/dist/{health-BIwN5H6b.js → health--v-C6lSf.js} +1 -1
  58. package/dist/{health-BaYDaHPT.js → health-D0jGdk53.js} +1 -1
  59. package/dist/{hooks-cli-ClMPrbD7.js → hooks-cli-CZ_pSdXS.js} +7 -7
  60. package/dist/{hooks-cli-CJ0OoLFk.js → hooks-cli-CrZvzan1.js} +7 -7
  61. package/dist/index.js +10 -10
  62. package/dist/llm-slug-generator.js +4 -4
  63. package/dist/{logs-cli-D8A5dpnm.js → logs-cli-Dde2Dp2w.js} +3 -3
  64. package/dist/{logs-cli-CK9YhKnf.js → logs-cli-vIxaNVmF.js} +3 -3
  65. package/dist/{manager-Ct4kRT7n.js → manager--GmDbwza.js} +1 -1
  66. package/dist/{manager-Dh_-GTcG.js → manager-BMA3iRMq.js} +1 -1
  67. package/dist/{manager-DjhxLEpd.js → manager-DjhE8yLr.js} +1 -1
  68. package/dist/{manager-807ZlqEf.js → manager-S5d36_EM.js} +1 -1
  69. package/dist/{memory-CkJCn1Gg.js → memory-BcdI7NSs.js} +3 -3
  70. package/dist/{memory-B2hM774N.js → memory-DBx1wEvf.js} +3 -3
  71. package/dist/{memory-cli-C3CONZGB.js → memory-cli-CQSVrNAK.js} +2 -2
  72. package/dist/{memory-cli-CPebu_bx.js → memory-cli-jNf_SaXU.js} +2 -2
  73. package/dist/{models-Cbad7KB1.js → models-BgZWEpSL.js} +3 -3
  74. package/dist/{models-cli-C1yhTK5G.js → models-cli-6tdy2DaI.js} +9 -9
  75. package/dist/{models-cli-B_U9E8SV.js → models-cli-CiL6wDtk.js} +8 -8
  76. package/dist/{node-cli-CFIBFPOd.js → node-cli-BTXwMEJE.js} +1 -1
  77. package/dist/{node-cli-Cmfs9las.js → node-cli-ClniLggz.js} +1 -1
  78. package/dist/{nodes-cli-DlkO0Hyw.js → nodes-cli-DLaX4pgX.js} +3 -3
  79. package/dist/{nodes-cli-BH1TUf3n.js → nodes-cli-DrhMUDXx.js} +3 -3
  80. package/dist/{onboard-CWNtW-LS.js → onboard-DRn6pFfO.js} +3 -3
  81. package/dist/{onboard-channels-DPzbq3iB.js → onboard-channels-BN00--TD.js} +1 -1
  82. package/dist/{onboard-channels-BRi2UP_-.js → onboard-channels-DeRg97iI.js} +1 -1
  83. package/dist/{onboard-8eYravsD.js → onboard-fBxK2Bky.js} +3 -3
  84. package/dist/{onboard-helpers-DahbbzzQ.js → onboard-helpers-CAAZ0RDq.js} +1 -1
  85. package/dist/{onboard-helpers-Bf1LB5fd.js → onboard-helpers-Cv6fL8Vq.js} +1 -1
  86. package/dist/{onboard-remote-BgDE1b8f.js → onboard-remote-CXRFa8AU.js} +1 -1
  87. package/dist/{onboard-remote-B6Ox0wMi.js → onboard-remote-pucDu-pH.js} +1 -1
  88. package/dist/{onboard-skills-D-ppyTcQ.js → onboard-skills-BVTCfqlg.js} +1 -1
  89. package/dist/{onboard-skills-V1IT5l9E.js → onboard-skills-C_93kjju.js} +1 -1
  90. package/dist/{onboarding-Cw8abFVd.js → onboarding-CLOZkMhc.js} +8 -8
  91. package/dist/{onboarding-D35WPHUd.js → onboarding-i1rA1XGe.js} +8 -8
  92. package/dist/{onboarding.finalize-BStHm3Q-.js → onboarding.finalize-BV76YUaD.js} +9 -9
  93. package/dist/{onboarding.finalize-C50T8L4e.js → onboarding.finalize-gk9ot6lb.js} +8 -8
  94. package/dist/{onboarding.gateway-config-DJ1YAlBD.js → onboarding.gateway-config-eFJnSC-S.js} +3 -3
  95. package/dist/{onboarding.gateway-config-D6xPpItN.js → onboarding.gateway-config-wB3ShGU4.js} +3 -3
  96. package/dist/{pi-embedded-BxKs-STI.js → pi-embedded-BAgVs8XC.js} +35 -3
  97. package/dist/{plugin-registry-BFyeIJdT.js → plugin-registry-2DU3g0AT.js} +1 -1
  98. package/dist/{plugin-registry-B9SUsQmV.js → plugin-registry-CubHLj0v.js} +1 -1
  99. package/dist/plugin-sdk/gateway/protocol/index.d.ts +5 -2
  100. package/dist/plugin-sdk/gateway/protocol/schema/logs-chat.d.ts +26 -0
  101. package/dist/{plugins-cli-DKEgD6T2.js → plugins-cli-CIYGRkKI.js} +7 -7
  102. package/dist/{plugins-cli-BTdd7aE9.js → plugins-cli-Dpj76E3-.js} +7 -7
  103. package/dist/{program-C668x3bd.js → program-Qug3oi2C.js} +12 -12
  104. package/dist/{program-context-CV_ibEw9.js → program-context-CCIGjsQL.js} +38 -30
  105. package/dist/{prompt-select-styled-BlpvaJVg.js → prompt-select-styled-ARnCLf3Q.js} +7 -7
  106. package/dist/{prompt-select-styled-G6u6Q8v9.js → prompt-select-styled-BdNTADj2.js} +7 -7
  107. package/dist/{provider-auth-helpers-R-cnIeud.js → provider-auth-helpers-B_gA1eP9.js} +1 -1
  108. package/dist/{provider-auth-helpers-DAtMFGrU.js → provider-auth-helpers-LpT83BSS.js} +1 -1
  109. package/dist/{push-apns-Bx0i-bNw.js → push-apns-BWeNJb15.js} +1 -1
  110. package/dist/{push-apns--j8PeFrK.js → push-apns-CLngpXwL.js} +1 -1
  111. package/dist/{pw-ai-DLsdzdgc.js → pw-ai-DY_6l11g.js} +1 -1
  112. package/dist/{register.agent-muhvyTMD.js → register.agent-Dz24Zz7t.js} +11 -11
  113. package/dist/{register.agent-CYRt1iiv.js → register.agent-pWEv9TC7.js} +12 -12
  114. package/dist/{register.configure-CsvtHB87.js → register.configure-BMLA-3Mt.js} +14 -14
  115. package/dist/{register.configure-DUaVY9dt.js → register.configure-DQWtFNGt.js} +14 -14
  116. package/dist/{register.maintenance-BrNuk6hl.js → register.maintenance-BncnnneX.js} +12 -12
  117. package/dist/{register.maintenance-DMLKAqqc.js → register.maintenance-CTF70v5h.js} +13 -13
  118. package/dist/{register.message-9WxgUBSA.js → register.message-C-p-GZ8z.js} +7 -7
  119. package/dist/{register.message-DZG9UElS.js → register.message-vUwGF3E9.js} +7 -7
  120. package/dist/{register.onboard-C-5RaI3-.js → register.onboard-DhcpKFgU.js} +6 -6
  121. package/dist/{register.onboard-Bpo5ofDH.js → register.onboard-O0P6rCuX.js} +6 -6
  122. package/dist/{register.setup-D87mlpLA.js → register.setup-CZfWa9-Z.js} +6 -6
  123. package/dist/{register.setup-DQXuZsGD.js → register.setup-D3XQyELS.js} +6 -6
  124. package/dist/{register.status-health-sessions-B600sqsd.js → register.status-health-sessions-C9Zdn1ai.js} +8 -8
  125. package/dist/{register.status-health-sessions-ZYT6lFhO.js → register.status-health-sessions-Dn2gy0gi.js} +8 -8
  126. package/dist/{register.subclis-DdlLdgzD.js → register.subclis-Dv8bf2ox.js} +28 -20
  127. package/dist/{rpc-Co5Ci69t.js → rpc-DP3AhcZq.js} +1 -1
  128. package/dist/{rpc-DZpJ-mGE.js → rpc-KjYXUeLD.js} +1 -1
  129. package/dist/{run-main-C1YGbNWb.js → run-main-BsVhPYM4.js} +20 -20
  130. package/dist/{security-cli-Bkcil7sD.js → security-cli-CGLnA_ni.js} +3 -3
  131. package/dist/{security-cli-CAdCbDUS.js → security-cli-hTCYStCU.js} +3 -3
  132. package/dist/{server-methods-FxoNbY02.js → server-methods-C3_JU-DI.js} +36 -11
  133. package/dist/{server-methods-DMPwNvoz.js → server-methods-D_zGEWNK.js} +36 -11
  134. package/dist/{server-node-events-Dp9EiddI.js → server-node-events-CRYzL3TY.js} +8 -8
  135. package/dist/{server-node-events-k7h7NWLL.js → server-node-events-CW5ilXPN.js} +8 -8
  136. package/dist/{status-CYqfS1u_.js → status-1ACP62Xm.js} +5 -5
  137. package/dist/{status-BU-hn3iH.js → status-C_K3wapX.js} +1 -1
  138. package/dist/{status-D3h1mSLx.js → status-DbIBRkrV.js} +5 -5
  139. package/dist/{status-CHEd1LqO.js → status-NK8EUhIy.js} +1 -1
  140. package/dist/{subagent-registry-4qeNm1OL.js → subagent-registry-SZbZfkbr.js} +5 -5
  141. package/dist/symframe-cli-BKrtoG8H.js +51 -0
  142. package/dist/symframe-cli-CsA_x7U9.js +56 -0
  143. package/dist/{synthesis-DceZPirI.js → synthesis-BLRsy_PZ.js} +6 -6
  144. package/dist/{synthesis-DFNyev83.js → synthesis-CA2zGGNE.js} +6 -6
  145. package/dist/{synthesis-CxR-cX-4.js → synthesis-CUbz4CaL.js} +2 -2
  146. package/dist/{synthesis-BH4onG1c.js → synthesis-Dv6bJWYX.js} +4 -4
  147. package/dist/{system-cli-BCAd92UF.js → system-cli-BoxTfo1R.js} +3 -3
  148. package/dist/{system-cli-GwzCZpdT.js → system-cli-CYgTroZA.js} +3 -3
  149. package/dist/{tui-9lZLkRZm.js → tui-BdtfeKft.js} +2 -2
  150. package/dist/{tui-ROL_b9BF.js → tui-CO7OA9ZO.js} +2 -2
  151. package/dist/{tui-cli-C7NUBeQi.js → tui-cli-CcSS08na.js} +3 -3
  152. package/dist/{tui-cli-C6Q0KKvj.js → tui-cli-_WzJLbOA.js} +3 -3
  153. package/dist/{unified-runner-D9LZYzyF.js → unified-runner-B0cMr4If.js} +5 -5
  154. package/dist/{unified-runner-LBbNjudz.js → unified-runner-ByJSAveb.js} +42 -10
  155. package/dist/{update-cli-Du-NLjgh.js → update-cli-CrP5Kvo4.js} +13 -13
  156. package/dist/{update-cli-CWYfdfuU.js → update-cli-y4Q__h4E.js} +14 -14
  157. package/package.json +1 -1
  158. /package/dist/{consolidate-BSUbtSDt.js → consolidate-BoM9cz9L.js} +0 -0
  159. /package/dist/{consolidate-DhoiF4n7.js → consolidate-nNhnUpNj.js} +0 -0
  160. /package/dist/{onboard-hooks-CXRw9BJY.js → onboard-hooks-CxJRzS5z.js} +0 -0
  161. /package/dist/{onboard-hooks-DfDF9AU4.js → onboard-hooks-D5-mtFUY.js} +0 -0
  162. /package/dist/{qmd-manager-CYEAMLE7.js → qmd-manager-C1levE0a.js} +0 -0
  163. /package/dist/{qmd-manager-C6wRtPm_.js → qmd-manager-CR71XjjR.js} +0 -0
  164. /package/dist/{webhooks-cli-C3uyehJS.js → webhooks-cli-BUWSS_ve.js} +0 -0
  165. /package/dist/{webhooks-cli-C3g4MxCE.js → webhooks-cli-BrDeMswO.js} +0 -0
@@ -1539,6 +1539,36 @@ const ChatHistoryParamsSchema = Type.Object({
1539
1539
  const ChatCommandsListParamsSchema = Type.Object({}, { additionalProperties: false });
1540
1540
  const ChatToolsListParamsSchema = Type.Object({}, { additionalProperties: false });
1541
1541
  const ChatSkillsListParamsSchema = Type.Object({}, { additionalProperties: false });
1542
+ /**
1543
+ * Push a card to the symframe (the right-column dynamic display panel
1544
+ * in Glass UI). Mirrors the registry methods on `window.symframe`:
1545
+ * - action="add" → `card` required (id auto-generated if missing)
1546
+ * - action="update" → `id` required, `card` carries the patch
1547
+ * - action="remove" → `id` required, no card
1548
+ *
1549
+ * The handler broadcasts a `symframe` event over the WebSocket; clients
1550
+ * route it to their local registry. The card schema is permissive
1551
+ * (additionalProperties on card) so new content types can ship without
1552
+ * a schema bump.
1553
+ */
1554
+ const ChatSymframePushParamsSchema = Type.Object({
1555
+ action: Type.Union([
1556
+ Type.Literal("add"),
1557
+ Type.Literal("update"),
1558
+ Type.Literal("remove")
1559
+ ]),
1560
+ id: Type.Optional(NonEmptyString),
1561
+ card: Type.Optional(Type.Object({
1562
+ id: Type.Optional(NonEmptyString),
1563
+ type: Type.Optional(Type.String()),
1564
+ title: Type.Optional(Type.String()),
1565
+ body: Type.Optional(Type.String()),
1566
+ bodyHtml: Type.Optional(Type.String()),
1567
+ actions: Type.Optional(Type.Array(Type.Unknown())),
1568
+ sticky: Type.Optional(Type.Boolean()),
1569
+ dismissable: Type.Optional(Type.Boolean())
1570
+ }, { additionalProperties: true }))
1571
+ }, { additionalProperties: false });
1542
1572
  const ChatSendParamsSchema = Type.Object({
1543
1573
  sessionKey: NonEmptyString,
1544
1574
  message: Type.String(),
@@ -1971,6 +2001,7 @@ const validateChatHistoryParams = ajv.compile(ChatHistoryParamsSchema);
1971
2001
  const validateChatCommandsListParams = ajv.compile(ChatCommandsListParamsSchema);
1972
2002
  const validateChatToolsListParams = ajv.compile(ChatToolsListParamsSchema);
1973
2003
  const validateChatSkillsListParams = ajv.compile(ChatSkillsListParamsSchema);
2004
+ const validateChatSymframePushParams = ajv.compile(ChatSymframePushParamsSchema);
1974
2005
  const validateChatSendParams = ajv.compile(ChatSendParamsSchema);
1975
2006
  const validateChatAbortParams = ajv.compile(ChatAbortParamsSchema);
1976
2007
  const validateChatInjectParams = ajv.compile(ChatInjectParamsSchema);
@@ -2291,4 +2322,4 @@ var GatewayClient = class {
2291
2322
  };
2292
2323
 
2293
2324
  //#endregion
2294
- export { validateNodeListParams as $, summarizeDeviceTokens as $t, validateCronRemoveParams as A, validateUpdateRunParams as At, validateDeviceTokenRotateParams as B, errorShape as Bt, validateConfigGetParams as C, validateSkillsBinsParams as Ct, validateConnectParams as D, validateTalkConfigParams as Dt, validateConfigSetParams as E, validateSkillsUpdateParams as Et, validateDevicePairApproveParams as F, validateWizardNextParams as Ft, validateExecApprovalsNodeSetParams as G, ensureDeviceToken as Gt, validateExecApprovalResolveParams as H, parseSessionLabel as Ht, validateDevicePairListParams as I, validateWizardStartParams as It, validateModelsListParams as J, rejectDevicePairing as Jt, validateExecApprovalsSetParams as K, getPairedDevice as Kt, validateDevicePairRejectParams as L, validateWizardStatusParams as Lt, validateCronRunsParams as M, validateWebLoginStartParams as Mt, validateCronStatusParams as N, validateWebLoginWaitParams as Nt, validateCronAddParams as O, validateTalkModeParams as Ot, validateCronUpdateParams as P, validateWizardCancelParams as Pt, validateNodeInvokeResultParams as Q, rotateDeviceToken as Qt, validateDevicePairRemoveParams as R, PROTOCOL_VERSION as Rt, validateConfigApplyParams as S, validateSessionsUsageParams as St, validateConfigSchemaParams as T, validateSkillsStatusParams as Tt, validateExecApprovalsGetParams as U, buildDeviceAuthPayload as Ut, validateExecApprovalRequestParams as V, SESSION_LABEL_MAX_LENGTH as Vt, validateExecApprovalsNodeGetParams as W, approveDevicePairing as Wt, validateNodeEventParams as X, requestDevicePairing as Xt, validateNodeDescribeParams as Y, removePairedDevice as Yt, validateNodeInvokeParams as Z, revokeDeviceToken as Zt, validateChatHistoryParams as _, validateSessionsPreviewParams as _t, validateAgentWaitParams as a, loadOrCreateDeviceIdentity as an, validateNodeRenameParams as at, validateChatSkillsListParams as b, validateSessionsRestoreParams as bt, validateAgentsFilesGetParams as c, validateRequestFrame as ct, validateAgentsListParams as d, validateSessionsCompactParams as dt, updatePairedDeviceMetadata as en, validateNodePairApproveParams as et, validateAgentsUpdateParams as f, validateSessionsDeleteFileParams as ft, validateChatCommandsListParams as g, validateSessionsPatchParams as gt, validateChatAbortParams as h, validateSessionsListParams as ht, validateAgentParams as i, deriveDeviceIdFromPublicKey as in, validateNodePairVerifyParams as it, validateCronRunParams as j, validateWakeParams as jt, validateCronListParams as k, validateTasksListParams as kt, validateAgentsFilesListParams as l, validateSendParams as lt, validateChannelsStatusParams as m, validateSessionsFavoriteFileParams as mt, formatValidationErrors as n, roleScopesAllow as nn, validateNodePairRejectParams as nt, validateAgentsCreateParams as o, normalizeDevicePublicKeyBase64Url as on, validatePollParams as ot, validateChannelsLogoutParams as p, validateSessionsDeleteParams as pt, validateLogsTailParams as q, listDevicePairing as qt, validateAgentIdentityParams as r, normalizeFingerprint as rn, validateNodePairRequestParams as rt, validateAgentsDeleteParams as s, verifyDeviceSignature as sn, validatePushTestParams as st, GatewayClient as t, verifyDeviceToken as tn, validateNodePairListParams as tt, validateAgentsFilesSetParams as u, validateSessionsAdoptFileParams as ut, validateChatInjectParams as v, validateSessionsResetParams as vt, validateConfigPatchParams as w, validateSkillsInstallParams as wt, validateChatToolsListParams as x, validateSessionsSearchParams as xt, validateChatSendParams as y, validateSessionsResolveParams as yt, validateDeviceTokenRevokeParams as z, ErrorCodes as zt };
2325
+ export { validateNodeInvokeResultParams as $, rotateDeviceToken as $t, validateCronListParams as A, validateTasksListParams as At, validateDeviceTokenRevokeParams as B, ErrorCodes as Bt, validateConfigApplyParams as C, validateSessionsUsageParams as Ct, validateConfigSetParams as D, validateSkillsUpdateParams as Dt, validateConfigSchemaParams as E, validateSkillsStatusParams as Et, validateCronUpdateParams as F, validateWizardCancelParams as Ft, validateExecApprovalsNodeGetParams as G, approveDevicePairing as Gt, validateExecApprovalRequestParams as H, SESSION_LABEL_MAX_LENGTH as Ht, validateDevicePairApproveParams as I, validateWizardNextParams as It, validateLogsTailParams as J, listDevicePairing as Jt, validateExecApprovalsNodeSetParams as K, ensureDeviceToken as Kt, validateDevicePairListParams as L, validateWizardStartParams as Lt, validateCronRunParams as M, validateWakeParams as Mt, validateCronRunsParams as N, validateWebLoginStartParams as Nt, validateConnectParams as O, validateTalkConfigParams as Ot, validateCronStatusParams as P, validateWebLoginWaitParams as Pt, validateNodeInvokeParams as Q, revokeDeviceToken as Qt, validateDevicePairRejectParams as R, validateWizardStatusParams as Rt, validateChatToolsListParams as S, validateSessionsSearchParams as St, validateConfigPatchParams as T, validateSkillsInstallParams as Tt, validateExecApprovalResolveParams as U, parseSessionLabel as Ut, validateDeviceTokenRotateParams as V, errorShape as Vt, validateExecApprovalsGetParams as W, buildDeviceAuthPayload as Wt, validateNodeDescribeParams as X, removePairedDevice as Xt, validateModelsListParams as Y, rejectDevicePairing as Yt, validateNodeEventParams as Z, requestDevicePairing as Zt, validateChatHistoryParams as _, validateSessionsPatchParams as _t, validateAgentWaitParams as a, deriveDeviceIdFromPublicKey as an, validateNodePairVerifyParams as at, validateChatSkillsListParams as b, validateSessionsResolveParams as bt, validateAgentsFilesGetParams as c, verifyDeviceSignature as cn, validatePushTestParams as ct, validateAgentsListParams as d, validateSessionsAdoptFileParams as dt, summarizeDeviceTokens as en, validateNodeListParams as et, validateAgentsUpdateParams as f, validateSessionsCompactParams as ft, validateChatCommandsListParams as g, validateSessionsListParams as gt, validateChatAbortParams as h, validateSessionsFavoriteFileParams as ht, validateAgentParams as i, normalizeFingerprint as in, validateNodePairRequestParams as it, validateCronRemoveParams as j, validateUpdateRunParams as jt, validateCronAddParams as k, validateTalkModeParams as kt, validateAgentsFilesListParams as l, validateRequestFrame as lt, validateChannelsStatusParams as m, validateSessionsDeleteParams as mt, formatValidationErrors as n, verifyDeviceToken as nn, validateNodePairListParams as nt, validateAgentsCreateParams as o, loadOrCreateDeviceIdentity as on, validateNodeRenameParams as ot, validateChannelsLogoutParams as p, validateSessionsDeleteFileParams as pt, validateExecApprovalsSetParams as q, getPairedDevice as qt, validateAgentIdentityParams as r, roleScopesAllow as rn, validateNodePairRejectParams as rt, validateAgentsDeleteParams as s, normalizeDevicePublicKeyBase64Url as sn, validatePollParams as st, GatewayClient as t, updatePairedDeviceMetadata as tn, validateNodePairApproveParams as tt, validateAgentsFilesSetParams as u, validateSendParams as ut, validateChatInjectParams as v, validateSessionsPreviewParams as vt, validateConfigGetParams as w, validateSkillsBinsParams as wt, validateChatSymframePushParams as x, validateSessionsRestoreParams as xt, validateChatSendParams as y, validateSessionsResetParams as yt, validateDevicePairRemoveParams as z, PROTOCOL_VERSION as zt };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
2
  import { Qt as getPrimaryCommand, tn as hasHelpOrVersion } from "./entry.js";
3
- import { i as registerSubCliCommands, o as reparseProgramFromActionArgs } from "./register.subclis-DdlLdgzD.js";
3
+ import { i as registerSubCliCommands, o as reparseProgramFromActionArgs } from "./register.subclis-Dv8bf2ox.js";
4
4
 
5
5
  //#region src/cli/program/command-registry.ts
6
6
  var command_registry_exports = /* @__PURE__ */ __exportAll({
@@ -22,7 +22,7 @@ const coreEntries = [
22
22
  hasSubcommands: false
23
23
  }],
24
24
  register: async ({ program }) => {
25
- (await import("./register.setup-DQXuZsGD.js")).registerSetupCommand(program);
25
+ (await import("./register.setup-D3XQyELS.js")).registerSetupCommand(program);
26
26
  }
27
27
  },
28
28
  {
@@ -32,7 +32,7 @@ const coreEntries = [
32
32
  hasSubcommands: false
33
33
  }],
34
34
  register: async ({ program }) => {
35
- (await import("./register.onboard-Bpo5ofDH.js")).registerOnboardCommand(program);
35
+ (await import("./register.onboard-O0P6rCuX.js")).registerOnboardCommand(program);
36
36
  }
37
37
  },
38
38
  {
@@ -42,7 +42,7 @@ const coreEntries = [
42
42
  hasSubcommands: false
43
43
  }],
44
44
  register: async ({ program }) => {
45
- (await import("./register.configure-CsvtHB87.js")).registerConfigureCommand(program);
45
+ (await import("./register.configure-BMLA-3Mt.js")).registerConfigureCommand(program);
46
46
  }
47
47
  },
48
48
  {
@@ -52,7 +52,7 @@ const coreEntries = [
52
52
  hasSubcommands: true
53
53
  }],
54
54
  register: async ({ program }) => {
55
- (await import("./config-cli-D12Nouyy.js")).registerConfigCli(program);
55
+ (await import("./config-cli-Cvylxp-R.js")).registerConfigCli(program);
56
56
  }
57
57
  },
58
58
  {
@@ -79,7 +79,7 @@ const coreEntries = [
79
79
  }
80
80
  ],
81
81
  register: async ({ program }) => {
82
- (await import("./register.maintenance-DMLKAqqc.js")).registerMaintenanceCommands(program);
82
+ (await import("./register.maintenance-CTF70v5h.js")).registerMaintenanceCommands(program);
83
83
  }
84
84
  },
85
85
  {
@@ -89,7 +89,7 @@ const coreEntries = [
89
89
  hasSubcommands: true
90
90
  }],
91
91
  register: async ({ program, ctx }) => {
92
- (await import("./register.message-9WxgUBSA.js")).registerMessageCommands(program, ctx);
92
+ (await import("./register.message-C-p-GZ8z.js")).registerMessageCommands(program, ctx);
93
93
  }
94
94
  },
95
95
  {
@@ -99,7 +99,7 @@ const coreEntries = [
99
99
  hasSubcommands: true
100
100
  }],
101
101
  register: async ({ program }) => {
102
- (await import("./memory-cli-C3CONZGB.js").then((n) => n.t)).registerMemoryCli(program);
102
+ (await import("./memory-cli-CQSVrNAK.js").then((n) => n.t)).registerMemoryCli(program);
103
103
  }
104
104
  },
105
105
  {
@@ -113,7 +113,7 @@ const coreEntries = [
113
113
  hasSubcommands: true
114
114
  }],
115
115
  register: async ({ program, ctx }) => {
116
- (await import("./register.agent-CYRt1iiv.js")).registerAgentCommands(program, { agentChannelOptions: ctx.agentChannelOptions });
116
+ (await import("./register.agent-pWEv9TC7.js")).registerAgentCommands(program, { agentChannelOptions: ctx.agentChannelOptions });
117
117
  }
118
118
  },
119
119
  {
@@ -135,7 +135,7 @@ const coreEntries = [
135
135
  }
136
136
  ],
137
137
  register: async ({ program }) => {
138
- (await import("./register.status-health-sessions-B600sqsd.js")).registerStatusHealthSessionsCommands(program);
138
+ (await import("./register.status-health-sessions-C9Zdn1ai.js")).registerStatusHealthSessionsCommands(program);
139
139
  }
140
140
  },
141
141
  {
@@ -145,7 +145,7 @@ const coreEntries = [
145
145
  hasSubcommands: true
146
146
  }],
147
147
  register: async ({ program }) => {
148
- (await import("./browser-cli-BT0akXlr.js")).registerBrowserCli(program);
148
+ (await import("./browser-cli-CXDzGAN7.js")).registerBrowserCli(program);
149
149
  }
150
150
  }
151
151
  ];
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
2
  import { _ as resolveStateDir } from "./paths-By0XjHBk.js";
3
3
  import { f as pathExists } from "./utils-CTPsqyE_.js";
4
4
  import { i as routeLogsToStderr } from "./subsystem-CHbO_DkH.js";
5
- import { a as registerCoreCliByName, c as getSubCliEntries, l as registerSubCliByName, r as getCoreCliCommandNames, t as getProgramContext } from "./program-context-CV_ibEw9.js";
5
+ import { a as registerCoreCliByName, c as getSubCliEntries, l as registerSubCliByName, r as getCoreCliCommandNames, t as getProgramContext } from "./program-context-CCIGjsQL.js";
6
6
  import path from "node:path";
7
7
  import os from "node:os";
8
8
  import fs from "node:fs/promises";
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
2
  import { Mt as pathExists, l as routeLogsToStderr, yt as resolveStateDir } from "./entry.js";
3
- import { n as getSubCliEntries, r as registerSubCliByName } from "./register.subclis-DdlLdgzD.js";
4
- import { i as registerCoreCliByName, n as getCoreCliCommandNames } from "./command-registry-CjxdlqkY.js";
3
+ import { n as getSubCliEntries, r as registerSubCliByName } from "./register.subclis-Dv8bf2ox.js";
4
+ import { i as registerCoreCliByName, n as getCoreCliCommandNames } from "./command-registry-2hfSOaGL.js";
5
5
  import { t as getProgramContext } from "./program-context-CGKRxOBU.js";
6
6
  import os from "node:os";
7
7
  import path from "node:path";
@@ -201,7 +201,7 @@ async function runConfigUnset(opts) {
201
201
  }
202
202
  function registerConfigCli(program) {
203
203
  const cmd = program.command("config").description("Non-interactive config helpers (get/set/unset). Run without subcommand for the setup wizard.").addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/config", "docs.symi.ai/cli/config")}\n`).option("--section <section>", "Configure wizard sections (repeatable). Use with no subcommand.", (value, previous) => [...previous, value], []).action(async (opts) => {
204
- const { configureCommandFromSectionsArg } = await import("./configure-B8-2sqW3.js").then((n) => n.t);
204
+ const { configureCommandFromSectionsArg } = await import("./configure-DRDyxmMR.js").then((n) => n.t);
205
205
  await configureCommandFromSectionsArg(opts.section, defaultRuntime);
206
206
  });
207
207
  cmd.command("get").description("Get a config value by dot path").argument("<path>", "Config path (dot or bracket notation)").option("--json", "Output JSON", false).action(async (path, opts) => {
@@ -206,7 +206,7 @@ async function runConfigUnset(opts) {
206
206
  }
207
207
  function registerConfigCli(program) {
208
208
  const cmd = program.command("config").description("Non-interactive config helpers (get/set/unset). Run without subcommand for the setup wizard.").addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/config", "docs.symi.ai/cli/config")}\n`).option("--section <section>", "Configure wizard sections (repeatable). Use with no subcommand.", (value, previous) => [...previous, value], []).action(async (opts) => {
209
- const { configureCommandFromSectionsArg } = await import("./configure-CJp0NIbm.js").then((n) => n.t);
209
+ const { configureCommandFromSectionsArg } = await import("./configure-BMRfSJ5h.js").then((n) => n.t);
210
210
  await configureCommandFromSectionsArg(opts.section, defaultRuntime);
211
211
  });
212
212
  cmd.command("get").description("Get a config value by dot path").argument("<path>", "Config path (dot or bracket notation)").option("--json", "Output JSON", false).action(async (path, opts) => {
@@ -12,22 +12,22 @@ import { n as stylePromptMessage, r as stylePromptTitle, t as stylePromptHint }
12
12
  import { t as note$1 } from "./note-ytwb4wwn.js";
13
13
  import { t as WizardCancelledError } from "./prompts-B98rp78m.js";
14
14
  import { t as createClackPrompter } from "./clack-prompter-v9MYo-5u.js";
15
- import { r as setupChannels, t as noteChannelStatus } from "./onboard-channels-DPzbq3iB.js";
15
+ import { r as setupChannels, t as noteChannelStatus } from "./onboard-channels-BN00--TD.js";
16
16
  import { a as gatewayInstallErrorHint, i as buildGatewayInstallPlan, n as GATEWAY_DAEMON_RUNTIME_OPTIONS, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-7YBz5otm.js";
17
- import { a as ensureWorkspaceAndSessions, b as waitForGatewayReachable, g as resolveControlUiLinks, h as randomToken, m as probeGatewayReachable, n as applyWizardMetadata, p as printWizardHeader, s as guardCancel, t as DEFAULT_WORKSPACE, u as normalizeGatewayTokenInput, v as summarizeExistingConfig, y as validateGatewayPasswordInput } from "./onboard-helpers-Bf1LB5fd.js";
17
+ import { a as ensureWorkspaceAndSessions, b as waitForGatewayReachable, g as resolveControlUiLinks, h as randomToken, m as probeGatewayReachable, n as applyWizardMetadata, p as printWizardHeader, s as guardCancel, t as DEFAULT_WORKSPACE, u as normalizeGatewayTokenInput, v as summarizeExistingConfig, y as validateGatewayPasswordInput } from "./onboard-helpers-Cv6fL8Vq.js";
18
18
  import { t as resolveGatewayService } from "./service-BF50XyKr.js";
19
- import { r as healthCommand } from "./health-BIwN5H6b.js";
19
+ import { r as healthCommand } from "./health--v-C6lSf.js";
20
20
  import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-CnX0W3vy.js";
21
21
  import { n as logConfigUpdated } from "./logging-BmJ5ky59.js";
22
22
  import { n as promptAuthChoiceGrouped } from "./auth-choice-prompt-BnvC700A.js";
23
- import { i as applyAuthChoice, n as resolvePreferredProviderForAuthChoice } from "./auth-choice-9XyVfAyH.js";
23
+ import { i as applyAuthChoice, n as resolvePreferredProviderForAuthChoice } from "./auth-choice-B8n3tJtT.js";
24
24
  import { a as promptDefaultModel, n as applyModelFallbacksFromSelection, o as promptModelAllowlist, r as applyPrimaryModel, t as applyModelAllowlist } from "./model-picker-DN-co6Oy.js";
25
25
  import { t as ensureSystemdUserLingerInteractive } from "./systemd-linger-BBxRNFXz.js";
26
26
  import { a as promptCustomApiConfig } from "./onboard-custom-BCcuL4Uq.js";
27
27
  import { i as TAILSCALE_MISSING_BIN_NOTE_LINES, n as TAILSCALE_DOCS_LINES, r as TAILSCALE_EXPOSURE_OPTIONS, t as validateIPv4AddressInput } from "./ipv4-CCdAVmwu.js";
28
28
  import { t as formatHealthCheckFailure } from "./health-format-Dp4xmTKn.js";
29
- import { n as promptRemoteGatewayConfig } from "./onboard-remote-B6Ox0wMi.js";
30
- import { n as setupSkills } from "./onboard-skills-D-ppyTcQ.js";
29
+ import { n as promptRemoteGatewayConfig } from "./onboard-remote-pucDu-pH.js";
30
+ import { n as setupSkills } from "./onboard-skills-BVTCfqlg.js";
31
31
  import { confirm, intro, outro, select, text } from "@clack/prompts";
32
32
 
33
33
  //#region src/commands/configure.shared.ts
@@ -10,22 +10,22 @@ import { n as stylePromptMessage, r as stylePromptTitle, t as stylePromptHint }
10
10
  import { t as note$1 } from "./note-Cltpxj6i.js";
11
11
  import { t as WizardCancelledError } from "./prompts-CqJkfsHC.js";
12
12
  import { t as createClackPrompter } from "./clack-prompter-_kEnSVz4.js";
13
- import { r as setupChannels, t as noteChannelStatus } from "./onboard-channels-BRi2UP_-.js";
13
+ import { r as setupChannels, t as noteChannelStatus } from "./onboard-channels-DeRg97iI.js";
14
14
  import { a as gatewayInstallErrorHint, i as buildGatewayInstallPlan, n as GATEWAY_DAEMON_RUNTIME_OPTIONS, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-DaJ4Tf2a.js";
15
- import { a as ensureWorkspaceAndSessions, b as waitForGatewayReachable, g as resolveControlUiLinks, h as randomToken, m as probeGatewayReachable, n as applyWizardMetadata, p as printWizardHeader, s as guardCancel, t as DEFAULT_WORKSPACE, u as normalizeGatewayTokenInput, v as summarizeExistingConfig, y as validateGatewayPasswordInput } from "./onboard-helpers-DahbbzzQ.js";
15
+ import { a as ensureWorkspaceAndSessions, b as waitForGatewayReachable, g as resolveControlUiLinks, h as randomToken, m as probeGatewayReachable, n as applyWizardMetadata, p as printWizardHeader, s as guardCancel, t as DEFAULT_WORKSPACE, u as normalizeGatewayTokenInput, v as summarizeExistingConfig, y as validateGatewayPasswordInput } from "./onboard-helpers-CAAZ0RDq.js";
16
16
  import { t as resolveGatewayService } from "./service-Ccv3Zi5_.js";
17
- import { r as healthCommand } from "./health-BaYDaHPT.js";
17
+ import { r as healthCommand } from "./health-D0jGdk53.js";
18
18
  import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-DfBRXG5y.js";
19
19
  import { n as logConfigUpdated } from "./logging-BRejMykf.js";
20
20
  import { n as promptAuthChoiceGrouped } from "./auth-choice-prompt-kt2FcieM.js";
21
- import { i as applyAuthChoice, n as resolvePreferredProviderForAuthChoice } from "./auth-choice-BYOypIGE.js";
21
+ import { i as applyAuthChoice, n as resolvePreferredProviderForAuthChoice } from "./auth-choice-C8ElO44A.js";
22
22
  import { a as promptDefaultModel, n as applyModelFallbacksFromSelection, o as promptModelAllowlist, r as applyPrimaryModel, t as applyModelAllowlist } from "./model-picker-CS_h9RHv.js";
23
23
  import { t as ensureSystemdUserLingerInteractive } from "./systemd-linger-DjoQVcOq.js";
24
24
  import { a as promptCustomApiConfig } from "./onboard-custom-C-wfNtOM.js";
25
25
  import { i as TAILSCALE_MISSING_BIN_NOTE_LINES, n as TAILSCALE_DOCS_LINES, r as TAILSCALE_EXPOSURE_OPTIONS, t as validateIPv4AddressInput } from "./ipv4-DFUXU3PT.js";
26
26
  import { t as formatHealthCheckFailure } from "./health-format-Li703vy6.js";
27
- import { n as promptRemoteGatewayConfig } from "./onboard-remote-BgDE1b8f.js";
28
- import { n as setupSkills } from "./onboard-skills-V1IT5l9E.js";
27
+ import { n as promptRemoteGatewayConfig } from "./onboard-remote-CXRFa8AU.js";
28
+ import { n as setupSkills } from "./onboard-skills-C_93kjju.js";
29
29
  import { confirm, intro, outro, select, text } from "@clack/prompts";
30
30
 
31
31
  //#region src/commands/configure.shared.ts
@@ -907,6 +907,86 @@ body {
907
907
  border-color: rgba(0, 212, 255, 0.18);
908
908
  }
909
909
 
910
+ /* Phase 2: dynamic-card sub-elements (only present on cards added via
911
+ symframe.add(); the 3 sticky panels render their own internals). */
912
+ .symframe-card-header {
913
+ display: flex;
914
+ align-items: center;
915
+ justify-content: space-between;
916
+ gap: 8px;
917
+ }
918
+ .symframe-card-dismiss {
919
+ background: transparent;
920
+ border: none;
921
+ color: var(--text-dim);
922
+ font-size: 16px;
923
+ line-height: 1;
924
+ width: 18px;
925
+ height: 18px;
926
+ border-radius: 4px;
927
+ cursor: pointer;
928
+ opacity: 0.6;
929
+ transition:
930
+ opacity 0.15s ease,
931
+ color 0.15s ease,
932
+ background 0.15s ease;
933
+ padding: 0;
934
+ display: flex;
935
+ align-items: center;
936
+ justify-content: center;
937
+ }
938
+ .symframe-card-dismiss:hover {
939
+ opacity: 1;
940
+ color: var(--accent-cyan);
941
+ background: rgba(0, 212, 255, 0.08);
942
+ }
943
+ .symframe-card-body {
944
+ font-family: var(--font-mono);
945
+ font-size: 11px;
946
+ line-height: 1.5;
947
+ color: var(--text);
948
+ margin-top: 8px;
949
+ white-space: pre-wrap;
950
+ word-break: break-word;
951
+ max-height: 320px;
952
+ overflow-y: auto;
953
+ }
954
+ .symframe-card-actions {
955
+ display: flex;
956
+ gap: 6px;
957
+ margin-top: 10px;
958
+ padding-top: 8px;
959
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
960
+ flex-wrap: wrap;
961
+ }
962
+ .symframe-card-action {
963
+ flex: 1 1 auto;
964
+ min-width: 60px;
965
+ padding: 6px 10px;
966
+ border: 1px solid var(--glass-border);
967
+ border-radius: 5px;
968
+ background: rgba(255, 255, 255, 0.03);
969
+ color: var(--text-dim);
970
+ font-family: var(--font-mono);
971
+ font-size: 10px;
972
+ letter-spacing: 0.04em;
973
+ cursor: pointer;
974
+ transition: all 0.15s ease;
975
+ }
976
+ .symframe-card-action:hover {
977
+ border-color: var(--accent-cyan);
978
+ color: var(--text);
979
+ }
980
+ .symframe-card-action-primary {
981
+ background: rgba(0, 212, 255, 0.08);
982
+ border-color: var(--accent-cyan);
983
+ color: var(--accent-cyan);
984
+ }
985
+ .symframe-card-action-primary:hover {
986
+ background: rgba(0, 212, 255, 0.14);
987
+ box-shadow: 0 0 8px rgba(0, 212, 255, 0.18);
988
+ }
989
+
910
990
  /* ── Response Area ────────────────────────────────────────────────── */
911
991
  .response-area {
912
992
  position: fixed;
@@ -1059,5 +1059,6 @@
1059
1059
  <script src="js/scheduling.js"></script>
1060
1060
  <script src="js/models.js"></script>
1061
1061
  <script src="js/slash-autocomplete.js"></script>
1062
+ <script src="js/symframe.js"></script>
1062
1063
  </body>
1063
1064
  </html>
@@ -158,6 +158,16 @@ class SymiGateway extends EventTarget {
158
158
  return;
159
159
  }
160
160
 
161
+ if (type === "symframe") {
162
+ // Phase 3 of the symframe arc: server-pushed cards. The payload is
163
+ // { action: "add"|"update"|"remove", id?, card? } and routes to
164
+ // window.symframe.{add,update,remove}. Dispatched via a window-
165
+ // level CustomEvent so symframe.js can subscribe without holding
166
+ // a direct reference to the gateway.
167
+ window.dispatchEvent(new CustomEvent("symi:symframe", { detail: msg.payload }));
168
+ return;
169
+ }
170
+
161
171
  if (type === "profile") {
162
172
  // Model profile broadcast — apply to Glass UI immediately
163
173
  if (msg.payload?.profile) {