@symerian/symi 2.0.7 → 2.0.9

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 (249) hide show
  1. package/dist/{agents-CNsMe4Dr.js → agents-DhimA7PX.js} +4 -4
  2. package/dist/{agents.config-yx78oSLx.js → agents.config-Dx90DAnM.js} +1 -1
  3. package/dist/{agents.config-CdDf19dm.js → agents.config-fv5KaNkC.js} +1 -1
  4. package/dist/{audio-preflight-Cq4C-m27.js → audio-preflight-B6L8N6Ly.js} +13 -12
  5. package/dist/{audio-preflight-DbUFnPX1.js → audio-preflight-Bk54IW__.js} +17 -16
  6. package/dist/{audio-preflight-DSeaWZZW.js → audio-preflight-C2U7KMim.js} +6 -5
  7. package/dist/{audio-preflight-CO2seHjy.js → audio-preflight-DQDfh7hZ.js} +12 -11
  8. package/dist/{audit-DKUpFt8z.js → audit--HKrSvGg.js} +2 -2
  9. package/dist/{audit-CiugrQda.js → audit-C1KuICJa.js} +2 -2
  10. package/dist/{auth-choice-mw9ndZQO.js → auth-choice-B4zjI12P.js} +4 -4
  11. package/dist/{auth-choice-CXMFi9LR.js → auth-choice-BqU5qMZy.js} +1 -1
  12. package/dist/{banner-B-joBGLz.js → banner-XTz_k5N3.js} +1 -1
  13. package/dist/build-info.json +3 -3
  14. package/dist/bundled/boot-md/handler.js +34 -34
  15. package/dist/bundled/session-memory/handler.js +34 -34
  16. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  17. package/dist/{channel-options-XPRRVrmU.js → channel-options-Bbd-uPQW.js} +1 -1
  18. package/dist/{channel-options-D74Jofp4.js → channel-options-mU0wiiP2.js} +1 -1
  19. package/dist/{channel-web-vRvvtf0S.js → channel-web-CT8JWl10.js} +8 -8
  20. package/dist/{channels-cli-D3lj5dXo.js → channels-cli-16POci9_.js} +32 -32
  21. package/dist/{channels-cli-DgxPfJF7.js → channels-cli-DMCnP5KN.js} +12 -12
  22. package/dist/{chrome-BATLK3yK.js → chrome-2-wXJfuH.js} +8 -8
  23. package/dist/{chrome-h6BnL8Lp.js → chrome-B_zrSLce.js} +7 -7
  24. package/dist/{chunk-BW5f05BR.js → chunk-BPSLqkZN.js} +1 -1
  25. package/dist/{chunk-DTMTDXwE.js → chunk-rw3-yl6B.js} +1 -1
  26. package/dist/{cli-Bg_5WQFe.js → cli-Bzq5mSbu.js} +9 -9
  27. package/dist/{cli-DQQAfUbo.js → cli-nuP_OZI0.js} +29 -29
  28. package/dist/{command-registry-Cde2LqTh.js → command-registry-DbtbOY_4.js} +9 -9
  29. package/dist/{commands-registry-C3C4Rv3O.js → commands-registry-CZ5P8CpC.js} +2 -2
  30. package/dist/{commands-registry-Copoizgv.js → commands-registry-UwWpNkQg.js} +1 -1
  31. package/dist/{completion-cli-KJUTWJP3.js → completion-cli-BwRqjgrI.js} +2 -2
  32. package/dist/{completion-cli-Cx9htCOm.js → completion-cli-mwQhHtOm.js} +1 -1
  33. package/dist/{config-DM0K7qC1.js → config-D3XlX-h-.js} +1 -1
  34. package/dist/{config-cli-C5-P9Nzz.js → config-cli-Bu_y5erZ.js} +1 -1
  35. package/dist/{config-cli-ozfA6MGF.js → config-cli-CoceKyQv.js} +1 -1
  36. package/dist/{config-guard-Cnu2qssk.js → config-guard-CFGZ0BjX.js} +3 -2
  37. package/dist/{config-guard-BpQn1MKk.js → config-guard-DujvCAc6.js} +1 -1
  38. package/dist/{configure-DiuQ_aTS.js → configure-C27dLO_C.js} +6 -6
  39. package/dist/{configure-ktsZw1bT.js → configure-DekriuOk.js} +3 -3
  40. package/dist/{deliver-2Y_F_0yh.js → deliver-B572qYqb.js} +5 -5
  41. package/dist/{deliver-DD3gs9SF.js → deliver-DGaRNkFI.js} +5 -5
  42. package/dist/{deliver-CZF9f8aC.js → deliver-jK_qcWx-.js} +5 -5
  43. package/dist/{deliver-DONp5mgd.js → deliver-l9I03N1d.js} +2 -2
  44. package/dist/{diagnostic-CI0kRQkt.js → diagnostic-BIVLRT_X.js} +1 -1
  45. package/dist/{diagnostic-D0xmLpej.js → diagnostic-C-7DW8ZL.js} +1 -1
  46. package/dist/{doctor-completion-CrN6Ly8x.js → doctor-completion-D2AFiL0G.js} +1 -1
  47. package/dist/{doctor-completion-Vwi_je1c.js → doctor-completion-RScd9m4s.js} +1 -1
  48. package/dist/{doctor-config-flow-C_56SUPO.js → doctor-config-flow-Cpwv-_yJ.js} +1 -1
  49. package/dist/{doctor-config-flow-B150h841.js → doctor-config-flow-ZeM3rJqG.js} +1 -1
  50. package/dist/entry.js +1 -1
  51. package/dist/extensionAPI.js +29 -29
  52. package/dist/{fetch-DTNGXEzX.js → fetch-BrtlUMgb.js} +1 -1
  53. package/dist/{fetch-guard-DOPkVbh3.js → fetch-guard-DPA1vbaF.js} +1 -1
  54. package/dist/{gateway-cli-DyqK4XZ1.js → gateway-cli-D98Kj3_n.js} +43 -43
  55. package/dist/{gateway-cli-CwO3878F.js → gateway-cli-N4jJ2_RN.js} +20 -20
  56. package/dist/{gemini-auth-7AWT6JXV.js → gemini-auth-Ca6F0cNq.js} +1 -1
  57. package/dist/{glass-ui-ws-zVNodseh.js → glass-ui-ws-B2fxjJTt.js} +39 -39
  58. package/dist/{glass-ui-ws-BmqwQaCf.js → glass-ui-ws-Dd-MN6YA.js} +16 -16
  59. package/dist/{health-Q1RP1M2f.js → health-C1_ivVPh.js} +5 -5
  60. package/dist/{health-UjXEBnzA.js → health-Da2Nvp6A.js} +4 -4
  61. package/dist/{heartbeat-visibility-U4BL57eQ.js → heartbeat-visibility-D4Xy8Sv0.js} +2 -2
  62. package/dist/{heartbeat-visibility-B8TDjqpW.js → heartbeat-visibility-DS9JNq6T.js} +2 -2
  63. package/dist/{hooks-cli-D4qJl6do.js → hooks-cli-Bv6VXisB.js} +10 -10
  64. package/dist/{hooks-cli-DOT9uGZw.js → hooks-cli-GzTpm8sN.js} +30 -30
  65. package/dist/{image-RLbZ3RUn.js → image-BJiE96Ml.js} +4 -4
  66. package/dist/{image-B4LY9KFw.js → image-BW-m96jq.js} +1 -1
  67. package/dist/{image-DrZEJQwQ.js → image-B_WF7Uie.js} +2 -2
  68. package/dist/{image-DOnOTocl.js → image-qnqUW4nb.js} +2 -2
  69. package/dist/index.js +36 -36
  70. package/dist/{ir-DccrnjsE.js → ir-B4l25ISI.js} +3 -3
  71. package/dist/{ir-DZam9q5M.js → ir-DEVHhjq7.js} +1 -1
  72. package/dist/{ir-F0moAwIl.js → ir-DPLo2LIn.js} +3 -3
  73. package/dist/llm-slug-generator.js +34 -34
  74. package/dist/{local-roots-CC8jiKDk.js → local-roots-BDORNz_Q.js} +1 -1
  75. package/dist/{local-roots-aAFLQGkY.js → local-roots-C31eq7PP.js} +1 -1
  76. package/dist/{local-roots-DMwIh5cS.js → local-roots-Dg0r0pJL.js} +1 -1
  77. package/dist/{login-BG_7eJLu.js → login-DNi-TGJT.js} +2 -2
  78. package/dist/{login-qr-9OQSnm5L.js → login-qr-DWlyS1Bc.js} +4 -4
  79. package/dist/{manager-B5EXdBQV.js → manager-BX65xO2I.js} +2 -2
  80. package/dist/{manager-C_DoJrcP.js → manager-DjVWQ1JF.js} +3 -3
  81. package/dist/{memory-cli-D4J9SO7Z.js → memory-cli-BsBiPX0L.js} +4 -4
  82. package/dist/{model-auth-CeL58m55.js → model-auth-Daguh6Kb.js} +1 -1
  83. package/dist/{model-picker-DXwUsLAy.js → model-picker-CiSWZdy1.js} +1 -1
  84. package/dist/{models-DKsiIvSx.js → models-B7W1r9j8.js} +2 -2
  85. package/dist/{models-cli-ULbdeSgc.js → models-cli-B3XOSnTQ.js} +30 -30
  86. package/dist/{models-cli-BS6UJ98e.js → models-cli-BBFKprvF.js} +11 -11
  87. package/dist/{onboard-B387frTY.js → onboard-D54rYSt2.js} +5 -5
  88. package/dist/{onboard-Bt-BwfkR.js → onboard-DEBJWlyh.js} +2 -2
  89. package/dist/{onboard-channels-COcxT5Q0.js → onboard-channels-CwXnFQgu.js} +1 -1
  90. package/dist/{onboard-channels-ybPEmcP8.js → onboard-channels-D4U3bHOF.js} +1 -1
  91. package/dist/{onboard-custom-DoIhWPnb.js → onboard-custom-B3RZopk5.js} +2 -2
  92. package/dist/{onboard-skills-BD8JNVwL.js → onboard-skills-DfKmsYuM.js} +1 -1
  93. package/dist/{onboarding-CdN_NU2d.js → onboarding-Ch56YN4Q.js} +7 -7
  94. package/dist/{onboarding-BibGEGIS.js → onboarding-Do5IBVbx.js} +4 -4
  95. package/dist/{onboarding.finalize-CY1NjrGb.js → onboarding.finalize-C8I4yJ1J.js} +15 -15
  96. package/dist/{onboarding.finalize-CvahVrDM.js → onboarding.finalize-ijmEZx2f.js} +34 -34
  97. package/dist/{onboarding.gateway-config-Cj_s_IG8.js → onboarding.gateway-config-BxgvBGxU.js} +2 -1
  98. package/dist/{onboarding.gateway-config-DipSuaKH.js → onboarding.gateway-config-EtWmSCuC.js} +2 -1
  99. package/dist/{openai-model-default-DF334-MD.js → openai-model-default-BkscYpXX.js} +1 -1
  100. package/dist/{outbound-DfOF58G2.js → outbound-56UQxS1I.js} +2 -2
  101. package/dist/{outbound-BNMysnJ1.js → outbound-ByC0HdWz.js} +2 -2
  102. package/dist/{outbound-Cedd_yui.js → outbound-DpGc1neG.js} +3 -3
  103. package/dist/{outbound-attachment-D_QuKi8U.js → outbound-attachment-C-GD7uJh.js} +1 -1
  104. package/dist/{outbound-attachment-DjNDa3zn.js → outbound-attachment-CJZwroQb.js} +2 -2
  105. package/dist/{outbound-attachment-entfcjDW.js → outbound-attachment-Cir36qaG.js} +2 -2
  106. package/dist/{pi-auth-json-BNhcohVK.js → pi-auth-json-CHgA276j.js} +2 -2
  107. package/dist/{pi-embedded-ZzUH4ioO.js → pi-embedded-C5XncARS.js} +66 -161
  108. package/dist/{pi-embedded-BvCoZBNg.js → pi-embedded-FBOXa0Py.js} +54 -149
  109. package/dist/{pi-embedded-helpers-x8rJur4F.js → pi-embedded-helpers-B8JQjQlx.js} +109 -13
  110. package/dist/{pi-embedded-helpers--yFTAWwW.js → pi-embedded-helpers-BqnI9Mzn.js} +107 -11
  111. package/dist/{pi-embedded-helpers-ueCT6VlS.js → pi-embedded-helpers-V5QifZSd.js} +2 -2
  112. package/dist/{pi-embedded-helpers-CgxKWHj9.js → pi-embedded-helpers-dLW7QMQa.js} +1 -1
  113. package/dist/{pi-tools.policy-T6Z5F-_n.js → pi-tools.policy-B9nQ2esl.js} +1 -1
  114. package/dist/{pi-tools.policy-DPmdlOwE.js → pi-tools.policy-C747j2xs.js} +1 -1
  115. package/dist/{plugin-registry-BAbkdLQ7.js → plugin-registry-BQ_14aNH.js} +1 -1
  116. package/dist/{plugin-registry-CEoSVvL1.js → plugin-registry-Dso3ttvf.js} +1 -1
  117. package/dist/plugin-sdk/{audio-preflight-CpYjfwrA.js → audio-preflight-CAWn5TBW.js} +4 -3
  118. package/dist/plugin-sdk/{channel-web-xXTpy0N_.js → channel-web-CdAlKpn7.js} +3 -3
  119. package/dist/plugin-sdk/{deliver-BwnrMlHO.js → deliver-PnVwVXLm.js} +1 -1
  120. package/dist/plugin-sdk/gateway/chat-sanitize.d.ts +11 -0
  121. package/dist/plugin-sdk/{image-k_W1USVr.js → image-BGfQ0dkr.js} +1 -1
  122. package/dist/plugin-sdk/index.js +6 -6
  123. package/dist/plugin-sdk/{pi-embedded-helpers-Cs2-_EpL.js → pi-embedded-helpers-BMudP5Tn.js} +98 -2
  124. package/dist/plugin-sdk/{reply-EEvLfWgt.js → reply-QYyMp-Tw.js} +12 -107
  125. package/dist/plugin-sdk/{runner-Br1179I4.js → runner-qajBqJHY.js} +1 -1
  126. package/dist/plugin-sdk/{web-COWtpMAH.js → web-CVs35ve3.js} +6 -6
  127. package/dist/{plugins-cli-C_S07pgO.js → plugins-cli-BVyrgA8I.js} +30 -30
  128. package/dist/{plugins-cli-BpuQ7Y9l.js → plugins-cli-CgbeQGSF.js} +10 -10
  129. package/dist/{program-context-QBBvnWFX.js → program-context-hfUEmZz7.js} +21 -21
  130. package/dist/{program-cO9YX6wL.js → program-kfkuCFKS.js} +16 -16
  131. package/dist/{prompt-select-styled-D3dYbx2P.js → prompt-select-styled-116ZbBko.js} +7 -7
  132. package/dist/{prompt-select-styled-CepuQSKg.js → prompt-select-styled-J9mSr0OH.js} +10 -10
  133. package/dist/{provider-auth-helpers-DXqvuBCi.js → provider-auth-helpers-B6VXmCAd.js} +1 -1
  134. package/dist/{provider-auth-helpers-BMACaaEd.js → provider-auth-helpers-C6JINKCe.js} +1 -1
  135. package/dist/{push-apns-DhZgao_r.js → push-apns-DPN9gxCf.js} +1 -1
  136. package/dist/{push-apns-8YIzbTM7.js → push-apns-jxwr84iE.js} +1 -1
  137. package/dist/{pw-ai-CCt1nIO-.js → pw-ai-D8UzqLyI.js} +4 -4
  138. package/dist/{pw-ai-C_C5as1t.js → pw-ai-s-d46DCX.js} +1 -1
  139. package/dist/{qmd-manager-D85GJrir.js → qmd-manager-DeZm1nJL.js} +1 -1
  140. package/dist/{register.agent-CiTS9lyx.js → register.agent-DuJFFLJT.js} +35 -35
  141. package/dist/{register.agent-CSUoUVKd.js → register.agent-zXM0Ehps.js} +14 -14
  142. package/dist/{register.configure-BbE9MAer.js → register.configure-CNCoYc7M.js} +39 -39
  143. package/dist/{register.configure-CuCVLOW0.js → register.configure-DS0YVUwx.js} +14 -14
  144. package/dist/{register.maintenance-CJG75LTu.js → register.maintenance-BXnLhacM.js} +17 -17
  145. package/dist/{register.maintenance-D8bthvou.js → register.maintenance-D3oTcEuA.js} +37 -37
  146. package/dist/{register.message-CyqE4E2O.js → register.message-BjdjpA_Z.js} +10 -10
  147. package/dist/{register.message-nUpHGrEE.js → register.message-DyIz3Dyp.js} +30 -30
  148. package/dist/{register.onboard-BDlne5KX.js → register.onboard-CStFDwlr.js} +12 -12
  149. package/dist/{register.onboard-Dlw-TCPH.js → register.onboard-DN3MQsVM.js} +35 -35
  150. package/dist/{register.setup-ByMyofSq.js → register.setup-6f2WvCYV.js} +12 -12
  151. package/dist/{register.setup-B8kiMuah.js → register.setup-BMsroiDO.js} +35 -35
  152. package/dist/{register.status-health-sessions-Diirshgb.js → register.status-health-sessions-Bioq718n.js} +34 -34
  153. package/dist/{register.status-health-sessions-0odRpA-p.js → register.status-health-sessions-CQB3d6mV.js} +13 -13
  154. package/dist/{register.subclis-CqEj9vfW.js → register.subclis-DjRoIlDB.js} +12 -12
  155. package/dist/{replies-D9V19U2-.js → replies-B4-OBhpP.js} +2 -2
  156. package/dist/{replies-DqdOBkTB.js → replies-ConxSQu4.js} +2 -2
  157. package/dist/{replies-QloQerhz.js → replies-DPvPoRgq.js} +2 -2
  158. package/dist/{reply-B9o45s3E.js → reply-b43dsTx2.js} +45 -166
  159. package/dist/{run-main-C__lZ7VF.js → run-main-DYbAd0T1.js} +25 -25
  160. package/dist/{runner-BXN4KYDK.js → runner-CQnf083C.js} +1 -1
  161. package/dist/{runner-DjHRFXSI.js → runner-Ct0-sE8b.js} +8 -8
  162. package/dist/{runner-C0tJTZmp.js → runner-DhtP_e8E.js} +6 -6
  163. package/dist/{runner-uDZlTCm2.js → runner-t-wbbvf-.js} +4 -4
  164. package/dist/{sandbox-CbuJolk2.js → sandbox-DofcD9ax.js} +1 -1
  165. package/dist/{sandbox-cli-C90jqh9l.js → sandbox-cli-Dx6F5FaT.js} +3 -2
  166. package/dist/{sandbox-cli-Duc05KL9.js → sandbox-cli-l_OcbOYC.js} +3 -2
  167. package/dist/{sandbox-rMmahr2s.js → sandbox-yaTFb84E.js} +1 -1
  168. package/dist/{security-cli-YGXUUBvD.js → security-cli-BJ3IXZfm.js} +5 -4
  169. package/dist/{security-cli-Bt0VkUtO.js → security-cli-CSpwKdww.js} +5 -4
  170. package/dist/{send-CzE5UKr-.js → send-B9JhmJSo.js} +5 -5
  171. package/dist/{send-D_yJMeJa.js → send-COvqFO3S.js} +4 -4
  172. package/dist/{send-DEWzWqfZ.js → send-CiVBt5gu.js} +4 -4
  173. package/dist/{send-BeASPkFg.js → send-D3qb_2Q-.js} +4 -4
  174. package/dist/{send-mi3NHnwI.js → send-DBTO2dLX.js} +2 -2
  175. package/dist/{send-De_WCeGZ.js → send-DDt3Bdxx.js} +4 -4
  176. package/dist/{send-3YM-aarb.js → send-DXoJ5lC_.js} +1 -1
  177. package/dist/{send-Do-0Kcmv.js → send-DmlK72uJ.js} +3 -3
  178. package/dist/{send-BsocounR.js → send-Dz76LuDQ.js} +2 -2
  179. package/dist/{send-CHOArYFe.js → send-DzmRVAHq.js} +3 -3
  180. package/dist/{send-BVZGeP2r.js → send-LZO3UNRb.js} +3 -3
  181. package/dist/{send-B18gkuvz.js → send-OEyo5LFE.js} +2 -2
  182. package/dist/{send-D0dzPf6g.js → send-TQWniAsM.js} +2 -2
  183. package/dist/{send-D16XtYvC.js → send-bTMPppyJ.js} +4 -4
  184. package/dist/{send-D3M6pMr5.js → send-yBb6c4og.js} +5 -5
  185. package/dist/{server-methods-Df9KsV_-.js → server-methods-B_y_To6u.js} +13 -13
  186. package/dist/{server-methods-B_NSJmhc.js → server-methods-DIMQMEoV.js} +14 -14
  187. package/dist/{server-node-events-ZG0SBDkU.js → server-node-events-Cl8uQahY.js} +30 -30
  188. package/dist/{server-node-events-C2mugatX.js → server-node-events-xk6gk1TZ.js} +10 -10
  189. package/dist/{session-T0JXlYWe.js → session-_ViRAnAz.js} +1 -1
  190. package/dist/{session-utils-Cdv2Qaq2.js → session-utils-kkbiQhvc.js} +1 -1
  191. package/dist/{sessions-BEyCtqBB.js → sessions-8_kZyON5.js} +271 -3
  192. package/dist/{sessions-DJAxaVI7.js → sessions-BYcI2Zrm.js} +270 -2
  193. package/dist/{sessions-CX93jXmG.js → sessions-C-C7dQBK.js} +2 -2
  194. package/dist/{skill-commands-DWcJOIzP.js → skill-commands-Bc-ztbDr.js} +1 -1
  195. package/dist/{skill-commands-B64uavY9.js → skill-commands-D_bBwwvA.js} +1 -1
  196. package/dist/{skills-install-D67isO1L.js → skills-install-CKFZBTH2.js} +1 -1
  197. package/dist/{status-BTF6_aBO.js → status-B2lMU2Pm.js} +1 -1
  198. package/dist/{status-BytVj4kU.js → status-Bz1iwxQ8.js} +1 -1
  199. package/dist/{status-PADx9rG7.js → status-D0xPNlv4.js} +5 -5
  200. package/dist/{status-hgm5EhwS.js → status-Dy0ocYJ8.js} +7 -7
  201. package/dist/{status.update-DlaskfTr.js → status.update-D40obmG1.js} +1 -1
  202. package/dist/{store-C0wvOkae.js → store-Bb4oiLME.js} +1 -1
  203. package/dist/{store-bnzGvI16.js → store-C4ZvS7QX.js} +1 -1
  204. package/dist/{subagent-registry-BR2Qhqjf.js → subagent-registry-7kBxT_d_.js} +17 -138
  205. package/dist/{tables-BEzT0Da4.js → tables-CjPLB3aX.js} +1 -1
  206. package/dist/{tables-DuZspiBu.js → tables-XnT3BCYh.js} +1 -1
  207. package/dist/{tables-COnZ169v.js → tables-dfFTl4Oa.js} +1 -1
  208. package/dist/{target-errors-7AvoVa10.js → target-errors-B_xs1J06.js} +1 -1
  209. package/dist/{target-errors-BbOqxMY0.js → target-errors-CL9BfceM.js} +2 -2
  210. package/dist/{target-errors-Be1SwYlW.js → target-errors-LR7w6--g.js} +2 -2
  211. package/dist/{thinking-CdlENGRW.js → thinking-EjJEKdLq.js} +1 -1
  212. package/dist/{thinking-W85Rb32m.js → thinking-XA7vussX.js} +1 -1
  213. package/dist/{tool-images-ChC2CXaN.js → tool-images-BHM4TeU5.js} +1 -1
  214. package/dist/{tool-images-DXB7tqWi.js → tool-images-BwAkbbBM.js} +1 -1
  215. package/dist/{tui-0rURH3b3.js → tui-Bmq33rYO.js} +2 -2
  216. package/dist/{tui-CcirlGg5.js → tui-DSGlMzTS.js} +3 -3
  217. package/dist/{tui-cli-hcbzeOtp.js → tui-cli-8Ln6C319.js} +5 -4
  218. package/dist/{tui-cli-D3VMk5c8.js → tui-cli-yL_gg_7w.js} +7 -6
  219. package/dist/{update-check-CtckACbb.js → update-check-DK1kMuwI.js} +1 -1
  220. package/dist/{update-cli-qacplfF4.js → update-cli-B4FtAyNd.js} +38 -38
  221. package/dist/{update-cli-CHr8rjf-.js → update-cli-D0Jlnkzy.js} +17 -17
  222. package/dist/{update-runner-DNA7FJa2.js → update-runner-CDnlfyP5.js} +1 -1
  223. package/dist/{update-runner-DM8zQvQB.js → update-runner-Ci3cNYff.js} +2 -2
  224. package/dist/{web-DkQc82PT.js → web-10GxXUo7.js} +9 -9
  225. package/dist/{web-0bP0TLM2.js → web-ENDSDPaD.js} +37 -37
  226. package/dist/{web-G0LUda_q.js → web-cJUlI_Wb.js} +30 -30
  227. package/dist/{web-UroM-w6c.js → web-gNZ16539.js} +31 -31
  228. package/dist/{whatsapp-actions-Jfx4zcwv.js → whatsapp-actions-BcsFR5tf.js} +7 -7
  229. package/dist/{whatsapp-actions-BIjGyW3T.js → whatsapp-actions-CUczC854.js} +9 -9
  230. package/dist/{whatsapp-actions-BL7tCNC_.js → whatsapp-actions-ia2odzch.js} +12 -12
  231. package/package.json +1 -1
  232. /package/dist/{accounts-8zZqL37v.js → accounts-9VRq1rY7.js} +0 -0
  233. /package/dist/{accounts-CWktKM8a.js → accounts-BCS-nbgN.js} +0 -0
  234. /package/dist/{api-key-rotation-BukD0zzl.js → api-key-rotation-erqZ9Tuc.js} +0 -0
  235. /package/dist/{diagnostic-session-state-Bxo4UHOL.js → diagnostic-session-state-Bu3E4Enn.js} +0 -0
  236. /package/dist/{diagnostic-session-state-C1vRJs5w.js → diagnostic-session-state-DmrztgHU.js} +0 -0
  237. /package/dist/{fetch-timeout-Db3da8yR.js → fetch-timeout-DoySHqfO.js} +0 -0
  238. /package/dist/{github-copilot-token-C_qUP7p5.js → github-copilot-token-BqpAEW8G.js} +0 -0
  239. /package/dist/{image-ops-CvJzsyvE.js → image-ops-DD37OhdR.js} +0 -0
  240. /package/dist/{image-ops-ByaQt43P.js → image-ops-UtlmP67m.js} +0 -0
  241. /package/dist/{message-channel-BQINJQIT.js → message-channel-B3YUM8IG.js} +0 -0
  242. /package/dist/{message-channel-Dz5lr5b0.js → message-channel-Bj7aZphL.js} +0 -0
  243. /package/dist/{model-catalog-DjJ9GtKX.js → model-catalog-DhaH7him.js} +0 -0
  244. /package/dist/{pi-model-discovery-j5tVLINv.js → pi-model-discovery-C-yOXpma.js} +0 -0
  245. /package/dist/{sqlite-Dx3J_aSE.js → sqlite-DhNyBVPk.js} +0 -0
  246. /package/dist/{tokens-BuceUQDl.js → tokens-DBCvs-Ns.js} +0 -0
  247. /package/dist/{tool-display-D8N3rsYt.js → tool-display-pHB3J5PK.js} +0 -0
  248. /package/dist/{tool-images-DvUBlqjX.js → tool-images-CLRUTPlM.js} +0 -0
  249. /package/dist/{transcript-events-DdnTeoR1.js → transcript-events-CJRvASY_.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { y as resolveRequiredHomeDir } from "./paths-Cqn-zk3M.js";
2
- import { m as normalizeE164 } from "./utils-B-0b9bGM.js";
2
+ import { l as escapeRegExp, m as normalizeE164 } from "./utils-B-0b9bGM.js";
3
3
  import { c as normalizeMainKey, g as normalizeOptionalAccountId, r as buildAgentMainSessionKey, s as normalizeAgentId, t as DEFAULT_AGENT_ID } from "./session-key-DCt45XZa.js";
4
4
  import { t as createSubsystemLogger } from "./subsystem-D9vIQve0.js";
5
5
  import { Lt as resolveProcessScopedMap, Rt as isPidAlive } from "./model-selection-Csawd2_i.js";
@@ -12,7 +12,8 @@ import { r as normalizeChannelId } from "./plugins-DKDeQZF0.js";
12
12
  import { a as resolveSessionTranscriptPathInDir, c as resolveStorePath, i as resolveSessionTranscriptPath, n as resolveSessionFilePath, t as resolveDefaultSessionStorePath } from "./paths-CyhzMxFA.js";
13
13
  import { r as hasInterSessionUserProvenance } from "./input-provenance-BzbXHcaD.js";
14
14
  import { n as extractToolCallNames, r as hasToolCall } from "./transcript-tools-INJPQ2KD.js";
15
- import { t as emitSessionTranscriptUpdate } from "./transcript-events-DdnTeoR1.js";
15
+ import { r as SYMIPULSE_TOKEN } from "./tokens-DBCvs-Ns.js";
16
+ import { t as emitSessionTranscriptUpdate } from "./transcript-events-CJRvASY_.js";
16
17
  import fs from "node:fs";
17
18
  import os from "node:os";
18
19
  import path from "node:path";
@@ -603,6 +604,127 @@ function resolveSessionKey(scope, ctx, mainKey) {
603
604
  return `agent:${DEFAULT_AGENT_ID}:${raw}`;
604
605
  }
605
606
 
607
+ //#endregion
608
+ //#region src/auto-reply/heartbeat.ts
609
+ const HEARTBEAT_PROMPT = "Read SYMIPULSE.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply SYMIPULSE_OK.";
610
+ const DEFAULT_HEARTBEAT_EVERY = "30m";
611
+ const DEFAULT_HEARTBEAT_ACK_MAX_CHARS = 300;
612
+ /**
613
+ * Check if SYMIPULSE.md content is "effectively empty" - meaning it has no actionable tasks.
614
+ * This allows skipping heartbeat API calls when no tasks are configured.
615
+ *
616
+ * A file is considered effectively empty if it contains only:
617
+ * - Whitespace
618
+ * - Comment lines (lines starting with #)
619
+ * - Empty lines
620
+ *
621
+ * Note: A missing file returns false (not effectively empty) so the LLM can still
622
+ * decide what to do. This function is only for when the file exists but has no content.
623
+ */
624
+ function isHeartbeatContentEffectivelyEmpty(content) {
625
+ if (content === void 0 || content === null) return false;
626
+ if (typeof content !== "string") return false;
627
+ const lines = content.split("\n");
628
+ for (const line of lines) {
629
+ const trimmed = line.trim();
630
+ if (!trimmed) continue;
631
+ if (/^#+(\s|$)/.test(trimmed)) continue;
632
+ if (/^[-*+]\s*(\[[\sXx]?\]\s*)?$/.test(trimmed)) continue;
633
+ return false;
634
+ }
635
+ return true;
636
+ }
637
+ function resolveHeartbeatPrompt(raw) {
638
+ return (typeof raw === "string" ? raw.trim() : "") || HEARTBEAT_PROMPT;
639
+ }
640
+ function stripTokenAtEdges(raw) {
641
+ let text = raw.trim();
642
+ if (!text) return {
643
+ text: "",
644
+ didStrip: false
645
+ };
646
+ const token = SYMIPULSE_TOKEN;
647
+ const tokenAtEndWithOptionalTrailingPunctuation = new RegExp(`${escapeRegExp(token)}[^\\w]{0,4}$`);
648
+ if (!text.includes(token)) return {
649
+ text,
650
+ didStrip: false
651
+ };
652
+ let didStrip = false;
653
+ let changed = true;
654
+ while (changed) {
655
+ changed = false;
656
+ const next = text.trim();
657
+ if (next.startsWith(token)) {
658
+ text = next.slice(token.length).trimStart();
659
+ didStrip = true;
660
+ changed = true;
661
+ continue;
662
+ }
663
+ if (tokenAtEndWithOptionalTrailingPunctuation.test(next)) {
664
+ const idx = next.lastIndexOf(token);
665
+ const before = next.slice(0, idx).trimEnd();
666
+ if (!before) text = "";
667
+ else text = `${before}${next.slice(idx + token.length).trimStart()}`.trimEnd();
668
+ didStrip = true;
669
+ changed = true;
670
+ }
671
+ }
672
+ return {
673
+ text: text.replace(/\s+/g, " ").trim(),
674
+ didStrip
675
+ };
676
+ }
677
+ function stripHeartbeatToken(raw, opts = {}) {
678
+ if (!raw) return {
679
+ shouldSkip: true,
680
+ text: "",
681
+ didStrip: false
682
+ };
683
+ const trimmed = raw.trim();
684
+ if (!trimmed) return {
685
+ shouldSkip: true,
686
+ text: "",
687
+ didStrip: false
688
+ };
689
+ const mode = opts.mode ?? "message";
690
+ const maxAckCharsRaw = opts.maxAckChars;
691
+ const parsedAckChars = typeof maxAckCharsRaw === "string" ? Number(maxAckCharsRaw) : maxAckCharsRaw;
692
+ const maxAckChars = Math.max(0, typeof parsedAckChars === "number" && Number.isFinite(parsedAckChars) ? parsedAckChars : DEFAULT_HEARTBEAT_ACK_MAX_CHARS);
693
+ const stripMarkup = (text) => text.replace(/<[^>]*>/g, " ").replace(/&nbsp;/gi, " ").replace(/^[*`~_]+/, "").replace(/[*`~_]+$/, "");
694
+ const trimmedNormalized = stripMarkup(trimmed);
695
+ if (!(trimmed.includes(SYMIPULSE_TOKEN) || trimmedNormalized.includes(SYMIPULSE_TOKEN))) return {
696
+ shouldSkip: false,
697
+ text: trimmed,
698
+ didStrip: false
699
+ };
700
+ const strippedOriginal = stripTokenAtEdges(trimmed);
701
+ const strippedNormalized = stripTokenAtEdges(trimmedNormalized);
702
+ const picked = strippedOriginal.didStrip && strippedOriginal.text ? strippedOriginal : strippedNormalized;
703
+ if (!picked.didStrip) return {
704
+ shouldSkip: false,
705
+ text: trimmed,
706
+ didStrip: false
707
+ };
708
+ if (!picked.text) return {
709
+ shouldSkip: true,
710
+ text: "",
711
+ didStrip: true
712
+ };
713
+ const rest = picked.text.trim();
714
+ if (mode === "heartbeat") {
715
+ if (rest.length <= maxAckChars) return {
716
+ shouldSkip: true,
717
+ text: "",
718
+ didStrip: true
719
+ };
720
+ }
721
+ return {
722
+ shouldSkip: false,
723
+ text: rest,
724
+ didStrip: true
725
+ };
726
+ }
727
+
606
728
  //#endregion
607
729
  //#region src/auto-reply/reply/strip-inbound-meta.ts
608
730
  /**
@@ -790,6 +912,152 @@ function stripEnvelopeFromMessages(messages) {
790
912
  });
791
913
  return changed ? next : messages;
792
914
  }
915
+ /**
916
+ * Extract text from a message's content (string, array of content blocks, or .text field).
917
+ */
918
+ function extractMessageText(message) {
919
+ if (typeof message.content === "string") return message.content;
920
+ if (Array.isArray(message.content)) return message.content.filter((b) => b?.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
921
+ if (typeof message.text === "string") return message.text;
922
+ return "";
923
+ }
924
+ /**
925
+ * Detect whether a user message is a heartbeat prompt.
926
+ */
927
+ function isHeartbeatUserMessage(text) {
928
+ const trimmed = text.trim();
929
+ if (trimmed.startsWith("Read SYMIPULSE.md")) return true;
930
+ if (trimmed.includes(HEARTBEAT_PROMPT.slice(0, 40))) return true;
931
+ return false;
932
+ }
933
+ /**
934
+ * Detect whether an assistant message is heartbeat noise (SYMIPULSE_OK, heartbeat state JSON, etc.).
935
+ */
936
+ function isHeartbeatAssistantMessage(text) {
937
+ const trimmed = text.trim();
938
+ if (new RegExp(`^\\s*${SYMIPULSE_TOKEN}\\b`).test(trimmed)) return true;
939
+ return false;
940
+ }
941
+ const CURRENT_TIME_LINE_RE = /\nCurrent time:.*$/;
942
+ /**
943
+ * Strip "Current time:" lines appended to user messages by the heartbeat/cron system.
944
+ */
945
+ function stripCurrentTimeLine(text) {
946
+ return text.replace(CURRENT_TIME_LINE_RE, "");
947
+ }
948
+ const SESSION_META_RE = /^# Session:.*\n(?:- \*\*(?:Session Key|Session ID|Source)\*\*:.*\n)*/gm;
949
+ /**
950
+ * Strip session metadata blocks injected by the session-memory hook.
951
+ */
952
+ function stripSessionMetadata(text) {
953
+ return text.replace(SESSION_META_RE, "").replace(/^\n+/, "");
954
+ }
955
+ /**
956
+ * Apply text-level sanitization to a single content string for chat history display.
957
+ * Strips timestamps, session metadata, and other AI-facing noise.
958
+ */
959
+ function sanitizeUserTextForDisplay(text) {
960
+ let result = stripCurrentTimeLine(text);
961
+ result = stripSessionMetadata(result);
962
+ return result.trim();
963
+ }
964
+ /**
965
+ * Apply display sanitization to a message's content (works on string or content block arrays).
966
+ */
967
+ function sanitizeMessageTextForDisplay(message) {
968
+ if (!message || typeof message !== "object") return {
969
+ message,
970
+ changed: false
971
+ };
972
+ const entry = message;
973
+ if ((typeof entry.role === "string" ? entry.role.toLowerCase() : "") !== "user") return {
974
+ message,
975
+ changed: false
976
+ };
977
+ let changed = false;
978
+ const next = { ...entry };
979
+ if (typeof entry.content === "string") {
980
+ const sanitized = sanitizeUserTextForDisplay(entry.content);
981
+ if (sanitized !== entry.content) {
982
+ next.content = sanitized;
983
+ changed = true;
984
+ }
985
+ } else if (Array.isArray(entry.content)) {
986
+ const updated = entry.content.map((block) => {
987
+ if (block?.type !== "text" || typeof block.text !== "string") return block;
988
+ const sanitized = sanitizeUserTextForDisplay(block.text);
989
+ if (sanitized !== block.text) {
990
+ changed = true;
991
+ return {
992
+ ...block,
993
+ text: sanitized
994
+ };
995
+ }
996
+ return block;
997
+ });
998
+ if (changed) next.content = updated;
999
+ } else if (typeof entry.text === "string") {
1000
+ const sanitized = sanitizeUserTextForDisplay(entry.text);
1001
+ if (sanitized !== entry.text) {
1002
+ next.text = sanitized;
1003
+ changed = true;
1004
+ }
1005
+ }
1006
+ return {
1007
+ message: changed ? next : message,
1008
+ changed
1009
+ };
1010
+ }
1011
+ /**
1012
+ * Filter out heartbeat message chains and strip noise from chat history messages.
1013
+ *
1014
+ * This removes:
1015
+ * - Entire heartbeat run chains: heartbeat user prompt + all subsequent
1016
+ * assistant/toolResult messages until the next user message
1017
+ * - "Current time:" lines from user messages
1018
+ * - Session metadata blocks from user messages
1019
+ * - Standalone SYMIPULSE_OK assistant messages
1020
+ */
1021
+ function filterChatHistoryNoise(messages) {
1022
+ if (messages.length === 0) return messages;
1023
+ const result = [];
1024
+ let changed = false;
1025
+ let skippingHeartbeatChain = false;
1026
+ for (let i = 0; i < messages.length; i++) {
1027
+ const msg = messages[i];
1028
+ if (!msg || typeof msg !== "object") {
1029
+ result.push(msg);
1030
+ continue;
1031
+ }
1032
+ const role = typeof msg.role === "string" ? msg.role.toLowerCase() : "";
1033
+ const text = extractMessageText(msg);
1034
+ if (role === "user") {
1035
+ skippingHeartbeatChain = false;
1036
+ if (isHeartbeatUserMessage(text)) {
1037
+ changed = true;
1038
+ skippingHeartbeatChain = true;
1039
+ continue;
1040
+ }
1041
+ const sanitized = sanitizeMessageTextForDisplay(msg);
1042
+ if (sanitized.changed) {
1043
+ changed = true;
1044
+ if (!extractMessageText(sanitized.message).trim()) continue;
1045
+ }
1046
+ result.push(sanitized.message);
1047
+ continue;
1048
+ }
1049
+ if (skippingHeartbeatChain) {
1050
+ changed = true;
1051
+ continue;
1052
+ }
1053
+ if (role === "assistant" && isHeartbeatAssistantMessage(text)) {
1054
+ changed = true;
1055
+ continue;
1056
+ }
1057
+ result.push(msg);
1058
+ }
1059
+ return changed ? result : messages;
1060
+ }
793
1061
 
794
1062
  //#endregion
795
1063
  //#region src/gateway/session-utils.fs.ts
@@ -2043,4 +2311,4 @@ function extractDeliveryInfo(sessionKey) {
2043
2311
  }
2044
2312
 
2045
2313
  //#endregion
2046
- export { deriveSessionKey as A, resolveAgentMainSessionKey as B, capArrayByJsonBytes as C, resolveSessionTranscriptCandidates as D, readSessionTitleFieldsFromTranscript as E, resolveSessionResetType as F, snapshotSessionOrigin as G, resolveMainSessionKey as H, resolveThreadFlag as I, acquireSessionWriteLock as J, buildGroupDisplayName as K, DEFAULT_RESET_TRIGGERS as L, evaluateSessionFreshness as M, resolveChannelResetConfig as N, stripEnvelopeFromMessages as O, resolveSessionResetPolicy as P, resolveFreshSessionTotalTokens as R, archiveSessionTranscripts as S, readSessionPreviewItemsFromTranscript as T, resolveMainSessionKeyFromConfig as U, resolveExplicitAgentSessionKey as V, deriveSessionMetaPatch as W, resolveSessionLockMaxHoldFromTimeout as X, cleanStaleLockFiles as Y, mergeDeliveryContext as _, resolveAndPersistSessionFile as a, normalizeAccountId as b, recordSessionMetaFromInbound as c, updateSessionStore as d, updateSessionStoreEntry as f, deliveryContextKey as g, deliveryContextFromSession as h, resolveMirroredTranscriptText as i, resolveSessionKey as j, stripLeadingInboundMetadata as k, saveSessionStore as l, resolveCacheTtlMs as m, parseSessionThreadInfo as n, loadSessionStore as o, isCacheEnabled as p, resolveGroupSessionKey as q, appendAssistantMessageToSessionTranscript as r, readSessionUpdatedAt as s, extractDeliveryInfo as t, updateLastRoute as u, normalizeDeliveryContext as v, readSessionMessages as w, archiveFileOnDisk as x, normalizeSessionDeliveryFields as y, canonicalizeMainSessionAlias as z };
2314
+ export { resolveGroupSessionKey as $, stripLeadingInboundMetadata as A, resolveSessionResetPolicy as B, capArrayByJsonBytes as C, resolveSessionTranscriptCandidates as D, readSessionTitleFieldsFromTranscript as E, stripHeartbeatToken as F, canonicalizeMainSessionAlias as G, resolveThreadFlag as H, deriveSessionKey as I, resolveMainSessionKey as J, resolveAgentMainSessionKey as K, resolveSessionKey as L, DEFAULT_HEARTBEAT_EVERY as M, isHeartbeatContentEffectivelyEmpty as N, filterChatHistoryNoise as O, resolveHeartbeatPrompt as P, buildGroupDisplayName as Q, evaluateSessionFreshness as R, archiveSessionTranscripts as S, readSessionPreviewItemsFromTranscript as T, DEFAULT_RESET_TRIGGERS as U, resolveSessionResetType as V, resolveFreshSessionTotalTokens as W, deriveSessionMetaPatch as X, resolveMainSessionKeyFromConfig as Y, snapshotSessionOrigin as Z, mergeDeliveryContext as _, resolveAndPersistSessionFile as a, normalizeAccountId as b, recordSessionMetaFromInbound as c, updateSessionStore as d, acquireSessionWriteLock as et, updateSessionStoreEntry as f, deliveryContextKey as g, deliveryContextFromSession as h, resolveMirroredTranscriptText as i, DEFAULT_HEARTBEAT_ACK_MAX_CHARS as j, stripEnvelopeFromMessages as k, saveSessionStore as l, resolveCacheTtlMs as m, parseSessionThreadInfo as n, resolveSessionLockMaxHoldFromTimeout as nt, loadSessionStore as o, isCacheEnabled as p, resolveExplicitAgentSessionKey as q, appendAssistantMessageToSessionTranscript as r, readSessionUpdatedAt as s, extractDeliveryInfo as t, cleanStaleLockFiles as tt, updateLastRoute as u, normalizeDeliveryContext as v, readSessionMessages as w, archiveFileOnDisk as x, normalizeSessionDeliveryFields as y, resolveChannelResetConfig as z };
@@ -1,9 +1,10 @@
1
- import { o as createSubsystemLogger, pn as resolveRequiredHomeDir, tt as normalizeE164 } from "./entry.js";
1
+ import { X as escapeRegExp, o as createSubsystemLogger, pn as resolveRequiredHomeDir, tt as normalizeE164 } from "./entry.js";
2
2
  import { D as resolveProcessScopedMap, O as isPidAlive } from "./auth-profiles-BD22fK4p.js";
3
3
  import { c as normalizeMainKey, g as normalizeOptionalAccountId, r as buildAgentMainSessionKey, s as normalizeAgentId, t as DEFAULT_AGENT_ID } from "./session-key-DjZ7Z1hW.js";
4
4
  import { C as parseDurationMs, f as parseByteSize, i as loadConfig } from "./config-amjzHiWZ.js";
5
5
  import { c as listDeliverableMessageChannels, l as normalizeMessageChannel } from "./message-channel-C9dERklz.js";
6
6
  import { r as hasInterSessionUserProvenance } from "./input-provenance-D0lNkCf6.js";
7
+ import { r as SYMIPULSE_TOKEN } from "./tokens-Csntmwwn.js";
7
8
  import { r as normalizeChannelId } from "./plugins-CwSlLxM8.js";
8
9
  import { t as normalizeChatType } from "./chat-type-CeFzWU-6.js";
9
10
  import { c as normalizeHyphenSlug, t as getChannelDock } from "./dock-DKxQXuAg.js";
@@ -99,6 +100,127 @@ function deliveryContextKey(context) {
99
100
  return `${normalized.channel}|${normalized.to}|${normalized.accountId ?? ""}|${threadId}`;
100
101
  }
101
102
 
103
+ //#endregion
104
+ //#region src/auto-reply/heartbeat.ts
105
+ const HEARTBEAT_PROMPT = "Read SYMIPULSE.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply SYMIPULSE_OK.";
106
+ const DEFAULT_HEARTBEAT_EVERY = "30m";
107
+ const DEFAULT_HEARTBEAT_ACK_MAX_CHARS = 300;
108
+ /**
109
+ * Check if SYMIPULSE.md content is "effectively empty" - meaning it has no actionable tasks.
110
+ * This allows skipping heartbeat API calls when no tasks are configured.
111
+ *
112
+ * A file is considered effectively empty if it contains only:
113
+ * - Whitespace
114
+ * - Comment lines (lines starting with #)
115
+ * - Empty lines
116
+ *
117
+ * Note: A missing file returns false (not effectively empty) so the LLM can still
118
+ * decide what to do. This function is only for when the file exists but has no content.
119
+ */
120
+ function isHeartbeatContentEffectivelyEmpty(content) {
121
+ if (content === void 0 || content === null) return false;
122
+ if (typeof content !== "string") return false;
123
+ const lines = content.split("\n");
124
+ for (const line of lines) {
125
+ const trimmed = line.trim();
126
+ if (!trimmed) continue;
127
+ if (/^#+(\s|$)/.test(trimmed)) continue;
128
+ if (/^[-*+]\s*(\[[\sXx]?\]\s*)?$/.test(trimmed)) continue;
129
+ return false;
130
+ }
131
+ return true;
132
+ }
133
+ function resolveHeartbeatPrompt(raw) {
134
+ return (typeof raw === "string" ? raw.trim() : "") || HEARTBEAT_PROMPT;
135
+ }
136
+ function stripTokenAtEdges(raw) {
137
+ let text = raw.trim();
138
+ if (!text) return {
139
+ text: "",
140
+ didStrip: false
141
+ };
142
+ const token = SYMIPULSE_TOKEN;
143
+ const tokenAtEndWithOptionalTrailingPunctuation = new RegExp(`${escapeRegExp(token)}[^\\w]{0,4}$`);
144
+ if (!text.includes(token)) return {
145
+ text,
146
+ didStrip: false
147
+ };
148
+ let didStrip = false;
149
+ let changed = true;
150
+ while (changed) {
151
+ changed = false;
152
+ const next = text.trim();
153
+ if (next.startsWith(token)) {
154
+ text = next.slice(token.length).trimStart();
155
+ didStrip = true;
156
+ changed = true;
157
+ continue;
158
+ }
159
+ if (tokenAtEndWithOptionalTrailingPunctuation.test(next)) {
160
+ const idx = next.lastIndexOf(token);
161
+ const before = next.slice(0, idx).trimEnd();
162
+ if (!before) text = "";
163
+ else text = `${before}${next.slice(idx + token.length).trimStart()}`.trimEnd();
164
+ didStrip = true;
165
+ changed = true;
166
+ }
167
+ }
168
+ return {
169
+ text: text.replace(/\s+/g, " ").trim(),
170
+ didStrip
171
+ };
172
+ }
173
+ function stripHeartbeatToken(raw, opts = {}) {
174
+ if (!raw) return {
175
+ shouldSkip: true,
176
+ text: "",
177
+ didStrip: false
178
+ };
179
+ const trimmed = raw.trim();
180
+ if (!trimmed) return {
181
+ shouldSkip: true,
182
+ text: "",
183
+ didStrip: false
184
+ };
185
+ const mode = opts.mode ?? "message";
186
+ const maxAckCharsRaw = opts.maxAckChars;
187
+ const parsedAckChars = typeof maxAckCharsRaw === "string" ? Number(maxAckCharsRaw) : maxAckCharsRaw;
188
+ const maxAckChars = Math.max(0, typeof parsedAckChars === "number" && Number.isFinite(parsedAckChars) ? parsedAckChars : DEFAULT_HEARTBEAT_ACK_MAX_CHARS);
189
+ const stripMarkup = (text) => text.replace(/<[^>]*>/g, " ").replace(/&nbsp;/gi, " ").replace(/^[*`~_]+/, "").replace(/[*`~_]+$/, "");
190
+ const trimmedNormalized = stripMarkup(trimmed);
191
+ if (!(trimmed.includes(SYMIPULSE_TOKEN) || trimmedNormalized.includes(SYMIPULSE_TOKEN))) return {
192
+ shouldSkip: false,
193
+ text: trimmed,
194
+ didStrip: false
195
+ };
196
+ const strippedOriginal = stripTokenAtEdges(trimmed);
197
+ const strippedNormalized = stripTokenAtEdges(trimmedNormalized);
198
+ const picked = strippedOriginal.didStrip && strippedOriginal.text ? strippedOriginal : strippedNormalized;
199
+ if (!picked.didStrip) return {
200
+ shouldSkip: false,
201
+ text: trimmed,
202
+ didStrip: false
203
+ };
204
+ if (!picked.text) return {
205
+ shouldSkip: true,
206
+ text: "",
207
+ didStrip: true
208
+ };
209
+ const rest = picked.text.trim();
210
+ if (mode === "heartbeat") {
211
+ if (rest.length <= maxAckChars) return {
212
+ shouldSkip: true,
213
+ text: "",
214
+ didStrip: true
215
+ };
216
+ }
217
+ return {
218
+ shouldSkip: false,
219
+ text: rest,
220
+ didStrip: true
221
+ };
222
+ }
223
+
102
224
  //#endregion
103
225
  //#region src/agents/session-write-lock.ts
104
226
  const CLEANUP_SIGNALS = [
@@ -870,6 +992,152 @@ function stripEnvelopeFromMessages(messages) {
870
992
  });
871
993
  return changed ? next : messages;
872
994
  }
995
+ /**
996
+ * Extract text from a message's content (string, array of content blocks, or .text field).
997
+ */
998
+ function extractMessageText(message) {
999
+ if (typeof message.content === "string") return message.content;
1000
+ if (Array.isArray(message.content)) return message.content.filter((b) => b?.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
1001
+ if (typeof message.text === "string") return message.text;
1002
+ return "";
1003
+ }
1004
+ /**
1005
+ * Detect whether a user message is a heartbeat prompt.
1006
+ */
1007
+ function isHeartbeatUserMessage(text) {
1008
+ const trimmed = text.trim();
1009
+ if (trimmed.startsWith("Read SYMIPULSE.md")) return true;
1010
+ if (trimmed.includes(HEARTBEAT_PROMPT.slice(0, 40))) return true;
1011
+ return false;
1012
+ }
1013
+ /**
1014
+ * Detect whether an assistant message is heartbeat noise (SYMIPULSE_OK, heartbeat state JSON, etc.).
1015
+ */
1016
+ function isHeartbeatAssistantMessage(text) {
1017
+ const trimmed = text.trim();
1018
+ if (new RegExp(`^\\s*${SYMIPULSE_TOKEN}\\b`).test(trimmed)) return true;
1019
+ return false;
1020
+ }
1021
+ const CURRENT_TIME_LINE_RE = /\nCurrent time:.*$/;
1022
+ /**
1023
+ * Strip "Current time:" lines appended to user messages by the heartbeat/cron system.
1024
+ */
1025
+ function stripCurrentTimeLine(text) {
1026
+ return text.replace(CURRENT_TIME_LINE_RE, "");
1027
+ }
1028
+ const SESSION_META_RE = /^# Session:.*\n(?:- \*\*(?:Session Key|Session ID|Source)\*\*:.*\n)*/gm;
1029
+ /**
1030
+ * Strip session metadata blocks injected by the session-memory hook.
1031
+ */
1032
+ function stripSessionMetadata(text) {
1033
+ return text.replace(SESSION_META_RE, "").replace(/^\n+/, "");
1034
+ }
1035
+ /**
1036
+ * Apply text-level sanitization to a single content string for chat history display.
1037
+ * Strips timestamps, session metadata, and other AI-facing noise.
1038
+ */
1039
+ function sanitizeUserTextForDisplay(text) {
1040
+ let result = stripCurrentTimeLine(text);
1041
+ result = stripSessionMetadata(result);
1042
+ return result.trim();
1043
+ }
1044
+ /**
1045
+ * Apply display sanitization to a message's content (works on string or content block arrays).
1046
+ */
1047
+ function sanitizeMessageTextForDisplay(message) {
1048
+ if (!message || typeof message !== "object") return {
1049
+ message,
1050
+ changed: false
1051
+ };
1052
+ const entry = message;
1053
+ if ((typeof entry.role === "string" ? entry.role.toLowerCase() : "") !== "user") return {
1054
+ message,
1055
+ changed: false
1056
+ };
1057
+ let changed = false;
1058
+ const next = { ...entry };
1059
+ if (typeof entry.content === "string") {
1060
+ const sanitized = sanitizeUserTextForDisplay(entry.content);
1061
+ if (sanitized !== entry.content) {
1062
+ next.content = sanitized;
1063
+ changed = true;
1064
+ }
1065
+ } else if (Array.isArray(entry.content)) {
1066
+ const updated = entry.content.map((block) => {
1067
+ if (block?.type !== "text" || typeof block.text !== "string") return block;
1068
+ const sanitized = sanitizeUserTextForDisplay(block.text);
1069
+ if (sanitized !== block.text) {
1070
+ changed = true;
1071
+ return {
1072
+ ...block,
1073
+ text: sanitized
1074
+ };
1075
+ }
1076
+ return block;
1077
+ });
1078
+ if (changed) next.content = updated;
1079
+ } else if (typeof entry.text === "string") {
1080
+ const sanitized = sanitizeUserTextForDisplay(entry.text);
1081
+ if (sanitized !== entry.text) {
1082
+ next.text = sanitized;
1083
+ changed = true;
1084
+ }
1085
+ }
1086
+ return {
1087
+ message: changed ? next : message,
1088
+ changed
1089
+ };
1090
+ }
1091
+ /**
1092
+ * Filter out heartbeat message chains and strip noise from chat history messages.
1093
+ *
1094
+ * This removes:
1095
+ * - Entire heartbeat run chains: heartbeat user prompt + all subsequent
1096
+ * assistant/toolResult messages until the next user message
1097
+ * - "Current time:" lines from user messages
1098
+ * - Session metadata blocks from user messages
1099
+ * - Standalone SYMIPULSE_OK assistant messages
1100
+ */
1101
+ function filterChatHistoryNoise(messages) {
1102
+ if (messages.length === 0) return messages;
1103
+ const result = [];
1104
+ let changed = false;
1105
+ let skippingHeartbeatChain = false;
1106
+ for (let i = 0; i < messages.length; i++) {
1107
+ const msg = messages[i];
1108
+ if (!msg || typeof msg !== "object") {
1109
+ result.push(msg);
1110
+ continue;
1111
+ }
1112
+ const role = typeof msg.role === "string" ? msg.role.toLowerCase() : "";
1113
+ const text = extractMessageText(msg);
1114
+ if (role === "user") {
1115
+ skippingHeartbeatChain = false;
1116
+ if (isHeartbeatUserMessage(text)) {
1117
+ changed = true;
1118
+ skippingHeartbeatChain = true;
1119
+ continue;
1120
+ }
1121
+ const sanitized = sanitizeMessageTextForDisplay(msg);
1122
+ if (sanitized.changed) {
1123
+ changed = true;
1124
+ if (!extractMessageText(sanitized.message).trim()) continue;
1125
+ }
1126
+ result.push(sanitized.message);
1127
+ continue;
1128
+ }
1129
+ if (skippingHeartbeatChain) {
1130
+ changed = true;
1131
+ continue;
1132
+ }
1133
+ if (role === "assistant" && isHeartbeatAssistantMessage(text)) {
1134
+ changed = true;
1135
+ continue;
1136
+ }
1137
+ result.push(msg);
1138
+ }
1139
+ return changed ? result : messages;
1140
+ }
873
1141
 
874
1142
  //#endregion
875
1143
  //#region src/gateway/session-utils.fs.ts
@@ -2041,4 +2309,4 @@ function extractDeliveryInfo(sessionKey) {
2041
2309
  }
2042
2310
 
2043
2311
  //#endregion
2044
- export { DEFAULT_RESET_TRIGGERS as A, resolveGroupSessionKey as B, stripLeadingInboundMetadata as C, resolveSessionResetPolicy as D, resolveChannelResetConfig as E, resolveMainSessionKey as F, deliveryContextKey as G, cleanStaleLockFiles as H, resolveMainSessionKeyFromConfig as I, normalizeSessionDeliveryFields as J, mergeDeliveryContext as K, deriveSessionMetaPatch as L, canonicalizeMainSessionAlias as M, resolveAgentMainSessionKey as N, resolveSessionResetType as O, resolveExplicitAgentSessionKey as P, snapshotSessionOrigin as R, stripEnvelopeFromMessages as S, evaluateSessionFreshness as T, resolveSessionLockMaxHoldFromTimeout as U, acquireSessionWriteLock as V, deliveryContextFromSession as W, normalizeAccountId as Y, capArrayByJsonBytes as _, resolveAndPersistSessionFile as a, readSessionTitleFieldsFromTranscript as b, recordSessionMetaFromInbound as c, updateSessionStore as d, updateSessionStoreEntry as f, archiveSessionTranscripts as g, archiveFileOnDisk as h, resolveMirroredTranscriptText as i, resolveFreshSessionTotalTokens as j, resolveThreadFlag as k, saveSessionStore as l, resolveCacheTtlMs as m, parseSessionThreadInfo as n, loadSessionStore as o, isCacheEnabled as p, normalizeDeliveryContext as q, appendAssistantMessageToSessionTranscript as r, readSessionUpdatedAt as s, extractDeliveryInfo as t, updateLastRoute as u, readSessionMessages as v, resolveSessionKey as w, resolveSessionTranscriptCandidates as x, readSessionPreviewItemsFromTranscript as y, buildGroupDisplayName as z };
2312
+ export { normalizeDeliveryContext as $, resolveThreadFlag as A, buildGroupDisplayName as B, stripEnvelopeFromMessages as C, resolveChannelResetConfig as D, evaluateSessionFreshness as E, resolveExplicitAgentSessionKey as F, DEFAULT_HEARTBEAT_ACK_MAX_CHARS as G, acquireSessionWriteLock as H, resolveMainSessionKey as I, resolveHeartbeatPrompt as J, DEFAULT_HEARTBEAT_EVERY as K, resolveMainSessionKeyFromConfig as L, resolveFreshSessionTotalTokens as M, canonicalizeMainSessionAlias as N, resolveSessionResetPolicy as O, resolveAgentMainSessionKey as P, mergeDeliveryContext as Q, deriveSessionMetaPatch as R, filterChatHistoryNoise as S, resolveSessionKey as T, cleanStaleLockFiles as U, resolveGroupSessionKey as V, resolveSessionLockMaxHoldFromTimeout as W, deliveryContextFromSession as X, stripHeartbeatToken as Y, deliveryContextKey as Z, capArrayByJsonBytes as _, resolveAndPersistSessionFile as a, readSessionTitleFieldsFromTranscript as b, recordSessionMetaFromInbound as c, updateSessionStore as d, normalizeSessionDeliveryFields as et, updateSessionStoreEntry as f, archiveSessionTranscripts as g, archiveFileOnDisk as h, resolveMirroredTranscriptText as i, DEFAULT_RESET_TRIGGERS as j, resolveSessionResetType as k, saveSessionStore as l, resolveCacheTtlMs as m, parseSessionThreadInfo as n, loadSessionStore as o, isCacheEnabled as p, isHeartbeatContentEffectivelyEmpty as q, appendAssistantMessageToSessionTranscript as r, readSessionUpdatedAt as s, extractDeliveryInfo as t, normalizeAccountId as tt, updateLastRoute as u, readSessionMessages as v, stripLeadingInboundMetadata as w, resolveSessionTranscriptCandidates as x, readSessionPreviewItemsFromTranscript as y, snapshotSessionOrigin as z };
@@ -3,10 +3,10 @@ import { Dt as theme, Et as isRich, gt as info } from "./entry.js";
3
3
  import { Ht as DEFAULT_MODEL, Ut as DEFAULT_PROVIDER, V as resolveConfiguredModelRef, Vt as DEFAULT_CONTEXT_TOKENS } from "./auth-profiles-BD22fK4p.js";
4
4
  import { S as parseAgentSessionKey } from "./session-key-DjZ7Z1hW.js";
5
5
  import { i as loadConfig } from "./config-amjzHiWZ.js";
6
- import { j as resolveFreshSessionTotalTokens, o as loadSessionStore } from "./sessions-DJAxaVI7.js";
6
+ import { M as resolveFreshSessionTotalTokens, o as loadSessionStore } from "./sessions-BYcI2Zrm.js";
7
7
  import { c as resolveStorePath } from "./paths-DNdWAq7b.js";
8
8
  import { n as formatTimeAgo } from "./format-relative-DX-rh76l.js";
9
- import { l as resolveSessionModelRef, n as classifySessionKey, u as lookupContextTokens } from "./session-utils-Cdv2Qaq2.js";
9
+ import { l as resolveSessionModelRef, n as classifySessionKey, u as lookupContextTokens } from "./session-utils-kkbiQhvc.js";
10
10
 
11
11
  //#region src/commands/sessions.ts
12
12
  var sessions_exports = /* @__PURE__ */ __exportAll({ sessionsCommand: () => sessionsCommand });
@@ -4,7 +4,7 @@ import { P as resolveUserPath, b as CONFIG_DIR } from "./registry-BhoUuugi.js";
4
4
  import { s as resolveAgentWorkspaceDir, t as listAgentIds } from "./agent-scope-Cbl5pNe1.js";
5
5
  import { t as createSubsystemLogger } from "./subsystem-CZixfwU8.js";
6
6
  import { o as resolvePluginSkillDirs, t as buildWorkspaceSkillCommandSpecs } from "./skills-BNpGMnp-.js";
7
- import { i as listChatCommands } from "./commands-registry-Copoizgv.js";
7
+ import { i as listChatCommands } from "./commands-registry-UwWpNkQg.js";
8
8
  import path from "node:path";
9
9
  import fs from "node:fs";
10
10
  import os from "node:os";
@@ -4,7 +4,7 @@ import { I as resolveUserPath, S as CONFIG_DIR } from "./registry-CK4e9hn8.js";
4
4
  import { s as resolveAgentWorkspaceDir, t as listAgentIds } from "./agent-scope-BxoUQqgM.js";
5
5
  import { t as createSubsystemLogger } from "./subsystem-Bs9YvKLa.js";
6
6
  import { o as resolvePluginSkillDirs, t as buildWorkspaceSkillCommandSpecs } from "./skills-BFekKL7i.js";
7
- import { i as listChatCommands } from "./commands-registry-C3C4Rv3O.js";
7
+ import { i as listChatCommands } from "./commands-registry-CZ5P8CpC.js";
8
8
  import fs from "node:fs/promises";
9
9
  import os from "node:os";
10
10
  import path from "node:path";
@@ -2,7 +2,7 @@ import { c as ensureDir, g as resolveConfigDir, y as resolveUserPath } from "./u
2
2
  import { t as runCommandWithTimeout } from "./exec-CWkblSrI.js";
3
3
  import { d as hasBinary } from "./frontmatter-DWQhtOo7.js";
4
4
  import { i as loadWorkspaceSkillEntries, t as resolveSkillsInstallPreferences, x as resolveSkillKey } from "./skills-6jdJQ5ZL.js";
5
- import { t as fetchWithSsrFGuard } from "./fetch-guard-DOPkVbh3.js";
5
+ import { t as fetchWithSsrFGuard } from "./fetch-guard-DPA1vbaF.js";
6
6
  import { t as resolveBrewExecutable } from "./brew-DjNEjKAo.js";
7
7
  import { t as isWithinDir } from "./path-safety-BqPJ8DDQ.js";
8
8
  import { a as extractArchive$1, d as resolveArchiveOutputPath, f as stripArchivePath, p as validateArchiveEntryPath, r as safePathSegmentHashed, u as isWindowsDrivePath } from "./install-safe-path-tCLiMpmO.js";
@@ -1,7 +1,7 @@
1
1
  import { o as createSubsystemLogger } from "./entry.js";
2
2
  import { D as resolveDefaultAgentWorkspaceDir, c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-D-jRCY0d.js";
3
3
  import { i as loadConfig } from "./config-amjzHiWZ.js";
4
- import { _ as loadSymiPlugins, g as createPluginLoaderLogger } from "./subagent-registry-BR2Qhqjf.js";
4
+ import { _ as loadSymiPlugins, g as createPluginLoaderLogger } from "./subagent-registry-7kBxT_d_.js";
5
5
 
6
6
  //#region src/plugins/status.ts
7
7
  const log = createSubsystemLogger("plugins");
@@ -1,4 +1,4 @@
1
- import { gt as loadSymiPlugins, ht as createPluginLoaderLogger } from "./reply-B9o45s3E.js";
1
+ import { gt as loadSymiPlugins, ht as createPluginLoaderLogger } from "./reply-b43dsTx2.js";
2
2
  import { t as createSubsystemLogger } from "./subsystem-D9vIQve0.js";
3
3
  import { D as resolveDefaultAgentWorkspaceDir, c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-CgUHAtCo.js";
4
4
  import { i as loadConfig } from "./config-Dgn_cL29.js";