@symerian/symi 3.4.30 → 3.4.32

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 (422) hide show
  1. package/dist/{agent-O3PihJOY.js → agent-BaSGoKPq.js} +17 -17
  2. package/dist/{agent-tdS4G7e8.js → agent-C8IIjDyn.js} +21 -21
  3. package/dist/{agent-scope-Ck_TLGsV.js → agent-scope-B6p555mP.js} +1 -1
  4. package/dist/{agent-scope-DJI5ijOw.js → agent-scope-DIjW66iO.js} +3 -3
  5. package/dist/{agents-C2MpIr16.js → agents-D6Ygz9ED.js} +12 -12
  6. package/dist/{agents.config-PPeqGzAc.js → agents.config-D1nFwU81.js} +1 -1
  7. package/dist/{agents.config-LRW5SZoE.js → agents.config-D7cHU-OU.js} +1 -1
  8. package/dist/{audit-TmPjr_wD.js → audit-BI8Rbs5q.js} +19 -19
  9. package/dist/{audit-yf3H4Y1h.js → audit-nqP-JeOr.js} +17 -17
  10. package/dist/{auth-BSmNj-Lv.js → auth-BbwD4lRX.js} +1 -1
  11. package/dist/{auth-choice-Bw2Kd6RM.js → auth-choice-BBrEzoy2.js} +8 -8
  12. package/dist/{auth-choice-CyBcsQ9T.js → auth-choice-Bx4Duu6u.js} +8 -8
  13. package/dist/{auth-profiles-C1lvfaCM.js → auth-profiles-BFSVvFKy.js} +6 -6
  14. package/dist/{auth-profiles-BG_wMJz6.js → auth-profiles-Bs5D0GUv.js} +4 -4
  15. package/dist/{auth-token-C0-TDuag.js → auth-token-Brb1Askz.js} +2 -2
  16. package/dist/{auth-token-BwQ5Nv4O.js → auth-token-SebYuqfR.js} +2 -2
  17. package/dist/{banner-D7__HlM-.js → banner-l9GjW5Rm.js} +2 -2
  18. package/dist/{bindings-D5s2VRjL.js → bindings-9LSA3Jr1.js} +1 -1
  19. package/dist/{bonjour-discovery-YoubCASb.js → bonjour-discovery-BTpm6P8H.js} +1 -1
  20. package/dist/{bonjour-discovery-CPzedvdf.js → bonjour-discovery-CU1mz7AC.js} +2 -2
  21. package/dist/{browser-cli-R6JagRCf.js → browser-cli-BAxOL41p.js} +22 -22
  22. package/dist/{browser-cli-B_6WWHm_.js → browser-cli-Bk8DxxeA.js} +13 -13
  23. package/dist/build-info.json +3 -3
  24. package/dist/bundled/boot-md/handler.js +4 -4
  25. package/dist/bundled/session-memory/handler.js +4 -4
  26. package/dist/{call-IfleM0ap.js → call-5IE9ycvm.js} +3 -4
  27. package/dist/{call-sikajorp.js → call-BPJn2_th.js} +5 -6
  28. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  29. package/dist/{catalog-DgsRZ5Yu.js → catalog-CJzUbDcX.js} +2 -2
  30. package/dist/{catalog-Bc0hKvgn.js → catalog-CSgSg5Gp.js} +2 -2
  31. package/dist/{channel-options-DrHwfPTb.js → channel-options-COanIUoQ.js} +5 -5
  32. package/dist/{channel-options-B5974x-7.js → channel-options-DGUqfnbP.js} +2 -2
  33. package/dist/{channel-selection-Cc4Pvn6b.js → channel-selection-BvIcXQLj.js} +2 -2
  34. package/dist/{channels-cli-D50PQAPc.js → channels-cli-B1zmnm5a.js} +83 -83
  35. package/dist/{channels-cli-C6Nv9mzy.js → channels-cli-CZ3M3yE1.js} +62 -62
  36. package/dist/{channels-status-issues-VZcSU4qT.js → channels-status-issues-DC8vgOMo.js} +1 -1
  37. package/dist/{chrome-DJCkCRLf.js → chrome-B0wRtBRB.js} +3 -3
  38. package/dist/{chrome-DT1fIVG1.js → chrome-B4P7ycw5.js} +7 -7
  39. package/dist/{chrome-CPSDqbK6.js → chrome-CQn8fDIy.js} +7 -7
  40. package/dist/{chrome-BM8HZu2p.js → chrome-VbDUdW0_.js} +4 -4
  41. package/dist/{chunk-D2_aCcvs.js → chunk-DQGU0F8t.js} +1 -1
  42. package/dist/{clack-prompter-BwhCW0Jc.js → clack-prompter-CWQQn_CK.js} +5 -5
  43. package/dist/cli-C7I5uEFC.js +128 -0
  44. package/dist/{cli-DZoms4qg.js → cli-CC5GrdTI.js} +52 -52
  45. package/dist/{client-Bcz3rG5V.js → client-Dp8LUTmF.js} +3 -5
  46. package/dist/{client-BzacpVvW.js → client-qjXXRKCO.js} +5 -7
  47. package/dist/{clipboard-Dz-Ob0yt.js → clipboard-McRwF3r0.js} +1 -1
  48. package/dist/{command-format-6B5tP-i9.js → command-format-Xm6vX3qJ.js} +1 -1
  49. package/dist/{command-registry--D98SJ6k.js → command-registry-D8fj6th4.js} +12 -12
  50. package/dist/{commands-DgyiLrAe.js → commands-B3UrgxIz.js} +2 -2
  51. package/dist/{commands-BN08daX-.js → commands-CHkx0oTl.js} +1 -1
  52. package/dist/{commands-registry-Bbs_ugoi.js → commands-registry-BNCcZy2y.js} +5 -5
  53. package/dist/{commands-registry-QB7xD3bc.js → commands-registry-Bccp0eH5.js} +3 -3
  54. package/dist/{completion-cli-CHYvpIPw.js → completion-cli-BxspmuYm.js} +3 -3
  55. package/dist/{completion-cli-QxWULepB.js → completion-cli-C-85b5b8.js} +4 -4
  56. package/dist/{config-vtCLkS2w.js → config-DqMsGcSQ.js} +7 -21
  57. package/dist/{config-cli-CcZo2229.js → config-cli-BqzjDmIH.js} +13 -13
  58. package/dist/{config-cli-DstpcB33.js → config-cli-DSDGwckX.js} +12 -12
  59. package/dist/{config-guard-CC-lFWDU.js → config-guard-CJcSKMuP.js} +21 -21
  60. package/dist/{config-guard-CCJrDmON.js → config-guard-Cu-dwAgi.js} +4 -4
  61. package/dist/{config-BTSBEAnk.js → config-igdtSRrZ.js} +10 -24
  62. package/dist/{config-validation-DSnQNdDO.js → config-validation-Bp2wJ610.js} +1 -1
  63. package/dist/{config-validation-YCrMlM9Z.js → config-validation-Bs1Gp2oG.js} +2 -2
  64. package/dist/{configure-B-UvSZZ7.js → configure-BazJdwKU.js} +14 -14
  65. package/dist/{configure-C4Qjzxdq.js → configure-Dl1f1Den.js} +25 -25
  66. package/dist/{consolidate-CPVaVTv0.js → consolidate-7Usm-b2g.js} +4 -4
  67. package/dist/{control-service-CwRG4M_O.js → control-service-DO8FjrS6.js} +4 -4
  68. package/dist/{control-service--TrXUUt_.js → control-service-Fn3d9AlH.js} +5 -5
  69. package/dist/{control-ui-assets-DI1jLkM6.js → control-ui-assets-DUhvOLUL.js} +2 -2
  70. package/dist/{cron-cli-DUETe3Of.js → cron-cli-DXgI5Lid.js} +10 -10
  71. package/dist/{cron-cli-BfUM5_Kw.js → cron-cli-DZyH2BfZ.js} +19 -19
  72. package/dist/{daemon-cli-DRDkDw_M.js → daemon-cli-C6FSROt1.js} +18 -18
  73. package/dist/{daemon-cli-Dy5eY4M7.js → daemon-cli-DmMYx5Uf.js} +10 -10
  74. package/dist/daemon-cli.js +0 -3
  75. package/dist/{daemon-runtime-ChztAKDA.js → daemon-runtime-2Y9RfgcP.js} +2 -2
  76. package/dist/{daemon-runtime-CqMnoGym.js → daemon-runtime-BpfA4d6Q.js} +2 -2
  77. package/dist/{deliver-59sRVaYQ.js → deliver-BkCYBlzi.js} +4 -4
  78. package/dist/{deliver-Mqq3tgqB.js → deliver-DvW5xHHr.js} +4 -4
  79. package/dist/{deliver-fvcQPsBc.js → deliver-RwovDEDy.js} +8 -8
  80. package/dist/{deliver-BHmK4isn.js → deliver-izdrXPr4.js} +5 -5
  81. package/dist/{delivery-queue-Du1ukE9B.js → delivery-queue-DDs84baU.js} +1 -1
  82. package/dist/{delivery-queue-Bqja5xKq.js → delivery-queue-nheCYaMd.js} +1 -1
  83. package/dist/{deps-CeHgkkO6.js → deps-bCHNuszw.js} +1 -1
  84. package/dist/{devices-cli-DV8wT4cj.js → devices-cli-D6xXc9Ym.js} +17 -17
  85. package/dist/{devices-cli-BCZ2HHjT.js → devices-cli-IMv-0zor.js} +9 -9
  86. package/dist/{diagnostic-Db9MI5bh.js → diagnostic-CwF3MnBL.js} +1 -1
  87. package/dist/{diagnostics-B9e2Kvx8.js → diagnostics-DxdqTfpW.js} +1 -1
  88. package/dist/{directory-cli-BVGd0l0T.js → directory-cli-3wlYB9In.js} +7 -7
  89. package/dist/{directory-cli-B6Ja7314.js → directory-cli-ClbYhd6z.js} +17 -17
  90. package/dist/{dm-policy-shared-Bjdk2L7B.js → dm-policy-shared-5HLej1br.js} +2 -2
  91. package/dist/{dm-policy-shared-BBTioONS.js → dm-policy-shared-CSF4Tw_F.js} +1 -1
  92. package/dist/{dns-cli-MEjZBWpL.js → dns-cli-CY2voLuR.js} +14 -14
  93. package/dist/{dns-cli-DH-ksmiI.js → dns-cli-CoVIqRWx.js} +8 -8
  94. package/dist/{dock-CSF4Y7tm.js → dock-CnGWTXL4.js} +2 -2
  95. package/dist/{docs-cli-BuX8FDdh.js → docs-cli-CFklWCND.js} +5 -5
  96. package/dist/{docs-cli-Cc3Rhfkx.js → docs-cli-DjQ3SvBq.js} +8 -8
  97. package/dist/{doctor-completion-rBc-f29C.js → doctor-completion-BwHbIZjF.js} +2 -2
  98. package/dist/{doctor-completion-C4Sf8CFV.js → doctor-completion-CX7LjkOD.js} +2 -2
  99. package/dist/{doctor-config-flow-CrnteetS.js → doctor-config-flow-CYDx1U0Z.js} +7 -7
  100. package/dist/{doctor-config-flow-BhmF6EAq.js → doctor-config-flow-wvoEFNeZ.js} +8 -8
  101. package/dist/entry.js +4 -7
  102. package/dist/{env-DoZWjLUy.js → env-B97Ms861.js} +1 -1
  103. package/dist/{exec-BcMHopF9.js → exec-DKyLtSjm.js} +2 -2
  104. package/dist/{exec-approvals-BndOYKTM.js → exec-approvals-B8n8es8o.js} +1 -1
  105. package/dist/{exec-approvals-BZBjOrJL.js → exec-approvals-CZOc8M5w.js} +1 -1
  106. package/dist/{exec-approvals-cli-Bqh3x_d1.js → exec-approvals-cli-B_P-1zVp.js} +24 -24
  107. package/dist/{exec-approvals-cli-CyXTXgft.js → exec-approvals-cli-Dy1jvh2M.js} +16 -16
  108. package/dist/extensionAPI.js +4 -4
  109. package/dist/{fetch-guard-BuQQKfW1.js → fetch-guard-DG6T0ZdL.js} +1 -1
  110. package/dist/{frontmatter-BH3ExkUY.js → frontmatter-B4levtVg.js} +2 -2
  111. package/dist/{gateway-cli-BrcMZGyF.js → gateway-cli-CTcK1Az2.js} +113 -114
  112. package/dist/{gateway-cli-fT43bqlv.js → gateway-cli-CW-Z71cE.js} +88 -89
  113. package/dist/{gateway-rpc-BEqCo2JK.js → gateway-rpc-C1xjWlxu.js} +1 -1
  114. package/dist/{gateway-rpc-cpgRv0Yq.js → gateway-rpc-DD_aXogj.js} +3 -3
  115. package/dist/{github-copilot-token-DIIEouRg.js → github-copilot-token-BTNK6Tcd.js} +1 -1
  116. package/dist/{github-copilot-token-CrM1aEWo.js → github-copilot-token-a6a53zx_.js} +1 -1
  117. package/dist/{glass-ui-ws-dERcmtve.js → glass-ui-ws-BNJkhJrL.js} +96 -96
  118. package/dist/{glass-ui-ws-BfMKuf9v.js → glass-ui-ws-BZvH4MBO.js} +68 -68
  119. package/dist/{gmail-setup-utils-Cz9Tb30q.js → gmail-setup-utils-B1BYpISg.js} +2 -2
  120. package/dist/{gmail-setup-utils-5bVmaBiu.js → gmail-setup-utils-fA1VaWLv.js} +3 -3
  121. package/dist/{health-Bpjd5_Oq.js → health-D8cKia4i.js} +10 -10
  122. package/dist/{health-DDxrkioj.js → health-DdzNc1yA.js} +5 -5
  123. package/dist/{health-format-BQcmGV4C.js → health-format-39e76m9p.js} +1 -1
  124. package/dist/{help-format-Bm9CoBSa.js → help-format-BI_G2p1e.js} +1 -1
  125. package/dist/{hooks-cli-Bkp-j7h6.js → hooks-cli-DkP3Y4ou.js} +76 -76
  126. package/dist/{hooks-cli-Btgk__9z.js → hooks-cli-qO421UdO.js} +59 -59
  127. package/dist/{hooks-status-BjjfBQnp.js → hooks-status-COU9Cw9_.js} +2 -2
  128. package/dist/{hooks-status-BaV4_YaJ.js → hooks-status-uaFS2SUa.js} +3 -3
  129. package/dist/{image-ops-CiGlXf65.js → image-ops-C-gIIp7Q.js} +1 -1
  130. package/dist/index.js +81 -81
  131. package/dist/{inspect-B_hklr0u.js → inspect-BDzd6yBs.js} +1 -1
  132. package/dist/{installs-DjzewzNC.js → installs-DhSLZRT7.js} +2 -2
  133. package/dist/{installs-B7y-N4mr.js → installs-cPraL4Dg.js} +2 -2
  134. package/dist/{lifecycle-core-CHB-QdED.js → lifecycle-core-BEmljRfh.js} +7 -7
  135. package/dist/{lifecycle-core-B0tG8ERp.js → lifecycle-core-uN2bsrZs.js} +3 -3
  136. package/dist/{links-Bmkpld9F.js → links-CSaUKNKm.js} +1 -1
  137. package/dist/{links-D4w-tJYZ.js → links-Db3Rw0Tg.js} +1 -1
  138. package/dist/llm-slug-generator.js +4 -4
  139. package/dist/{local-roots-DSeNuIW-.js → local-roots-Bk3321gv.js} +2 -2
  140. package/dist/{local-roots-lknhM9c3.js → local-roots-BnDnugq3.js} +3 -3
  141. package/dist/{logging-miJdTAeb.js → logging-B96FQvnn.js} +2 -2
  142. package/dist/{logging-DrqPd0Fg.js → logging-BeA4q4J_.js} +1 -1
  143. package/dist/{logs-cli-CUhZrDw7.js → logs-cli-BB0Mq8D1.js} +11 -11
  144. package/dist/{logs-cli-CGcdfvBo.js → logs-cli-Dbmzz8m_.js} +18 -18
  145. package/dist/{manager-BeNnzSJv.js → manager-BD_cpL9b.js} +1 -1
  146. package/dist/{manager-Di9qtuZF.js → manager-BQaZlWzK.js} +6 -6
  147. package/dist/{manager-uBAL1G42.js → manager-D0NIHMuQ.js} +1 -1
  148. package/dist/{manager-DqMx0qDw.js → manager-DOiW-Koo.js} +9 -9
  149. package/dist/{manifest-registry-0FO1WTmC.js → manifest-registry-DJcKcUQ9.js} +1 -1
  150. package/dist/{manifest-registry-DYQQ9Cci.js → manifest-registry-D_LsBSyt.js} +1 -1
  151. package/dist/{markdown-tables-Ca1j7TYS.js → markdown-tables-GTLvbzuR.js} +1 -1
  152. package/dist/{memory-BDeydRz3.js → memory-Cl4I_45k.js} +6 -6
  153. package/dist/{memory-cli-D4hZiGr5.js → memory-cli-CszP57Ee.js} +8 -8
  154. package/dist/{memory-cli-BXclq7qt.js → memory-cli-DkD_OD70.js} +13 -13
  155. package/dist/{memory-BXoRMmVn.js → memory-kIYeV9aO.js} +7 -7
  156. package/dist/{message-channel-BqrA0uMO.js → message-channel-C_V8IAYx.js} +1 -1
  157. package/dist/{model-DibfNW71.js → model-BRcKPW49.js} +1 -1
  158. package/dist/{model-Czbmn47-.js → model-DgN15006.js} +1 -1
  159. package/dist/{model-catalog-DPnCNs5N.js → model-catalog-C2rNhRI4.js} +4 -4
  160. package/dist/{model-catalog-Ds0dg_ob.js → model-catalog-CaGfL-2g.js} +4 -4
  161. package/dist/{model-picker-DuPommMc.js → model-picker-4NUXHy8M.js} +3 -3
  162. package/dist/{model-picker-BbaEgNir.js → model-picker-CV56GE8A.js} +3 -3
  163. package/dist/{models-B0wNKA18.js → models-BYi0Fo1a.js} +21 -21
  164. package/dist/{models-cli-CZY5Me88.js → models-cli-Bn9M1TgO.js} +83 -83
  165. package/dist/{models-cli-CL5K06Wu.js → models-cli-EdjvkvFO.js} +59 -59
  166. package/dist/{models-config-Box19p27.js → models-config-Unnduxgs.js} +3 -3
  167. package/dist/{models-config-CPlvO1b0.js → models-config-yKxNCn4V.js} +3 -3
  168. package/dist/{node-cli-BFBfD3vK.js → node-cli-39H0MZ8q.js} +36 -36
  169. package/dist/{node-cli-CWWMajKF.js → node-cli-C8FYMIjN.js} +21 -21
  170. package/dist/{node-service-CkP4-uRI.js → node-service-tPO_yUk7.js} +1 -1
  171. package/dist/{nodes-cli-BY4Ppctn.js → nodes-cli-C-03nIJ0.js} +22 -22
  172. package/dist/{nodes-cli-YmE7S-JB.js → nodes-cli-CqxQexTU.js} +14 -14
  173. package/dist/{nodes-screen-BfQScwqX.js → nodes-screen-Bkq2kswx.js} +2 -2
  174. package/dist/{nodes-screen-BMUoHTPZ.js → nodes-screen-JELuBMBi.js} +1 -1
  175. package/dist/{note-C4Pc_hIl.js → note-CHrtEumO.js} +2 -2
  176. package/dist/{npm-registry-spec-C8W7KCAB.js → npm-registry-spec-BXw_6vF6.js} +2 -2
  177. package/dist/{npm-registry-spec-s-9OX2Kw.js → npm-registry-spec-NLo2PCol.js} +1 -1
  178. package/dist/{onboard-DjlI4mIw.js → onboard-C8IQnigm.js} +19 -19
  179. package/dist/{onboard-HqUZVKyD.js → onboard-CAIujkV7.js} +13 -13
  180. package/dist/{onboard-channels-BbF5-N3g.js → onboard-channels-B2l6OoMg.js} +7 -7
  181. package/dist/{onboard-channels-C5EUFcLq.js → onboard-channels-D_uUQbem.js} +9 -9
  182. package/dist/{onboard-custom-C-6Cooq5.js → onboard-custom-B2fJvyxt.js} +3 -3
  183. package/dist/{onboard-custom-63SI3jrk.js → onboard-custom-DcZ2SEUv.js} +3 -3
  184. package/dist/{onboard-helpers-Cb3WFLl9.js → onboard-helpers-Bm-oyLWy.js} +5 -5
  185. package/dist/{onboard-helpers-Bpa6_3vl.js → onboard-helpers-CHfdRdZR.js} +9 -9
  186. package/dist/{onboard-hooks-ggR6fsQs.js → onboard-hooks-DBYkemjF.js} +8 -8
  187. package/dist/{onboard-hooks-DXXg3YH9.js → onboard-hooks-DgRzMz0E.js} +5 -5
  188. package/dist/{onboard-remote-Cnxe89N8.js → onboard-remote-ecyetiyL.js} +3 -3
  189. package/dist/{onboard-remote-CqtCrqtm.js → onboard-remote-z8XLK4M0.js} +3 -3
  190. package/dist/{onboard-skills-D5Ww8pwO.js → onboard-skills-BLvL0KPR.js} +4 -4
  191. package/dist/{onboard-skills-CS3l5fhH.js → onboard-skills-C53RGq_5.js} +5 -5
  192. package/dist/{onboarding-BPmsmDud.js → onboarding-4v9LJueP.js} +18 -18
  193. package/dist/{onboarding-Be_HJIFA.js → onboarding-BIq5BxG0.js} +16 -16
  194. package/dist/{onboarding.finalize-QwO5yuPm.js → onboarding.finalize-Bkcwe5RS.js} +51 -51
  195. package/dist/{onboarding.finalize-dsCUTKCQ.js → onboarding.finalize-CXAQzVXM.js} +32 -32
  196. package/dist/{onboarding.gateway-config-BZDShYzP.js → onboarding.gateway-config-3JMN1xRf.js} +22 -22
  197. package/dist/{onboarding.gateway-config-Ctd1_QW4.js → onboarding.gateway-config-Ft3f6Jba.js} +11 -11
  198. package/dist/{openai-model-default-Dxlm7Pvs.js → openai-model-default-BVPmAuXK.js} +3 -3
  199. package/dist/{openai-model-default-DT9-42Xb.js → openai-model-default-CDDFpxUr.js} +3 -3
  200. package/dist/{outbound-send-deps-DPsU_Xdy.js → outbound-send-deps-Dmc3B-LK.js} +1 -1
  201. package/dist/{pairing-cli-PtlNv7Gr.js → pairing-cli-B_icqS8Y.js} +9 -9
  202. package/dist/{pairing-cli-C1TeY-2m.js → pairing-cli-CJGA4j6G.js} +15 -15
  203. package/dist/{pairing-store-5oyzSW2X.js → pairing-store-BGf29nPx.js} +4 -4
  204. package/dist/{pairing-store-B9MEud_Y.js → pairing-store-CtBnCGHZ.js} +2 -2
  205. package/dist/{pairing-token-Cup-49D-.js → pairing-token-Bnr7QjVF.js} +1 -1
  206. package/dist/{pairing-token-BaZLnDjo.js → pairing-token-CURbSHdi.js} +1 -1
  207. package/dist/{path-env-C8hRAfiL.js → path-env-DuQralyy.js} +1 -1
  208. package/dist/{paths-By0XjHBk.js → paths-BSzKwaxE.js} +1 -4
  209. package/dist/{paths-BldkKgCk.js → paths-CJcw9nbZ.js} +1 -1
  210. package/dist/{paths-gcw23t43.js → paths-CNexk5_o.js} +1 -1
  211. package/dist/{paths-7zaGPdLp.js → paths-CsQkeUQ3.js} +1 -1
  212. package/dist/{paths-DeDKrl27.js → paths-Dc6A9_vI.js} +1 -1
  213. package/dist/{pi-auth-json-BOXWkXms.js → pi-auth-json-CUZ7IgY7.js} +1 -1
  214. package/dist/{pi-auth-json-DVUJqaKg.js → pi-auth-json-SHGGQzOL.js} +1 -1
  215. package/dist/{pi-embedded-Cp7d6jtB.js → pi-embedded-CGebiST2.js} +10 -13
  216. package/dist/{pi-embedded-helpers-CVKIHnFv.js → pi-embedded-helpers-BwBjqJM5.js} +2 -2
  217. package/dist/{pi-embedded-helpers-DMVyRPBT.js → pi-embedded-helpers-CAdI9wJ5.js} +4 -4
  218. package/dist/{pi-tools.policy-8_wTu7v2.js → pi-tools.policy-BaRznBvu.js} +3 -3
  219. package/dist/{pi-tools.policy-C5aC-K5q.js → pi-tools.policy-Dyx3nBmp.js} +5 -5
  220. package/dist/{plugin-auto-enable-CYoZQPJO.js → plugin-auto-enable-D2TNEv3x.js} +4 -4
  221. package/dist/{plugin-auto-enable-BWd5lJQf.js → plugin-auto-enable-DSliW8o4.js} +3 -3
  222. package/dist/{plugin-registry-BG51uZOA.js → plugin-registry-D7ACpV2Y.js} +3 -3
  223. package/dist/{plugin-registry-BouuQy-X.js → plugin-registry-d4hMhLLZ.js} +5 -5
  224. package/dist/plugin-sdk/gateway/protocol/index.d.ts +2 -5
  225. package/dist/plugin-sdk/gateway/protocol/schema/logs-chat.d.ts +0 -1
  226. package/dist/{plugins-CypN_04v.js → plugins-DuuHorqi.js} +1 -1
  227. package/dist/{plugins-cli-Bk7Al8u3.js → plugins-cli-CPf1hMaZ.js} +76 -76
  228. package/dist/{plugins-cli-B-zVOiQN.js → plugins-cli-D1gd8p9T.js} +58 -58
  229. package/dist/{ports-BgvsHTN5.js → ports-BAzQoIw0.js} +2 -2
  230. package/dist/{ports-YkSuli-C.js → ports-Cv4kt1bT.js} +1 -1
  231. package/dist/{ports-BxtK6PMH.js → ports-DRHSHvqY.js} +2 -2
  232. package/dist/{ports-CduvYJlk.js → ports-DqxP-bXz.js} +3 -3
  233. package/dist/{program-BOh0XGsA.js → program-C19G7o-Q.js} +63 -63
  234. package/dist/{program-context-D73fzUUe.js → program-context-BSUkEz3n.js} +39 -39
  235. package/dist/{progress-B3rWk9lR.js → progress-CyPyGCDn.js} +2 -2
  236. package/dist/{prompt-select-styled-Bz1VV3Qu.js → prompt-select-styled-B5wlPYN5.js} +40 -40
  237. package/dist/{prompt-select-styled-Bj-hrPCx.js → prompt-select-styled-CnYM7W0j.js} +24 -24
  238. package/dist/{prompt-style-LtRrtcTi.js → prompt-style-Cad0BDRS.js} +1 -1
  239. package/dist/{provider-auth-helpers-BK6NFk2Q.js → provider-auth-helpers-BUC4xGK9.js} +5 -5
  240. package/dist/{provider-auth-helpers-D3hXI6HN.js → provider-auth-helpers-DpRoNr_8.js} +7 -7
  241. package/dist/{push-apns-C1guJr4R.js → push-apns-Bm39oOO9.js} +5 -5
  242. package/dist/{push-apns-CMxk3Hxf.js → push-apns-DqmFEcqh.js} +3 -3
  243. package/dist/{pw-ai-CE2TBGif.js → pw-ai-B0-pgbYu.js} +9 -9
  244. package/dist/{pw-ai-EtT_bBJY.js → pw-ai-B2NuWIL7.js} +13 -13
  245. package/dist/{pw-ai-w6Qalz1W.js → pw-ai-BB1pJj9_.js} +1 -1
  246. package/dist/{pw-ai-C5MJKzUM.js → pw-ai-BsEf8C15.js} +1 -1
  247. package/dist/{qmd-manager--xIse9H_.js → qmd-manager--kGuC39q.js} +4 -4
  248. package/dist/{qmd-manager-DgCmfS8D.js → qmd-manager-358OTDns.js} +8 -8
  249. package/dist/{qr-cli-BeHlC33g.js → qr-cli-Cx7DYTSk.js} +5 -5
  250. package/dist/{qr-cli-zto9YWnY.js → qr-cli-hPIeUYAT.js} +11 -11
  251. package/dist/{redact-identifier-B1VHIbnd.js → redact-identifier-Cm1VfV7E.js} +4 -4
  252. package/dist/{register.agent-CNhg2KUt.js → register.agent-CCKcgAXs.js} +91 -91
  253. package/dist/{register.agent-COv5OPLQ.js → register.agent-DZuxoC0a.js} +71 -71
  254. package/dist/register.configure-CJErdFO_.js +129 -0
  255. package/dist/register.configure-JT8T7HO5.js +125 -0
  256. package/dist/{register.maintenance-BAK-DiQY.js → register.maintenance-CKsv0lok.js} +70 -70
  257. package/dist/{register.maintenance-B_slxJa6.js → register.maintenance-DDzKUGYJ.js} +98 -98
  258. package/dist/{register.message-Bbtej3vy.js → register.message-CpOXi1rz.js} +74 -74
  259. package/dist/{register.message-CCBmn5ja.js → register.message-_bfhetTg.js} +55 -55
  260. package/dist/{register.onboard-Cu2KnArg.js → register.onboard-BHtTh0b_.js} +42 -42
  261. package/dist/{register.onboard-B3jO_Goy.js → register.onboard-CkIM3hU7.js} +24 -24
  262. package/dist/{register.setup-Ca6zdWpf.js → register.setup-CLhdFQHW.js} +42 -42
  263. package/dist/{register.setup-CYSISTDO.js → register.setup-CYtYDKMU.js} +27 -27
  264. package/dist/{register.status-health-sessions-D9p0ClqJ.js → register.status-health-sessions-DZnebsxZ.js} +60 -60
  265. package/dist/{register.status-health-sessions-CGbg9k6d.js → register.status-health-sessions-DmX0DLAt.js} +39 -39
  266. package/dist/{register.subclis-loifbhVx.js → register.subclis-CnDo2jzv.js} +29 -29
  267. package/dist/{registry-Sbac4a4z.js → registry-DKJLAPDB.js} +2 -2
  268. package/dist/{replies-PetyGT0p.js → replies-B2O2eRh6.js} +3 -3
  269. package/dist/{replies-Dj640LxQ.js → replies-DIHkSwoW.js} +2 -2
  270. package/dist/{reply-prefix-CXsO5E1Z.js → reply-prefix-B7pYEiW_.js} +1 -1
  271. package/dist/{reply-prefix-DKeEUCUp.js → reply-prefix-BOdARKaY.js} +1 -1
  272. package/dist/{resolve-route-8JoEBwi6.js → resolve-route-CRWE36h5.js} +4 -4
  273. package/dist/{resolve-route-BcYnh5es.js → resolve-route-DNKcB7Q9.js} +1 -1
  274. package/dist/{routes-CJ4en0jL.js → routes-BMShi_eY.js} +7 -7
  275. package/dist/{routes-B5y-oAKp.js → routes-Cio8is5Y.js} +5 -5
  276. package/dist/{rpc-qWm1bRo5.js → rpc-CEhoSTGo.js} +1 -1
  277. package/dist/{rpc-ElDiKzq4.js → rpc-D0Ldc6Hv.js} +3 -3
  278. package/dist/{run-main-B7Ria3zD.js → run-main-BIRbWKyA.js} +73 -73
  279. package/dist/{runtime-guard-oeRbIq84.js → runtime-guard-BZ3_1QqS.js} +1 -1
  280. package/dist/{sandbox-BJgHc4Vu.js → sandbox-B4RfQ7k1.js} +9 -9
  281. package/dist/{sandbox-C8Gh5iJW.js → sandbox-C-UeHmuJ.js} +11 -11
  282. package/dist/{sandbox-cli-CSudrHYL.js → sandbox-cli-B43FqqPT.js} +17 -17
  283. package/dist/{sandbox-cli-DkMmnojU.js → sandbox-cli-CNAPNXJ4.js} +29 -29
  284. package/dist/{security-cli-pLoqKkfb.js → security-cli-BSd8_Gsq.js} +38 -38
  285. package/dist/{security-cli-B2lCR2xX.js → security-cli-DDM0Z6IW.js} +27 -27
  286. package/dist/{send-DuYvWRLE.js → send-DSK6O8SC.js} +9 -9
  287. package/dist/{send-CY9na-Jw.js → send-EluKytgO.js} +3 -3
  288. package/dist/{server-context-DdWWaDf6.js → server-context-CDTuNR-O.js} +5 -5
  289. package/dist/{server-context-CJFU_WfI.js → server-context-DFO6o83F.js} +8 -8
  290. package/dist/{server-methods-Dk_EnINI.js → server-methods-Dz6NGEg3.js} +35 -59
  291. package/dist/{server-methods-RhVqtIqB.js → server-methods-vp5zi6v5.js} +41 -65
  292. package/dist/{server-node-events-BHegSgG9.js → server-node-events-4ufB_olv.js} +55 -55
  293. package/dist/{server-node-events-UQx561GA.js → server-node-events-B7UtUhkC.js} +74 -74
  294. package/dist/{service-BCu0FBzN.js → service-AP9pR9R5.js} +1 -1
  295. package/dist/{session-cost-usage-5VmVPhKy.js → session-cost-usage-Cj3vd7lZ.js} +1 -1
  296. package/dist/{session-cost-usage-XhPrxXSs.js → session-cost-usage-DYcv40ss.js} +1 -1
  297. package/dist/{session-utils-DFJztVrF.js → session-utils-CgGDr4eh.js} +12 -12
  298. package/dist/{session-utils-CAVPV2Hh.js → session-utils-D1VcHni_.js} +7 -7
  299. package/dist/{sessions-CqLQkkWg.js → sessions-BNEDanZO.js} +4 -4
  300. package/dist/{sessions-BsGGoTdl.js → sessions-Dh88Kqd6.js} +9 -9
  301. package/dist/{sessions-BDM9kNY0.js → sessions-iLfSd6VD.js} +5 -5
  302. package/dist/{shared-CpwtQRJB.js → shared-CIeW3aWF.js} +4 -4
  303. package/dist/{shared-D7tsGdxc.js → shared-DP6YX7_w.js} +1 -1
  304. package/dist/{shared-B7nP44vU.js → shared-DmYHvtn2.js} +2 -2
  305. package/dist/{shared-CbUpEKXt.js → shared-_wwqvx84.js} +3 -3
  306. package/dist/{skill-commands-B45w-suH.js → skill-commands-5QB5E8bv.js} +4 -4
  307. package/dist/{skill-commands-CRQniaHy.js → skill-commands-CcCCVblU.js} +4 -4
  308. package/dist/{skills-CTcjFd_F.js → skills-BP6p7GnN.js} +3 -3
  309. package/dist/{skills-haW9gU7e.js → skills-Bmjf5nFv.js} +3 -3
  310. package/dist/{skills-cli-9Mlb7VRg.js → skills-cli-BJDvUT_e.js} +13 -13
  311. package/dist/{skills-cli-CV_42wby.js → skills-cli-Byp9MfZh.js} +17 -17
  312. package/dist/{skills-install-B4JPO_Np.js → skills-install-BB27sD4d.js} +4 -4
  313. package/dist/{skills-install-D5ikt72d.js → skills-install-BzqoHn0x.js} +3 -3
  314. package/dist/{skills-remote-BW2GvG2l.js → skills-remote-CqwR3Zvp.js} +5 -5
  315. package/dist/{skills-remote-BASG1Doo.js → skills-remote-DHfuS68n.js} +4 -4
  316. package/dist/{skills-status-1iVfuVIG.js → skills-status-01KNlWUS.js} +3 -3
  317. package/dist/{skills-status-C9lLJu0B.js → skills-status-BNDqwHkP.js} +3 -3
  318. package/dist/{sqlite-DL_ZWVN-.js → sqlite-DBEvS-Ne.js} +2 -2
  319. package/dist/{sqlite-67BqaVPd.js → sqlite-l3CZYU6t.js} +1 -1
  320. package/dist/{status-CrddsMfu.js → status-B0HecH1s.js} +4 -4
  321. package/dist/{status-D5RhVO0A.js → status-BD8gFYKH.js} +18 -18
  322. package/dist/{status-DPu7qNXE.js → status-DEXnB1sw.js} +27 -27
  323. package/dist/{status-Bci6O3aA.js → status-MMLxoRgQ.js} +3 -3
  324. package/dist/{status.update-D5CachQ_.js → status.update-Be8PuHCh.js} +2 -2
  325. package/dist/{status.update-Dfd0eZOH.js → status.update-CB9e3eWW.js} +2 -2
  326. package/dist/{subagent-registry-CsXaK_sy.js → subagent-registry-C57PFGHU.js} +61 -61
  327. package/dist/{subsystem-CHbO_DkH.js → subsystem-CtH6J8AV.js} +1 -1
  328. package/dist/{synthesis-BwcfS9jt.js → synthesis-CQdzrLFL.js} +4 -4
  329. package/dist/{synthesis-CU_MR7nV.js → synthesis-CjsIBd8X.js} +71 -71
  330. package/dist/{synthesis-dplLmFIP.js → synthesis-DSdF0vsi.js} +4 -4
  331. package/dist/{synthesis-BoZf8BeO.js → synthesis-j_kjlFo1.js} +52 -52
  332. package/dist/{system-cli-CCn-08Zm.js → system-cli-BM8KbtUc.js} +18 -18
  333. package/dist/{system-cli-D5FffFX5.js → system-cli-CQFH_HwX.js} +10 -10
  334. package/dist/{systemd-bkj5giUQ.js → systemd-9LEEqibe.js} +2 -2
  335. package/dist/{systemd-hints-UeG2BDXq.js → systemd-hints-A1W3AdVo.js} +3 -3
  336. package/dist/{systemd-hints-CufcSfMk.js → systemd-hints-BejQ6J2Y.js} +2 -2
  337. package/dist/{systemd-linger-DVkUgWAi.js → systemd-linger-PqG8iGCt.js} +2 -2
  338. package/dist/{table-Sfrx6RZ-.js → table-CSEp22Mk.js} +1 -1
  339. package/dist/{table-B4DunWtf.js → table-DkAQzCOR.js} +2 -2
  340. package/dist/{tailscale-G_tEEN9T.js → tailscale-D7dC-5EX.js} +3 -3
  341. package/dist/{tokens-BdVB8KXo.js → tokens-BKbemuIk.js} +1 -1
  342. package/dist/{tokens-h4i8ww8n.js → tokens-K3kGchJA.js} +1 -1
  343. package/dist/{tool-display-BngPYwnR.js → tool-display-Dr6VaTg5.js} +1 -1
  344. package/dist/{tool-display-DccYrlOh.js → tool-display-wSdT0Ynz.js} +1 -1
  345. package/dist/{tool-loop-detection-ckNnHN4a.js → tool-loop-detection-CLDr_JBu.js} +1 -1
  346. package/dist/{tool-loop-detection-DldKffR8.js → tool-loop-detection-CSSq5kkt.js} +4 -4
  347. package/dist/{trash-S6FbJcDo.js → trash-BjVrPcAx.js} +1 -1
  348. package/dist/{tui-DZ8gksSZ.js → tui-D0j61PXx.js} +8 -8
  349. package/dist/{tui-DroW8IOb.js → tui-DFuScHlA.js} +10 -10
  350. package/dist/{tui-cli-CyBJYh9u.js → tui-cli-25xTveHh.js} +24 -24
  351. package/dist/{tui-cli-1SpmbQMM.js → tui-cli-C3dXNtPo.js} +36 -36
  352. package/dist/{unified-runner-BFLLzEHE.js → unified-runner-BNt7TQKM.js} +10 -13
  353. package/dist/{unified-runner-CSPkKZHX.js → unified-runner-DCiPB--z.js} +73 -73
  354. package/dist/{update-BITFZPr2.js → update-C1rkPV1C.js} +3 -3
  355. package/dist/{update-OkPZ3jjl.js → update-CjZgU686.js} +3 -3
  356. package/dist/{update-check-CMbKkelk.js → update-check-CZxZhEXr.js} +2 -2
  357. package/dist/{update-cli-Dh5dvdv-.js → update-cli-CWufRpkr.js} +104 -104
  358. package/dist/{update-cli-yW6Xl6fs.js → update-cli-Dl_QbjXc.js} +77 -77
  359. package/dist/{update-runner-BI8ZSR1b.js → update-runner-Dq5UYQbo.js} +5 -5
  360. package/dist/{update-runner-CIgLduhH.js → update-runner-ENJw0Mco.js} +2 -2
  361. package/dist/{utils-CTPsqyE_.js → utils-BU8jVQFM.js} +1 -1
  362. package/dist/{webhooks-cli-Cwhu9vyD.js → webhooks-cli-Clx8DGfA.js} +14 -14
  363. package/dist/{webhooks-cli-4bmyKzwb.js → webhooks-cli-UfO_WffC.js} +11 -11
  364. package/dist/{widearea-dns-BZ7fV_kq.js → widearea-dns-C5NqCQ3L.js} +1 -1
  365. package/dist/{widearea-dns-D9KXb2gb.js → widearea-dns-drOINmDM.js} +1 -1
  366. package/dist/{with-timeout-D_FOTx48.js → with-timeout-BE7lxhxW.js} +2 -2
  367. package/dist/{with-timeout-bWr6yBeX.js → with-timeout-BcL6qAbd.js} +2 -2
  368. package/dist/{workspace-DxscDsm6.js → workspace-B3sO7QlN.js} +2 -2
  369. package/dist/{workspace-BHDa_VCi.js → workspace-Bb1HX2I0.js} +1 -1
  370. package/dist/{workspace-dirs-2xcWGse3.js → workspace-dirs-23IYtZj2.js} +1 -1
  371. package/dist/{workspace-dirs-aYEM1rQE.js → workspace-dirs-D5OnUmvw.js} +1 -1
  372. package/extensions/memory-core/node_modules/.bin/symi +0 -0
  373. package/extensions/msteams/node_modules/.bin/symi +0 -0
  374. package/extensions/outlook/node_modules/.bin/symi +0 -0
  375. package/extensions/slack/node_modules/.bin/symi +0 -0
  376. package/package.json +108 -79
  377. package/dist/cli-CK62Eh_9.js +0 -128
  378. package/dist/control-ui/css/revert-red-theme.md +0 -141
  379. package/dist/control-ui/css/style.css +0 -5843
  380. package/dist/control-ui/css/style.css.backup-2026-03-03-162525 +0 -3546
  381. package/dist/control-ui/css/style.css.backup-before-red-2026-03-03-162525 +0 -3546
  382. package/dist/control-ui/css/style.css.backup-before-red-theme-2026-03-03-162530 +0 -3546
  383. package/dist/control-ui/css/style.css.pre-2row +0 -2165
  384. package/dist/control-ui/css/style.css.pre-brand +0 -1776
  385. package/dist/control-ui/css/style.css.pre-history +0 -1974
  386. package/dist/control-ui/css/style.css.pre-nav +0 -2264
  387. package/dist/control-ui/css/style.css.pre-newsession +0 -1898
  388. package/dist/control-ui/css/style.css.pre-queue +0 -2195
  389. package/dist/control-ui/css/style.css.pre-red-prompt +0 -2524
  390. package/dist/control-ui/css/style.css.pre-stop +0 -2239
  391. package/dist/control-ui/css/style.css.pre-textarea +0 -2184
  392. package/dist/control-ui/css/style.css.pre-watchdog +0 -1848
  393. package/dist/control-ui/css/style.css.red-theme +0 -2999
  394. package/dist/control-ui/index.html +0 -1042
  395. package/dist/control-ui/js/app.js +0 -1304
  396. package/dist/control-ui/js/app.js.pre-2row +0 -463
  397. package/dist/control-ui/js/app.js.pre-heartbeat-filter +0 -595
  398. package/dist/control-ui/js/app.js.pre-newsession +0 -408
  399. package/dist/control-ui/js/app.js.pre-queue +0 -476
  400. package/dist/control-ui/js/app.js.pre-stop +0 -564
  401. package/dist/control-ui/js/app.js.pre-textarea +0 -467
  402. package/dist/control-ui/js/app.js.pre-watchdog +0 -293
  403. package/dist/control-ui/js/connections.js +0 -438
  404. package/dist/control-ui/js/gateway.js +0 -233
  405. package/dist/control-ui/js/gateway.js.pre-stop +0 -110
  406. package/dist/control-ui/js/history.js +0 -732
  407. package/dist/control-ui/js/logs.js +0 -238
  408. package/dist/control-ui/js/menu.js +0 -230
  409. package/dist/control-ui/js/menu.js.pre-nav +0 -66
  410. package/dist/control-ui/js/metrics.js +0 -53
  411. package/dist/control-ui/js/models.js +0 -138
  412. package/dist/control-ui/js/render.js +0 -882
  413. package/dist/control-ui/js/render.test.js +0 -112
  414. package/dist/control-ui/js/scheduling.js +0 -461
  415. package/dist/control-ui/js/settings.js +0 -909
  416. package/dist/control-ui/js/slash-autocomplete.js +0 -168
  417. package/dist/control-ui/js/subagents.js +0 -560
  418. package/dist/control-ui/js/utils.js +0 -29
  419. package/dist/control-ui/vendor/highlight.min.js +0 -2518
  420. package/dist/control-ui/vendor/marked.min.js +0 -69
  421. package/dist/register.configure-RhKVlfWH.js +0 -125
  422. package/dist/register.configure-q33027ym.js +0 -129
@@ -1,882 +0,0 @@
1
- // ── Symi UI — Message Renderer ────────────────────────────────────────
2
- // Handles all content types: text (markdown), thinking, tool_use,
3
- // tool_result, image. Mirrors the Standard UI feature set.
4
-
5
- // ── Configure marked ──────────────────────────────────────────────────
6
- if (typeof marked !== "undefined") {
7
- marked.setOptions({
8
- breaks: true,
9
- gfm: true,
10
- pedantic: false,
11
- });
12
-
13
- // GFM task list extension (- [ ] and - [x])
14
- const _taskListExt = {
15
- name: "taskList",
16
- level: "inline",
17
- start(src) {
18
- return src.indexOf("[ ]") !== -1 || src.indexOf("[x]") !== -1 ? 0 : -1;
19
- },
20
- };
21
- marked.use({
22
- hooks: {
23
- postprocess(html) {
24
- return html
25
- .replace(
26
- /<li>\s*\[ \]/g,
27
- '<li class="task-item"><input type="checkbox" disabled class="task-cb"> ',
28
- )
29
- .replace(
30
- /<li>\s*\[x\]/gi,
31
- '<li class="task-item task-done"><input type="checkbox" disabled checked class="task-cb"> ',
32
- );
33
- },
34
- },
35
- });
36
-
37
- // Custom renderer — open links in new tab, add copy buttons to code blocks
38
- const renderer = new marked.Renderer();
39
-
40
- // marked v15+: renderer methods receive a token object
41
- renderer.link = (token) => {
42
- const href = typeof token === "string" ? token : (token.href ?? "");
43
- const title = typeof token === "object" ? (token.title ?? "") : "";
44
- const text = typeof token === "object" ? (token.text ?? "") : "";
45
- const t = title ? ` title="${escAttr(title)}"` : "";
46
- return `<a href="${escAttr(href)}"${t} target="_blank" rel="noopener">${text}</a>`;
47
- };
48
-
49
- renderer.code = (token) => {
50
- const raw = typeof token === "string" ? token : (token.text ?? "");
51
- const meta = typeof token === "object" ? (token.lang ?? "") : "";
52
-
53
- // Split "python filename.py" -> lang + optional filename
54
- const parts = meta.trim().split(/\s+/);
55
- const lang = parts[0] || "";
56
- const filename = parts.slice(1).join(" ");
57
- const language = lang && hljs && hljs.getLanguage(lang) ? lang : "plaintext";
58
-
59
- let highlighted = escHtml(raw);
60
- try {
61
- if (typeof hljs !== "undefined") {
62
- highlighted = hljs.highlight(raw, { language }).value;
63
- }
64
- } catch {
65
- /* ignore */
66
- }
67
-
68
- // Build line-numbered HTML
69
- const lines = highlighted.split("\n");
70
- if (lines[lines.length - 1] === "") {
71
- lines.pop();
72
- }
73
- const numbered = lines
74
- .map((line, i) => {
75
- return (
76
- '<span class="code-line"><span class="line-num">' +
77
- (i + 1) +
78
- '</span><span class="line-content">' +
79
- (line || "\u200b") +
80
- "</span></span>"
81
- );
82
- })
83
- .join("\n");
84
-
85
- const langIcon = codeIcon(lang);
86
- const langColor = codeLangColor(lang);
87
- const id = "code-" + Math.random().toString(36).slice(2);
88
- const collapsible = lines.length > 30;
89
- const linesLabel = lines.length + " line" + (lines.length !== 1 ? "s" : "");
90
-
91
- let html =
92
- '<div class="code-block code-block-full' +
93
- (collapsible ? " code-collapsible" : "") +
94
- '" id="' +
95
- id +
96
- '">';
97
- html += '<div class="code-header">';
98
- html += '<div class="code-header-left">';
99
- html +=
100
- '<span class="code-lang-badge" style="--lang-color:' +
101
- langColor +
102
- '">' +
103
- langIcon +
104
- escHtml(lang || "code") +
105
- "</span>";
106
- if (filename) {
107
- html += '<span class="code-filename">' + escHtml(filename) + "</span>";
108
- }
109
- html += '<span class="code-lines-count">' + linesLabel + "</span>";
110
- html += "</div>";
111
- html += '<div class="code-header-right">';
112
- if (collapsible) {
113
- html +=
114
- '<button class="code-expand-btn" onclick="toggleCodeExpand(\'' +
115
- id +
116
- '\')" title="Expand">⤢</button>';
117
- }
118
- html += '<button class="code-copy" onclick="copyCode(this)" title="Copy code">';
119
- html +=
120
- '<svg width="13" height="13" viewBox="0 0 24 24" fill="none"><rect x="9" y="9" width="13" height="13" rx="2" stroke="currentColor" stroke-width="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2"/></svg> Copy';
121
- html += "</button></div></div>";
122
- html += '<div class="code-body' + (collapsible ? " code-body-collapsed" : "") + '">';
123
- html +=
124
- '<pre class="code-pre"><code class="hljs language-' +
125
- escHtml(language) +
126
- ' code-numbered">' +
127
- numbered +
128
- "</code></pre>";
129
- html += "</div>";
130
- if (collapsible) {
131
- html +=
132
- '<button class="code-show-more" onclick="toggleCodeExpand(\'' +
133
- id +
134
- "')\">Show all " +
135
- lines.length +
136
- " lines ▾</button>";
137
- }
138
- html += "</div>";
139
- return html;
140
- };
141
-
142
- renderer.codespan = (token) => {
143
- const text = typeof token === "string" ? token : (token.text ?? "");
144
- return `<code class="inline-code">${text}</code>`;
145
- };
146
-
147
- marked.use({ renderer });
148
- }
149
-
150
- // ── Helpers ───────────────────────────────────────────────────────────
151
- function escHtml(t) {
152
- return String(t ?? "")
153
- .replace(/&/g, "&amp;")
154
- .replace(/</g, "&lt;")
155
- .replace(/>/g, "&gt;")
156
- .replace(/"/g, "&quot;")
157
- .replace(/'/g, "&#39;");
158
- }
159
- function escAttr(t) {
160
- return escHtml(t);
161
- }
162
-
163
- // ── Language icon + color ─────────────────────────────────────────────
164
- function codeIcon(lang = "") {
165
- const l = lang.toLowerCase();
166
- if (["js", "javascript", "ts", "typescript", "jsx", "tsx"].includes(l)) {
167
- return "⬡ ";
168
- }
169
- if (["py", "python"].includes(l)) {
170
- return "🐍 ";
171
- }
172
- if (["bash", "sh", "zsh", "shell"].includes(l)) {
173
- return "$ ";
174
- }
175
- if (["json"].includes(l)) {
176
- return "{ ";
177
- }
178
- if (["css", "scss", "sass"].includes(l)) {
179
- return "🎨 ";
180
- }
181
- if (["html", "xml", "svg"].includes(l)) {
182
- return "⟨⟩ ";
183
- }
184
- if (["sql"].includes(l)) {
185
- return "⛁ ";
186
- }
187
- if (["go"].includes(l)) {
188
- return "◉ ";
189
- }
190
- if (["rust"].includes(l)) {
191
- return "⚙ ";
192
- }
193
- if (["java", "kotlin"].includes(l)) {
194
- return "☕ ";
195
- }
196
- if (["c", "cpp", "c++"].includes(l)) {
197
- return "⚡ ";
198
- }
199
- if (["yaml", "yml", "toml"].includes(l)) {
200
- return "⚙ ";
201
- }
202
- if (["dockerfile", "docker"].includes(l)) {
203
- return "🐳 ";
204
- }
205
- return "◇ ";
206
- }
207
-
208
- function codeLangColor(lang = "") {
209
- const l = lang.toLowerCase();
210
- if (["js", "javascript", "jsx"].includes(l)) {
211
- return "#f7df1e";
212
- }
213
- if (["ts", "typescript", "tsx"].includes(l)) {
214
- return "#3178c6";
215
- }
216
- if (["py", "python"].includes(l)) {
217
- return "#3572a5";
218
- }
219
- if (["bash", "sh", "zsh", "shell"].includes(l)) {
220
- return "#89e051";
221
- }
222
- if (["json"].includes(l)) {
223
- return "#cbcb41";
224
- }
225
- if (["css", "scss"].includes(l)) {
226
- return "#563d7c";
227
- }
228
- if (["html", "xml"].includes(l)) {
229
- return "#e34c26";
230
- }
231
- if (["sql"].includes(l)) {
232
- return "#e38c00";
233
- }
234
- if (["go"].includes(l)) {
235
- return "#00add8";
236
- }
237
- if (["rust"].includes(l)) {
238
- return "#dea584";
239
- }
240
- if (["java"].includes(l)) {
241
- return "#b07219";
242
- }
243
- if (["c", "cpp"].includes(l)) {
244
- return "#555555";
245
- }
246
- if (["yaml", "yml"].includes(l)) {
247
- return "#cb171e";
248
- }
249
- if (["dockerfile", "docker"].includes(l)) {
250
- return "#0db7ed";
251
- }
252
- return "#aaaaaa";
253
- }
254
-
255
- // ── Toggle code block expand ──────────────────────────────────────────
256
- window.toggleCodeExpand = (id) => {
257
- const block = document.getElementById(id);
258
- if (!block) {
259
- return;
260
- }
261
- const body = block.querySelector(".code-body");
262
- const showBtn = block.querySelector(".code-show-more");
263
- const expBtn = block.querySelector(".code-expand-btn");
264
- const isOpen = block.classList.toggle("code-expanded");
265
- if (body) {
266
- body.classList.toggle("code-body-collapsed", !isOpen);
267
- }
268
- if (showBtn) {
269
- showBtn.textContent = isOpen
270
- ? "Collapse ▴"
271
- : `Show all ${body?.querySelectorAll(".code-line").length || "?"} lines ▾`;
272
- }
273
- if (expBtn) {
274
- expBtn.textContent = isOpen ? "⤡" : "⤢";
275
- }
276
- };
277
-
278
- window.copyCode = async (btn) => {
279
- const code = btn.closest(".code-block")?.querySelector("code")?.innerText ?? "";
280
- try {
281
- await navigator.clipboard.writeText(code);
282
- btn.classList.add("copied");
283
- btn.textContent = "Copied!";
284
- setTimeout(() => {
285
- btn.classList.remove("copied");
286
- btn.innerHTML = `<svg width="13" height="13" viewBox="0 0 24 24" fill="none"><rect x="9" y="9" width="13" height="13" rx="2" stroke="currentColor" stroke-width="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2"/></svg> Copy`;
287
- }, 2000);
288
- } catch {}
289
- };
290
-
291
- // ── Model token stripping (profile-driven) ───────────────────────────
292
- // Strips whatever patterns the active profile declares in
293
- // profile.filters.stripPatterns. There are no hardcoded Gemma patterns
294
- // here — relying on the profile means Qwen/Nemotron/Claude (which declare
295
- // empty stripPatterns) pass through untouched, and the Ollama/Gemma
296
- // profiles apply their own patterns. Server-side stripping in
297
- // output-normalizer.ts remains the primary defense; this is best-effort
298
- // for history messages that predate the active profile.
299
- function stripModelTokensClient(text) {
300
- const profile = window.activeModelProfile;
301
- const patterns = profile?.filters?.stripPatterns;
302
- if (!patterns?.length) {
303
- return text;
304
- }
305
- let cleaned = text;
306
- for (const pat of patterns) {
307
- try {
308
- cleaned = cleaned.replace(new RegExp(pat, "gi"), "");
309
- } catch {
310
- /* skip invalid patterns */
311
- }
312
- }
313
- return cleaned;
314
- }
315
-
316
- // NOTE: Monologue suppression has moved to the OutputNormalizer (server-side).
317
- // The model stream is cleaned before events reach the Glass UI, so client-side
318
- // monologue detection is no longer needed.
319
-
320
- // ── Markdown renderer ─────────────────────────────────────────────────
321
- function renderMarkdown(text) {
322
- if (!text) {
323
- return "";
324
- }
325
- try {
326
- return typeof marked !== "undefined"
327
- ? marked.parse(text)
328
- : escHtml(text).replace(/\n/g, "<br>");
329
- } catch {
330
- return escHtml(text).replace(/\n/g, "<br>");
331
- }
332
- }
333
-
334
- // ── Extract plain text from content blocks ────────────────────────────
335
- window.extractText = function (content) {
336
- if (!content) {
337
- return "";
338
- }
339
- if (typeof content === "string") {
340
- return content;
341
- }
342
- if (Array.isArray(content)) {
343
- return content
344
- .filter((b) => b?.type === "text")
345
- .map((b) => b.text ?? "")
346
- .join("");
347
- }
348
- if (content?.content) {
349
- return window.extractText(content.content);
350
- }
351
- return "";
352
- };
353
-
354
- // ── Tool name formatter ───────────────────────────────────────────────
355
- function formatToolName(name) {
356
- if (!name) {
357
- return "Tool";
358
- }
359
- return name.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
360
- }
361
-
362
- function toolIcon(name = "") {
363
- if (name.includes("read") || name.includes("file")) {
364
- return "📄";
365
- }
366
- if (name.includes("write") || name.includes("edit")) {
367
- return "✏️";
368
- }
369
- if (name.includes("exec") || name.includes("run")) {
370
- return "⚡";
371
- }
372
- if (name.includes("search") || name.includes("web")) {
373
- return "🔍";
374
- }
375
- if (name.includes("browser")) {
376
- return "🌐";
377
- }
378
- if (name.includes("memory")) {
379
- return "🧠";
380
- }
381
- if (name.includes("spawn") || name.includes("agent")) {
382
- return "🤖";
383
- }
384
- return "🔧";
385
- }
386
-
387
- // ── Render a single content block ─────────────────────────────────────
388
- function renderBlock(block) {
389
- const el = document.createElement("div");
390
-
391
- switch (block.type) {
392
- // ── Plain text with markdown ──────────────────────────────────────
393
- case "text": {
394
- el.className = "msg-text";
395
- const rawText = block.text ?? "";
396
- const stripped = stripModelTokensClient(rawText);
397
- // If stripping ate everything but we started with real text, render
398
- // the raw text rather than silently dropping the message. Prevents
399
- // the "response appeared then disappeared" regression.
400
- const safeText = stripped.trim() ? stripped : rawText;
401
- if (!safeText) {
402
- break;
403
- }
404
- el.innerHTML = renderMarkdown(safeText);
405
- break;
406
- }
407
-
408
- // ── Thinking block (collapsible) ──────────────────────────────────
409
- case "thinking": {
410
- el.className = "msg-thinking";
411
- const id = "think-" + Math.random().toString(36).slice(2);
412
- el.innerHTML = `
413
- <button class="thinking-toggle" onclick="toggleThinking('${id}')">
414
- <span class="thinking-icon">◈</span>
415
- <span class="thinking-label">Reasoning</span>
416
- <span class="thinking-chevron">▾</span>
417
- </button>
418
- <div class="thinking-body" id="${id}">
419
- <div class="thinking-text">${escHtml(block.thinking ?? "")}</div>
420
- </div>
421
- `;
422
- break;
423
- }
424
-
425
- // ── Tool use (what was called) ────────────────────────────────────
426
- case "tool_use": {
427
- el.className = "msg-tool-card";
428
- const name = block.name ?? "tool";
429
- const input = block.input ? JSON.stringify(block.input, null, 2) : "";
430
- const id = "tool-" + Math.random().toString(36).slice(2);
431
- el.innerHTML = `
432
- <button class="tool-header" onclick="toggleTool('${id}')">
433
- <span class="tool-icon">${toolIcon(name)}</span>
434
- <span class="tool-name">${escHtml(formatToolName(name))}</span>
435
- <span class="tool-chevron">▾</span>
436
- </button>
437
- <div class="tool-body" id="${id}">
438
- <pre class="tool-input">${escHtml(input)}</pre>
439
- </div>
440
- `;
441
- break;
442
- }
443
-
444
- // ── Tool result ───────────────────────────────────────────────────
445
- case "tool_result": {
446
- el.className = "msg-tool-result";
447
- const content = Array.isArray(block.content)
448
- ? block.content.map((b) => b.text ?? "").join("\n")
449
- : String(block.content ?? "");
450
- const _preview = content.slice(0, 120);
451
- const more = content.length > 120;
452
- const id = "result-" + Math.random().toString(36).slice(2);
453
- el.innerHTML = `
454
- <div class="result-header">
455
- <span class="result-icon">↩</span>
456
- <span class="result-label">Result</span>
457
- ${more ? `<button class="result-expand" onclick="toggleTool('${id}')">Expand</button>` : ""}
458
- </div>
459
- <div class="result-preview" id="${id}">
460
- <pre class="result-text">${escHtml(content)}</pre>
461
- </div>
462
- `;
463
- if (!more) {
464
- el.querySelector(".result-preview")?.classList.add("result-open");
465
- }
466
- break;
467
- }
468
-
469
- // ── Image ─────────────────────────────────────────────────────────
470
- case "image": {
471
- el.className = "msg-image";
472
- const src =
473
- block.source?.url ??
474
- (block.source?.type === "base64"
475
- ? `data:${block.source.media_type};base64,${block.source.data}`
476
- : "");
477
- if (src) {
478
- el.innerHTML = `<img src="${escAttr(src)}" alt="image" />`;
479
- }
480
- break;
481
- }
482
-
483
- default:
484
- break;
485
- }
486
-
487
- return el;
488
- }
489
-
490
- // ── Toggle helpers ────────────────────────────────────────────────────
491
- window.toggleThinking = (id) => {
492
- const body = document.getElementById(id);
493
- const btn = body?.previousElementSibling;
494
- if (!body) {
495
- return;
496
- }
497
- const open = body.classList.toggle("thinking-open");
498
- if (btn) {
499
- btn.querySelector(".thinking-chevron").textContent = open ? "▴" : "▾";
500
- }
501
- };
502
-
503
- window.toggleTool = (id) => {
504
- const body = document.getElementById(id);
505
- if (!body) {
506
- return;
507
- }
508
- body.classList.toggle("tool-open");
509
- const btn = body?.previousElementSibling?.querySelector?.(".tool-chevron");
510
- if (btn) {
511
- btn.textContent = body.classList.contains("tool-open") ? "▴" : "▾";
512
- }
513
- };
514
-
515
- // ── Copy message text ─────────────────────────────────────────────────
516
- window.copyMessage = async (btn) => {
517
- const bubble = btn.closest(".stream-bubble, .bubble");
518
- const text = bubble?.querySelector(".msg-text")?.innerText ?? bubble?.innerText ?? "";
519
- try {
520
- await navigator.clipboard.writeText(text.trim());
521
- btn.classList.add("copied");
522
- setTimeout(() => btn.classList.remove("copied"), 2000);
523
- } catch {}
524
- };
525
-
526
- // ── Timestamp formatter ───────────────────────────────────────────────
527
- function formatTime(ts) {
528
- if (!ts) {
529
- return "";
530
- }
531
- const d = new Date(typeof ts === "number" && ts < 1e12 ? ts * 1000 : ts);
532
- return d.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
533
- }
534
-
535
- // Expose renderBlock for use in app.js streaming finalization
536
- window.renderBlock = renderBlock;
537
-
538
- // ── Reasoning Panel — append a block ─────────────────────────────────
539
- window.appendToReasoningPanel = function (block) {
540
- const feed = document.getElementById("reasoning-feed");
541
- if (!feed) {
542
- return;
543
- }
544
-
545
- // Remove empty-state placeholder on first real entry
546
- const empty = document.getElementById("reasoning-empty");
547
- if (empty) {
548
- empty.remove();
549
- }
550
-
551
- const entry = document.createElement("div");
552
- entry.className = "reasoning-entry";
553
-
554
- switch (block.type) {
555
- // ── Narration text (agent step descriptions routed here) ────────
556
- case "text": {
557
- const text = (block.text ?? "").trim();
558
- if (!text) {
559
- return;
560
- }
561
- entry.innerHTML = `
562
- <div class="reasoning-entry-header">
563
- <span class="reasoning-entry-badge badge-narration">✦ NOTE</span>
564
- <span class="reasoning-entry-name">${escHtml(String(text).split("\n")[0].slice(0, 60))}${text.length > 60 ? "…" : ""}</span>
565
- </div>
566
- `;
567
- break;
568
- }
569
-
570
- // ── Thinking block ──────────────────────────────────────────────
571
- case "thinking": {
572
- const text = (block.thinking ?? "").trim();
573
- if (!text) {
574
- return;
575
- }
576
- entry.innerHTML = `
577
- <div class="reasoning-entry-header">
578
- <span class="reasoning-entry-badge badge-think">◈ THINK</span>
579
- <span class="reasoning-entry-name">${escHtml(String(text).split("\n")[0].slice(0, 60))}${text.length > 60 ? "…" : ""}</span>
580
- </div>
581
- <div class="reasoning-think-body">${escHtml(text)}</div>
582
- `;
583
- break;
584
- }
585
-
586
- // ── Tool call (Anthropic: tool_use, Ollama/OpenAI: toolCall) ────
587
- case "tool_use":
588
- case "toolCall": {
589
- const name = block.name ?? "tool";
590
- const inputData = block.input ?? block.arguments ?? {};
591
- const inputJson = inputData ? JSON.stringify(inputData, null, 2) : "{}";
592
- // One-line preview: first key=value pair
593
- let preview = "";
594
- try {
595
- const obj = typeof inputData === "string" ? JSON.parse(inputData) : inputData;
596
- const keys = Object.keys(obj ?? {});
597
- if (keys.length) {
598
- const val = String(obj[keys[0]]).slice(0, 50);
599
- preview = `${keys[0]}: ${val}${val.length >= 50 ? "…" : ""}`;
600
- }
601
- } catch {
602
- /* ignore */
603
- }
604
- entry.innerHTML = `
605
- <div class="reasoning-entry-header">
606
- <span class="reasoning-entry-badge badge-tool">${escHtml(toolIcon(name))} TOOL</span>
607
- <span class="reasoning-entry-name">${escHtml(formatToolName(name))}</span>
608
- </div>
609
- ${preview ? `<div class="reasoning-tool-preview">${escHtml(preview)}</div>` : ""}
610
- <div class="reasoning-tool-detail">${escHtml(inputJson)}</div>
611
- `;
612
- // Toggle expand on click
613
- entry.style.cursor = "pointer";
614
- entry.addEventListener("click", () => entry.classList.toggle("expanded"));
615
- break;
616
- }
617
-
618
- // ── Tool result ─────────────────────────────────────────────────
619
- case "tool_result": {
620
- const content = Array.isArray(block.content)
621
- ? block.content.map((b) => b.text ?? "").join("\n")
622
- : String(block.content ?? "");
623
- const chars = content.length;
624
- const isError = block.is_error === true;
625
- entry.innerHTML = `
626
- <div class="reasoning-entry-header">
627
- <span class="reasoning-entry-badge badge-result">${isError ? "⚠ ERROR" : "↩ RESULT"}</span>
628
- <span class="reasoning-entry-name">${chars} chars</span>
629
- </div>
630
- <div class="reasoning-result-meta">${escHtml(content.slice(0, 80))}${chars > 80 ? "…" : ""}</div>
631
- `;
632
- break;
633
- }
634
-
635
- default:
636
- return; // unknown block — skip
637
- }
638
-
639
- feed.appendChild(entry);
640
- feed.scrollTop = feed.scrollHeight;
641
- };
642
-
643
- // ── Reasoning Panel — run separator ──────────────────────────────────
644
- window.injectReasoningRunSeparator = function () {
645
- const feed = document.getElementById("reasoning-feed");
646
- if (!feed) {
647
- return;
648
- }
649
- const empty = document.getElementById("reasoning-empty");
650
- if (empty) {
651
- empty.remove();
652
- }
653
- const now = new Date();
654
- const hhmm = now.toLocaleTimeString("en-US", {
655
- hour: "2-digit",
656
- minute: "2-digit",
657
- hour12: false,
658
- });
659
- const sep = document.createElement("div");
660
- sep.className = "reasoning-run-sep";
661
- sep.innerHTML = `<span class="reasoning-run-sep-label">RUN · ${hhmm}</span>`;
662
- feed.appendChild(sep);
663
- feed.scrollTop = feed.scrollHeight;
664
- };
665
-
666
- // ── Reasoning Panel — clear ───────────────────────────────────────────
667
- window.clearReasoningPanel = function () {
668
- const feed = document.getElementById("reasoning-feed");
669
- if (!feed) {
670
- return;
671
- }
672
- feed.innerHTML = `
673
- <div class="reasoning-empty" id="reasoning-empty">
674
- <div class="reasoning-empty-icon">
675
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
676
- <circle cx="12" cy="12" r="3"/>
677
- <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
678
- </svg>
679
- </div>
680
- <div class="reasoning-empty-text">No reasoning yet</div>
681
- </div>`;
682
- };
683
-
684
- // ── Reasoning Panel — live thinking update (streaming) ───────────────
685
- // Called repeatedly during a run to accumulate thinking text in real-time.
686
- // Creates a single "live" entry and updates it in-place until finalized.
687
- let _liveThinkEntry = null;
688
- let _liveThinkBody = null;
689
- let _liveThinkBuffer = "";
690
-
691
- window.openLiveThinking = function () {
692
- const feed = document.getElementById("reasoning-feed");
693
- if (!feed) {
694
- return;
695
- }
696
- const empty = document.getElementById("reasoning-empty");
697
- if (empty) {
698
- empty.remove();
699
- }
700
- _liveThinkBuffer = "";
701
- const entry = document.createElement("div");
702
- entry.className = "reasoning-entry";
703
- entry.id = "reasoning-live-think";
704
- entry.innerHTML = `
705
- <div class="reasoning-entry-header">
706
- <span class="reasoning-entry-badge badge-think">◈ THINK</span>
707
- <span class="reasoning-entry-name" id="reasoning-live-name">…</span>
708
- </div>
709
- <div class="reasoning-think-body" id="reasoning-live-body"></div>
710
- `;
711
- feed.appendChild(entry);
712
- _liveThinkEntry = entry;
713
- _liveThinkBody = entry.querySelector("#reasoning-live-body");
714
- feed.scrollTop = feed.scrollHeight;
715
- };
716
-
717
- window.updateLiveThinking = function (text) {
718
- if (!_liveThinkBody) {
719
- window.openLiveThinking();
720
- }
721
- _liveThinkBuffer += text;
722
- if (_liveThinkBody) {
723
- _liveThinkBody.textContent = _liveThinkBuffer;
724
- const feed = document.getElementById("reasoning-feed");
725
- if (feed) {
726
- feed.scrollTop = feed.scrollHeight;
727
- }
728
- }
729
- // Update name preview
730
- const nameEl = _liveThinkEntry?.querySelector("#reasoning-live-name");
731
- if (nameEl) {
732
- const firstLine = _liveThinkBuffer.split("\n")[0].slice(0, 60);
733
- nameEl.textContent = firstLine + (_liveThinkBuffer.length > 60 ? "…" : "");
734
- }
735
- };
736
-
737
- window.closeLiveThinking = function () {
738
- if (_liveThinkEntry) {
739
- _liveThinkEntry.removeAttribute("id");
740
- _liveThinkEntry = null;
741
- _liveThinkBody = null;
742
- _liveThinkBuffer = "";
743
- }
744
- };
745
-
746
- // ── Extract thinking text from a content array (for streaming deltas) ─
747
- window.extractThinkingText = function (content) {
748
- if (!content) {
749
- return "";
750
- }
751
- if (typeof content === "string") {
752
- return "";
753
- }
754
- if (Array.isArray(content)) {
755
- return content
756
- .filter((b) => b?.type === "thinking")
757
- .map((b) => b.thinking ?? "")
758
- .join("");
759
- }
760
- if (content?.content) {
761
- return window.extractThinkingText(content.content);
762
- }
763
- return "";
764
- };
765
-
766
- // ── Main render function — builds a full message element ──────────────
767
- window.renderMessage = function (message) {
768
- const { role, content, timestamp } = message;
769
- const isUser = role === "user";
770
-
771
- // ── Filter noisy/internal messages ────────────────────────────────
772
- const _msgText = Array.isArray(content)
773
- ? content
774
- .filter((b) => b.type === "text")
775
- .map((b) => b.text ?? "")
776
- .join("")
777
- .trim()
778
- : extractText(content).trim();
779
-
780
- // NOTE: Monologue suppression moved server-side to OutputNormalizer.
781
-
782
- // Plugin context messages (e.g. "[Outlook 365] Not connected...")
783
- if (role === "user" && /^\[.+\]\s+(Not connected|Connected as)\b/i.test(_msgText)) {
784
- if (typeof window.appendToReasoningPanel === "function") {
785
- window.appendToReasoningPanel({ type: "text", text: "[Plugin context]" });
786
- }
787
- return null;
788
- }
789
-
790
- // Post-generation verification user messages
791
- if (
792
- role === "user" &&
793
- /^Review your response against the original user request/i.test(_msgText)
794
- ) {
795
- if (typeof window.appendToReasoningPanel === "function") {
796
- window.appendToReasoningPanel({ type: "text", text: "[Post-generation verification]" });
797
- }
798
- return null;
799
- }
800
-
801
- const wrapper = document.createElement("div");
802
- wrapper.className = `message ${isUser ? "user-msg" : "symi-msg"}`;
803
-
804
- const bubble = document.createElement("div");
805
- bubble.className = isUser ? "bubble" : "bubble stream-bubble done";
806
-
807
- // Add copy button for assistant messages
808
- if (!isUser) {
809
- const copyBtn = document.createElement("button");
810
- copyBtn.className = "msg-copy-btn";
811
- copyBtn.title = "Copy";
812
- copyBtn.addEventListener("click", function () {
813
- window.copyMessage(this);
814
- });
815
- copyBtn.innerHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none">
816
- <rect x="9" y="9" width="13" height="13" rx="2" stroke="currentColor" stroke-width="2"/>
817
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2"/>
818
- </svg>`;
819
- bubble.appendChild(copyBtn);
820
- }
821
-
822
- // Render each content block — route reasoning/tool blocks to the side panel
823
- const REASONING_TYPES = new Set(["thinking", "tool_use", "tool_result", "toolCall"]);
824
- const isNarration = !isUser && message.stopReason === "toolUse";
825
- const blocks = Array.isArray(content) ? content : [{ type: "text", text: extractText(content) }];
826
- for (const block of blocks) {
827
- if (!isUser && REASONING_TYPES.has(block.type)) {
828
- // Route to Reasoning Panel — keep response bubble clean
829
- window.appendToReasoningPanel(block);
830
- continue;
831
- }
832
- // Text blocks in tool-use messages are narration — route to Reasoning Panel
833
- if (isNarration && block.type === "text") {
834
- window.appendToReasoningPanel(block);
835
- continue;
836
- }
837
- const el = renderBlock(block);
838
- if (el.childNodes.length || el.innerHTML) {
839
- bubble.appendChild(el);
840
- }
841
- }
842
-
843
- // If the bubble has no visible content (only copy button), skip it entirely
844
- const visibleChildren = bubble.querySelectorAll(
845
- ".msg-text, .msg-image, .msg-thinking, .msg-tool-card, .msg-tool-result",
846
- );
847
- if (!isUser && visibleChildren.length === 0) {
848
- return null;
849
- }
850
-
851
- // Timestamp
852
- if (timestamp) {
853
- const ts = document.createElement("div");
854
- ts.className = "msg-timestamp";
855
- ts.textContent = formatTime(timestamp);
856
- bubble.appendChild(ts);
857
- }
858
-
859
- wrapper.appendChild(bubble);
860
- wrapper.appendChild(
861
- Object.assign(document.createElement("div"), { className: "message-clearfix" }),
862
- );
863
- return wrapper;
864
- };
865
-
866
- // ── Re-render for streaming (plain text, no markdown until final) ──────
867
- window.renderStreamText = function (el, text) {
868
- if (!el) {
869
- return;
870
- }
871
- el.textContent = text;
872
- };
873
-
874
- // ── Apply highlight.js to any unhighlighted code blocks ──────────────
875
- window.applyHighlighting = function (container) {
876
- if (typeof hljs === "undefined") {
877
- return;
878
- }
879
- container.querySelectorAll("pre code:not(.hljs)").forEach((block) => {
880
- hljs.highlightElement(block);
881
- });
882
- };