winclaw 2026.3.21 → 2026.3.23

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 (201) hide show
  1. package/dist/{agents-_gcdm-kb.js → agents-Dc_S8rZ8.js} +4 -4
  2. package/dist/{agents.config-BkgsJJng.js → agents.config-BC6TW53i.js} +1 -1
  3. package/dist/{agents.config-Bw1hbsLj.js → agents.config-ZESYvAuZ.js} +1 -1
  4. package/dist/{auth-choice-sfRzFTug.js → auth-choice-CHCEiG_5.js} +1 -1
  5. package/dist/{auth-choice-i771W71t.js → auth-choice-CSZQYOpt.js} +1 -1
  6. package/dist/{banner-C-01b-if.js → banner-C3BSkrQk.js} +1 -1
  7. package/dist/build-info.json +2 -2
  8. package/dist/bundled/boot-md/handler.js +1 -1
  9. package/dist/bundled/session-memory/handler.js +1 -1
  10. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  11. package/dist/{channel-options-BAvRIwTX.js → channel-options-DG60shRM.js} +1 -1
  12. package/dist/{channel-options-it9Z3dNk.js → channel-options-XEKts1bm.js} +1 -1
  13. package/dist/{channel-web-BiIs0cCf.js → channel-web-XARrFQNi.js} +1 -1
  14. package/dist/{channel-web-CJ_jcZSw.js → channel-web-_2_SqIZ4.js} +1 -1
  15. package/dist/{channels-cli-CNbBNhlO.js → channels-cli-BEXYziVz.js} +6 -6
  16. package/dist/{channels-cli-miFqkj2-.js → channels-cli-ZssJjBmG.js} +6 -6
  17. package/dist/{cli-Da0pNyXg.js → cli-BZZG4J_j.js} +1 -1
  18. package/dist/{cli-BhZvhDWg.js → cli-CY_Senie.js} +1 -1
  19. package/dist/{command-registry-m8nfRV-J.js → command-registry-CWxe1f-O.js} +9 -9
  20. package/dist/{completion-cli-B-8mTxbh.js → completion-cli-BKoxA3-3.js} +2 -2
  21. package/dist/{completion-cli-c9ogb7DR.js → completion-cli-DisKMPGI.js} +1 -1
  22. package/dist/{config-cli-D2natFSq.js → config-cli-Bfwm9TCS.js} +1 -1
  23. package/dist/{config-cli-1ecjxVfC.js → config-cli-FMUUH4Ti.js} +1 -1
  24. package/dist/{configure-B-tOY-wa.js → configure-BJxly9Yt.js} +3 -3
  25. package/dist/{configure-BgqQPO5L.js → configure-DarTg7E_.js} +3 -3
  26. package/dist/{deps-send-whatsapp.runtime-BJV7VcRP.js → deps-send-whatsapp.runtime-CeFobiyN.js} +2 -2
  27. package/dist/{deps-send-whatsapp.runtime-DlmzDIzc.js → deps-send-whatsapp.runtime-D7OYrbTL.js} +2 -2
  28. package/dist/{deps-send-whatsapp.runtime-Dflrvnq-.js → deps-send-whatsapp.runtime-Dk3bVJzk.js} +3 -3
  29. package/dist/{deps-send-whatsapp.runtime-BHJLeHSL.js → deps-send-whatsapp.runtime-iiQJpw-8.js} +3 -3
  30. package/dist/{doctor-completion-DEdT-_9v.js → doctor-completion-BtQY4Eaa.js} +1 -1
  31. package/dist/{doctor-completion-C3SXIoSh.js → doctor-completion-t3rdrQev.js} +1 -1
  32. package/dist/entry.js +2 -2
  33. package/dist/extensionAPI.js +1 -1
  34. package/dist/{gateway-cli-C_4mlmOW.js → gateway-cli-BeABpkZ1.js} +11 -11
  35. package/dist/{gateway-cli-CL5LDNmu.js → gateway-cli-Juhp3APs.js} +11 -11
  36. package/dist/{health-C5a0wlfE.js → health-8quueFaP.js} +1 -1
  37. package/dist/{health-CqiwN5ZR.js → health-BoOzWD1m.js} +1 -1
  38. package/dist/{hooks-cli-C79J_WG7.js → hooks-cli-B475HcKz.js} +2 -2
  39. package/dist/{hooks-cli-DDWnA5Zx.js → hooks-cli-BcKW3j9V.js} +2 -2
  40. package/dist/index.js +6 -6
  41. package/dist/llm-slug-generator.js +1 -1
  42. package/dist/{models-Do96D4zT.js → models-FzoA9YFe.js} +2 -2
  43. package/dist/{models-cli-pblTciC_.js → models-cli-B9FoteUK.js} +3 -3
  44. package/dist/{models-cli-DOfsOmW1.js → models-cli-DPCSWjYD.js} +2 -2
  45. package/dist/{npm-resolution-Bd8dB7rI.js → npm-resolution-DUcSV3Er.js} +1 -1
  46. package/dist/{npm-resolution-DE7xcGkg.js → npm-resolution-Kay_MP5U.js} +1 -1
  47. package/dist/{onboard-CReGZ3G9.js → onboard-DSE0sFKG.js} +2 -2
  48. package/dist/{onboard-channels-DvpqJP6s.js → onboard-channels-DleZdwBe.js} +1 -1
  49. package/dist/{onboard-channels-ljMkIe7O.js → onboard-channels-DuQfbGvH.js} +1 -1
  50. package/dist/{onboard-CXyqQtlq.js → onboard-lgDkrSqS.js} +2 -2
  51. package/dist/{onboarding-BZWA8Nqq.js → onboarding-D713_nF-.js} +3 -3
  52. package/dist/{onboarding-CoH1hPY0.js → onboarding-tBrb0kFS.js} +3 -3
  53. package/dist/{onboarding.finalize-B1qRlV6H.js → onboarding.finalize-DenRnQtC.js} +5 -5
  54. package/dist/{onboarding.finalize-DzRWtkmA.js → onboarding.finalize-femvpEYf.js} +6 -6
  55. package/dist/{pi-embedded-DUO1eQ_J.js → pi-embedded-CPqoXbPh.js} +15 -15
  56. package/dist/{pi-embedded-xAf-RVi5.js → pi-embedded-yo67-7fx.js} +15 -15
  57. package/dist/{plugin-registry-DckyegZB.js → plugin-registry-ByrPvIy8.js} +1 -1
  58. package/dist/{plugin-registry-Cb_XRQUR.js → plugin-registry-C_HMboob.js} +1 -1
  59. package/dist/plugin-sdk/{channel-web-CfZNFYCV.js → channel-web-CZNn3YpA.js} +1 -1
  60. package/dist/plugin-sdk/{channel-web-D02gHjxz.js → channel-web-ut6coWO5.js} +1 -1
  61. package/dist/plugin-sdk/compat.js +50 -50
  62. package/dist/plugin-sdk/{deps-send-whatsapp.runtime-DJlWl-wv.js → deps-send-whatsapp.runtime-7Y4jFeSR.js} +3 -3
  63. package/dist/plugin-sdk/{deps-send-whatsapp.runtime-BxQ5tZO2.js → deps-send-whatsapp.runtime-BYqY0Q9J.js} +3 -3
  64. package/dist/plugin-sdk/imessage.js +2 -2
  65. package/dist/plugin-sdk/index.js +2 -2
  66. package/dist/plugin-sdk/{reply-BEBnUyG7.js → reply-CHTGOm7N.js} +15 -15
  67. package/dist/plugin-sdk/{reply-Cx_4UtvJ.js → reply-CbZPef0p.js} +15 -15
  68. package/dist/plugin-sdk/slack.js +2 -2
  69. package/dist/plugin-sdk/{slash-dispatch.runtime-C74v1zF9.js → slash-dispatch.runtime-CU94t3bC.js} +1 -1
  70. package/dist/plugin-sdk/{slash-dispatch.runtime-DN7TWAWh.js → slash-dispatch.runtime-fens4sxk.js} +1 -1
  71. package/dist/plugin-sdk/{subagent-registry-runtime-CprGCjIU.js → subagent-registry-runtime-CwlC6o7G.js} +1 -1
  72. package/dist/plugin-sdk/{subagent-registry-runtime-9CC9qb9s.js → subagent-registry-runtime-DE56KyD-.js} +1 -1
  73. package/dist/plugin-sdk/telegram.js +2 -2
  74. package/dist/plugin-sdk/{web-D9wJfMr_.js → web-DSbskSAb.js} +2 -2
  75. package/dist/plugin-sdk/{web-D0OZnnn7.js → web-Oo_Fd7RA.js} +2 -2
  76. package/dist/plugin-sdk/whatsapp.js +2 -2
  77. package/dist/plugin-sdk/zalouser.js +2 -2
  78. package/dist/{plugins-cli-BWCjQEMr.js → plugins-cli-CI8xpqVq.js} +2 -2
  79. package/dist/{plugins-cli-C6Oo9R6E.js → plugins-cli-DQCpV91t.js} +2 -2
  80. package/dist/{program-CEJ6CsoR.js → program-N2SbF1HK.js} +7 -7
  81. package/dist/{program-context-EXWtPjXg.js → program-context-DMg-_LjD.js} +17 -17
  82. package/dist/{prompt-select-styled-D-f3R2mt.js → prompt-select-styled-BehogMCm.js} +4 -4
  83. package/dist/{prompt-select-styled-B_AHrNLY.js → prompt-select-styled-pMhNy-Rt.js} +4 -4
  84. package/dist/{provider-auth-helpers-CN4iPBfs.js → provider-auth-helpers-4bL3VgNE.js} +1 -1
  85. package/dist/{provider-auth-helpers-CiXbjGH-.js → provider-auth-helpers-Rpp9Sh_y.js} +1 -1
  86. package/dist/{push-apns-D7Si-92v.js → push-apns-CGUAuXgJ.js} +1 -1
  87. package/dist/{push-apns-BEZdCQsM.js → push-apns-hyDzrrIU.js} +1 -1
  88. package/dist/{register.agent-BDosszM8.js → register.agent-CFrG4s6H.js} +6 -6
  89. package/dist/{register.agent-BjxrirHi.js → register.agent-CTNWQCtt.js} +7 -7
  90. package/dist/{register.configure-MduIRRMt.js → register.configure-DIKLgW8P.js} +7 -7
  91. package/dist/{register.configure-C0B9vKwT.js → register.configure-Di8Uh5GB.js} +7 -7
  92. package/dist/{register.maintenance-CfnzY1OX.js → register.maintenance-Cc675Yxz.js} +7 -7
  93. package/dist/{register.maintenance-BfdiJ7KX.js → register.maintenance-GewLmA3i.js} +8 -8
  94. package/dist/{register.message-D4VYaBqq.js → register.message-BI_R0TJs.js} +2 -2
  95. package/dist/{register.message-BszoJEBm.js → register.message-CtBJO09g.js} +2 -2
  96. package/dist/{register.onboard-CbJU4Y-3.js → register.onboard-45htf4DA.js} +2 -2
  97. package/dist/{register.onboard-CjuT9fKW.js → register.onboard-Jv--xCKB.js} +2 -2
  98. package/dist/{register.setup-DZzf7J04.js → register.setup-Bm99k2pm.js} +2 -2
  99. package/dist/{register.setup-BTTBsCT0.js → register.setup-CqrPLejH.js} +2 -2
  100. package/dist/{register.status-health-sessions-C3Ji8sqv.js → register.status-health-sessions-BBDVWYvb.js} +3 -3
  101. package/dist/{register.status-health-sessions-BKcFfUR6.js → register.status-health-sessions-BmpJln2_.js} +3 -3
  102. package/dist/{register.subclis-2iN-TxPh.js → register.subclis-4LlGcEld.js} +9 -9
  103. package/dist/{reply-KTubTl9h.js → reply-a2GVvnP2.js} +15 -15
  104. package/dist/{run-main-BEtPk_9z.js → run-main-B3eIQkhk.js} +14 -14
  105. package/dist/{server-node-events-BozhXo6J.js → server-node-events-Bn6C-kB6.js} +2 -2
  106. package/dist/{server-node-events-CFcRS-lD.js → server-node-events-CbUk95yd.js} +2 -2
  107. package/dist/{slash-dispatch.runtime-D5Cl7j1v.js → slash-dispatch.runtime-B4quYJn4.js} +1 -1
  108. package/dist/{slash-dispatch.runtime-B0OIPdp3.js → slash-dispatch.runtime-BBH2jQsL.js} +1 -1
  109. package/dist/{slash-dispatch.runtime-DDLolsGY.js → slash-dispatch.runtime-BLQZdvZW.js} +1 -1
  110. package/dist/{slash-dispatch.runtime-DtN2NmXJ.js → slash-dispatch.runtime-wBORF-o1.js} +1 -1
  111. package/dist/{status-B5hylgEQ.js → status-BqpyCRc4.js} +2 -2
  112. package/dist/{status-DClHhy30.js → status-DHIaRvxs.js} +2 -2
  113. package/dist/{subagent-registry-iD-ynHA9.js → subagent-registry-CRAr7csi.js} +15 -15
  114. package/dist/{subagent-registry-runtime-DfMDVaOY.js → subagent-registry-runtime-BfYm3d-n.js} +1 -1
  115. package/dist/{subagent-registry-runtime-CdEy9DKy.js → subagent-registry-runtime-CnPoAflv.js} +1 -1
  116. package/dist/{subagent-registry-runtime-Cv_Xt2cx.js → subagent-registry-runtime-DQb8qzq2.js} +1 -1
  117. package/dist/{subagent-registry-runtime-LH0OBaWN.js → subagent-registry-runtime-sMbEjW_q.js} +1 -1
  118. package/dist/{update-cli-C1nysDmM.js → update-cli-Bk3xkEPl.js} +8 -8
  119. package/dist/{update-cli-Dj_9Bokl.js → update-cli-G1w1hdg4.js} +7 -7
  120. package/dist/{update-runner-BpzbDTnQ.js → update-runner-CgS5D8t8.js} +1 -1
  121. package/dist/{update-runner-BUoHYjl8.js → update-runner-TyDM6-ms.js} +1 -1
  122. package/dist/{web-DxHq9RWt.js → web-7w_9CsnG.js} +2 -2
  123. package/dist/{web-Dbqs3hbC.js → web-B790MBdK.js} +1 -1
  124. package/dist/{web-CodV11ZY.js → web-BPiSo--I.js} +1 -1
  125. package/dist/{web-YBvuT4WS.js → web-BmYQFz4q.js} +2 -2
  126. package/package.json +1 -1
  127. package/dist/plugin-sdk/accounts-B71rIfIG.js +0 -35
  128. package/dist/plugin-sdk/accounts-Bh_CxVlh.js +0 -46
  129. package/dist/plugin-sdk/accounts-BoD7489q.js +0 -288
  130. package/dist/plugin-sdk/active-listener-6CPAmAh-.js +0 -50
  131. package/dist/plugin-sdk/api-key-rotation-DEDhmJAk.js +0 -181
  132. package/dist/plugin-sdk/audio-preflight-CMPZ9BXN.js +0 -69
  133. package/dist/plugin-sdk/audio-transcription-runner-CdADoJed.js +0 -2176
  134. package/dist/plugin-sdk/audit-membership-runtime-CxP2fdgS.js +0 -58
  135. package/dist/plugin-sdk/channel-activity-9ivqqvRB.js +0 -94
  136. package/dist/plugin-sdk/channel-web-CHDoy_Ex.js +0 -2256
  137. package/dist/plugin-sdk/chrome-B1yeIHRg.js +0 -2415
  138. package/dist/plugin-sdk/commands-registry-D-wyzYid.js +0 -1125
  139. package/dist/plugin-sdk/config-CmS6HzGU.js +0 -17959
  140. package/dist/plugin-sdk/deliver-Cy287pZ5.js +0 -1719
  141. package/dist/plugin-sdk/deliver-runtime-BH3fUFW1.js +0 -32
  142. package/dist/plugin-sdk/deps-send-discord.runtime-CLboFQJz.js +0 -23
  143. package/dist/plugin-sdk/deps-send-imessage.runtime-BVlGKP96.js +0 -22
  144. package/dist/plugin-sdk/deps-send-signal.runtime-0640YmBr.js +0 -21
  145. package/dist/plugin-sdk/deps-send-slack.runtime-BqbFKjcg.js +0 -19
  146. package/dist/plugin-sdk/deps-send-telegram.runtime-1a2RXcA2.js +0 -24
  147. package/dist/plugin-sdk/deps-send-whatsapp.runtime-CpOH0wYd.js +0 -57
  148. package/dist/plugin-sdk/diagnostic-DGt5TnqW.js +0 -319
  149. package/dist/plugin-sdk/errors-D7zDdduc.js +0 -54
  150. package/dist/plugin-sdk/fetch-guard-BsatETDz.js +0 -156
  151. package/dist/plugin-sdk/fs-safe-ynDN1AOr.js +0 -352
  152. package/dist/plugin-sdk/image-6No3eiOM.js +0 -2314
  153. package/dist/plugin-sdk/image-ops-CmFoHyKE.js +0 -584
  154. package/dist/plugin-sdk/image-runtime-D57a2W4s.js +0 -25
  155. package/dist/plugin-sdk/ir-CX1ZjDTn.js +0 -1296
  156. package/dist/plugin-sdk/local-roots-DnE8988Y.js +0 -186
  157. package/dist/plugin-sdk/logger-cN8CgKqt.js +0 -1163
  158. package/dist/plugin-sdk/login-hk6_2GSM.js +0 -57
  159. package/dist/plugin-sdk/login-qr-UaVS_Rce.js +0 -320
  160. package/dist/plugin-sdk/manager-CBP2ZQ5W.js +0 -3929
  161. package/dist/plugin-sdk/manager-runtime-3rKbDrJp.js +0 -15
  162. package/dist/plugin-sdk/outbound-B0Ab6CJM.js +0 -212
  163. package/dist/plugin-sdk/outbound-attachment-CktA053B.js +0 -19
  164. package/dist/plugin-sdk/path-alias-guards-WXu8eYZ3.js +0 -43
  165. package/dist/plugin-sdk/paths-Brta7ydd.js +0 -166
  166. package/dist/plugin-sdk/pi-embedded-helpers-BfbOXbe6.js +0 -9627
  167. package/dist/plugin-sdk/pi-model-discovery-ruarR-_j.js +0 -134
  168. package/dist/plugin-sdk/pi-model-discovery-runtime-26px0QfL.js +0 -8
  169. package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-VVLpfXqQ.js +0 -354
  170. package/dist/plugin-sdk/plugins-C995vsQz.js +0 -864
  171. package/dist/plugin-sdk/proxy-fetch-iSQrNgP-.js +0 -38
  172. package/dist/plugin-sdk/pw-ai-BJXHSS3q.js +0 -1938
  173. package/dist/plugin-sdk/qmd-manager-A7m15SeJ.js +0 -1448
  174. package/dist/plugin-sdk/query-expansion-DngcFbkC.js +0 -1011
  175. package/dist/plugin-sdk/redact-CIb5VTTO.js +0 -319
  176. package/dist/plugin-sdk/reply-vuWmM3Ra.js +0 -100211
  177. package/dist/plugin-sdk/resolve-outbound-target-CQ6hRY-h.js +0 -40
  178. package/dist/plugin-sdk/run-with-concurrency-BlfAoChN.js +0 -1994
  179. package/dist/plugin-sdk/runtime-whatsapp-login.runtime-YsrzSsFL.js +0 -10
  180. package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-DL6Ses5K.js +0 -19
  181. package/dist/plugin-sdk/send-BEy8EUzH.js +0 -414
  182. package/dist/plugin-sdk/send-CWP6COto.js +0 -3135
  183. package/dist/plugin-sdk/send-DQTgt3Cu.js +0 -540
  184. package/dist/plugin-sdk/send-DzpV-k17.js +0 -2587
  185. package/dist/plugin-sdk/send-HuIksBS6.js +0 -503
  186. package/dist/plugin-sdk/session-Cc3Y4mXL.js +0 -169
  187. package/dist/plugin-sdk/skill-commands-p8Zwjnwy.js +0 -353
  188. package/dist/plugin-sdk/skills-k8XpacZa.js +0 -1428
  189. package/dist/plugin-sdk/slash-commands.runtime-ynnr6oUR.js +0 -13
  190. package/dist/plugin-sdk/slash-dispatch.runtime-DOmMrwMj.js +0 -52
  191. package/dist/plugin-sdk/slash-skill-commands.runtime-eAk1jhVy.js +0 -16
  192. package/dist/plugin-sdk/ssrf-DZSsYJgJ.js +0 -202
  193. package/dist/plugin-sdk/store-Cn0oLCP4.js +0 -81
  194. package/dist/plugin-sdk/subagent-registry-runtime-CQ3m7TwQ.js +0 -52
  195. package/dist/plugin-sdk/tables-KWxXnbkq.js +0 -55
  196. package/dist/plugin-sdk/target-errors-Cr0q4o7K.js +0 -195
  197. package/dist/plugin-sdk/thinking-CfA6xbI_.js +0 -1206
  198. package/dist/plugin-sdk/tokens-B-D1YRTV.js +0 -52
  199. package/dist/plugin-sdk/tool-images-CVV7LNFW.js +0 -274
  200. package/dist/plugin-sdk/web-B1Svh1KM.js +0 -56
  201. package/dist/plugin-sdk/whatsapp-actions-CLNhBLJz.js +0 -80
@@ -1,10 +0,0 @@
1
- import "./run-with-concurrency-BlfAoChN.js";
2
- import "./accounts-BoD7489q.js";
3
- import "./paths-BEfQqXwE.js";
4
- import "./github-copilot-token-BCc3snHh.js";
5
- import "./config-CmS6HzGU.js";
6
- import "./logger-cN8CgKqt.js";
7
- import "./session-Cc3Y4mXL.js";
8
- import { t as loginWeb } from "./login-hk6_2GSM.js";
9
-
10
- export { loginWeb };
@@ -1,19 +0,0 @@
1
- import "./run-with-concurrency-BlfAoChN.js";
2
- import "./accounts-BoD7489q.js";
3
- import "./paths-BEfQqXwE.js";
4
- import "./github-copilot-token-BCc3snHh.js";
5
- import "./config-CmS6HzGU.js";
6
- import "./logger-cN8CgKqt.js";
7
- import "./image-ops-CmFoHyKE.js";
8
- import "./plugins-C995vsQz.js";
9
- import "./path-alias-guards-WXu8eYZ3.js";
10
- import "./fs-safe-ynDN1AOr.js";
11
- import "./ssrf-DZSsYJgJ.js";
12
- import "./fetch-guard-BsatETDz.js";
13
- import "./local-roots-DnE8988Y.js";
14
- import "./ir-CX1ZjDTn.js";
15
- import "./render-A563BsDG.js";
16
- import "./tables-KWxXnbkq.js";
17
- import { n as sendPollWhatsApp, t as sendMessageWhatsApp } from "./outbound-B0Ab6CJM.js";
18
-
19
- export { sendMessageWhatsApp, sendPollWhatsApp };
@@ -1,414 +0,0 @@
1
- import { n as loadConfig } from "./config-CmS6HzGU.js";
2
- import { L as logVerbose } from "./logger-cN8CgKqt.js";
3
- import { F as resolveSlackBotToken, M as resolveSlackAccount, m as parseSlackTarget } from "./plugins-C995vsQz.js";
4
- import { r as withTrustedEnvProxyGuardedFetchMode, t as fetchWithSsrFGuard } from "./fetch-guard-BsatETDz.js";
5
- import { c as chunkMarkdownTextWithMode, d as resolveChunkMode, f as resolveTextChunkLimit, i as resolveMarkdownTableMode, n as markdownToIR, t as chunkMarkdownIR, v as loadWebMedia } from "./ir-CX1ZjDTn.js";
6
- import { t as renderMarkdownWithMarkers } from "./render-A563BsDG.js";
7
- import { i as isSilentReplyText } from "./tokens-B-D1YRTV.js";
8
- import { WebClient } from "@slack/web-api";
9
-
10
- //#region src/slack/blocks-input.ts
11
- const SLACK_MAX_BLOCKS = 50;
12
- function parseBlocksJson(raw) {
13
- try {
14
- return JSON.parse(raw);
15
- } catch {
16
- throw new Error("blocks must be valid JSON");
17
- }
18
- }
19
- function assertBlocksArray(raw) {
20
- if (!Array.isArray(raw)) throw new Error("blocks must be an array");
21
- if (raw.length === 0) throw new Error("blocks must contain at least one block");
22
- if (raw.length > SLACK_MAX_BLOCKS) throw new Error(`blocks cannot exceed ${SLACK_MAX_BLOCKS} items`);
23
- for (const block of raw) {
24
- if (!block || typeof block !== "object" || Array.isArray(block)) throw new Error("each block must be an object");
25
- const type = block.type;
26
- if (typeof type !== "string" || type.trim().length === 0) throw new Error("each block must include a non-empty string type");
27
- }
28
- }
29
- function validateSlackBlocksArray(raw) {
30
- assertBlocksArray(raw);
31
- return raw;
32
- }
33
- function parseSlackBlocksInput(raw) {
34
- if (raw == null) return;
35
- return validateSlackBlocksArray(typeof raw === "string" ? parseBlocksJson(raw) : raw);
36
- }
37
-
38
- //#endregion
39
- //#region src/slack/client.ts
40
- const SLACK_DEFAULT_RETRY_OPTIONS = {
41
- retries: 2,
42
- factor: 2,
43
- minTimeout: 500,
44
- maxTimeout: 3e3,
45
- randomize: true
46
- };
47
- function resolveSlackWebClientOptions(options = {}) {
48
- return {
49
- ...options,
50
- retryConfig: options.retryConfig ?? SLACK_DEFAULT_RETRY_OPTIONS
51
- };
52
- }
53
- function createSlackWebClient(token, options = {}) {
54
- return new WebClient(token, resolveSlackWebClientOptions(options));
55
- }
56
-
57
- //#endregion
58
- //#region src/slack/blocks-fallback.ts
59
- function cleanCandidate(value) {
60
- if (typeof value !== "string") return;
61
- const normalized = value.replace(/\s+/g, " ").trim();
62
- return normalized.length > 0 ? normalized : void 0;
63
- }
64
- function readSectionText(block) {
65
- return cleanCandidate(block.text?.text);
66
- }
67
- function readHeaderText(block) {
68
- return cleanCandidate(block.text?.text);
69
- }
70
- function readImageText(block) {
71
- return cleanCandidate(block.alt_text) ?? cleanCandidate(block.title?.text);
72
- }
73
- function readVideoText(block) {
74
- return cleanCandidate(block.title?.text) ?? cleanCandidate(block.alt_text);
75
- }
76
- function readContextText(block) {
77
- if (!Array.isArray(block.elements)) return;
78
- const textParts = block.elements.map((element) => cleanCandidate(element.text)).filter((value) => Boolean(value));
79
- return textParts.length > 0 ? textParts.join(" ") : void 0;
80
- }
81
- function buildSlackBlocksFallbackText(blocks) {
82
- for (const raw of blocks) {
83
- const block = raw;
84
- switch (block.type) {
85
- case "header": {
86
- const text = readHeaderText(block);
87
- if (text) return text;
88
- break;
89
- }
90
- case "section": {
91
- const text = readSectionText(block);
92
- if (text) return text;
93
- break;
94
- }
95
- case "image": {
96
- const text = readImageText(block);
97
- if (text) return text;
98
- return "Shared an image";
99
- }
100
- case "video": {
101
- const text = readVideoText(block);
102
- if (text) return text;
103
- return "Shared a video";
104
- }
105
- case "file": return "Shared a file";
106
- case "context": {
107
- const text = readContextText(block);
108
- if (text) return text;
109
- break;
110
- }
111
- default: break;
112
- }
113
- }
114
- return "Shared a Block Kit message";
115
- }
116
-
117
- //#endregion
118
- //#region src/slack/format.ts
119
- function escapeSlackMrkdwnSegment(text) {
120
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
121
- }
122
- const SLACK_ANGLE_TOKEN_RE = /<[^>\n]+>/g;
123
- function isAllowedSlackAngleToken(token) {
124
- if (!token.startsWith("<") || !token.endsWith(">")) return false;
125
- const inner = token.slice(1, -1);
126
- return inner.startsWith("@") || inner.startsWith("#") || inner.startsWith("!") || inner.startsWith("mailto:") || inner.startsWith("tel:") || inner.startsWith("http://") || inner.startsWith("https://") || inner.startsWith("slack://");
127
- }
128
- function escapeSlackMrkdwnContent(text) {
129
- if (!text) return "";
130
- if (!text.includes("&") && !text.includes("<") && !text.includes(">")) return text;
131
- SLACK_ANGLE_TOKEN_RE.lastIndex = 0;
132
- const out = [];
133
- let lastIndex = 0;
134
- for (let match = SLACK_ANGLE_TOKEN_RE.exec(text); match; match = SLACK_ANGLE_TOKEN_RE.exec(text)) {
135
- const matchIndex = match.index ?? 0;
136
- out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex, matchIndex)));
137
- const token = match[0] ?? "";
138
- out.push(isAllowedSlackAngleToken(token) ? token : escapeSlackMrkdwnSegment(token));
139
- lastIndex = matchIndex + token.length;
140
- }
141
- out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex)));
142
- return out.join("");
143
- }
144
- function escapeSlackMrkdwnText(text) {
145
- if (!text) return "";
146
- if (!text.includes("&") && !text.includes("<") && !text.includes(">")) return text;
147
- return text.split("\n").map((line) => {
148
- if (line.startsWith("> ")) return `> ${escapeSlackMrkdwnContent(line.slice(2))}`;
149
- return escapeSlackMrkdwnContent(line);
150
- }).join("\n");
151
- }
152
- function buildSlackLink(link, text) {
153
- const href = link.href.trim();
154
- if (!href) return null;
155
- const trimmedLabel = text.slice(link.start, link.end).trim();
156
- const comparableHref = href.startsWith("mailto:") ? href.slice(7) : href;
157
- if (!(trimmedLabel.length > 0 && trimmedLabel !== href && trimmedLabel !== comparableHref)) return null;
158
- const safeHref = escapeSlackMrkdwnSegment(href);
159
- return {
160
- start: link.start,
161
- end: link.end,
162
- open: `<${safeHref}|`,
163
- close: ">"
164
- };
165
- }
166
- function buildSlackRenderOptions() {
167
- return {
168
- styleMarkers: {
169
- bold: {
170
- open: "*",
171
- close: "*"
172
- },
173
- italic: {
174
- open: "_",
175
- close: "_"
176
- },
177
- strikethrough: {
178
- open: "~",
179
- close: "~"
180
- },
181
- code: {
182
- open: "`",
183
- close: "`"
184
- },
185
- code_block: {
186
- open: "```\n",
187
- close: "```"
188
- }
189
- },
190
- escapeText: escapeSlackMrkdwnText,
191
- buildLink: buildSlackLink
192
- };
193
- }
194
- function markdownToSlackMrkdwn(markdown, options = {}) {
195
- return renderMarkdownWithMarkers(markdownToIR(markdown ?? "", {
196
- linkify: false,
197
- autolink: false,
198
- headingStyle: "bold",
199
- blockquotePrefix: "> ",
200
- tableMode: options.tableMode
201
- }), buildSlackRenderOptions());
202
- }
203
- function normalizeSlackOutboundText(markdown) {
204
- return markdownToSlackMrkdwn(markdown ?? "");
205
- }
206
- function markdownToSlackMrkdwnChunks(markdown, limit, options = {}) {
207
- const chunks = chunkMarkdownIR(markdownToIR(markdown ?? "", {
208
- linkify: false,
209
- autolink: false,
210
- headingStyle: "bold",
211
- blockquotePrefix: "> ",
212
- tableMode: options.tableMode
213
- }), limit);
214
- const renderOptions = buildSlackRenderOptions();
215
- return chunks.map((chunk) => renderMarkdownWithMarkers(chunk, renderOptions));
216
- }
217
-
218
- //#endregion
219
- //#region src/slack/send.ts
220
- const SLACK_TEXT_LIMIT = 4e3;
221
- const SLACK_UPLOAD_SSRF_POLICY = {
222
- allowedHostnames: [
223
- "*.slack.com",
224
- "*.slack-edge.com",
225
- "*.slack-files.com"
226
- ],
227
- allowRfc2544BenchmarkRange: true
228
- };
229
- function hasCustomIdentity(identity) {
230
- return Boolean(identity?.username || identity?.iconUrl || identity?.iconEmoji);
231
- }
232
- function isSlackCustomizeScopeError(err) {
233
- if (!(err instanceof Error)) return false;
234
- const maybeData = err;
235
- if (maybeData.data?.error?.toLowerCase() !== "missing_scope") return false;
236
- if ((maybeData.data?.needed?.toLowerCase())?.includes("chat:write.customize")) return true;
237
- return [...maybeData.data?.response_metadata?.scopes ?? [], ...maybeData.data?.response_metadata?.acceptedScopes ?? []].map((scope) => scope.toLowerCase()).includes("chat:write.customize");
238
- }
239
- async function postSlackMessageBestEffort(params) {
240
- const basePayload = {
241
- channel: params.channelId,
242
- text: params.text,
243
- thread_ts: params.threadTs,
244
- ...params.blocks?.length ? { blocks: params.blocks } : {}
245
- };
246
- try {
247
- if (params.identity?.iconUrl) return await params.client.chat.postMessage({
248
- ...basePayload,
249
- ...params.identity.username ? { username: params.identity.username } : {},
250
- icon_url: params.identity.iconUrl
251
- });
252
- if (params.identity?.iconEmoji) return await params.client.chat.postMessage({
253
- ...basePayload,
254
- ...params.identity.username ? { username: params.identity.username } : {},
255
- icon_emoji: params.identity.iconEmoji
256
- });
257
- return await params.client.chat.postMessage({
258
- ...basePayload,
259
- ...params.identity?.username ? { username: params.identity.username } : {}
260
- });
261
- } catch (err) {
262
- if (!hasCustomIdentity(params.identity) || !isSlackCustomizeScopeError(err)) throw err;
263
- logVerbose("slack send: missing chat:write.customize, retrying without custom identity");
264
- return params.client.chat.postMessage(basePayload);
265
- }
266
- }
267
- function resolveToken(params) {
268
- const explicit = resolveSlackBotToken(params.explicit);
269
- if (explicit) return explicit;
270
- const fallback = resolveSlackBotToken(params.fallbackToken);
271
- if (!fallback) {
272
- logVerbose(`slack send: missing bot token for account=${params.accountId} explicit=${Boolean(params.explicit)} source=${params.fallbackSource ?? "unknown"}`);
273
- throw new Error(`Slack bot token missing for account "${params.accountId}" (set channels.slack.accounts.${params.accountId}.botToken or SLACK_BOT_TOKEN for default).`);
274
- }
275
- return fallback;
276
- }
277
- function parseRecipient(raw) {
278
- const target = parseSlackTarget(raw);
279
- if (!target) throw new Error("Recipient is required for Slack sends");
280
- return {
281
- kind: target.kind,
282
- id: target.id
283
- };
284
- }
285
- async function resolveChannelId(client, recipient) {
286
- if (!(recipient.kind === "user" || /^U[A-Z0-9]+$/i.test(recipient.id))) return { channelId: recipient.id };
287
- const channelId = (await client.conversations.open({ users: recipient.id })).channel?.id;
288
- if (!channelId) throw new Error("Failed to open Slack DM channel");
289
- return {
290
- channelId,
291
- isDm: true
292
- };
293
- }
294
- async function uploadSlackFile(params) {
295
- const { buffer, contentType, fileName } = await loadWebMedia(params.mediaUrl, {
296
- maxBytes: params.maxBytes,
297
- localRoots: params.mediaLocalRoots
298
- });
299
- const uploadUrlResp = await params.client.files.getUploadURLExternal({
300
- filename: fileName ?? "upload",
301
- length: buffer.length
302
- });
303
- if (!uploadUrlResp.ok || !uploadUrlResp.upload_url || !uploadUrlResp.file_id) throw new Error(`Failed to get upload URL: ${uploadUrlResp.error ?? "unknown error"}`);
304
- const uploadBody = new Uint8Array(buffer);
305
- const { response: uploadResp, release } = await fetchWithSsrFGuard(withTrustedEnvProxyGuardedFetchMode({
306
- url: uploadUrlResp.upload_url,
307
- init: {
308
- method: "POST",
309
- ...contentType ? { headers: { "Content-Type": contentType } } : {},
310
- body: uploadBody
311
- },
312
- policy: SLACK_UPLOAD_SSRF_POLICY,
313
- auditContext: "slack-upload-file"
314
- }));
315
- try {
316
- if (!uploadResp.ok) throw new Error(`Failed to upload file: HTTP ${uploadResp.status}`);
317
- } finally {
318
- await release();
319
- }
320
- const completeResp = await params.client.files.completeUploadExternal({
321
- files: [{
322
- id: uploadUrlResp.file_id,
323
- title: fileName ?? "upload"
324
- }],
325
- channel_id: params.channelId,
326
- ...params.caption ? { initial_comment: params.caption } : {},
327
- ...params.threadTs ? { thread_ts: params.threadTs } : {}
328
- });
329
- if (!completeResp.ok) throw new Error(`Failed to complete upload: ${completeResp.error ?? "unknown error"}`);
330
- return uploadUrlResp.file_id;
331
- }
332
- async function sendMessageSlack(to, message, opts = {}) {
333
- const trimmedMessage = message?.trim() ?? "";
334
- if (isSilentReplyText(trimmedMessage) && !opts.mediaUrl && !opts.blocks) {
335
- logVerbose("slack send: suppressed NO_REPLY token before API call");
336
- return {
337
- messageId: "suppressed",
338
- channelId: ""
339
- };
340
- }
341
- const blocks = opts.blocks == null ? void 0 : validateSlackBlocksArray(opts.blocks);
342
- if (!trimmedMessage && !opts.mediaUrl && !blocks) throw new Error("Slack send requires text, blocks, or media");
343
- const cfg = opts.cfg ?? loadConfig();
344
- const account = resolveSlackAccount({
345
- cfg,
346
- accountId: opts.accountId
347
- });
348
- const token = resolveToken({
349
- explicit: opts.token,
350
- accountId: account.accountId,
351
- fallbackToken: account.botToken,
352
- fallbackSource: account.botTokenSource
353
- });
354
- const client = opts.client ?? createSlackWebClient(token);
355
- const { channelId } = await resolveChannelId(client, parseRecipient(to));
356
- if (blocks) {
357
- if (opts.mediaUrl) throw new Error("Slack send does not support blocks with mediaUrl");
358
- return {
359
- messageId: (await postSlackMessageBestEffort({
360
- client,
361
- channelId,
362
- text: trimmedMessage || buildSlackBlocksFallbackText(blocks),
363
- threadTs: opts.threadTs,
364
- identity: opts.identity,
365
- blocks
366
- })).ts ?? "unknown",
367
- channelId
368
- };
369
- }
370
- const textLimit = resolveTextChunkLimit(cfg, "slack", account.accountId);
371
- const chunkLimit = Math.min(textLimit, SLACK_TEXT_LIMIT);
372
- const tableMode = resolveMarkdownTableMode({
373
- cfg,
374
- channel: "slack",
375
- accountId: account.accountId
376
- });
377
- const chunkMode = resolveChunkMode(cfg, "slack", account.accountId);
378
- const chunks = (chunkMode === "newline" ? chunkMarkdownTextWithMode(trimmedMessage, chunkLimit, chunkMode) : [trimmedMessage]).flatMap((markdown) => markdownToSlackMrkdwnChunks(markdown, chunkLimit, { tableMode }));
379
- if (!chunks.length && trimmedMessage) chunks.push(trimmedMessage);
380
- const mediaMaxBytes = typeof account.config.mediaMaxMb === "number" ? account.config.mediaMaxMb * 1024 * 1024 : void 0;
381
- let lastMessageId = "";
382
- if (opts.mediaUrl) {
383
- const [firstChunk, ...rest] = chunks;
384
- lastMessageId = await uploadSlackFile({
385
- client,
386
- channelId,
387
- mediaUrl: opts.mediaUrl,
388
- mediaLocalRoots: opts.mediaLocalRoots,
389
- caption: firstChunk,
390
- threadTs: opts.threadTs,
391
- maxBytes: mediaMaxBytes
392
- });
393
- for (const chunk of rest) lastMessageId = (await postSlackMessageBestEffort({
394
- client,
395
- channelId,
396
- text: chunk,
397
- threadTs: opts.threadTs,
398
- identity: opts.identity
399
- })).ts ?? lastMessageId;
400
- } else for (const chunk of chunks.length ? chunks : [""]) lastMessageId = (await postSlackMessageBestEffort({
401
- client,
402
- channelId,
403
- text: chunk,
404
- threadTs: opts.threadTs,
405
- identity: opts.identity
406
- })).ts ?? lastMessageId;
407
- return {
408
- messageId: lastMessageId || "unknown",
409
- channelId
410
- };
411
- }
412
-
413
- //#endregion
414
- export { createSlackWebClient as a, validateSlackBlocksArray as c, buildSlackBlocksFallbackText as i, markdownToSlackMrkdwnChunks as n, resolveSlackWebClientOptions as o, normalizeSlackOutboundText as r, parseSlackBlocksInput as s, sendMessageSlack as t };