@seanhogg/builderforce-agents 2026.10.12 → 2026.10.13

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 (186) hide show
  1. package/dist/{agent-DvDtjczG.js → agent-CeWx2EpQ.js} +1 -1
  2. package/dist/{agent-DiLX8OzY.js → agent-DrcnpqOF.js} +1 -1
  3. package/dist/{agents-BawpdEjP.js → agents-CRJM6qhK.js} +1 -1
  4. package/dist/{agents-COWLUJqm.js → agents-hATFRfwk.js} +1 -1
  5. package/dist/{audio-preflight-CYQiI74L.js → audio-preflight-B9CfGDD2.js} +1 -1
  6. package/dist/{audio-preflight-BN1u9Tpc.js → audio-preflight-DHHeocUj.js} +1 -1
  7. package/dist/{auth-choice-D9VN-WjA.js → auth-choice-CWbPLRN0.js} +1 -1
  8. package/dist/{auth-choice-3cdcHeim.js → auth-choice-CzhKgWJy.js} +1 -1
  9. package/dist/{auth-choice.apply-Cd0RR0Z-.js → auth-choice.apply-C0RTYtRN.js} +1 -1
  10. package/dist/{auth-choice.apply-CMDgoDNN.js → auth-choice.apply-ChrTTHkK.js} +1 -1
  11. package/dist/{auth-choice.apply-BAeGyEKW.js → auth-choice.apply-D4LYzI8l.js} +1 -1
  12. package/dist/{auth-choice.apply-CSXvPCea.js → auth-choice.apply-Dy4rVG6K.js} +1 -1
  13. package/dist/{auth-choice.apply.transformers-DkX2-OZa.js → auth-choice.apply.transformers-9v6HFzNs.js} +1 -1
  14. package/dist/{auth-choice.apply.transformers-CEVxl3ul.js → auth-choice.apply.transformers-Be8599JD.js} +1 -1
  15. package/dist/{auth-choice.apply.transformers-B2Nr9M7m.js → auth-choice.apply.transformers-CgfGlqy1.js} +1 -1
  16. package/dist/{auth-choice.apply.transformers-Dpy9gODo.js → auth-choice.apply.transformers-D9a8-sLS.js} +1 -1
  17. package/dist/{banner-C93QSUTe.js → banner-8F7-gU1V.js} +1 -1
  18. package/dist/build-info.json +3 -3
  19. package/dist/{builderforce-Dl4bZ63C.js → builderforce-CCfM1c79.js} +1 -1
  20. package/dist/{builderforce-C_tuO46t.js → builderforce-CImLd8Zo.js} +1 -1
  21. package/dist/bundled/boot-md/handler.js +1 -1
  22. package/dist/bundled/session-memory/handler.js +1 -1
  23. package/dist/{channel-options-CiYpNR-1.js → channel-options-CRng-5hZ.js} +1 -1
  24. package/dist/{channel-options-Cziy0WDc.js → channel-options-D5kOIN7b.js} +1 -1
  25. package/dist/{channel-web-Ae15MleJ.js → channel-web-B5HSpL4k.js} +1 -1
  26. package/dist/{channels-cli-CZM033Me.js → channels-cli-COl9TDHT.js} +1 -1
  27. package/dist/{channels-cli-yi1vxpvO.js → channels-cli-bR8QwOv3.js} +1 -1
  28. package/dist/chrome-ChzFLAeJ.js +4 -0
  29. package/dist/chrome-CrqJ4Ijz.js +4 -0
  30. package/dist/{cli-Bwv_-VuS.js → cli-BqJMHFNK.js} +1 -1
  31. package/dist/{cli-D8fndSEi.js → cli-DBn0qbHS.js} +1 -1
  32. package/dist/{command-registry-Cjom5ab0.js → command-registry-BqhtXJa7.js} +1 -1
  33. package/dist/{command-registry-8uEx2JjY.js → command-registry-DVH79C3B.js} +1 -1
  34. package/dist/{completion-cli-PTFpWp8Q.js → completion-cli-BFR0u1Uh.js} +1 -1
  35. package/dist/{completion-cli-LUuqgvVQ.js → completion-cli-BuUAEqQw.js} +1 -1
  36. package/dist/{completion-cli-DRsz70D2.js → completion-cli-CwaIh4zw.js} +1 -1
  37. package/dist/{completion-cli-BsXDz7T2.js → completion-cli-Da3-oE7r.js} +1 -1
  38. package/dist/{config-cli-BIx0enD5.js → config-cli-Bhrj7H1i.js} +1 -1
  39. package/dist/{config-cli-BFhOXrua.js → config-cli-DOHKZ1lO.js} +1 -1
  40. package/dist/{configure-D96xLIb6.js → configure-B-Yta1X3.js} +1 -1
  41. package/dist/{configure-S7YE6hn1.js → configure-BHVk4Ax9.js} +1 -1
  42. package/dist/{configure-dDKfCq_g.js → configure-D9YZEK_D.js} +1 -1
  43. package/dist/{configure-C7xdw9Kq.js → configure-DPE2hDzY.js} +1 -1
  44. package/dist/{deps-CGiO_NDu.js → deps-CrAVOWsA.js} +1 -1
  45. package/dist/{doctor-completion-ChhIrLd3.js → doctor-completion-CkjrUmbI.js} +1 -1
  46. package/dist/{doctor-completion-BUZwWoWB.js → doctor-completion-Dh9ah5lH.js} +1 -1
  47. package/dist/{embedded-DJYMy81Q.js → embedded-BrqzM5oT.js} +12 -12
  48. package/dist/{embedded-DjDnQMNx.js → embedded-wYxo-ADm.js} +12 -12
  49. package/dist/entry.js +1 -1
  50. package/dist/extensionAPI.js +1 -1
  51. package/dist/{gateway-cli-CN114d5j.js → gateway-cli-C2nh9UyY.js} +2 -2
  52. package/dist/{gateway-cli-Dzl70YBF.js → gateway-cli-CGkTLhet.js} +2 -2
  53. package/dist/{health-Cf1YoTRN.js → health-CEz2-7et.js} +1 -1
  54. package/dist/{health-AlkF1nUa.js → health-CFVx21sO.js} +1 -1
  55. package/dist/{health-ySVOGGNu.js → health-aKuq4xwa.js} +1 -1
  56. package/dist/{hooks-cli-6jeFEGg3.js → hooks-cli-DPSrycwI.js} +1 -1
  57. package/dist/{hooks-cli-DVPMCXUq.js → hooks-cli-uPHs7qnC.js} +1 -1
  58. package/dist/index.js +2 -2
  59. package/dist/llm-slug-generator.js +1 -1
  60. package/dist/{models-CGUxphfN.js → models--TwKHn8b.js} +1 -1
  61. package/dist/{models-CIMM_Z3u.js → models-BXJebxTU.js} +1 -1
  62. package/dist/{models-cli-Cijh2uON.js → models-cli-O1zCgeoA.js} +1 -1
  63. package/dist/{models-cli-Oys3e_I3.js → models-cli-iKu1IVeH.js} +1 -1
  64. package/dist/{onboard-DAEXNhNd.js → onboard--0I8pdee.js} +1 -1
  65. package/dist/{onboard-b2fWbf0Q.js → onboard-C40OvMZO.js} +1 -1
  66. package/dist/{onboard-channels-elaccQRE.js → onboard-channels-BbpyejX4.js} +1 -1
  67. package/dist/{onboard-channels-Bsd11scA.js → onboard-channels-CoJnsCfd.js} +1 -1
  68. package/dist/{onboard-channels-C_Q7OUow.js → onboard-channels-ZI4QC9WU.js} +1 -1
  69. package/dist/{onboard-channels-Tl1X4Pl_.js → onboard-channels-uvIeLPXK.js} +1 -1
  70. package/dist/{onboard-interactive-DyGNiYRI.js → onboard-interactive-B3Z0XLT6.js} +1 -1
  71. package/dist/{onboard-interactive-C0qmgHsH.js → onboard-interactive-CJdxqQ1b.js} +1 -1
  72. package/dist/{onboard-interactive-86s992_v.js → onboard-interactive-COnCCTTW.js} +1 -1
  73. package/dist/{onboard-interactive-CvMSTjPK.js → onboard-interactive-jss8R9r9.js} +1 -1
  74. package/dist/{onboarding-DzvbhsaR.js → onboarding-B1BmYWrs.js} +2 -2
  75. package/dist/{onboarding-B0tbaqZ7.js → onboarding-CdRbvLgp.js} +2 -2
  76. package/dist/{onboarding.finalize-D-Pi9Blv.js → onboarding.finalize-B0AjF6qZ.js} +1 -1
  77. package/dist/{onboarding.finalize-CERLBlRF.js → onboarding.finalize-WsL-ijTc.js} +1 -1
  78. package/dist/{outbound-send-deps-CzhBrVa7.js → outbound-send-deps-DuML6h7r.js} +1 -1
  79. package/dist/{plugin-registry-DtrHn5NR.js → plugin-registry-BjWNyeVY.js} +1 -1
  80. package/dist/{plugin-registry-Avx51RIY.js → plugin-registry-Cf_sv-ny.js} +1 -1
  81. package/dist/{plugin-registry-CFkQDTOt.js → plugin-registry-DdFb5usc.js} +1 -1
  82. package/dist/{plugin-registry-BEmyRfmb.js → plugin-registry-DrEpL5ac.js} +1 -1
  83. package/dist/plugin-sdk/{accounts-BwreSNAR.js → accounts-Cy3WCbWg.js} +1 -1
  84. package/dist/plugin-sdk/{active-listener-DpQ7aGYd.js → active-listener-DVWVNlT9.js} +1 -1
  85. package/dist/plugin-sdk/agent-runtime/src/agents/tool-retry.d.ts +40 -32
  86. package/dist/plugin-sdk/agent-runtime/src/builderforce/model/agent-types.d.ts +6 -0
  87. package/dist/plugin-sdk/{agent-scope-BQByW0cD.js → agent-scope-DgKN27hJ.js} +1 -1
  88. package/dist/plugin-sdk/{api-key-rotation-yqTCeKjV.js → api-key-rotation-D37jV9ZW.js} +1 -1
  89. package/dist/plugin-sdk/{audio-preflight-B6uTvVfA.js → audio-preflight-D4xyO8Zq.js} +1 -1
  90. package/dist/plugin-sdk/{auth-json-Dw6ij9Pa.js → auth-json-nASe57Uw.js} +1 -1
  91. package/dist/plugin-sdk/{bindings-CDEzl4kl.js → bindings-CH-YLOLC.js} +1 -1
  92. package/dist/plugin-sdk/{channel-web-DKbpA9xC.js → channel-web-huZSNTX3.js} +1 -1
  93. package/dist/plugin-sdk/{chrome-DriEqJRH.js → chrome-CRUzg3kA.js} +1 -1
  94. package/dist/plugin-sdk/{chunk-cW0POl22.js → chunk-C94IAOuf.js} +1 -1
  95. package/dist/plugin-sdk/{command-format-CAX9XFjI.js → command-format-B3XMq_73.js} +1 -1
  96. package/dist/plugin-sdk/{common-BxEWhN2X.js → common-n0l_XN-S.js} +1 -1
  97. package/dist/plugin-sdk/{config-3vPn_hmp.js → config--Ci8Y91R.js} +2 -2
  98. package/dist/plugin-sdk/{fetch-DH0Y8iyO.js → fetch-B-GxSYRO.js} +1 -1
  99. package/dist/plugin-sdk/index.js +1 -1
  100. package/dist/plugin-sdk/{login-Dhdx0bVL.js → login-DZliYZg8.js} +1 -1
  101. package/dist/plugin-sdk/{login-qr-DAjOuijP.js → login-qr-DKcGvAjv.js} +1 -1
  102. package/dist/plugin-sdk/{manager-i8psl2Er.js → manager-DioOqJm_.js} +1 -1
  103. package/dist/plugin-sdk/{markdown-tables-Epim9b-0.js → markdown-tables-BUfhHgfs.js} +1 -1
  104. package/dist/plugin-sdk/{message-channel-sBPQc_-T.js → message-channel-CuZ2xOAM.js} +1 -1
  105. package/dist/plugin-sdk/{model-catalog-COVRezOQ.js → model-catalog-DIQ5a-o4.js} +1 -1
  106. package/dist/plugin-sdk/{model-selection-Crz-xYNU.js → model-selection-_H_U9jWH.js} +1 -1
  107. package/dist/plugin-sdk/{outbound-CPutSvae.js → outbound-Djibdmi7.js} +1 -1
  108. package/dist/plugin-sdk/{plugins-CaUOZBVb.js → plugins-BdkC9v5E.js} +1 -1
  109. package/dist/plugin-sdk/{pw-ai-jI9AWvKe.js → pw-ai-Bbi8Us-p.js} +1 -1
  110. package/dist/plugin-sdk/{qmd-manager-BRe5fGZw.js → qmd-manager-Dxn0jCpE.js} +1 -1
  111. package/dist/plugin-sdk/{registry-DJq2Cvo9.js → registry-CZHRcH-q.js} +1 -1
  112. package/dist/plugin-sdk/{render-BUCRXPIk.js → render-CuA_WRX5.js} +1 -1
  113. package/dist/plugin-sdk/{replies-CYjI7bye.js → replies-Cf69aZLA.js} +1 -1
  114. package/dist/plugin-sdk/{reply-B5o-SSYy.js → reply-BOVC-7UD.js} +13 -13
  115. package/dist/plugin-sdk/{reply-prefix-CCymsmsP.js → reply-prefix-w7kAvH11.js} +1 -1
  116. package/dist/plugin-sdk/{resolve-route-DN1J7Wyc.js → resolve-route-0sbvl4ZN.js} +1 -1
  117. package/dist/plugin-sdk/{runner-C2pDJlRw.js → runner-DKoKK09-.js} +4 -4
  118. package/dist/plugin-sdk/{session-BnleckVX.js → session-DGLuyt10.js} +1 -1
  119. package/dist/plugin-sdk/{sqlite-BlMLqMl8.js → sqlite-JjFgDV-H.js} +1 -1
  120. package/dist/plugin-sdk/{subsystem-COTa5Ly_.js → subsystem-D0Ril4rt.js} +1 -1
  121. package/dist/plugin-sdk/{tool-images-DSpchb4x.js → tool-images-WRTP95FT.js} +1 -1
  122. package/dist/plugin-sdk/{tool-loop-detection-16p7mJ8N.js → tool-loop-detection-g8gPTCgJ.js} +1 -1
  123. package/dist/plugin-sdk/web-Cdu8TkUy.js +1 -0
  124. package/dist/plugin-sdk/{whatsapp-actions-C2B3iw8n.js → whatsapp-actions-CsSzy7G0.js} +1 -1
  125. package/dist/{plugins-DAlgx58e.js → plugins-Dr1wmnAf.js} +1 -1
  126. package/dist/{plugins-De7aK3yK.js → plugins-JhEblShx.js} +1 -1
  127. package/dist/{plugins-cli-CwdUVWjG.js → plugins-cli-DW4hoeeV.js} +1 -1
  128. package/dist/{plugins-cli-CfVCrrhx.js → plugins-cli-GewV3E8e.js} +1 -1
  129. package/dist/{program-CFL6mW3l.js → program-bggmBKuL.js} +2 -2
  130. package/dist/{program-context-DP4Xq9zC.js → program-context-BCTE8zEF.js} +1 -1
  131. package/dist/{prompt-select-styled-NxrGT7OR.js → prompt-select-styled-BtjhlTEH.js} +1 -1
  132. package/dist/{prompt-select-styled-Csz9HlSx.js → prompt-select-styled-CaNl41mG.js} +1 -1
  133. package/dist/{provider-auth-helpers-BMBw21Tn.js → provider-auth-helpers-CWUfg9zf.js} +1 -1
  134. package/dist/{provider-auth-helpers-VWPvSXPH.js → provider-auth-helpers-y1X8xKVE.js} +1 -1
  135. package/dist/{provider-dispatcher-CSOHd9zJ.js → provider-dispatcher-CRsPmKhJ.js} +1 -1
  136. package/dist/{provider-dispatcher-Bg9orQPy.js → provider-dispatcher-D9GbE_Ce.js} +1 -1
  137. package/dist/{push-apns-rMu8MKXi.js → push-apns-Cb1sQEEa.js} +1 -1
  138. package/dist/{push-apns-ep5WkyGz.js → push-apns-Cr-6aD3y.js} +1 -1
  139. package/dist/{pw-ai-UXo3gDGy.js → pw-ai-CG-kY5NP.js} +1 -1
  140. package/dist/{pw-ai-CIN6tj0G.js → pw-ai-DcZPg2vm.js} +1 -1
  141. package/dist/{register.agent-BynXVz7v.js → register.agent-B33EZBoL.js} +1 -1
  142. package/dist/{register.agent-RNVNKBP3.js → register.agent-DfYqZls1.js} +1 -1
  143. package/dist/{register.configure-BdqREs1-.js → register.configure-CREcJhKA.js} +1 -1
  144. package/dist/{register.configure-DDrvpBnA.js → register.configure-D8an7wc5.js} +1 -1
  145. package/dist/{register.maintenance-DT6t7mD_.js → register.maintenance-D84M5XLR.js} +1 -1
  146. package/dist/{register.maintenance-BSKHOCTV.js → register.maintenance-Dnp_Ii2x.js} +1 -1
  147. package/dist/{register.message-7KIfSUxS.js → register.message-B6E0uAEu.js} +1 -1
  148. package/dist/{register.message-DDhEvcaX.js → register.message-WOWC4tyf.js} +1 -1
  149. package/dist/{register.onboard-CKhooa7L.js → register.onboard-AgVEhehS.js} +1 -1
  150. package/dist/{register.onboard-CswvuzLx.js → register.onboard-Cwozk0Tx.js} +1 -1
  151. package/dist/{register.setup-1BmR-qlh.js → register.setup-BKyCvo9_.js} +1 -1
  152. package/dist/{register.setup-CivwfXf_.js → register.setup-C9IeGiAd.js} +1 -1
  153. package/dist/{register.status-health-sessions-CLdHZiJm.js → register.status-health-sessions-CYZctjpx.js} +1 -1
  154. package/dist/{register.status-health-sessions-BXpljfv3.js → register.status-health-sessions-CcL6srRC.js} +1 -1
  155. package/dist/{register.subclis-D_fHb-Aj.js → register.subclis-AFsfDByV.js} +1 -1
  156. package/dist/{register.subclis-CTTxdHaJ.js → register.subclis-C0DxtuRO.js} +1 -1
  157. package/dist/{reply-D9wUWhMx.js → reply-BuUSdq2L.js} +9 -9
  158. package/dist/{run-main-DNyQhVQT.js → run-main-CgJMiKPV.js} +1 -1
  159. package/dist/{runner-BNnckkaT.js → runner-C8oNv-9y.js} +3 -3
  160. package/dist/{runner-EHybuAt7.js → runner-nDoIXX7n.js} +3 -3
  161. package/dist/{server-node-events-BGrnw4ZT.js → server-node-events-BMsKmU5S.js} +1 -1
  162. package/dist/{server-node-events-D4WVcVHy.js → server-node-events-fS8TluXq.js} +1 -1
  163. package/dist/{session-dirs-eNN7E3kA.js → session-dirs-Bkfs-7vN.js} +1 -1
  164. package/dist/{session-dirs-C-pVBwSV.js → session-dirs-rYDCA_mQ.js} +1 -1
  165. package/dist/{status-Demw1HZ7.js → status-Ad1eFPKR.js} +1 -1
  166. package/dist/{status-CBieo24v.js → status-BMzVz5KY.js} +1 -1
  167. package/dist/{status-rkFgCaBM.js → status-CXRyaGws.js} +1 -1
  168. package/dist/{status-wTMmjZ7M.js → status-DpEUFAMk.js} +1 -1
  169. package/dist/{status-BhJw9Htq.js → status-oaiZkYBt.js} +1 -1
  170. package/dist/{subagent-registry-Bje3RAgk.js → subagent-registry-gVTWLPpL.js} +1 -1
  171. package/dist/{subagent-registry-B0kpBIxD.js → subagent-registry-hM0OCDzv.js} +1 -1
  172. package/dist/{subagent-registry-Cj5yC7B4.js → subagent-registry-m_x-JRkR.js} +9 -9
  173. package/dist/{tui-BCtecmPL.js → tui-HTtOgZ_X.js} +2 -2
  174. package/dist/{tui-BqHLI73U.js → tui-LemSel3H.js} +2 -2
  175. package/dist/{tui-cli-2R0xjpqW.js → tui-cli-BpzicV5H.js} +1 -1
  176. package/dist/{tui-cli-Dvd8BwzD.js → tui-cli-CruoIP1K.js} +1 -1
  177. package/dist/{update-cli-DUObGvw1.js → update-cli-Wa-nZ_Lq.js} +1 -1
  178. package/dist/{update-cli-Bt7Vfi7c.js → update-cli-zv67YxK1.js} +1 -1
  179. package/dist/{web--KblE8ax.js → web-BrsbhB1i.js} +1 -1
  180. package/dist/{web-C-yTnRvS.js → web-BzkO4Pbe.js} +1 -1
  181. package/dist/{web-0VRcRcFj.js → web-D_QYY7Gt.js} +1 -1
  182. package/dist/{web-BcUIWAAJ.js → web-jPbmSTQm.js} +1 -1
  183. package/package.json +1 -1
  184. package/dist/chrome-CmCESKt9.js +0 -4
  185. package/dist/chrome-D6qk0wxW.js +0 -4
  186. package/dist/plugin-sdk/web-CzJYJZZs.js +0 -1
@@ -1,4 +1,4 @@
1
- import{E as toWhatsappJid,F as shouldLogVerbose,M as logVerbose,U as getChildLogger,h as normalizeE164,m as jidToE164,p as isSelfChatMode,r as clamp,w as sleep,y as resolveJidToE164}from"./utils-DbaBVFaK.js";import{An as hasControlCommand,Bt as computeBackoff,Dn as formatInboundEnvelope,En as resolveInboundDebounceMs,Fn as normalizeMentionText,Ft as parseActivationCommand,On as resolveEnvelopeFormatOptions,Pn as buildMentionRegexes,Pt as normalizeGroupActivation,Tn as createInboundDebouncer,Vt as sleepWithAbort,_n as recordPendingHistoryEntryIfEnabled,di as enqueueSystemEvent,gn as buildHistoryContextFromEntries,hn as DEFAULT_GROUP_HISTORY_LIMIT,jn as shouldComputeCommandAuthorized,mn as resolveMentionGating,pn as buildPairingReply,t as getReplyFromConfig,vn as shouldAckReactionForWhatsApp,wn as createDedupeCache,yn as dispatchReplyWithBufferedBlockDispatcher}from"./reply-D9wUWhMx.js";import{a as buildAgentMainSessionKey,d as normalizeAgentId,i as DEFAULT_MAIN_KEY,s as buildGroupHistoryKey}from"./session-key-EoB0qaG9.js";import{i as defaultRuntime,t as createSubsystemLogger}from"./subsystem-B3TqcCrZ.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{r as loadConfig}from"./io-BNtgT4VB.js";import{t as finalizeInboundContext}from"./inbound-context-DdpnlRT9.js";import{l as registerUnhandledRejectionHandler}from"./runner-C3k1sKdu.js";import{r as saveMediaBuffer}from"./store-CmHBQ-yX.js";import{J as resolveChannelGroupRequireMention,Z as resolveGroupSessionKey,a as loadSessionStore,l as updateLastRoute,o as readSessionUpdatedAt,q as resolveChannelGroupPolicy,s as recordSessionMetaFromInbound}from"./sessions-BPr0-lkT.js";import{i as getWebAuthAgeMs,n as resolveWhatsAppAccount,u as readWebSelfId}from"./accounts-o35LU_iy.js";import{c as resolveStorePath}from"./paths-DJ6rztqJ.js";import{H as formatLocationText,U as toLocationContext}from"./send-CRSlal5z.js";import{c as resolveIdentityNamePrefix,l as resolveMessagePrefix,n as createReplyPrefixOptions}from"./reply-prefix-zIMgi6K6.js";import{c as resolveTextChunkLimit,i as chunkMarkdownTextWithMode,s as resolveChunkMode}from"./chunk-FCBlVOyo.js";import{t as resolveMarkdownTableMode}from"./markdown-tables-P6uoUSFa.js";import{a as loadWebMedia,s as getAgentScopedMediaLocalRoots}from"./ir-5BNoIXZm.js";import{n as recordChannelActivity}from"./channel-activity-CCNDbdD3.js";import{t as convertMarkdownTables}from"./tables-ERcoWFDp.js";import{i as readChannelAllowFromStore,o as upsertChannelPairingRequest}from"./pairing-store-C8gtsUDG.js";import{r as formatDurationPrecise}from"./format-duration-HN2dpHE0.js";import{n as resolveAgentRoute,t as buildAgentSessionKey}from"./resolve-route-D49haUnv.js";import{r as setActiveWebListener}from"./active-listener-Dcg19lJG.js";import{i as markdownToWhatsApp,r as sendReactionWhatsApp}from"./outbound-rhwRyIBV.js";import{i as waitForWaConnection,n as formatError,r as getStatusCode,t as createWaSocket}from"./session-PaEB8NU_.js";import{randomUUID}from"node:crypto";import{getMaxListeners,setMaxListeners}from"node:events";import{DisconnectReason,downloadMediaMessage,extractMessageContent,getContentType,isJidGroup,normalizeMessageContent}from"@whiskeysockets/baileys";const DEFAULT_RECONNECT_POLICY={initialMs:2e3,maxMs:3e4,factor:1.8,jitter:.25,maxAttempts:12};function resolveHeartbeatSeconds(cfg,overrideSeconds){let candidate=overrideSeconds??cfg.web?.heartbeatSeconds;return typeof candidate==`number`&&candidate>0?candidate:60}function resolveReconnectPolicy(cfg,overrides){let reconnectOverrides=cfg.web?.reconnect??{},overrideConfig=overrides??{},merged={...DEFAULT_RECONNECT_POLICY,...reconnectOverrides,...overrideConfig};return merged.initialMs=Math.max(250,merged.initialMs),merged.maxMs=Math.max(merged.initialMs,merged.maxMs),merged.factor=clamp(merged.factor,1.1,10),merged.jitter=clamp(merged.jitter,0,1),merged.maxAttempts=Math.max(0,Math.floor(merged.maxAttempts)),merged}function newConnectionId(){return randomUUID()}const whatsappLog=createSubsystemLogger(`gateway/channels/whatsapp`),whatsappInboundLog=whatsappLog.child(`inbound`),whatsappOutboundLog=whatsappLog.child(`outbound`),whatsappHeartbeatLog=whatsappLog.child(`heartbeat`);function elide(text,limit=400){return!text||text.length<=limit?text:`${text.slice(0,limit)}… (truncated ${text.length-limit} chars)`}function isLikelyWhatsAppCryptoError(reason){let haystack=(reason instanceof Error?`${reason.message}\n${reason.stack??``}`:(value=>{if(value==null)return``;if(typeof value==`string`)return value;if(value instanceof Error)return`${value.message}\n${value.stack??``}`;if(typeof value==`object`)try{return JSON.stringify(value)}catch{return Object.prototype.toString.call(value)}return typeof value==`number`||typeof value==`boolean`||typeof value==`bigint`?String(value):typeof value==`symbol`?value.description??value.toString():typeof value==`function`?value.name?`[function ${value.name}]`:`[function]`:Object.prototype.toString.call(value)})(reason)).toLowerCase();return haystack.includes(`unsupported state or unable to authenticate data`)||haystack.includes(`bad mac`)?haystack.includes(`@whiskeysockets/baileys`)||haystack.includes(`baileys`)||haystack.includes(`noise-handler`)||haystack.includes(`aesdecryptgcm`):!1}function waitForever(){return setInterval(()=>{},1e6).unref(),new Promise(()=>{})}const recentInboundMessages=createDedupeCache({ttlMs:20*6e4,maxSize:5e3});function isRecentInboundMessage(key){return recentInboundMessages.check(key)}const ALLOWED_VCARD_KEYS=new Set([`FN`,`N`,`TEL`]);function parseVcard(vcard){if(!vcard)return{phones:[]};let lines=vcard.split(/\r?\n/),nameFromN,nameFromFn,phones=[];for(let rawLine of lines){let line=rawLine.trim();if(!line)continue;let colonIndex=line.indexOf(`:`);if(colonIndex===-1)continue;let key=line.slice(0,colonIndex).toUpperCase(),rawValue=line.slice(colonIndex+1).trim();if(!rawValue)continue;let baseKey=normalizeVcardKey(key);if(!baseKey||!ALLOWED_VCARD_KEYS.has(baseKey))continue;let value=cleanVcardValue(rawValue);if(value){if(baseKey===`FN`&&!nameFromFn){nameFromFn=normalizeVcardName(value);continue}if(baseKey===`N`&&!nameFromN){nameFromN=normalizeVcardName(value);continue}if(baseKey===`TEL`){let phone=normalizeVcardPhone(value);phone&&phones.push(phone)}}}return{name:nameFromFn??nameFromN,phones}}function normalizeVcardKey(key){let[primary]=key.split(`;`);if(!primary)return;let segments=primary.split(`.`);return segments[segments.length-1]||void 0}function cleanVcardValue(value){return value.replace(/\\n/gi,` `).replace(/\\,/g,`,`).replace(/\\;/g,`;`).trim()}function normalizeVcardName(value){return value.replace(/;/g,` `).replace(/\s+/g,` `).trim()}function normalizeVcardPhone(value){let trimmed=value.trim();return trimmed?trimmed.toLowerCase().startsWith(`tel:`)?trimmed.slice(4).trim():trimmed:``}function unwrapMessage$1(message){return normalizeMessageContent(message)}function extractContextInfo(message){if(!message)return;let contentType=getContentType(message),candidate=contentType?message[contentType]:void 0,contextInfo=candidate&&typeof candidate==`object`&&`contextInfo`in candidate?candidate.contextInfo:void 0;if(contextInfo)return contextInfo;let fallback=message.extendedTextMessage?.contextInfo??message.imageMessage?.contextInfo??message.videoMessage?.contextInfo??message.documentMessage?.contextInfo??message.audioMessage?.contextInfo??message.stickerMessage?.contextInfo??message.buttonsResponseMessage?.contextInfo??message.listResponseMessage?.contextInfo??message.templateButtonReplyMessage?.contextInfo??message.interactiveResponseMessage?.contextInfo??message.buttonsMessage?.contextInfo??message.listMessage?.contextInfo;if(fallback)return fallback;for(let value of Object.values(message)){if(!value||typeof value!=`object`||!(`contextInfo`in value))continue;let candidateContext=value.contextInfo;if(candidateContext)return candidateContext}}function extractMentionedJids(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let flattened=[message.extendedTextMessage?.contextInfo?.mentionedJid,message.extendedTextMessage?.contextInfo?.quotedMessage?.extendedTextMessage?.contextInfo?.mentionedJid,message.imageMessage?.contextInfo?.mentionedJid,message.videoMessage?.contextInfo?.mentionedJid,message.documentMessage?.contextInfo?.mentionedJid,message.audioMessage?.contextInfo?.mentionedJid,message.stickerMessage?.contextInfo?.mentionedJid,message.buttonsResponseMessage?.contextInfo?.mentionedJid,message.listResponseMessage?.contextInfo?.mentionedJid].flatMap(arr=>arr??[]).filter(Boolean);if(flattened.length!==0)return Array.from(new Set(flattened))}function extractText(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let extracted=extractMessageContent(message),candidates=[message,extracted&&extracted!==message?extracted:void 0];for(let candidate of candidates){if(!candidate)continue;if(typeof candidate.conversation==`string`&&candidate.conversation.trim())return candidate.conversation.trim();let extended=candidate.extendedTextMessage?.text;if(extended?.trim())return extended.trim();let caption=candidate.imageMessage?.caption??candidate.videoMessage?.caption??candidate.documentMessage?.caption;if(caption?.trim())return caption.trim()}let contactPlaceholder=extractContactPlaceholder(message)??(extracted&&extracted!==message?extractContactPlaceholder(extracted):void 0);if(contactPlaceholder)return contactPlaceholder}function extractMediaPlaceholder(rawMessage){let message=unwrapMessage$1(rawMessage);if(message){if(message.imageMessage)return`<media:image>`;if(message.videoMessage)return`<media:video>`;if(message.audioMessage)return`<media:audio>`;if(message.documentMessage)return`<media:document>`;if(message.stickerMessage)return`<media:sticker>`}}function extractContactPlaceholder(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let contact=message.contactMessage??void 0;if(contact){let{name,phones}=describeContact({displayName:contact.displayName,vcard:contact.vcard});return formatContactPlaceholder(name,phones)}let contactsArray=message.contactsArrayMessage?.contacts??void 0;if(!(!contactsArray||contactsArray.length===0))return formatContactsPlaceholder(contactsArray.map(entry=>describeContact({displayName:entry.displayName,vcard:entry.vcard})).map(entry=>formatContactLabel(entry.name,entry.phones)).filter(value=>!!value),contactsArray.length)}function describeContact(input){let displayName=(input.displayName??``).trim(),parsed=parseVcard(input.vcard??void 0);return{name:displayName||parsed.name,phones:parsed.phones}}function formatContactPlaceholder(name,phones){let label=formatContactLabel(name,phones);return label?`<contact: ${label}>`:`<contact>`}function formatContactsPlaceholder(labels,total){let cleaned=labels.map(label=>label.trim()).filter(Boolean);if(cleaned.length===0)return`<contacts: ${total} ${total===1?`contact`:`contacts`}>`;let remaining=Math.max(total-cleaned.length,0),suffix=remaining>0?` +${remaining} more`:``;return`<contacts: ${cleaned.join(`, `)}${suffix}>`}function formatContactLabel(name,phones){let parts=[name,formatPhoneList(phones)].filter(value=>!!value);if(parts.length!==0)return parts.join(`, `)}function formatPhoneList(phones){let cleaned=phones?.map(phone=>phone.trim()).filter(Boolean)??[];if(cleaned.length===0)return;let{shown,remaining}=summarizeList(cleaned,cleaned.length,1),[primary]=shown;if(primary)return remaining===0?primary:`${primary} (+${remaining} more)`}function summarizeList(values,total,maxShown){let shown=values.slice(0,maxShown);return{shown,remaining:Math.max(total-shown.length,0)}}function extractLocationData(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return null;let live=message.liveLocationMessage??void 0;if(live){let latitudeRaw=live.degreesLatitude,longitudeRaw=live.degreesLongitude;if(latitudeRaw!=null&&longitudeRaw!=null){let latitude=Number(latitudeRaw),longitude=Number(longitudeRaw);if(Number.isFinite(latitude)&&Number.isFinite(longitude))return{latitude,longitude,accuracy:live.accuracyInMeters??void 0,caption:live.caption??void 0,source:`live`,isLive:!0}}}let location=message.locationMessage??void 0;if(location){let latitudeRaw=location.degreesLatitude,longitudeRaw=location.degreesLongitude;if(latitudeRaw!=null&&longitudeRaw!=null){let latitude=Number(latitudeRaw),longitude=Number(longitudeRaw);if(Number.isFinite(latitude)&&Number.isFinite(longitude)){let isLive=!!location.isLive;return{latitude,longitude,accuracy:location.accuracyInMeters??void 0,name:location.name??void 0,address:location.address??void 0,caption:location.comment??void 0,source:isLive?`live`:location.name||location.address?`place`:`pin`,isLive}}}}return null}function describeReplyContext(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return null;let contextInfo=extractContextInfo(message),quoted=normalizeMessageContent(contextInfo?.quotedMessage);if(!quoted)return null;let location=extractLocationData(quoted),locationText=location?formatLocationText(location):void 0,body=[extractText(quoted),locationText].filter(Boolean).join(`
1
+ import{E as toWhatsappJid,F as shouldLogVerbose,M as logVerbose,U as getChildLogger,h as normalizeE164,m as jidToE164,p as isSelfChatMode,r as clamp,w as sleep,y as resolveJidToE164}from"./utils-DbaBVFaK.js";import{An as hasControlCommand,Bt as computeBackoff,Dn as formatInboundEnvelope,En as resolveInboundDebounceMs,Fn as normalizeMentionText,Ft as parseActivationCommand,On as resolveEnvelopeFormatOptions,Pn as buildMentionRegexes,Pt as normalizeGroupActivation,Tn as createInboundDebouncer,Vt as sleepWithAbort,_n as recordPendingHistoryEntryIfEnabled,di as enqueueSystemEvent,gn as buildHistoryContextFromEntries,hn as DEFAULT_GROUP_HISTORY_LIMIT,jn as shouldComputeCommandAuthorized,mn as resolveMentionGating,pn as buildPairingReply,t as getReplyFromConfig,vn as shouldAckReactionForWhatsApp,wn as createDedupeCache,yn as dispatchReplyWithBufferedBlockDispatcher}from"./reply-BuUSdq2L.js";import{a as buildAgentMainSessionKey,d as normalizeAgentId,i as DEFAULT_MAIN_KEY,s as buildGroupHistoryKey}from"./session-key-EoB0qaG9.js";import{i as defaultRuntime,t as createSubsystemLogger}from"./subsystem-B3TqcCrZ.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{r as loadConfig}from"./io-BNtgT4VB.js";import{t as finalizeInboundContext}from"./inbound-context-DdpnlRT9.js";import{l as registerUnhandledRejectionHandler}from"./runner-C3k1sKdu.js";import{r as saveMediaBuffer}from"./store-CmHBQ-yX.js";import{J as resolveChannelGroupRequireMention,Z as resolveGroupSessionKey,a as loadSessionStore,l as updateLastRoute,o as readSessionUpdatedAt,q as resolveChannelGroupPolicy,s as recordSessionMetaFromInbound}from"./sessions-BPr0-lkT.js";import{i as getWebAuthAgeMs,n as resolveWhatsAppAccount,u as readWebSelfId}from"./accounts-o35LU_iy.js";import{c as resolveStorePath}from"./paths-DJ6rztqJ.js";import{H as formatLocationText,U as toLocationContext}from"./send-CRSlal5z.js";import{c as resolveIdentityNamePrefix,l as resolveMessagePrefix,n as createReplyPrefixOptions}from"./reply-prefix-zIMgi6K6.js";import{c as resolveTextChunkLimit,i as chunkMarkdownTextWithMode,s as resolveChunkMode}from"./chunk-FCBlVOyo.js";import{t as resolveMarkdownTableMode}from"./markdown-tables-P6uoUSFa.js";import{a as loadWebMedia,s as getAgentScopedMediaLocalRoots}from"./ir-5BNoIXZm.js";import{n as recordChannelActivity}from"./channel-activity-CCNDbdD3.js";import{t as convertMarkdownTables}from"./tables-ERcoWFDp.js";import{i as readChannelAllowFromStore,o as upsertChannelPairingRequest}from"./pairing-store-C8gtsUDG.js";import{r as formatDurationPrecise}from"./format-duration-HN2dpHE0.js";import{n as resolveAgentRoute,t as buildAgentSessionKey}from"./resolve-route-D49haUnv.js";import{r as setActiveWebListener}from"./active-listener-Dcg19lJG.js";import{i as markdownToWhatsApp,r as sendReactionWhatsApp}from"./outbound-rhwRyIBV.js";import{i as waitForWaConnection,n as formatError,r as getStatusCode,t as createWaSocket}from"./session-PaEB8NU_.js";import{randomUUID}from"node:crypto";import{getMaxListeners,setMaxListeners}from"node:events";import{DisconnectReason,downloadMediaMessage,extractMessageContent,getContentType,isJidGroup,normalizeMessageContent}from"@whiskeysockets/baileys";const DEFAULT_RECONNECT_POLICY={initialMs:2e3,maxMs:3e4,factor:1.8,jitter:.25,maxAttempts:12};function resolveHeartbeatSeconds(cfg,overrideSeconds){let candidate=overrideSeconds??cfg.web?.heartbeatSeconds;return typeof candidate==`number`&&candidate>0?candidate:60}function resolveReconnectPolicy(cfg,overrides){let reconnectOverrides=cfg.web?.reconnect??{},overrideConfig=overrides??{},merged={...DEFAULT_RECONNECT_POLICY,...reconnectOverrides,...overrideConfig};return merged.initialMs=Math.max(250,merged.initialMs),merged.maxMs=Math.max(merged.initialMs,merged.maxMs),merged.factor=clamp(merged.factor,1.1,10),merged.jitter=clamp(merged.jitter,0,1),merged.maxAttempts=Math.max(0,Math.floor(merged.maxAttempts)),merged}function newConnectionId(){return randomUUID()}const whatsappLog=createSubsystemLogger(`gateway/channels/whatsapp`),whatsappInboundLog=whatsappLog.child(`inbound`),whatsappOutboundLog=whatsappLog.child(`outbound`),whatsappHeartbeatLog=whatsappLog.child(`heartbeat`);function elide(text,limit=400){return!text||text.length<=limit?text:`${text.slice(0,limit)}… (truncated ${text.length-limit} chars)`}function isLikelyWhatsAppCryptoError(reason){let haystack=(reason instanceof Error?`${reason.message}\n${reason.stack??``}`:(value=>{if(value==null)return``;if(typeof value==`string`)return value;if(value instanceof Error)return`${value.message}\n${value.stack??``}`;if(typeof value==`object`)try{return JSON.stringify(value)}catch{return Object.prototype.toString.call(value)}return typeof value==`number`||typeof value==`boolean`||typeof value==`bigint`?String(value):typeof value==`symbol`?value.description??value.toString():typeof value==`function`?value.name?`[function ${value.name}]`:`[function]`:Object.prototype.toString.call(value)})(reason)).toLowerCase();return haystack.includes(`unsupported state or unable to authenticate data`)||haystack.includes(`bad mac`)?haystack.includes(`@whiskeysockets/baileys`)||haystack.includes(`baileys`)||haystack.includes(`noise-handler`)||haystack.includes(`aesdecryptgcm`):!1}function waitForever(){return setInterval(()=>{},1e6).unref(),new Promise(()=>{})}const recentInboundMessages=createDedupeCache({ttlMs:20*6e4,maxSize:5e3});function isRecentInboundMessage(key){return recentInboundMessages.check(key)}const ALLOWED_VCARD_KEYS=new Set([`FN`,`N`,`TEL`]);function parseVcard(vcard){if(!vcard)return{phones:[]};let lines=vcard.split(/\r?\n/),nameFromN,nameFromFn,phones=[];for(let rawLine of lines){let line=rawLine.trim();if(!line)continue;let colonIndex=line.indexOf(`:`);if(colonIndex===-1)continue;let key=line.slice(0,colonIndex).toUpperCase(),rawValue=line.slice(colonIndex+1).trim();if(!rawValue)continue;let baseKey=normalizeVcardKey(key);if(!baseKey||!ALLOWED_VCARD_KEYS.has(baseKey))continue;let value=cleanVcardValue(rawValue);if(value){if(baseKey===`FN`&&!nameFromFn){nameFromFn=normalizeVcardName(value);continue}if(baseKey===`N`&&!nameFromN){nameFromN=normalizeVcardName(value);continue}if(baseKey===`TEL`){let phone=normalizeVcardPhone(value);phone&&phones.push(phone)}}}return{name:nameFromFn??nameFromN,phones}}function normalizeVcardKey(key){let[primary]=key.split(`;`);if(!primary)return;let segments=primary.split(`.`);return segments[segments.length-1]||void 0}function cleanVcardValue(value){return value.replace(/\\n/gi,` `).replace(/\\,/g,`,`).replace(/\\;/g,`;`).trim()}function normalizeVcardName(value){return value.replace(/;/g,` `).replace(/\s+/g,` `).trim()}function normalizeVcardPhone(value){let trimmed=value.trim();return trimmed?trimmed.toLowerCase().startsWith(`tel:`)?trimmed.slice(4).trim():trimmed:``}function unwrapMessage$1(message){return normalizeMessageContent(message)}function extractContextInfo(message){if(!message)return;let contentType=getContentType(message),candidate=contentType?message[contentType]:void 0,contextInfo=candidate&&typeof candidate==`object`&&`contextInfo`in candidate?candidate.contextInfo:void 0;if(contextInfo)return contextInfo;let fallback=message.extendedTextMessage?.contextInfo??message.imageMessage?.contextInfo??message.videoMessage?.contextInfo??message.documentMessage?.contextInfo??message.audioMessage?.contextInfo??message.stickerMessage?.contextInfo??message.buttonsResponseMessage?.contextInfo??message.listResponseMessage?.contextInfo??message.templateButtonReplyMessage?.contextInfo??message.interactiveResponseMessage?.contextInfo??message.buttonsMessage?.contextInfo??message.listMessage?.contextInfo;if(fallback)return fallback;for(let value of Object.values(message)){if(!value||typeof value!=`object`||!(`contextInfo`in value))continue;let candidateContext=value.contextInfo;if(candidateContext)return candidateContext}}function extractMentionedJids(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let flattened=[message.extendedTextMessage?.contextInfo?.mentionedJid,message.extendedTextMessage?.contextInfo?.quotedMessage?.extendedTextMessage?.contextInfo?.mentionedJid,message.imageMessage?.contextInfo?.mentionedJid,message.videoMessage?.contextInfo?.mentionedJid,message.documentMessage?.contextInfo?.mentionedJid,message.audioMessage?.contextInfo?.mentionedJid,message.stickerMessage?.contextInfo?.mentionedJid,message.buttonsResponseMessage?.contextInfo?.mentionedJid,message.listResponseMessage?.contextInfo?.mentionedJid].flatMap(arr=>arr??[]).filter(Boolean);if(flattened.length!==0)return Array.from(new Set(flattened))}function extractText(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let extracted=extractMessageContent(message),candidates=[message,extracted&&extracted!==message?extracted:void 0];for(let candidate of candidates){if(!candidate)continue;if(typeof candidate.conversation==`string`&&candidate.conversation.trim())return candidate.conversation.trim();let extended=candidate.extendedTextMessage?.text;if(extended?.trim())return extended.trim();let caption=candidate.imageMessage?.caption??candidate.videoMessage?.caption??candidate.documentMessage?.caption;if(caption?.trim())return caption.trim()}let contactPlaceholder=extractContactPlaceholder(message)??(extracted&&extracted!==message?extractContactPlaceholder(extracted):void 0);if(contactPlaceholder)return contactPlaceholder}function extractMediaPlaceholder(rawMessage){let message=unwrapMessage$1(rawMessage);if(message){if(message.imageMessage)return`<media:image>`;if(message.videoMessage)return`<media:video>`;if(message.audioMessage)return`<media:audio>`;if(message.documentMessage)return`<media:document>`;if(message.stickerMessage)return`<media:sticker>`}}function extractContactPlaceholder(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return;let contact=message.contactMessage??void 0;if(contact){let{name,phones}=describeContact({displayName:contact.displayName,vcard:contact.vcard});return formatContactPlaceholder(name,phones)}let contactsArray=message.contactsArrayMessage?.contacts??void 0;if(!(!contactsArray||contactsArray.length===0))return formatContactsPlaceholder(contactsArray.map(entry=>describeContact({displayName:entry.displayName,vcard:entry.vcard})).map(entry=>formatContactLabel(entry.name,entry.phones)).filter(value=>!!value),contactsArray.length)}function describeContact(input){let displayName=(input.displayName??``).trim(),parsed=parseVcard(input.vcard??void 0);return{name:displayName||parsed.name,phones:parsed.phones}}function formatContactPlaceholder(name,phones){let label=formatContactLabel(name,phones);return label?`<contact: ${label}>`:`<contact>`}function formatContactsPlaceholder(labels,total){let cleaned=labels.map(label=>label.trim()).filter(Boolean);if(cleaned.length===0)return`<contacts: ${total} ${total===1?`contact`:`contacts`}>`;let remaining=Math.max(total-cleaned.length,0),suffix=remaining>0?` +${remaining} more`:``;return`<contacts: ${cleaned.join(`, `)}${suffix}>`}function formatContactLabel(name,phones){let parts=[name,formatPhoneList(phones)].filter(value=>!!value);if(parts.length!==0)return parts.join(`, `)}function formatPhoneList(phones){let cleaned=phones?.map(phone=>phone.trim()).filter(Boolean)??[];if(cleaned.length===0)return;let{shown,remaining}=summarizeList(cleaned,cleaned.length,1),[primary]=shown;if(primary)return remaining===0?primary:`${primary} (+${remaining} more)`}function summarizeList(values,total,maxShown){let shown=values.slice(0,maxShown);return{shown,remaining:Math.max(total-shown.length,0)}}function extractLocationData(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return null;let live=message.liveLocationMessage??void 0;if(live){let latitudeRaw=live.degreesLatitude,longitudeRaw=live.degreesLongitude;if(latitudeRaw!=null&&longitudeRaw!=null){let latitude=Number(latitudeRaw),longitude=Number(longitudeRaw);if(Number.isFinite(latitude)&&Number.isFinite(longitude))return{latitude,longitude,accuracy:live.accuracyInMeters??void 0,caption:live.caption??void 0,source:`live`,isLive:!0}}}let location=message.locationMessage??void 0;if(location){let latitudeRaw=location.degreesLatitude,longitudeRaw=location.degreesLongitude;if(latitudeRaw!=null&&longitudeRaw!=null){let latitude=Number(latitudeRaw),longitude=Number(longitudeRaw);if(Number.isFinite(latitude)&&Number.isFinite(longitude)){let isLive=!!location.isLive;return{latitude,longitude,accuracy:location.accuracyInMeters??void 0,name:location.name??void 0,address:location.address??void 0,caption:location.comment??void 0,source:isLive?`live`:location.name||location.address?`place`:`pin`,isLive}}}}return null}function describeReplyContext(rawMessage){let message=unwrapMessage$1(rawMessage);if(!message)return null;let contextInfo=extractContextInfo(message),quoted=normalizeMessageContent(contextInfo?.quotedMessage);if(!quoted)return null;let location=extractLocationData(quoted),locationText=location?formatLocationText(location):void 0,body=[extractText(quoted),locationText].filter(Boolean).join(`
2
2
  `).trim();if(body||=extractMediaPlaceholder(quoted),!body){let quotedType=quoted?getContentType(quoted):void 0;return logVerbose(`Quoted message missing extractable body${quotedType?` (type ${quotedType})`:``}`),null}let senderJid=contextInfo?.participant??void 0,senderE164=senderJid?jidToE164(senderJid)??senderJid:void 0,sender=senderE164??`unknown sender`;return{id:contextInfo?.stanzaId?String(contextInfo.stanzaId):void 0,body,sender,senderJid,senderE164}}async function checkInboundAccessControl(params){let cfg=loadConfig(),account=resolveWhatsAppAccount({cfg,accountId:params.accountId}),dmPolicy=account.dmPolicy??`pairing`,configuredAllowFrom=account.allowFrom,storeAllowFrom=await readChannelAllowFromStore(`whatsapp`,process.env,account.accountId).catch(()=>[]),combinedAllowFrom=Array.from(new Set([...configuredAllowFrom??[],...storeAllowFrom])),defaultAllowFrom=combinedAllowFrom.length===0&&params.selfE164?[params.selfE164]:void 0,allowFrom=combinedAllowFrom.length>0?combinedAllowFrom:defaultAllowFrom,groupAllowFrom=account.groupAllowFrom??(configuredAllowFrom&&configuredAllowFrom.length>0?configuredAllowFrom:void 0),isSamePhone=params.from===params.selfE164,isSelfChat=isSelfChatMode(params.selfE164,configuredAllowFrom),pairingGraceMs=typeof params.pairingGraceMs==`number`&&params.pairingGraceMs>0?params.pairingGraceMs:3e4,suppressPairingReply=typeof params.connectedAtMs==`number`&&typeof params.messageTimestampMs==`number`&&params.messageTimestampMs<params.connectedAtMs-pairingGraceMs,dmHasWildcard=allowFrom?.includes(`*`)??!1,normalizedAllowFrom=allowFrom&&allowFrom.length>0?allowFrom.filter(entry=>entry!==`*`).map(normalizeE164):[],groupHasWildcard=groupAllowFrom?.includes(`*`)??!1,normalizedGroupAllowFrom=groupAllowFrom&&groupAllowFrom.length>0?groupAllowFrom.filter(entry=>entry!==`*`).map(normalizeE164):[],defaultGroupPolicy=cfg.channels?.defaults?.groupPolicy,groupPolicy=account.groupPolicy??defaultGroupPolicy??`open`;if(params.group&&groupPolicy===`disabled`)return logVerbose(`Blocked group message (groupPolicy: disabled)`),{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId};if(params.group&&groupPolicy===`allowlist`){if(!groupAllowFrom||groupAllowFrom.length===0)return logVerbose(`Blocked group message (groupPolicy: allowlist, no groupAllowFrom)`),{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId};if(!(groupHasWildcard||params.senderE164!=null&&normalizedGroupAllowFrom.includes(params.senderE164)))return logVerbose(`Blocked group message from ${params.senderE164??`unknown sender`} (groupPolicy: allowlist)`),{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId}}if(!params.group){if(params.isFromMe&&!isSamePhone)return logVerbose(`Skipping outbound DM (fromMe); no pairing reply needed.`),{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId};if(dmPolicy===`disabled`)return logVerbose(`Blocked dm (dmPolicy: disabled)`),{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId};if(dmPolicy!==`open`&&!isSamePhone){let candidate=params.from;if(!(dmHasWildcard||normalizedAllowFrom.length>0&&normalizedAllowFrom.includes(candidate))){if(dmPolicy===`pairing`)if(suppressPairingReply)logVerbose(`Skipping pairing reply for historical DM from ${candidate}.`);else{let{code,created}=await upsertChannelPairingRequest({channel:`whatsapp`,id:candidate,accountId:account.accountId,meta:{name:(params.pushName??``).trim()||void 0}});if(created){logVerbose(`whatsapp pairing request sender=${candidate} name=${params.pushName??`unknown`}`);try{await params.sock.sendMessage(params.remoteJid,{text:buildPairingReply({channel:`whatsapp`,idLine:`Your WhatsApp phone number: ${candidate}`,code})})}catch(err){logVerbose(`whatsapp pairing reply failed for ${candidate}: ${String(err)}`)}}}else logVerbose(`Blocked unauthorized sender ${candidate} (dmPolicy=${dmPolicy})`);return{allowed:!1,shouldMarkRead:!1,isSelfChat,resolvedAccountId:account.accountId}}}}return{allowed:!0,shouldMarkRead:!0,isSelfChat,resolvedAccountId:account.accountId}}function unwrapMessage(message){return normalizeMessageContent(message)}function resolveMediaMimetype(message){let explicit=message.imageMessage?.mimetype??message.videoMessage?.mimetype??message.documentMessage?.mimetype??message.audioMessage?.mimetype??message.stickerMessage?.mimetype??void 0;if(explicit)return explicit;if(message.audioMessage)return`audio/ogg; codecs=opus`;if(message.imageMessage)return`image/jpeg`;if(message.videoMessage)return`video/mp4`;if(message.stickerMessage)return`image/webp`}async function downloadInboundMedia(msg,sock){let message=unwrapMessage(msg.message);if(!message)return;let mimetype=resolveMediaMimetype(message),fileName=message.documentMessage?.fileName??void 0;if(!(!message.imageMessage&&!message.videoMessage&&!message.documentMessage&&!message.audioMessage&&!message.stickerMessage))try{return{buffer:await downloadMediaMessage(msg,`buffer`,{},{reuploadRequest:sock.updateMediaMessage,logger:sock.logger}),mimetype,fileName}}catch(err){logVerbose(`downloadMediaMessage failed: ${String(err)}`);return}}function recordWhatsAppOutbound(accountId){recordChannelActivity({channel:`whatsapp`,accountId,direction:`outbound`})}function resolveOutboundMessageId(result){return typeof result==`object`&&result&&`key`in result?String(result.key?.id??`unknown`):`unknown`}function createWebSendApi(params){return{sendMessage:async(to,text,mediaBuffer,mediaType,sendOptions)=>{let jid=toWhatsappJid(to),payload;if(mediaBuffer&&mediaType)if(mediaType.startsWith(`image/`))payload={image:mediaBuffer,caption:text||void 0,mimetype:mediaType};else if(mediaType.startsWith(`audio/`))payload={audio:mediaBuffer,ptt:!0,mimetype:mediaType};else if(mediaType.startsWith(`video/`)){let gifPlayback=sendOptions?.gifPlayback;payload={video:mediaBuffer,caption:text||void 0,mimetype:mediaType,...gifPlayback?{gifPlayback:!0}:{}}}else payload={document:mediaBuffer,fileName:sendOptions?.fileName?.trim()||`file`,caption:text||void 0,mimetype:mediaType};else payload={text};let result=await params.sock.sendMessage(jid,payload);return recordWhatsAppOutbound(sendOptions?.accountId??params.defaultAccountId),{messageId:resolveOutboundMessageId(result)}},sendPoll:async(to,poll)=>{let jid=toWhatsappJid(to),result=await params.sock.sendMessage(jid,{poll:{name:poll.question,values:poll.options,selectableCount:poll.maxSelections??1}});return recordWhatsAppOutbound(params.defaultAccountId),{messageId:resolveOutboundMessageId(result)}},sendReaction:async(chatJid,messageId,emoji,fromMe,participant)=>{let jid=toWhatsappJid(chatJid);await params.sock.sendMessage(jid,{react:{text:emoji,key:{remoteJid:jid,id:messageId,fromMe,participant:participant?toWhatsappJid(participant):void 0}}})},sendComposingTo:async to=>{let jid=toWhatsappJid(to);await params.sock.sendPresenceUpdate(`composing`,jid)}}}async function monitorWebInbox(options){let inboundLogger=getChildLogger({module:`web-inbound`}),inboundConsoleLog=createSubsystemLogger(`gateway/channels/whatsapp`).child(`inbound`),sock=await createWaSocket(!1,options.verbose,{authDir:options.authDir});await waitForWaConnection(sock);let connectedAtMs=Date.now(),onCloseResolve=null,onClose=new Promise(resolve=>{onCloseResolve=resolve}),resolveClose=reason=>{if(!onCloseResolve)return;let resolver=onCloseResolve;onCloseResolve=null,resolver(reason)};try{await sock.sendPresenceUpdate(`available`),shouldLogVerbose()&&logVerbose(`Sent global 'available' presence on connect`)}catch(err){logVerbose(`Failed to send 'available' presence on connect: ${String(err)}`)}let selfJid=sock.user?.id,selfE164=selfJid?jidToE164(selfJid):null,debouncer=createInboundDebouncer({debounceMs:options.debounceMs??0,buildKey:msg=>{let senderKey=msg.chatType===`group`?msg.senderJid??msg.senderE164??msg.senderName??msg.from:msg.from;if(!senderKey)return null;let conversationKey=msg.chatType===`group`?msg.chatId:msg.from;return`${msg.accountId}:${conversationKey}:${senderKey}`},shouldDebounce:options.shouldDebounce,onFlush:async entries=>{let last=entries.at(-1);if(!last)return;if(entries.length===1){await options.onMessage(last);return}let mentioned=new Set;for(let entry of entries)for(let jid of entry.mentionedJids??[])mentioned.add(jid);let combinedBody=entries.map(entry=>entry.body).filter(Boolean).join(`
3
3
  `),combinedMessage={...last,body:combinedBody,mentionedJids:mentioned.size>0?Array.from(mentioned):void 0};await options.onMessage(combinedMessage)},onError:err=>{inboundLogger.error({error:String(err)},`failed handling inbound web message`),inboundConsoleLog.error(`Failed handling inbound web message: ${String(err)}`)}}),groupMetaCache=new Map,GROUP_META_TTL_MS=300*1e3,lidLookup=sock.signalRepository?.lidMapping,resolveInboundJid=async jid=>resolveJidToE164(jid,{authDir:options.authDir,lidLookup}),getGroupMeta=async jid=>{let cached=groupMetaCache.get(jid);if(cached&&cached.expires>Date.now())return cached;try{let meta=await sock.groupMetadata(jid),participants=(await Promise.all(meta.participants?.map(async p=>await resolveInboundJid(p.id)??p.id)??[])).filter(Boolean)??[],entry={subject:meta.subject,participants,expires:Date.now()+GROUP_META_TTL_MS};return groupMetaCache.set(jid,entry),entry}catch(err){return logVerbose(`Failed to fetch group metadata for ${jid}: ${String(err)}`),{expires:Date.now()+GROUP_META_TTL_MS}}},handleMessagesUpsert=async upsert=>{if(!(upsert.type!==`notify`&&upsert.type!==`append`))for(let msg of upsert.messages??[]){recordChannelActivity({channel:`whatsapp`,accountId:options.accountId,direction:`inbound`});let id=msg.key?.id??void 0,remoteJid=msg.key?.remoteJid;if(!remoteJid||remoteJid.endsWith(`@status`)||remoteJid.endsWith(`@broadcast`))continue;let group=isJidGroup(remoteJid)===!0;if(id&&isRecentInboundMessage(`${options.accountId}:${remoteJid}:${id}`))continue;let participantJid=msg.key?.participant??void 0,from=group?remoteJid:await resolveInboundJid(remoteJid);if(!from)continue;let senderE164=group?participantJid?await resolveInboundJid(participantJid):null:from,groupSubject,groupParticipants;if(group){let meta=await getGroupMeta(remoteJid);groupSubject=meta.subject,groupParticipants=meta.participants}let messageTimestampMs=msg.messageTimestamp?Number(msg.messageTimestamp)*1e3:void 0,access=await checkInboundAccessControl({accountId:options.accountId,from,selfE164,senderE164,group,pushName:msg.pushName??void 0,isFromMe:!!msg.key?.fromMe,messageTimestampMs,connectedAtMs,sock:{sendMessage:(jid,content)=>sock.sendMessage(jid,content)},remoteJid});if(!access.allowed)continue;if(id&&!access.isSelfChat&&options.sendReadReceipts!==!1){let participant=msg.key?.participant;try{await sock.readMessages([{remoteJid,id,participant,fromMe:!1}]),shouldLogVerbose()&&logVerbose(`Marked message ${id} as read for ${remoteJid}${participant?` (participant ${participant})`:``}`)}catch(err){logVerbose(`Failed to mark message ${id} read: ${String(err)}`)}}else id&&access.isSelfChat&&shouldLogVerbose()&&logVerbose(`Self-chat mode: skipping read receipt for ${id}`);if(upsert.type===`append`)continue;let location=extractLocationData(msg.message??void 0),locationText=location?formatLocationText(location):void 0,body=extractText(msg.message??void 0);if(locationText&&(body=[body,locationText].filter(Boolean).join(`
4
4
  `).trim()),!body&&(body=extractMediaPlaceholder(msg.message??void 0),!body))continue;let replyContext=describeReplyContext(msg.message),mediaPath,mediaType,mediaFileName;try{let inboundMedia=await downloadInboundMedia(msg,sock);if(inboundMedia){let maxBytes=(typeof options.mediaMaxMb==`number`&&options.mediaMaxMb>0?options.mediaMaxMb:50)*1024*1024;mediaPath=(await saveMediaBuffer(inboundMedia.buffer,inboundMedia.mimetype,`inbound`,maxBytes,inboundMedia.fileName)).path,mediaType=inboundMedia.mimetype,mediaFileName=inboundMedia.fileName}}catch(err){logVerbose(`Inbound media download failed: ${String(err)}`)}let chatJid=remoteJid,sendComposing=async()=>{try{await sock.sendPresenceUpdate(`composing`,chatJid)}catch(err){logVerbose(`Presence update failed: ${String(err)}`)}},reply=async text=>{await sock.sendMessage(chatJid,{text})},sendMedia=async payload=>{await sock.sendMessage(chatJid,payload)},timestamp=messageTimestampMs,mentionedJids=extractMentionedJids(msg.message),senderName=msg.pushName??void 0;inboundLogger.info({from,to:selfE164??`me`,body,mediaPath,mediaType,mediaFileName,timestamp},`inbound message`);let inboundMessage={id,from,conversationId:from,to:selfE164??`me`,accountId:access.resolvedAccountId,body,pushName:senderName,timestamp,chatType:group?`group`:`direct`,chatId:remoteJid,senderJid:participantJid,senderE164:senderE164??void 0,senderName,replyToId:replyContext?.id,replyToBody:replyContext?.body,replyToSender:replyContext?.sender,replyToSenderJid:replyContext?.senderJid,replyToSenderE164:replyContext?.senderE164,groupSubject,groupParticipants,mentionedJids:mentionedJids??void 0,selfJid,selfE164,location:location??void 0,sendComposing,reply,sendMedia,mediaPath,mediaType,mediaFileName};try{Promise.resolve(debouncer.enqueue(inboundMessage)).catch(err=>{inboundLogger.error({error:String(err)},`failed handling inbound web message`),inboundConsoleLog.error(`Failed handling inbound web message: ${String(err)}`)})}catch(err){inboundLogger.error({error:String(err)},`failed handling inbound web message`),inboundConsoleLog.error(`Failed handling inbound web message: ${String(err)}`)}}};sock.ev.on(`messages.upsert`,handleMessagesUpsert);let handleConnectionUpdate=update=>{try{if(update.connection===`close`){let status=getStatusCode(update.lastDisconnect?.error);resolveClose({status,isLoggedOut:status===DisconnectReason.loggedOut,error:update.lastDisconnect?.error})}}catch(err){inboundLogger.error({error:String(err)},`connection.update handler error`),resolveClose({status:void 0,isLoggedOut:!1,error:err})}};return sock.ev.on(`connection.update`,handleConnectionUpdate),{close:async()=>{try{let ev=sock.ev,messagesUpsertHandler=handleMessagesUpsert,connectionUpdateHandler=handleConnectionUpdate;typeof ev.off==`function`?(ev.off(`messages.upsert`,messagesUpsertHandler),ev.off(`connection.update`,connectionUpdateHandler)):typeof ev.removeListener==`function`&&(ev.removeListener(`messages.upsert`,messagesUpsertHandler),ev.removeListener(`connection.update`,connectionUpdateHandler)),sock.ws?.close()}catch(err){logVerbose(`Socket close failed: ${String(err)}`)}},onClose,signalClose:reason=>{resolveClose(reason??{status:void 0,isLoggedOut:!1,error:`closed`})},...createWebSendApi({sock:{sendMessage:(jid,content)=>sock.sendMessage(jid,content),sendPresenceUpdate:(presence,jid)=>sock.sendPresenceUpdate(presence,jid)},defaultAccountId:options.accountId})}}function buildMentionConfig(cfg,agentId){return{mentionRegexes:buildMentionRegexes(cfg,agentId),allowFrom:cfg.channels?.whatsapp?.allowFrom}}function resolveMentionTargets(msg,authDir){let jidOptions=authDir?{authDir}:void 0;return{normalizedMentions:msg.mentionedJids?.length?msg.mentionedJids.map(jid=>jidToE164(jid,jidOptions)??jid).filter(Boolean):[],selfE164:msg.selfE164??(msg.selfJid?jidToE164(msg.selfJid,jidOptions):null),selfJid:msg.selfJid?msg.selfJid.replace(/:\\d+/,``):null}}function isBotMentionedFromTargets(msg,mentionCfg,targets){let clean=text=>normalizeMentionText(text),isSelfChat=isSelfChatMode(targets.selfE164,mentionCfg.allowFrom);if((msg.mentionedJids?.length??0)>0&&!isSelfChat)return!!(targets.selfE164&&targets.normalizedMentions.includes(targets.selfE164)||targets.selfJid&&targets.normalizedMentions.includes(targets.selfJid));let bodyClean=clean(msg.body);if(mentionCfg.mentionRegexes.some(re=>re.test(bodyClean)))return!0;if(targets.selfE164){let selfDigits=targets.selfE164.replace(/\D/g,``);if(selfDigits){if(bodyClean.replace(/[^\d]/g,``).includes(selfDigits))return!0;let bodyNoSpace=msg.body.replace(/[\s-]/g,``);if(RegExp(`\\+?${selfDigits}`,`i`).test(bodyNoSpace))return!0}}return!1}function debugMention(msg,mentionCfg,authDir){let mentionTargets=resolveMentionTargets(msg,authDir);return{wasMentioned:isBotMentionedFromTargets(msg,mentionCfg,mentionTargets),details:{from:msg.from,body:msg.body,bodyClean:normalizeMentionText(msg.body),mentionedJids:msg.mentionedJids??null,normalizedMentionedJids:mentionTargets.normalizedMentions.length?mentionTargets.normalizedMentions:null,selfJid:msg.selfJid??null,selfJidBare:mentionTargets.selfJid,selfE164:msg.selfE164??null,resolvedSelfE164:mentionTargets.selfE164}}}function resolveOwnerList(mentionCfg,selfE164){let allowFrom=mentionCfg.allowFrom;return(Array.isArray(allowFrom)&&allowFrom.length>0?allowFrom:selfE164?[selfE164]:[]).filter(entry=>!!(entry&&entry!==`*`)).map(entry=>normalizeE164(entry)).filter(entry=>!!entry)}function createEchoTracker(params){let recentlySent=new Set,maxItems=Math.max(1,params.maxItems??100),buildCombinedKey=p=>`combined:${p.sessionKey}:${p.combinedBody}`,trim=()=>{for(;recentlySent.size>maxItems;){let firstKey=recentlySent.values().next().value;if(!firstKey)break;recentlySent.delete(firstKey)}};return{rememberText:(text,opts)=>{text&&(recentlySent.add(text),opts.combinedBody&&opts.combinedBodySessionKey&&recentlySent.add(buildCombinedKey({sessionKey:opts.combinedBodySessionKey,combinedBody:opts.combinedBody})),opts.logVerboseMessage&&params.logVerbose?.(`Added to echo detection set (size now: ${recentlySent.size}): ${text.substring(0,50)}...`),trim())},has:key=>recentlySent.has(key),forget:key=>{recentlySent.delete(key)},buildCombinedKey}}async function maybeBroadcastMessage(params){let broadcastAgents=params.cfg.broadcast?.[params.peerId];if(!broadcastAgents||!Array.isArray(broadcastAgents)||broadcastAgents.length===0)return!1;let strategy=params.cfg.broadcast?.strategy||`parallel`;whatsappInboundLog.info(`Broadcasting message to ${broadcastAgents.length} agents (${strategy})`);let agentIds=params.cfg.agents?.list?.map(agent=>normalizeAgentId(agent.id)),hasKnownAgents=(agentIds?.length??0)>0,groupHistorySnapshot=params.msg.chatType===`group`?params.groupHistories.get(params.groupHistoryKey)??[]:void 0,processForAgent=async agentId=>{let normalizedAgentId=normalizeAgentId(agentId);if(hasKnownAgents&&!agentIds?.includes(normalizedAgentId))return whatsappInboundLog.warn(`Broadcast agent ${agentId} not found in agents.list; skipping`),!1;let agentRoute={...params.route,agentId:normalizedAgentId,sessionKey:buildAgentSessionKey({agentId:normalizedAgentId,channel:`whatsapp`,accountId:params.route.accountId,peer:{kind:params.msg.chatType===`group`?`group`:`direct`,id:params.peerId},dmScope:params.cfg.session?.dmScope,identityLinks:params.cfg.session?.identityLinks}),mainSessionKey:buildAgentMainSessionKey({agentId:normalizedAgentId,mainKey:DEFAULT_MAIN_KEY})};try{return await params.processMessage(params.msg,agentRoute,params.groupHistoryKey,{groupHistory:groupHistorySnapshot,suppressGroupHistoryClear:!0})}catch(err){return whatsappInboundLog.error(`Broadcast agent ${agentId} failed: ${formatError(err)}`),!1}};if(strategy===`sequential`)for(let agentId of broadcastAgents)await processForAgent(agentId);else await Promise.allSettled(broadcastAgents.map(processForAgent));return params.msg.chatType===`group`&&params.groupHistories.set(params.groupHistoryKey,[]),!0}function stripMentionsForCommand(text,mentionRegexes,selfE164){let result=text;for(let re of mentionRegexes)result=result.replace(re,` `);if(selfE164){let digits=selfE164.replace(/\D/g,``);if(digits){let pattern=RegExp(`\\+?${digits}`,`g`);result=result.replace(pattern,` `)}}return result.replace(/\s+/g,` `).trim()}function resolveGroupPolicyFor(cfg,conversationId){let groupId=resolveGroupSessionKey({From:conversationId,ChatType:`group`,Provider:`whatsapp`})?.id;return resolveChannelGroupPolicy({cfg,channel:`whatsapp`,groupId:groupId??conversationId})}function resolveGroupRequireMentionFor(cfg,conversationId){let groupId=resolveGroupSessionKey({From:conversationId,ChatType:`group`,Provider:`whatsapp`})?.id;return resolveChannelGroupRequireMention({cfg,channel:`whatsapp`,groupId:groupId??conversationId})}function resolveGroupActivationFor(params){let entry=loadSessionStore(resolveStorePath(params.cfg.session?.store,{agentId:params.agentId}))[params.sessionKey],defaultActivation=resolveGroupRequireMentionFor(params.cfg,params.conversationId)?`mention`:`always`;return normalizeGroupActivation(entry?.groupActivation)??defaultActivation}function noteGroupMember(groupMemberNames,conversationId,e164,name){if(!e164||!name)return;let key=normalizeE164(e164)??e164;if(!key)return;let roster=groupMemberNames.get(conversationId);roster||(roster=new Map,groupMemberNames.set(conversationId,roster)),roster.set(key,name)}function formatGroupMembers(params){let{participants,roster,fallbackE164}=params,seen=new Set,ordered=[];if(participants?.length)for(let entry of participants){if(!entry)continue;let normalized=normalizeE164(entry)??entry;!normalized||seen.has(normalized)||(seen.add(normalized),ordered.push(normalized))}if(roster)for(let entry of roster.keys()){let normalized=normalizeE164(entry)??entry;!normalized||seen.has(normalized)||(seen.add(normalized),ordered.push(normalized))}if(ordered.length===0&&fallbackE164){let normalized=normalizeE164(fallbackE164)??fallbackE164;normalized&&ordered.push(normalized)}if(ordered.length!==0)return ordered.map(entry=>{let name=roster?.get(entry);return name?`${name} (${entry})`:entry}).join(`, `)}function isOwnerSender(baseMentionConfig,msg){let sender=normalizeE164(msg.senderE164??``);return sender?resolveOwnerList(baseMentionConfig,msg.selfE164??void 0).includes(sender):!1}function recordPendingGroupHistoryEntry(params){let sender=params.msg.senderName&&params.msg.senderE164?`${params.msg.senderName} (${params.msg.senderE164})`:params.msg.senderName??params.msg.senderE164??`Unknown`;recordPendingHistoryEntryIfEnabled({historyMap:params.groupHistories,historyKey:params.groupHistoryKey,limit:params.groupHistoryLimit,entry:{sender,body:params.msg.body,timestamp:params.msg.timestamp,id:params.msg.id,senderJid:params.msg.senderJid}})}function applyGroupGating(params){let groupPolicy=resolveGroupPolicyFor(params.cfg,params.conversationId);if(groupPolicy.allowlistEnabled&&!groupPolicy.allowed)return params.logVerbose(`Skipping group message ${params.conversationId} (not in allowlist)`),{shouldProcess:!1};noteGroupMember(params.groupMemberNames,params.groupHistoryKey,params.msg.senderE164,params.msg.senderName);let mentionConfig=buildMentionConfig(params.cfg,params.agentId),commandBody=stripMentionsForCommand(params.msg.body,mentionConfig.mentionRegexes,params.msg.selfE164),activationCommand=parseActivationCommand(commandBody),owner=isOwnerSender(params.baseMentionConfig,params.msg),shouldBypassMention=owner&&hasControlCommand(commandBody,params.cfg);if(activationCommand.hasCommand&&!owner)return params.logVerbose(`Ignoring /activation from non-owner in group ${params.conversationId}`),recordPendingGroupHistoryEntry({msg:params.msg,groupHistories:params.groupHistories,groupHistoryKey:params.groupHistoryKey,groupHistoryLimit:params.groupHistoryLimit}),{shouldProcess:!1};let mentionDebug=debugMention(params.msg,mentionConfig,params.authDir);params.replyLogger.debug({conversationId:params.conversationId,wasMentioned:mentionDebug.wasMentioned,...mentionDebug.details},`group mention debug`);let wasMentioned=mentionDebug.wasMentioned,requireMention=resolveGroupActivationFor({cfg:params.cfg,agentId:params.agentId,sessionKey:params.sessionKey,conversationId:params.conversationId})!==`always`,selfJid=params.msg.selfJid?.replace(/:\\d+/,``),replySenderJid=params.msg.replyToSenderJid?.replace(/:\\d+/,``),selfE164=params.msg.selfE164?normalizeE164(params.msg.selfE164):null,replySenderE164=params.msg.replyToSenderE164?normalizeE164(params.msg.replyToSenderE164):null,mentionGate=resolveMentionGating({requireMention,canDetectMention:!0,wasMentioned,implicitMention:!!(selfJid&&replySenderJid&&selfJid===replySenderJid||selfE164&&replySenderE164&&selfE164===replySenderE164),shouldBypassMention});return params.msg.wasMentioned=mentionGate.effectiveWasMentioned,!shouldBypassMention&&requireMention&&mentionGate.shouldSkip?(params.logVerbose(`Group message stored for context (no mention detected) in ${params.conversationId}: ${params.msg.body}`),recordPendingGroupHistoryEntry({msg:params.msg,groupHistories:params.groupHistories,groupHistoryKey:params.groupHistoryKey,groupHistoryLimit:params.groupHistoryLimit}),{shouldProcess:!1}):{shouldProcess:!0}}function trackBackgroundTask(backgroundTasks,task){backgroundTasks.add(task),task.finally(()=>{backgroundTasks.delete(task)})}function updateLastRouteInBackground(params){let storePath=resolveStorePath(params.cfg.session?.store,{agentId:params.storeAgentId}),task=updateLastRoute({storePath,sessionKey:params.sessionKey,deliveryContext:{channel:params.channel,to:params.to,accountId:params.accountId},ctx:params.ctx}).catch(err=>{params.warn({error:formatError(err),storePath,sessionKey:params.sessionKey,to:params.to},`failed updating last route`)});trackBackgroundTask(params.backgroundTasks,task)}function resolvePeerId(msg){return msg.chatType===`group`?msg.conversationId??msg.from:msg.senderE164?normalizeE164(msg.senderE164)??msg.senderE164:msg.from.includes(`@`)?jidToE164(msg.from)??msg.from:normalizeE164(msg.from)??msg.from}async function deliverWebReply(params){let{replyResult,msg,maxMediaBytes,textLimit,replyLogger,connectionId,skipLog}=params,replyStarted=Date.now(),tableMode=params.tableMode??`code`,chunkMode=params.chunkMode??`length`,textChunks=chunkMarkdownTextWithMode(markdownToWhatsApp(convertMarkdownTables(replyResult.text||``,tableMode)),textLimit,chunkMode),mediaList=replyResult.mediaUrls?.length?replyResult.mediaUrls:replyResult.mediaUrl?[replyResult.mediaUrl]:[],sendWithRetry=async(fn,label,maxAttempts=3)=>{let lastErr;for(let attempt=1;attempt<=maxAttempts;attempt++)try{return await fn()}catch(err){lastErr=err;let errText=formatError(err),isLast=attempt===maxAttempts;if(!/closed|reset|timed\\s*out|disconnect/i.test(errText)||isLast)throw err;let backoffMs=500*attempt;logVerbose(`Retrying ${label} to ${msg.from} after failure (${attempt}/${maxAttempts-1}) in ${backoffMs}ms: ${errText}`),await sleep(backoffMs)}throw lastErr};if(mediaList.length===0&&textChunks.length){let totalChunks=textChunks.length;for(let[index,chunk]of textChunks.entries()){let chunkStarted=Date.now();if(await sendWithRetry(()=>msg.reply(chunk),`text`),!skipLog){let durationMs=Date.now()-chunkStarted;whatsappOutboundLog.debug(`Sent chunk ${index+1}/${totalChunks} to ${msg.from} (${durationMs.toFixed(0)}ms)`)}}replyLogger.info({correlationId:msg.id??newConnectionId(),connectionId:connectionId??null,to:msg.from,from:msg.to,text:elide(replyResult.text,240),mediaUrl:null,mediaSizeBytes:null,mediaKind:null,durationMs:Date.now()-replyStarted},`auto-reply sent (text)`);return}let remainingText=[...textChunks];for(let[index,mediaUrl]of mediaList.entries()){let caption=index===0&&remainingText.shift()||void 0;try{let media=await loadWebMedia(mediaUrl,{maxBytes:maxMediaBytes,localRoots:params.mediaLocalRoots});if(shouldLogVerbose()&&(logVerbose(`Web auto-reply media size: ${(media.buffer.length/(1024*1024)).toFixed(2)}MB`),logVerbose(`Web auto-reply media source: ${mediaUrl} (kind ${media.kind})`)),media.kind===`image`)await sendWithRetry(()=>msg.sendMedia({image:media.buffer,caption,mimetype:media.contentType}),`media:image`);else if(media.kind===`audio`)await sendWithRetry(()=>msg.sendMedia({audio:media.buffer,ptt:!0,mimetype:media.contentType,caption}),`media:audio`);else if(media.kind===`video`)await sendWithRetry(()=>msg.sendMedia({video:media.buffer,caption,mimetype:media.contentType}),`media:video`);else{let fileName=media.fileName??mediaUrl.split(`/`).pop()??`file`,mimetype=media.contentType??`application/octet-stream`;await sendWithRetry(()=>msg.sendMedia({document:media.buffer,fileName,caption,mimetype}),`media:document`)}whatsappOutboundLog.info(`Sent media reply to ${msg.from} (${(media.buffer.length/(1024*1024)).toFixed(2)}MB)`),replyLogger.info({correlationId:msg.id??newConnectionId(),connectionId:connectionId??null,to:msg.from,from:msg.to,text:caption??null,mediaUrl,mediaSizeBytes:media.buffer.length,mediaKind:media.kind,durationMs:Date.now()-replyStarted},`auto-reply sent (media)`)}catch(err){if(whatsappOutboundLog.error(`Failed sending web media to ${msg.from}: ${formatError(err)}`),replyLogger.warn({err,mediaUrl},`failed to send web media reply`),index===0){let warning=err instanceof Error?`⚠️ Media failed: ${err.message}`:`⚠️ Media failed.`,fallbackText=[remainingText.shift()??caption??``,warning].filter(Boolean).join(`
@@ -1,4 +1,4 @@
1
- import"./paths-5FcIFMsj.js";import{B as theme,G as getResolvedLoggerSettings,O as danger,P as setVerbose,f as isRecord}from"./utils-DbaBVFaK.js";import"./embedded-helpers-2fP2Yq8h.js";import{Nt as deleteTelegramUpdateOffset}from"./reply-D9wUWhMx.js";import{n as DEFAULT_ACCOUNT_ID,u as normalizeAccountId}from"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import{i as defaultRuntime}from"./subsystem-B3TqcCrZ.js";import{r as DEFAULT_CHAT_CHANNEL}from"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import{c as resolveAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import{an as loadAuthProfileStore}from"./model-selection-Doyvd4lU.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-BifagO7i.js";import{a as readConfigFileSnapshot,c as writeConfigFile,r as loadConfig}from"./io-BNtgT4VB.js";import"./manifest-registry-BJCfNV1a.js";import"./config-BD801bpx.js";import"./runner-C3k1sKdu.js";import"./model-catalog-BoiWqBTw.js";import"./sandbox-1jtP0nhr.js";import"./chrome-Bfprrnm1.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-DKdrUePN.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-CRrqIFJR.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-BPr0-lkT.js";import"./message-channel-D_jXxXQj.js";import{l as resolveTelegramAccount,n as listChannelPlugins,r as normalizeChannelId,t as getChannelPlugin}from"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import{r as createSlackWebClient}from"./send-l9WWK31e.js";import{Z as parseDiscordTarget,yt as fetchChannelPermissionsDiscord}from"./send-CVgJk5kN.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import"./fetch-guard-8mwt3-hm.js";import"./api-key-rotation-Yn3MpU4F.js";import"./fetch-BuOLY9KP.js";import"./sqlite-C39E12XS.js";import"./tokens-CCU3zO-D.js";import"./project-context-store-Dbbjk8CQ.js";import"./with-timeout-CPd4-suw.js";import"./deliver-BiGCWHvZ.js";import"./send-CRSlal5z.js";import"./workspace-D4LK4thI.js";import"./reply-prefix-zIMgi6K6.js";import"./memory-cli-D-Khe5Ij.js";import"./manager-DNIg84rj.js";import"./retry-DlVhg5qu.js";import"./client-xfoidwPI.js";import{n as callGateway}from"./call-CJq3iGqu.js";import"./common-BTbIhLyt.js";import"./chunk-FCBlVOyo.js";import"./markdown-tables-P6uoUSFa.js";import"./ir-5BNoIXZm.js";import"./render-D1dVTEB1.js";import"./builderforcellm-syscheck-Cp4LMft_.js";import{n as formatTimeAgo}from"./format-relative-niF9gXss.js";import"./send-D_6wd5Y3.js";import"./outbound-attachment-C7wByQO5.js";import"./fetch-DnVtDecb.js";import"./delivery-queue-CXKynF1P.js";import"./channel-activity-CCNDbdD3.js";import"./tables-ERcoWFDp.js";import"./pairing-store-C8gtsUDG.js";import{t as formatDocsLink}from"./links-BgWWaaOT.js";import{n as runCommandWithRuntime}from"./cli-utils-LBYKdNFb.js";import{t as formatHelpExamples}from"./help-format-Qfk2vDNX.js";import{n as withProgress}from"./progress-BfOtdN6b.js";import"./resolve-route-D49haUnv.js";import"./replies-DAwcEPGb.js";import"./refresh-TiC_kLgE.js";import"./coding-tools.policy-COe2xa9K.js";import"./send-BIMaIwQV.js";import"./onboard-helpers-BmYUjl4j.js";import"./prompt-style-BpVK43GK.js";import"./pairing-labels-CD0lPAfY.js";import"./session-cost-usage-BjH7mxVj.js";import"./usage-format-DGf8ZWPH.js";import{n as formatUsageReportLines,t as loadProviderUsageSummary}from"./provider-usage-QGVVADJa.js";import"./active-listener-Dcg19lJG.js";import"./exec-approvals-BpVPDVtV.js";import"./nodes-screen-C3TDIi8d.js";import"./project-context-BLpMH93w.js";import"./control-service-DKBAemtq.js";import"./stagger-8EkqkqJv.js";import{n as resolveMessageChannelSelection}from"./channel-selection-DyAvzlY8.js";import"./mamba-state-engine-BQuRdgMU.js";import"./transformers-stream-D7nRu4Qu.js";import{r as listChannelPluginCatalogEntries}from"./catalog-rgiY__UQ.js";import"./plugin-registry-BEmyRfmb.js";import{t as formatCliChannelOptions}from"./channel-options-CiYpNR-1.js";import{t as hasExplicitOptions}from"./command-options-DzGFCQYs.js";import"./note-B6NtFdXt.js";import{t as createClackPrompter}from"./clack-prompter-Dg23_riR.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DTDCy17p.js";import"./plugin-auto-enable-zKMSAekH.js";import"./install-safe-path-DsLq2BUJ.js";import"./npm-registry-spec-DIW6RsGN.js";import"./skill-scanner-BUNvEK3Z.js";import"./installs-ZToTbCYE.js";import{i as reloadOnboardingPluginRegistry,n as setupChannels,r as ensureOnboardingPluginInstalled}from"./onboard-channels-Tl1X4Pl_.js";import{t as requireValidConfigSnapshot}from"./config-validation-PDTMTi8w.js";import{t as buildChannelAccountSnapshot}from"./status-PqZ4BoNw.js";import{t as parseLogLine}from"./parse-log-line-D-p4EvDQ.js";import{t as collectChannelStatusIssues}from"./channels-status-issues-BlOu0Ul_.js";import fs from"node:fs/promises";function applyAccountName(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountName;return apply?apply({cfg:params.cfg,accountId,name:params.name}):params.cfg}function applyChannelAccountConfig(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountConfig;return apply?apply({cfg:params.cfg,accountId,input:params.input}):params.cfg}async function requireValidConfig(runtime=defaultRuntime){return await requireValidConfigSnapshot(runtime)}function formatAccountLabel(params){let base=params.accountId||DEFAULT_ACCOUNT_ID;return params.name?.trim()?`${base} (${params.name.trim()})`:base}const channelLabel=channel=>getChannelPlugin(channel)?.meta.label??channel;function formatChannelAccountLabel(params){let channelText=channelLabel(params.channel),accountText=formatAccountLabel({accountId:params.accountId,name:params.name});return`${params.channelStyle?params.channelStyle(channelText):channelText} ${params.accountStyle?params.accountStyle(accountText):accountText}`}function shouldUseWizard(params){return params?.hasFlags===!1}function parseList(value){if(!value?.trim())return;let parsed=value.split(/[\n,;]+/g).map(entry=>entry.trim()).filter(Boolean);return parsed.length>0?parsed:void 0}function resolveCatalogChannelEntry(raw,cfg){let trimmed=raw.trim().toLowerCase();if(trimmed)return listChannelPluginCatalogEntries({workspaceDir:cfg?resolveAgentWorkspaceDir(cfg,resolveDefaultAgentId(cfg)):void 0}).find(entry=>entry.id.toLowerCase()===trimmed?!0:(entry.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===trimmed))}async function channelsAddCommand(opts,runtime=defaultRuntime,params){let cfg=await requireValidConfig(runtime);if(!cfg)return;let nextConfig=cfg;if(shouldUseWizard(params)){let prompter=createClackPrompter(),selection=[],accountIds={};await prompter.intro(`Channel setup`);let nextConfig=await setupChannels(cfg,runtime,prompter,{allowDisable:!1,allowSignalInstall:!0,promptAccountIds:!0,onSelection:value=>{selection=value},onAccountId:(channel,accountId)=>{accountIds[channel]=accountId}});if(selection.length===0){await prompter.outro(`No channels selected.`);return}if(await prompter.confirm({message:`Add display names for these accounts? (optional)`,initialValue:!1}))for(let channel of selection){let accountId=accountIds[channel]??DEFAULT_ACCOUNT_ID,plugin=getChannelPlugin(channel),account=plugin?.config.resolveAccount(nextConfig,accountId),existingName=plugin?.config.describeAccount?.(account,nextConfig)?.name??account?.name,name=await prompter.text({message:`${channel} account name (${accountId})`,initialValue:existingName});name?.trim()&&(nextConfig=applyAccountName({cfg:nextConfig,channel,accountId,name}))}await writeConfigFile(nextConfig),await prompter.outro(`Channels updated.`);return}let rawChannel=String(opts.channel??``),channel=normalizeChannelId(rawChannel),catalogEntry=channel?void 0:resolveCatalogChannelEntry(rawChannel,nextConfig);if(!channel&&catalogEntry){let prompter=createClackPrompter(),workspaceDir=resolveAgentWorkspaceDir(nextConfig,resolveDefaultAgentId(nextConfig)),result=await ensureOnboardingPluginInstalled({cfg:nextConfig,entry:catalogEntry,prompter,runtime,workspaceDir});if(nextConfig=result.cfg,!result.installed)return;reloadOnboardingPluginRegistry({cfg:nextConfig,runtime,workspaceDir}),channel=normalizeChannelId(catalogEntry.id)??catalogEntry.id}if(!channel){let hint=catalogEntry?`Plugin ${catalogEntry.meta.label} could not be loaded after install.`:`Unknown channel: ${String(opts.channel??``)}`;runtime.error(hint),runtime.exit(1);return}let plugin=getChannelPlugin(channel);if(!plugin?.setup?.applyAccountConfig){runtime.error(`Channel ${channel} does not support add.`),runtime.exit(1);return}let accountId=plugin.setup.resolveAccountId?.({cfg:nextConfig,accountId:opts.account})??normalizeAccountId(opts.account),useEnv=opts.useEnv===!0,initialSyncLimit=typeof opts.initialSyncLimit==`number`?opts.initialSyncLimit:typeof opts.initialSyncLimit==`string`&&opts.initialSyncLimit.trim()?Number.parseInt(opts.initialSyncLimit,10):void 0,groupChannels=parseList(opts.groupChannels),dmAllowlist=parseList(opts.dmAllowlist),input={name:opts.name,token:opts.token,tokenFile:opts.tokenFile,botToken:opts.botToken,appToken:opts.appToken,signalNumber:opts.signalNumber,cliPath:opts.cliPath,dbPath:opts.dbPath,service:opts.service,region:opts.region,authDir:opts.authDir,httpUrl:opts.httpUrl,httpHost:opts.httpHost,httpPort:opts.httpPort,webhookPath:opts.webhookPath,webhookUrl:opts.webhookUrl,audienceType:opts.audienceType,audience:opts.audience,homeserver:opts.homeserver,userId:opts.userId,accessToken:opts.accessToken,password:opts.password,deviceName:opts.deviceName,initialSyncLimit,useEnv,ship:opts.ship,url:opts.url,code:opts.code,groupChannels,dmAllowlist,autoDiscoverChannels:opts.autoDiscoverChannels},validationError=plugin.setup.validateInput?.({cfg:nextConfig,accountId,input});if(validationError){runtime.error(validationError),runtime.exit(1);return}let previousTelegramToken=channel===`telegram`?resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim():``;nextConfig=applyChannelAccountConfig({cfg:nextConfig,channel,accountId,input}),channel===`telegram`&&previousTelegramToken!==resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim()&&await deleteTelegramUpdateOffset({accountId}),await writeConfigFile(nextConfig),runtime.log(`Added ${channelLabel(channel)} account "${accountId}".`)}function collectScopes(value,into){if(value){if(Array.isArray(value)){for(let entry of value)typeof entry==`string`&&entry.trim()&&into.push(entry.trim());return}if(typeof value==`string`){let raw=value.trim();if(!raw)return;let parts=raw.split(/[,\s]+/).map(part=>part.trim());for(let part of parts)part&&into.push(part);return}if(isRecord(value))for(let entry of Object.values(value))(Array.isArray(entry)||typeof entry==`string`)&&collectScopes(entry,into)}}function normalizeScopes(scopes){return Array.from(new Set(scopes.map(scope=>scope.trim()).filter(Boolean))).toSorted()}function extractScopes(payload){if(!isRecord(payload))return[];let scopes=[];return collectScopes(payload.scopes,scopes),collectScopes(payload.scope,scopes),isRecord(payload.info)&&(collectScopes(payload.info.scopes,scopes),collectScopes(payload.info.scope,scopes),collectScopes(payload.info.user_scopes,scopes),collectScopes(payload.info.bot_scopes,scopes)),normalizeScopes(scopes)}function readError(payload){if(!isRecord(payload))return;let error=payload.error;return typeof error==`string`&&error.trim()?error.trim():void 0}async function callSlack(client,method){try{let result=await client.apiCall(method);return isRecord(result)?result:null}catch(err){return{ok:!1,error:err instanceof Error?err.message:String(err)}}}async function fetchSlackScopes(token,timeoutMs){let client=createSlackWebClient(token,{timeout:timeoutMs}),attempts=[`auth.scopes`,`apps.permissions.info`],errors=[];for(let method of attempts){let result=await callSlack(client,method),scopes=extractScopes(result);if(scopes.length>0)return{ok:!0,scopes,source:method};let error=readError(result);error&&errors.push(`${method}: ${error}`)}return{ok:!1,error:errors.length>0?errors.join(` | `):`no scopes returned`}}const REQUIRED_DISCORD_PERMISSIONS=[`ViewChannel`,`SendMessages`],TEAMS_GRAPH_PERMISSION_HINTS={"ChannelMessage.Read.All":`channel history`,"Chat.Read.All":`chat history`,"Channel.ReadBasic.All":`channel list`,"Team.ReadBasic.All":`team list`,"TeamsActivity.Read.All":`teams activity`,"Sites.Read.All":`files (SharePoint)`,"Files.Read.All":`files (OneDrive)`};function normalizeTimeout(raw,fallback=1e4){let value=Number(raw);return!Number.isFinite(value)||value<=0?fallback:value}function formatSupport(capabilities){if(!capabilities)return`unknown`;let bits=[];return capabilities.chatTypes?.length&&bits.push(`chatTypes=${capabilities.chatTypes.join(`,`)}`),capabilities.polls&&bits.push(`polls`),capabilities.reactions&&bits.push(`reactions`),capabilities.edit&&bits.push(`edit`),capabilities.unsend&&bits.push(`unsend`),capabilities.reply&&bits.push(`reply`),capabilities.effects&&bits.push(`effects`),capabilities.groupManagement&&bits.push(`groupManagement`),capabilities.threads&&bits.push(`threads`),capabilities.media&&bits.push(`media`),capabilities.nativeCommands&&bits.push(`nativeCommands`),capabilities.blockStreaming&&bits.push(`blockStreaming`),bits.length?bits.join(` `):`none`}function summarizeDiscordTarget(raw){if(!raw)return;let target=parseDiscordTarget(raw,{defaultKind:`channel`});return target?target.kind===`channel`?{raw,normalized:target.normalized,kind:`channel`,channelId:target.id}:target.kind===`user`?{raw,normalized:target.normalized,kind:`user`}:{raw,normalized:target.normalized}:{raw}}function formatDiscordIntents(intents){return intents?[`messageContent=${intents.messageContent??`unknown`}`,`guildMembers=${intents.guildMembers??`unknown`}`,`presence=${intents.presence??`unknown`}`].join(` `):`unknown`}function formatProbeLines(channelId,probe){let lines=[];if(!probe||typeof probe!=`object`)return lines;let probeObj=probe;if(channelId===`discord`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let app=probeObj.application;app?.intents&&lines.push(`Intents: ${formatDiscordIntents(app.intents)}`)}if(channelId===`telegram`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let flags=[],canJoinGroups=bot?.canJoinGroups,canReadAll=bot?.canReadAllGroupMessages,inlineQueries=bot?.supportsInlineQueries;typeof canJoinGroups==`boolean`&&flags.push(`joinGroups=${canJoinGroups}`),typeof canReadAll==`boolean`&&flags.push(`readAllGroupMessages=${canReadAll}`),typeof inlineQueries==`boolean`&&flags.push(`inlineQueries=${inlineQueries}`),flags.length>0&&lines.push(`Flags: ${flags.join(` `)}`);let webhook=probeObj.webhook;webhook?.url!==void 0&&lines.push(`Webhook: ${webhook.url||`none`}`)}if(channelId===`slack`){let bot=probeObj.bot,team=probeObj.team;if(bot?.name&&lines.push(`Bot: ${theme.accent(`@${bot.name}`)}`),team?.name||team?.id){let id=team?.id?` (${team.id})`:``;lines.push(`Team: ${team?.name??`unknown`}${id}`)}}if(channelId===`signal`){let version=probeObj.version;version&&lines.push(`Signal daemon: ${version}`)}if(channelId===`msteams`){let appId=typeof probeObj.appId==`string`?probeObj.appId.trim():``;appId&&lines.push(`App: ${theme.accent(appId)}`);let graph=probeObj.graph;if(graph){let roles=Array.isArray(graph.roles)?graph.roles.map(role=>String(role).trim()).filter(Boolean):[],scopes=typeof graph.scopes==`string`?graph.scopes.split(/\s+/).map(scope=>scope.trim()).filter(Boolean):Array.isArray(graph.scopes)?graph.scopes.map(scope=>String(scope).trim()).filter(Boolean):[];if(graph.ok===!1)lines.push(`Graph: ${theme.error(graph.error??`failed`)}`);else if(roles.length>0||scopes.length>0){let formatPermission=permission=>{let hint=TEAMS_GRAPH_PERMISSION_HINTS[permission];return hint?`${permission} (${hint})`:permission};roles.length>0&&lines.push(`Graph roles: ${roles.map(formatPermission).join(`, `)}`),scopes.length>0&&lines.push(`Graph scopes: ${scopes.map(formatPermission).join(`, `)}`)}else graph.ok===!0&&lines.push(`Graph: ok`)}}let ok=typeof probeObj.ok==`boolean`?probeObj.ok:void 0;if(ok===!0&&lines.length===0&&lines.push(`Probe: ok`),ok===!1){let error=typeof probeObj.error==`string`&&probeObj.error?` (${probeObj.error})`:``;lines.push(`Probe: ${theme.error(`failed${error}`)}`)}return lines}async function buildDiscordPermissions(params){let target=summarizeDiscordTarget(params.target?.trim());if(!target)return{};if(target.kind!==`channel`||!target.channelId)return{target,report:{error:`Target looks like a DM user; pass channel:<id> to audit channel permissions.`}};let token=params.account.token?.trim();if(!token)return{target,report:{channelId:target.channelId,error:`Discord bot token missing for permission audit.`}};try{let perms=await fetchChannelPermissionsDiscord(target.channelId,{token,accountId:params.account.accountId??void 0}),missing=REQUIRED_DISCORD_PERMISSIONS.filter(permission=>!perms.permissions.includes(permission));return{target,report:{channelId:perms.channelId,guildId:perms.guildId,isDm:perms.isDm,channelType:perms.channelType,permissions:perms.permissions,missingRequired:missing.length?missing:[],raw:perms.raw}}}catch(err){return{target,report:{channelId:target.channelId,error:err instanceof Error?err.message:String(err)}}}}async function resolveChannelReports(params){let{plugin,cfg,timeoutMs}=params,accountIds=params.accountOverride?[params.accountOverride]:(()=>{let ids=plugin.config.listAccountIds(cfg);return ids.length>0?ids:[resolveChannelDefaultAccountId({plugin,cfg,accountIds:ids})]})(),reports=[],listedActions=plugin.actions?.listActions?.({cfg})??[],actions=Array.from(new Set([`send`,`broadcast`,...listedActions.map(action=>String(action))]));for(let accountId of accountIds){let resolvedAccount=plugin.config.resolveAccount(cfg,accountId),configured=plugin.config.isConfigured?await plugin.config.isConfigured(resolvedAccount,cfg):!!resolvedAccount,enabled=plugin.config.isEnabled?plugin.config.isEnabled(resolvedAccount,cfg):resolvedAccount.enabled!==!1,probe;if(configured&&enabled&&plugin.status?.probeAccount)try{probe=await plugin.status.probeAccount({account:resolvedAccount,timeoutMs,cfg})}catch(err){probe={ok:!1,error:err instanceof Error?err.message:String(err)}}let slackScopes;if(plugin.id===`slack`&&configured&&enabled){let botToken=resolvedAccount.botToken?.trim(),userToken=resolvedAccount.config?.userToken?.trim(),scopeReports=[];botToken?scopeReports.push({tokenType:`bot`,result:await fetchSlackScopes(botToken,timeoutMs)}):scopeReports.push({tokenType:`bot`,result:{ok:!1,error:`Slack bot token missing.`}}),userToken&&scopeReports.push({tokenType:`user`,result:await fetchSlackScopes(userToken,timeoutMs)}),slackScopes=scopeReports}let discordTarget,discordPermissions;if(plugin.id===`discord`&&params.target){let perms=await buildDiscordPermissions({account:resolvedAccount,target:params.target});discordTarget=perms.target,discordPermissions=perms.report}reports.push({channel:plugin.id,accountId,accountName:typeof resolvedAccount.name==`string`&&resolvedAccount.name?.trim()||void 0,configured,enabled,support:plugin.capabilities,probe,target:discordTarget,channelPermissions:discordPermissions,actions,slackScopes})}return reports}async function channelsCapabilitiesCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let timeoutMs=normalizeTimeout(opts.timeout,1e4),rawChannel=typeof opts.channel==`string`?opts.channel.trim().toLowerCase():``,rawTarget=typeof opts.target==`string`?opts.target.trim():``;if(opts.account&&(!rawChannel||rawChannel===`all`)){runtime.error(danger(`--account requires a specific --channel.`)),runtime.exit(1);return}if(rawTarget&&rawChannel!==`discord`){runtime.error(danger(`--target requires --channel discord.`)),runtime.exit(1);return}let plugins=listChannelPlugins(),selected=!rawChannel||rawChannel===`all`?plugins:(()=>{let plugin=getChannelPlugin(rawChannel);return plugin?[plugin]:null})();if(!selected||selected.length===0){runtime.error(danger(`Unknown channel "${rawChannel}".`)),runtime.exit(1);return}let reports=[];for(let plugin of selected){let accountOverride=opts.account?.trim()||void 0;reports.push(...await resolveChannelReports({plugin,cfg,timeoutMs,accountOverride,target:rawTarget&&plugin.id===`discord`?rawTarget:void 0}))}if(opts.json){runtime.log(JSON.stringify({channels:reports},null,2));return}let lines=[];for(let report of reports){let label=formatChannelAccountLabel({channel:report.channel,accountId:report.accountId,name:report.accountName,channelStyle:theme.accent,accountStyle:theme.heading});if(lines.push(theme.heading(label)),lines.push(`Support: ${formatSupport(report.support)}`),report.actions&&report.actions.length>0&&lines.push(`Actions: ${report.actions.join(`, `)}`),report.configured===!1||report.enabled===!1){let configuredLabel=report.configured===!1?`not configured`:`configured`,enabledLabel=report.enabled===!1?`disabled`:`enabled`;lines.push(`Status: ${configuredLabel}, ${enabledLabel}`)}let probeLines=formatProbeLines(report.channel,report.probe);if(probeLines.length>0?lines.push(...probeLines):report.configured&&report.enabled&&lines.push(theme.muted(`Probe: unavailable`)),report.channel===`slack`&&report.slackScopes)for(let entry of report.slackScopes){let source=entry.result.source?` (${entry.result.source})`:``,label=entry.tokenType===`user`?`User scopes`:`Bot scopes`;entry.result.ok&&entry.result.scopes?.length?lines.push(`${label}${source}: ${entry.result.scopes.join(`, `)}`):entry.result.error&&lines.push(`${label}: ${theme.error(entry.result.error)}`)}if(report.channel===`discord`&&report.channelPermissions){let perms=report.channelPermissions;if(perms.error)lines.push(`Permissions: ${theme.error(perms.error)}`);else{let list=perms.permissions?.length?perms.permissions.join(`, `):`none`,label=perms.channelId?` (${perms.channelId})`:``;lines.push(`Permissions${label}: ${list}`),perms.missingRequired&&perms.missingRequired.length>0?lines.push(`${theme.warn(`Missing required:`)} ${perms.missingRequired.join(`, `)}`):lines.push(theme.success(`Missing required: none`))}}else report.channel===`discord`&&rawTarget&&!report.channelPermissions&&lines.push(theme.muted(`Permissions: skipped (no target).`));lines.push(``)}runtime.log(lines.join(`
1
+ import"./paths-5FcIFMsj.js";import{B as theme,G as getResolvedLoggerSettings,O as danger,P as setVerbose,f as isRecord}from"./utils-DbaBVFaK.js";import"./embedded-helpers-2fP2Yq8h.js";import{Nt as deleteTelegramUpdateOffset}from"./reply-BuUSdq2L.js";import{n as DEFAULT_ACCOUNT_ID,u as normalizeAccountId}from"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import{i as defaultRuntime}from"./subsystem-B3TqcCrZ.js";import{r as DEFAULT_CHAT_CHANNEL}from"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import{c as resolveAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import{an as loadAuthProfileStore}from"./model-selection-Doyvd4lU.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-BifagO7i.js";import{a as readConfigFileSnapshot,c as writeConfigFile,r as loadConfig}from"./io-BNtgT4VB.js";import"./manifest-registry-BJCfNV1a.js";import"./config-BD801bpx.js";import"./runner-C3k1sKdu.js";import"./model-catalog-BoiWqBTw.js";import"./sandbox-1jtP0nhr.js";import"./chrome-Bfprrnm1.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-DKdrUePN.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-CRrqIFJR.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-BPr0-lkT.js";import"./message-channel-D_jXxXQj.js";import{l as resolveTelegramAccount,n as listChannelPlugins,r as normalizeChannelId,t as getChannelPlugin}from"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import{r as createSlackWebClient}from"./send-l9WWK31e.js";import{Z as parseDiscordTarget,yt as fetchChannelPermissionsDiscord}from"./send-CVgJk5kN.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import"./fetch-guard-8mwt3-hm.js";import"./api-key-rotation-Yn3MpU4F.js";import"./fetch-BuOLY9KP.js";import"./sqlite-C39E12XS.js";import"./tokens-CCU3zO-D.js";import"./project-context-store-Dbbjk8CQ.js";import"./with-timeout-CPd4-suw.js";import"./deliver-BiGCWHvZ.js";import"./send-CRSlal5z.js";import"./workspace-D4LK4thI.js";import"./reply-prefix-zIMgi6K6.js";import"./memory-cli-D-Khe5Ij.js";import"./manager-DNIg84rj.js";import"./retry-DlVhg5qu.js";import"./client-xfoidwPI.js";import{n as callGateway}from"./call-CJq3iGqu.js";import"./common-BTbIhLyt.js";import"./chunk-FCBlVOyo.js";import"./markdown-tables-P6uoUSFa.js";import"./ir-5BNoIXZm.js";import"./render-D1dVTEB1.js";import"./builderforcellm-syscheck-Cp4LMft_.js";import{n as formatTimeAgo}from"./format-relative-niF9gXss.js";import"./send-D_6wd5Y3.js";import"./outbound-attachment-C7wByQO5.js";import"./fetch-DnVtDecb.js";import"./delivery-queue-CXKynF1P.js";import"./channel-activity-CCNDbdD3.js";import"./tables-ERcoWFDp.js";import"./pairing-store-C8gtsUDG.js";import{t as formatDocsLink}from"./links-BgWWaaOT.js";import{n as runCommandWithRuntime}from"./cli-utils-LBYKdNFb.js";import{t as formatHelpExamples}from"./help-format-Qfk2vDNX.js";import{n as withProgress}from"./progress-BfOtdN6b.js";import"./resolve-route-D49haUnv.js";import"./replies-DAwcEPGb.js";import"./refresh-TiC_kLgE.js";import"./coding-tools.policy-COe2xa9K.js";import"./send-BIMaIwQV.js";import"./onboard-helpers-BmYUjl4j.js";import"./prompt-style-BpVK43GK.js";import"./pairing-labels-CD0lPAfY.js";import"./session-cost-usage-BjH7mxVj.js";import"./usage-format-DGf8ZWPH.js";import{n as formatUsageReportLines,t as loadProviderUsageSummary}from"./provider-usage-QGVVADJa.js";import"./active-listener-Dcg19lJG.js";import"./exec-approvals-BpVPDVtV.js";import"./nodes-screen-C3TDIi8d.js";import"./project-context-BLpMH93w.js";import"./control-service-DKBAemtq.js";import"./stagger-8EkqkqJv.js";import{n as resolveMessageChannelSelection}from"./channel-selection-DyAvzlY8.js";import"./mamba-state-engine-BQuRdgMU.js";import"./transformers-stream-D7nRu4Qu.js";import{r as listChannelPluginCatalogEntries}from"./catalog-rgiY__UQ.js";import"./plugin-registry-DrEpL5ac.js";import{t as formatCliChannelOptions}from"./channel-options-CRng-5hZ.js";import{t as hasExplicitOptions}from"./command-options-DzGFCQYs.js";import"./note-B6NtFdXt.js";import{t as createClackPrompter}from"./clack-prompter-Dg23_riR.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DTDCy17p.js";import"./plugin-auto-enable-zKMSAekH.js";import"./install-safe-path-DsLq2BUJ.js";import"./npm-registry-spec-DIW6RsGN.js";import"./skill-scanner-BUNvEK3Z.js";import"./installs-ZToTbCYE.js";import{i as reloadOnboardingPluginRegistry,n as setupChannels,r as ensureOnboardingPluginInstalled}from"./onboard-channels-uvIeLPXK.js";import{t as requireValidConfigSnapshot}from"./config-validation-PDTMTi8w.js";import{t as buildChannelAccountSnapshot}from"./status-PqZ4BoNw.js";import{t as parseLogLine}from"./parse-log-line-D-p4EvDQ.js";import{t as collectChannelStatusIssues}from"./channels-status-issues-BlOu0Ul_.js";import fs from"node:fs/promises";function applyAccountName(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountName;return apply?apply({cfg:params.cfg,accountId,name:params.name}):params.cfg}function applyChannelAccountConfig(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountConfig;return apply?apply({cfg:params.cfg,accountId,input:params.input}):params.cfg}async function requireValidConfig(runtime=defaultRuntime){return await requireValidConfigSnapshot(runtime)}function formatAccountLabel(params){let base=params.accountId||DEFAULT_ACCOUNT_ID;return params.name?.trim()?`${base} (${params.name.trim()})`:base}const channelLabel=channel=>getChannelPlugin(channel)?.meta.label??channel;function formatChannelAccountLabel(params){let channelText=channelLabel(params.channel),accountText=formatAccountLabel({accountId:params.accountId,name:params.name});return`${params.channelStyle?params.channelStyle(channelText):channelText} ${params.accountStyle?params.accountStyle(accountText):accountText}`}function shouldUseWizard(params){return params?.hasFlags===!1}function parseList(value){if(!value?.trim())return;let parsed=value.split(/[\n,;]+/g).map(entry=>entry.trim()).filter(Boolean);return parsed.length>0?parsed:void 0}function resolveCatalogChannelEntry(raw,cfg){let trimmed=raw.trim().toLowerCase();if(trimmed)return listChannelPluginCatalogEntries({workspaceDir:cfg?resolveAgentWorkspaceDir(cfg,resolveDefaultAgentId(cfg)):void 0}).find(entry=>entry.id.toLowerCase()===trimmed?!0:(entry.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===trimmed))}async function channelsAddCommand(opts,runtime=defaultRuntime,params){let cfg=await requireValidConfig(runtime);if(!cfg)return;let nextConfig=cfg;if(shouldUseWizard(params)){let prompter=createClackPrompter(),selection=[],accountIds={};await prompter.intro(`Channel setup`);let nextConfig=await setupChannels(cfg,runtime,prompter,{allowDisable:!1,allowSignalInstall:!0,promptAccountIds:!0,onSelection:value=>{selection=value},onAccountId:(channel,accountId)=>{accountIds[channel]=accountId}});if(selection.length===0){await prompter.outro(`No channels selected.`);return}if(await prompter.confirm({message:`Add display names for these accounts? (optional)`,initialValue:!1}))for(let channel of selection){let accountId=accountIds[channel]??DEFAULT_ACCOUNT_ID,plugin=getChannelPlugin(channel),account=plugin?.config.resolveAccount(nextConfig,accountId),existingName=plugin?.config.describeAccount?.(account,nextConfig)?.name??account?.name,name=await prompter.text({message:`${channel} account name (${accountId})`,initialValue:existingName});name?.trim()&&(nextConfig=applyAccountName({cfg:nextConfig,channel,accountId,name}))}await writeConfigFile(nextConfig),await prompter.outro(`Channels updated.`);return}let rawChannel=String(opts.channel??``),channel=normalizeChannelId(rawChannel),catalogEntry=channel?void 0:resolveCatalogChannelEntry(rawChannel,nextConfig);if(!channel&&catalogEntry){let prompter=createClackPrompter(),workspaceDir=resolveAgentWorkspaceDir(nextConfig,resolveDefaultAgentId(nextConfig)),result=await ensureOnboardingPluginInstalled({cfg:nextConfig,entry:catalogEntry,prompter,runtime,workspaceDir});if(nextConfig=result.cfg,!result.installed)return;reloadOnboardingPluginRegistry({cfg:nextConfig,runtime,workspaceDir}),channel=normalizeChannelId(catalogEntry.id)??catalogEntry.id}if(!channel){let hint=catalogEntry?`Plugin ${catalogEntry.meta.label} could not be loaded after install.`:`Unknown channel: ${String(opts.channel??``)}`;runtime.error(hint),runtime.exit(1);return}let plugin=getChannelPlugin(channel);if(!plugin?.setup?.applyAccountConfig){runtime.error(`Channel ${channel} does not support add.`),runtime.exit(1);return}let accountId=plugin.setup.resolveAccountId?.({cfg:nextConfig,accountId:opts.account})??normalizeAccountId(opts.account),useEnv=opts.useEnv===!0,initialSyncLimit=typeof opts.initialSyncLimit==`number`?opts.initialSyncLimit:typeof opts.initialSyncLimit==`string`&&opts.initialSyncLimit.trim()?Number.parseInt(opts.initialSyncLimit,10):void 0,groupChannels=parseList(opts.groupChannels),dmAllowlist=parseList(opts.dmAllowlist),input={name:opts.name,token:opts.token,tokenFile:opts.tokenFile,botToken:opts.botToken,appToken:opts.appToken,signalNumber:opts.signalNumber,cliPath:opts.cliPath,dbPath:opts.dbPath,service:opts.service,region:opts.region,authDir:opts.authDir,httpUrl:opts.httpUrl,httpHost:opts.httpHost,httpPort:opts.httpPort,webhookPath:opts.webhookPath,webhookUrl:opts.webhookUrl,audienceType:opts.audienceType,audience:opts.audience,homeserver:opts.homeserver,userId:opts.userId,accessToken:opts.accessToken,password:opts.password,deviceName:opts.deviceName,initialSyncLimit,useEnv,ship:opts.ship,url:opts.url,code:opts.code,groupChannels,dmAllowlist,autoDiscoverChannels:opts.autoDiscoverChannels},validationError=plugin.setup.validateInput?.({cfg:nextConfig,accountId,input});if(validationError){runtime.error(validationError),runtime.exit(1);return}let previousTelegramToken=channel===`telegram`?resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim():``;nextConfig=applyChannelAccountConfig({cfg:nextConfig,channel,accountId,input}),channel===`telegram`&&previousTelegramToken!==resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim()&&await deleteTelegramUpdateOffset({accountId}),await writeConfigFile(nextConfig),runtime.log(`Added ${channelLabel(channel)} account "${accountId}".`)}function collectScopes(value,into){if(value){if(Array.isArray(value)){for(let entry of value)typeof entry==`string`&&entry.trim()&&into.push(entry.trim());return}if(typeof value==`string`){let raw=value.trim();if(!raw)return;let parts=raw.split(/[,\s]+/).map(part=>part.trim());for(let part of parts)part&&into.push(part);return}if(isRecord(value))for(let entry of Object.values(value))(Array.isArray(entry)||typeof entry==`string`)&&collectScopes(entry,into)}}function normalizeScopes(scopes){return Array.from(new Set(scopes.map(scope=>scope.trim()).filter(Boolean))).toSorted()}function extractScopes(payload){if(!isRecord(payload))return[];let scopes=[];return collectScopes(payload.scopes,scopes),collectScopes(payload.scope,scopes),isRecord(payload.info)&&(collectScopes(payload.info.scopes,scopes),collectScopes(payload.info.scope,scopes),collectScopes(payload.info.user_scopes,scopes),collectScopes(payload.info.bot_scopes,scopes)),normalizeScopes(scopes)}function readError(payload){if(!isRecord(payload))return;let error=payload.error;return typeof error==`string`&&error.trim()?error.trim():void 0}async function callSlack(client,method){try{let result=await client.apiCall(method);return isRecord(result)?result:null}catch(err){return{ok:!1,error:err instanceof Error?err.message:String(err)}}}async function fetchSlackScopes(token,timeoutMs){let client=createSlackWebClient(token,{timeout:timeoutMs}),attempts=[`auth.scopes`,`apps.permissions.info`],errors=[];for(let method of attempts){let result=await callSlack(client,method),scopes=extractScopes(result);if(scopes.length>0)return{ok:!0,scopes,source:method};let error=readError(result);error&&errors.push(`${method}: ${error}`)}return{ok:!1,error:errors.length>0?errors.join(` | `):`no scopes returned`}}const REQUIRED_DISCORD_PERMISSIONS=[`ViewChannel`,`SendMessages`],TEAMS_GRAPH_PERMISSION_HINTS={"ChannelMessage.Read.All":`channel history`,"Chat.Read.All":`chat history`,"Channel.ReadBasic.All":`channel list`,"Team.ReadBasic.All":`team list`,"TeamsActivity.Read.All":`teams activity`,"Sites.Read.All":`files (SharePoint)`,"Files.Read.All":`files (OneDrive)`};function normalizeTimeout(raw,fallback=1e4){let value=Number(raw);return!Number.isFinite(value)||value<=0?fallback:value}function formatSupport(capabilities){if(!capabilities)return`unknown`;let bits=[];return capabilities.chatTypes?.length&&bits.push(`chatTypes=${capabilities.chatTypes.join(`,`)}`),capabilities.polls&&bits.push(`polls`),capabilities.reactions&&bits.push(`reactions`),capabilities.edit&&bits.push(`edit`),capabilities.unsend&&bits.push(`unsend`),capabilities.reply&&bits.push(`reply`),capabilities.effects&&bits.push(`effects`),capabilities.groupManagement&&bits.push(`groupManagement`),capabilities.threads&&bits.push(`threads`),capabilities.media&&bits.push(`media`),capabilities.nativeCommands&&bits.push(`nativeCommands`),capabilities.blockStreaming&&bits.push(`blockStreaming`),bits.length?bits.join(` `):`none`}function summarizeDiscordTarget(raw){if(!raw)return;let target=parseDiscordTarget(raw,{defaultKind:`channel`});return target?target.kind===`channel`?{raw,normalized:target.normalized,kind:`channel`,channelId:target.id}:target.kind===`user`?{raw,normalized:target.normalized,kind:`user`}:{raw,normalized:target.normalized}:{raw}}function formatDiscordIntents(intents){return intents?[`messageContent=${intents.messageContent??`unknown`}`,`guildMembers=${intents.guildMembers??`unknown`}`,`presence=${intents.presence??`unknown`}`].join(` `):`unknown`}function formatProbeLines(channelId,probe){let lines=[];if(!probe||typeof probe!=`object`)return lines;let probeObj=probe;if(channelId===`discord`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let app=probeObj.application;app?.intents&&lines.push(`Intents: ${formatDiscordIntents(app.intents)}`)}if(channelId===`telegram`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let flags=[],canJoinGroups=bot?.canJoinGroups,canReadAll=bot?.canReadAllGroupMessages,inlineQueries=bot?.supportsInlineQueries;typeof canJoinGroups==`boolean`&&flags.push(`joinGroups=${canJoinGroups}`),typeof canReadAll==`boolean`&&flags.push(`readAllGroupMessages=${canReadAll}`),typeof inlineQueries==`boolean`&&flags.push(`inlineQueries=${inlineQueries}`),flags.length>0&&lines.push(`Flags: ${flags.join(` `)}`);let webhook=probeObj.webhook;webhook?.url!==void 0&&lines.push(`Webhook: ${webhook.url||`none`}`)}if(channelId===`slack`){let bot=probeObj.bot,team=probeObj.team;if(bot?.name&&lines.push(`Bot: ${theme.accent(`@${bot.name}`)}`),team?.name||team?.id){let id=team?.id?` (${team.id})`:``;lines.push(`Team: ${team?.name??`unknown`}${id}`)}}if(channelId===`signal`){let version=probeObj.version;version&&lines.push(`Signal daemon: ${version}`)}if(channelId===`msteams`){let appId=typeof probeObj.appId==`string`?probeObj.appId.trim():``;appId&&lines.push(`App: ${theme.accent(appId)}`);let graph=probeObj.graph;if(graph){let roles=Array.isArray(graph.roles)?graph.roles.map(role=>String(role).trim()).filter(Boolean):[],scopes=typeof graph.scopes==`string`?graph.scopes.split(/\s+/).map(scope=>scope.trim()).filter(Boolean):Array.isArray(graph.scopes)?graph.scopes.map(scope=>String(scope).trim()).filter(Boolean):[];if(graph.ok===!1)lines.push(`Graph: ${theme.error(graph.error??`failed`)}`);else if(roles.length>0||scopes.length>0){let formatPermission=permission=>{let hint=TEAMS_GRAPH_PERMISSION_HINTS[permission];return hint?`${permission} (${hint})`:permission};roles.length>0&&lines.push(`Graph roles: ${roles.map(formatPermission).join(`, `)}`),scopes.length>0&&lines.push(`Graph scopes: ${scopes.map(formatPermission).join(`, `)}`)}else graph.ok===!0&&lines.push(`Graph: ok`)}}let ok=typeof probeObj.ok==`boolean`?probeObj.ok:void 0;if(ok===!0&&lines.length===0&&lines.push(`Probe: ok`),ok===!1){let error=typeof probeObj.error==`string`&&probeObj.error?` (${probeObj.error})`:``;lines.push(`Probe: ${theme.error(`failed${error}`)}`)}return lines}async function buildDiscordPermissions(params){let target=summarizeDiscordTarget(params.target?.trim());if(!target)return{};if(target.kind!==`channel`||!target.channelId)return{target,report:{error:`Target looks like a DM user; pass channel:<id> to audit channel permissions.`}};let token=params.account.token?.trim();if(!token)return{target,report:{channelId:target.channelId,error:`Discord bot token missing for permission audit.`}};try{let perms=await fetchChannelPermissionsDiscord(target.channelId,{token,accountId:params.account.accountId??void 0}),missing=REQUIRED_DISCORD_PERMISSIONS.filter(permission=>!perms.permissions.includes(permission));return{target,report:{channelId:perms.channelId,guildId:perms.guildId,isDm:perms.isDm,channelType:perms.channelType,permissions:perms.permissions,missingRequired:missing.length?missing:[],raw:perms.raw}}}catch(err){return{target,report:{channelId:target.channelId,error:err instanceof Error?err.message:String(err)}}}}async function resolveChannelReports(params){let{plugin,cfg,timeoutMs}=params,accountIds=params.accountOverride?[params.accountOverride]:(()=>{let ids=plugin.config.listAccountIds(cfg);return ids.length>0?ids:[resolveChannelDefaultAccountId({plugin,cfg,accountIds:ids})]})(),reports=[],listedActions=plugin.actions?.listActions?.({cfg})??[],actions=Array.from(new Set([`send`,`broadcast`,...listedActions.map(action=>String(action))]));for(let accountId of accountIds){let resolvedAccount=plugin.config.resolveAccount(cfg,accountId),configured=plugin.config.isConfigured?await plugin.config.isConfigured(resolvedAccount,cfg):!!resolvedAccount,enabled=plugin.config.isEnabled?plugin.config.isEnabled(resolvedAccount,cfg):resolvedAccount.enabled!==!1,probe;if(configured&&enabled&&plugin.status?.probeAccount)try{probe=await plugin.status.probeAccount({account:resolvedAccount,timeoutMs,cfg})}catch(err){probe={ok:!1,error:err instanceof Error?err.message:String(err)}}let slackScopes;if(plugin.id===`slack`&&configured&&enabled){let botToken=resolvedAccount.botToken?.trim(),userToken=resolvedAccount.config?.userToken?.trim(),scopeReports=[];botToken?scopeReports.push({tokenType:`bot`,result:await fetchSlackScopes(botToken,timeoutMs)}):scopeReports.push({tokenType:`bot`,result:{ok:!1,error:`Slack bot token missing.`}}),userToken&&scopeReports.push({tokenType:`user`,result:await fetchSlackScopes(userToken,timeoutMs)}),slackScopes=scopeReports}let discordTarget,discordPermissions;if(plugin.id===`discord`&&params.target){let perms=await buildDiscordPermissions({account:resolvedAccount,target:params.target});discordTarget=perms.target,discordPermissions=perms.report}reports.push({channel:plugin.id,accountId,accountName:typeof resolvedAccount.name==`string`&&resolvedAccount.name?.trim()||void 0,configured,enabled,support:plugin.capabilities,probe,target:discordTarget,channelPermissions:discordPermissions,actions,slackScopes})}return reports}async function channelsCapabilitiesCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let timeoutMs=normalizeTimeout(opts.timeout,1e4),rawChannel=typeof opts.channel==`string`?opts.channel.trim().toLowerCase():``,rawTarget=typeof opts.target==`string`?opts.target.trim():``;if(opts.account&&(!rawChannel||rawChannel===`all`)){runtime.error(danger(`--account requires a specific --channel.`)),runtime.exit(1);return}if(rawTarget&&rawChannel!==`discord`){runtime.error(danger(`--target requires --channel discord.`)),runtime.exit(1);return}let plugins=listChannelPlugins(),selected=!rawChannel||rawChannel===`all`?plugins:(()=>{let plugin=getChannelPlugin(rawChannel);return plugin?[plugin]:null})();if(!selected||selected.length===0){runtime.error(danger(`Unknown channel "${rawChannel}".`)),runtime.exit(1);return}let reports=[];for(let plugin of selected){let accountOverride=opts.account?.trim()||void 0;reports.push(...await resolveChannelReports({plugin,cfg,timeoutMs,accountOverride,target:rawTarget&&plugin.id===`discord`?rawTarget:void 0}))}if(opts.json){runtime.log(JSON.stringify({channels:reports},null,2));return}let lines=[];for(let report of reports){let label=formatChannelAccountLabel({channel:report.channel,accountId:report.accountId,name:report.accountName,channelStyle:theme.accent,accountStyle:theme.heading});if(lines.push(theme.heading(label)),lines.push(`Support: ${formatSupport(report.support)}`),report.actions&&report.actions.length>0&&lines.push(`Actions: ${report.actions.join(`, `)}`),report.configured===!1||report.enabled===!1){let configuredLabel=report.configured===!1?`not configured`:`configured`,enabledLabel=report.enabled===!1?`disabled`:`enabled`;lines.push(`Status: ${configuredLabel}, ${enabledLabel}`)}let probeLines=formatProbeLines(report.channel,report.probe);if(probeLines.length>0?lines.push(...probeLines):report.configured&&report.enabled&&lines.push(theme.muted(`Probe: unavailable`)),report.channel===`slack`&&report.slackScopes)for(let entry of report.slackScopes){let source=entry.result.source?` (${entry.result.source})`:``,label=entry.tokenType===`user`?`User scopes`:`Bot scopes`;entry.result.ok&&entry.result.scopes?.length?lines.push(`${label}${source}: ${entry.result.scopes.join(`, `)}`):entry.result.error&&lines.push(`${label}: ${theme.error(entry.result.error)}`)}if(report.channel===`discord`&&report.channelPermissions){let perms=report.channelPermissions;if(perms.error)lines.push(`Permissions: ${theme.error(perms.error)}`);else{let list=perms.permissions?.length?perms.permissions.join(`, `):`none`,label=perms.channelId?` (${perms.channelId})`:``;lines.push(`Permissions${label}: ${list}`),perms.missingRequired&&perms.missingRequired.length>0?lines.push(`${theme.warn(`Missing required:`)} ${perms.missingRequired.join(`, `)}`):lines.push(theme.success(`Missing required: none`))}}else report.channel===`discord`&&rawTarget&&!report.channelPermissions&&lines.push(theme.muted(`Permissions: skipped (no target).`));lines.push(``)}runtime.log(lines.join(`
2
2
  `).trimEnd())}const colorValue=value=>value===`none`?theme.error(value):value===`env`?theme.accent(value):theme.success(value);function formatEnabled(value){return value===!1?theme.error(`disabled`):theme.success(`enabled`)}function formatConfigured(value){return value?theme.success(`configured`):theme.warn(`not configured`)}function formatTokenSource(source){return`token=${colorValue(source||`none`)}`}function formatSource(label,source){return`${label}=${colorValue(source||`none`)}`}function formatLinked(value){return value?theme.success(`linked`):theme.warn(`not linked`)}function shouldShowConfigured(channel){return channel.meta.showConfigured!==!1}function formatAccountLine(params){let{channel,snapshot}=params,label=formatChannelAccountLabel({channel:channel.id,accountId:snapshot.accountId,name:snapshot.name,channelStyle:theme.accent,accountStyle:theme.heading}),bits=[];return snapshot.linked!==void 0&&bits.push(formatLinked(snapshot.linked)),shouldShowConfigured(channel)&&typeof snapshot.configured==`boolean`&&bits.push(formatConfigured(snapshot.configured)),snapshot.tokenSource&&bits.push(formatTokenSource(snapshot.tokenSource)),snapshot.botTokenSource&&bits.push(formatSource(`bot`,snapshot.botTokenSource)),snapshot.appTokenSource&&bits.push(formatSource(`app`,snapshot.appTokenSource)),snapshot.baseUrl&&bits.push(`base=${theme.muted(snapshot.baseUrl)}`),typeof snapshot.enabled==`boolean`&&bits.push(formatEnabled(snapshot.enabled)),`- ${label}: ${bits.join(`, `)}`}async function loadUsageWithProgress(runtime){try{return await withProgress({label:`Fetching usage snapshot…`,indeterminate:!0,enabled:!0},async()=>await loadProviderUsageSummary())}catch(err){return runtime.error(String(err)),null}}async function channelsListCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let includeUsage=opts.usage!==!1,plugins=listChannelPlugins(),authStore=await loadAuthProfileStore(),authProfiles=Object.entries(authStore.profiles).map(([profileId,profile])=>({id:profileId,provider:profile.provider,type:profile.type,isExternal:!1}));if(opts.json){let usage=includeUsage?await loadProviderUsageSummary():void 0,chat={};for(let plugin of plugins)chat[plugin.id]=plugin.config.listAccountIds(cfg);let payload={chat,auth:authProfiles,...usage?{usage}:{}};runtime.log(JSON.stringify(payload,null,2));return}let lines=[];lines.push(theme.heading(`Chat channels:`));for(let plugin of plugins){let accounts=plugin.config.listAccountIds(cfg);if(!(!accounts||accounts.length===0))for(let accountId of accounts){let snapshot=await buildChannelAccountSnapshot({plugin,cfg,accountId});lines.push(formatAccountLine({channel:plugin,snapshot}))}}if(lines.push(``),lines.push(theme.heading(`Auth providers (OAuth + API keys):`)),authProfiles.length===0)lines.push(theme.muted(`- none`));else for(let profile of authProfiles){let external=profile.isExternal?theme.muted(` (synced)`):``;lines.push(`- ${theme.accent(profile.id)} (${theme.success(profile.type)}${external})`)}if(runtime.log(lines.join(`
3
3
  `)),includeUsage){runtime.log(``);let usage=await loadUsageWithProgress(runtime);if(usage){let usageLines=formatUsageReportLines(usage);usageLines.length>0&&(usageLines[0]=theme.accent(usageLines[0]),runtime.log(usageLines.join(`
4
4
  `)))}}runtime.log(``),runtime.log(`Docs: ${formatDocsLink(`/gateway/configuration`,`gateway/configuration`)}`)}const getChannelSet=()=>new Set([...listChannelPlugins().map(plugin=>plugin.id),`all`]);function parseChannelFilter(raw){let trimmed=raw?.trim().toLowerCase();return trimmed&&getChannelSet().has(trimmed)?trimmed:`all`}function matchesChannel(line,channel){if(channel===`all`)return!0;let needle=`gateway/channels/${channel}`;return!!(line.subsystem?.includes(needle)||line.module?.includes(channel))}async function readTailLines(file,limit){let stat=await fs.stat(file).catch(()=>null);if(!stat)return[];let size=stat.size,start=Math.max(0,size-1e6),handle=await fs.open(file,`r`);try{let length=Math.max(0,size-start);if(length===0)return[];let buffer=Buffer.alloc(length),readResult=await handle.read(buffer,0,length,start),lines=buffer.toString(`utf8`,0,readResult.bytesRead).split(`
@@ -1,4 +1,4 @@
1
- import"./paths-BHg-VHB4.js";import{r as DEFAULT_CHAT_CHANNEL}from"./registry-Cv7CoWAs.js";import{D as danger,N as setVerbose,W as getResolvedLoggerSettings,d as isRecord,z as theme}from"./utils-BP60e80M.js";import{p as defaultRuntime}from"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./warning-filter-nSTjpMIH.js";import{x as loadAuthProfileStore}from"./auth-profiles-CuAFgjuQ.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import{n as DEFAULT_ACCOUNT_ID,u as normalizeAccountId}from"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import{c as resolveAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-CufEmNj_.js";import"./env-file-DeS6x2OL.js";import"./src-C8c9naq-.js";import{a as readConfigFileSnapshot,c as writeConfigFile,r as loadConfig}from"./io-CsCa3_1Z.js";import"./manifest-registry-009gLJ4l.js";import"./config-DmxNxDRW.js";import"./model-discovery-RTHjxEvZ.js";import"./model-catalog-D8OQ7p7I.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./refresh-C4vwneXT.js";import"./client-CGgp3zkQ.js";import{n as callGateway}from"./call-O-iC_P5t.js";import"./message-channel-z5YRpR2d.js";import{T as deleteTelegramUpdateOffset}from"./subagent-registry-Cj5yC7B4.js";import"./sessions-CmJXMlLP.js";import"./project-context-store-BNXYrLJz.js";import"./tokens-CFKkpUIu.js";import{l as resolveTelegramAccount,n as listChannelPlugins,r as normalizeChannelId,t as getChannelPlugin}from"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import{r as createSlackWebClient}from"./send-CGcNbbV7.js";import{Q as fetchChannelPermissionsDiscord,tt as parseDiscordTarget}from"./send-DPRTlcZh.js";import"./with-timeout-CBXVw0An.js";import"./deliver--eLCRJc2.js";import"./accounts-Cx82nj4E.js";import"./send-DfHAMPcD.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-BZGiFZlP.js";import"./sandbox-C-Owvt1-.js";import"./chrome-BfwLDcFc.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-BjYYSEVE.js";import"./routes-Dnfsevhw.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./workspace-waBqRxiy.js";import"./reply-prefix-Cg7AqaK0.js";import"./sqlite-CIGM1WKg.js";import"./memory-cli-CiwWAhp5.js";import"./manager-Bjb9ptCz.js";import"./gemini-auth-KBXMhaRQ.js";import"./retry-B151Hej5.js";import"./common-BfwMxpLu.js";import"./runner-DwPaM8kz.js";import"./tool-display-Cs4hDP1f.js";import"./chunk-Dly7lM4r.js";import"./markdown-tables-B1Rx8hv6.js";import"./fetch-guard-DnXqPKae.js";import"./fetch-Cn_THzz8.js";import"./ir-CSdQJPqu.js";import"./render-DlHYsbvQ.js";import"./builderforcellm-syscheck-tquUDu_7.js";import{n as formatTimeAgo}from"./format-relative-CruqE52s.js";import"./session-utils-D2_j4c6U.js";import"./coding-tools.policy-BwdtwuXY.js";import"./pairing-store-BCsvhT6-.js";import"./fetch-DnWD6ydH.js";import"./exec-approvals-D7ZPAZpt.js";import"./nodes-screen-D6GHv_S0.js";import"./session-cost-usage-S0nkbPoW.js";import"./usage-format-5sp5AMSu.js";import{n as formatUsageReportLines,t as loadProviderUsageSummary}from"./provider-usage-DsI3qJRy.js";import"./send-BOSlm5fG.js";import"./outbound-attachment-BaTYE4qp.js";import"./delivery-queue-Cp3t4Upn.js";import"./project-context-BdK18hVI.js";import"./control-service-Ca0CBlhO.js";import"./stagger-CRe77dWL.js";import{n as resolveMessageChannelSelection}from"./channel-selection-BLwXhb9t.js";import"./send-BOBan2eG.js";import"./resolve-route-DEIW5uKy.js";import"./channel-activity-DX36RadH.js";import"./tables-CojSfTth.js";import{t as formatDocsLink}from"./links-BKzP7VVP.js";import{n as runCommandWithRuntime}from"./cli-utils-C9pW69LF.js";import{t as formatHelpExamples}from"./help-format-CfFf-w62.js";import{n as withProgress}from"./progress-Cqb-jAjT.js";import"./replies-DATdLu15.js";import"./onboard-helpers-D2vxAtv8.js";import"./prompt-style-BMWmaqSC.js";import"./pairing-labels-BUXpRejW.js";import"./active-listener-Di9e1YAD.js";import"./mamba-state-engine-DJt_RpLC.js";import"./transformers-stream-Buj40qHl.js";import{t as hasExplicitOptions}from"./command-options-DbMbMxM2.js";import{r as listChannelPluginCatalogEntries}from"./catalog-li4bSIE2.js";import"./note-DgDXuE0F.js";import{t as createClackPrompter}from"./clack-prompter-B52CP7eY.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DPPVplyk.js";import"./plugin-auto-enable-DT7HMdAA.js";import"./install-safe-path-ObPl6zIf.js";import"./npm-registry-spec-BV1VDmuN.js";import"./skill-scanner-C2gXLVti.js";import"./installs-C7X7CT9a.js";import{i as reloadOnboardingPluginRegistry,n as setupChannels,r as ensureOnboardingPluginInstalled}from"./onboard-channels-C_Q7OUow.js";import{t as requireValidConfigSnapshot}from"./config-validation-DZ_PL8zv.js";import{t as buildChannelAccountSnapshot}from"./status-BXI_BTqV.js";import{t as parseLogLine}from"./parse-log-line-Xw9Ui348.js";import{t as collectChannelStatusIssues}from"./channels-status-issues-NLYb8w9i.js";import"./plugin-registry-CFkQDTOt.js";import{t as formatCliChannelOptions}from"./channel-options-Cziy0WDc.js";import fs from"node:fs/promises";function applyAccountName(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountName;return apply?apply({cfg:params.cfg,accountId,name:params.name}):params.cfg}function applyChannelAccountConfig(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountConfig;return apply?apply({cfg:params.cfg,accountId,input:params.input}):params.cfg}async function requireValidConfig(runtime=defaultRuntime){return await requireValidConfigSnapshot(runtime)}function formatAccountLabel(params){let base=params.accountId||DEFAULT_ACCOUNT_ID;return params.name?.trim()?`${base} (${params.name.trim()})`:base}const channelLabel=channel=>getChannelPlugin(channel)?.meta.label??channel;function formatChannelAccountLabel(params){let channelText=channelLabel(params.channel),accountText=formatAccountLabel({accountId:params.accountId,name:params.name});return`${params.channelStyle?params.channelStyle(channelText):channelText} ${params.accountStyle?params.accountStyle(accountText):accountText}`}function shouldUseWizard(params){return params?.hasFlags===!1}function parseList(value){if(!value?.trim())return;let parsed=value.split(/[\n,;]+/g).map(entry=>entry.trim()).filter(Boolean);return parsed.length>0?parsed:void 0}function resolveCatalogChannelEntry(raw,cfg){let trimmed=raw.trim().toLowerCase();if(trimmed)return listChannelPluginCatalogEntries({workspaceDir:cfg?resolveAgentWorkspaceDir(cfg,resolveDefaultAgentId(cfg)):void 0}).find(entry=>entry.id.toLowerCase()===trimmed?!0:(entry.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===trimmed))}async function channelsAddCommand(opts,runtime=defaultRuntime,params){let cfg=await requireValidConfig(runtime);if(!cfg)return;let nextConfig=cfg;if(shouldUseWizard(params)){let prompter=createClackPrompter(),selection=[],accountIds={};await prompter.intro(`Channel setup`);let nextConfig=await setupChannels(cfg,runtime,prompter,{allowDisable:!1,allowSignalInstall:!0,promptAccountIds:!0,onSelection:value=>{selection=value},onAccountId:(channel,accountId)=>{accountIds[channel]=accountId}});if(selection.length===0){await prompter.outro(`No channels selected.`);return}if(await prompter.confirm({message:`Add display names for these accounts? (optional)`,initialValue:!1}))for(let channel of selection){let accountId=accountIds[channel]??DEFAULT_ACCOUNT_ID,plugin=getChannelPlugin(channel),account=plugin?.config.resolveAccount(nextConfig,accountId),existingName=plugin?.config.describeAccount?.(account,nextConfig)?.name??account?.name,name=await prompter.text({message:`${channel} account name (${accountId})`,initialValue:existingName});name?.trim()&&(nextConfig=applyAccountName({cfg:nextConfig,channel,accountId,name}))}await writeConfigFile(nextConfig),await prompter.outro(`Channels updated.`);return}let rawChannel=String(opts.channel??``),channel=normalizeChannelId(rawChannel),catalogEntry=channel?void 0:resolveCatalogChannelEntry(rawChannel,nextConfig);if(!channel&&catalogEntry){let prompter=createClackPrompter(),workspaceDir=resolveAgentWorkspaceDir(nextConfig,resolveDefaultAgentId(nextConfig)),result=await ensureOnboardingPluginInstalled({cfg:nextConfig,entry:catalogEntry,prompter,runtime,workspaceDir});if(nextConfig=result.cfg,!result.installed)return;reloadOnboardingPluginRegistry({cfg:nextConfig,runtime,workspaceDir}),channel=normalizeChannelId(catalogEntry.id)??catalogEntry.id}if(!channel){let hint=catalogEntry?`Plugin ${catalogEntry.meta.label} could not be loaded after install.`:`Unknown channel: ${String(opts.channel??``)}`;runtime.error(hint),runtime.exit(1);return}let plugin=getChannelPlugin(channel);if(!plugin?.setup?.applyAccountConfig){runtime.error(`Channel ${channel} does not support add.`),runtime.exit(1);return}let accountId=plugin.setup.resolveAccountId?.({cfg:nextConfig,accountId:opts.account})??normalizeAccountId(opts.account),useEnv=opts.useEnv===!0,initialSyncLimit=typeof opts.initialSyncLimit==`number`?opts.initialSyncLimit:typeof opts.initialSyncLimit==`string`&&opts.initialSyncLimit.trim()?Number.parseInt(opts.initialSyncLimit,10):void 0,groupChannels=parseList(opts.groupChannels),dmAllowlist=parseList(opts.dmAllowlist),input={name:opts.name,token:opts.token,tokenFile:opts.tokenFile,botToken:opts.botToken,appToken:opts.appToken,signalNumber:opts.signalNumber,cliPath:opts.cliPath,dbPath:opts.dbPath,service:opts.service,region:opts.region,authDir:opts.authDir,httpUrl:opts.httpUrl,httpHost:opts.httpHost,httpPort:opts.httpPort,webhookPath:opts.webhookPath,webhookUrl:opts.webhookUrl,audienceType:opts.audienceType,audience:opts.audience,homeserver:opts.homeserver,userId:opts.userId,accessToken:opts.accessToken,password:opts.password,deviceName:opts.deviceName,initialSyncLimit,useEnv,ship:opts.ship,url:opts.url,code:opts.code,groupChannels,dmAllowlist,autoDiscoverChannels:opts.autoDiscoverChannels},validationError=plugin.setup.validateInput?.({cfg:nextConfig,accountId,input});if(validationError){runtime.error(validationError),runtime.exit(1);return}let previousTelegramToken=channel===`telegram`?resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim():``;nextConfig=applyChannelAccountConfig({cfg:nextConfig,channel,accountId,input}),channel===`telegram`&&previousTelegramToken!==resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim()&&await deleteTelegramUpdateOffset({accountId}),await writeConfigFile(nextConfig),runtime.log(`Added ${channelLabel(channel)} account "${accountId}".`)}function collectScopes(value,into){if(value){if(Array.isArray(value)){for(let entry of value)typeof entry==`string`&&entry.trim()&&into.push(entry.trim());return}if(typeof value==`string`){let raw=value.trim();if(!raw)return;let parts=raw.split(/[,\s]+/).map(part=>part.trim());for(let part of parts)part&&into.push(part);return}if(isRecord(value))for(let entry of Object.values(value))(Array.isArray(entry)||typeof entry==`string`)&&collectScopes(entry,into)}}function normalizeScopes(scopes){return Array.from(new Set(scopes.map(scope=>scope.trim()).filter(Boolean))).toSorted()}function extractScopes(payload){if(!isRecord(payload))return[];let scopes=[];return collectScopes(payload.scopes,scopes),collectScopes(payload.scope,scopes),isRecord(payload.info)&&(collectScopes(payload.info.scopes,scopes),collectScopes(payload.info.scope,scopes),collectScopes(payload.info.user_scopes,scopes),collectScopes(payload.info.bot_scopes,scopes)),normalizeScopes(scopes)}function readError(payload){if(!isRecord(payload))return;let error=payload.error;return typeof error==`string`&&error.trim()?error.trim():void 0}async function callSlack(client,method){try{let result=await client.apiCall(method);return isRecord(result)?result:null}catch(err){return{ok:!1,error:err instanceof Error?err.message:String(err)}}}async function fetchSlackScopes(token,timeoutMs){let client=createSlackWebClient(token,{timeout:timeoutMs}),attempts=[`auth.scopes`,`apps.permissions.info`],errors=[];for(let method of attempts){let result=await callSlack(client,method),scopes=extractScopes(result);if(scopes.length>0)return{ok:!0,scopes,source:method};let error=readError(result);error&&errors.push(`${method}: ${error}`)}return{ok:!1,error:errors.length>0?errors.join(` | `):`no scopes returned`}}const REQUIRED_DISCORD_PERMISSIONS=[`ViewChannel`,`SendMessages`],TEAMS_GRAPH_PERMISSION_HINTS={"ChannelMessage.Read.All":`channel history`,"Chat.Read.All":`chat history`,"Channel.ReadBasic.All":`channel list`,"Team.ReadBasic.All":`team list`,"TeamsActivity.Read.All":`teams activity`,"Sites.Read.All":`files (SharePoint)`,"Files.Read.All":`files (OneDrive)`};function normalizeTimeout(raw,fallback=1e4){let value=Number(raw);return!Number.isFinite(value)||value<=0?fallback:value}function formatSupport(capabilities){if(!capabilities)return`unknown`;let bits=[];return capabilities.chatTypes?.length&&bits.push(`chatTypes=${capabilities.chatTypes.join(`,`)}`),capabilities.polls&&bits.push(`polls`),capabilities.reactions&&bits.push(`reactions`),capabilities.edit&&bits.push(`edit`),capabilities.unsend&&bits.push(`unsend`),capabilities.reply&&bits.push(`reply`),capabilities.effects&&bits.push(`effects`),capabilities.groupManagement&&bits.push(`groupManagement`),capabilities.threads&&bits.push(`threads`),capabilities.media&&bits.push(`media`),capabilities.nativeCommands&&bits.push(`nativeCommands`),capabilities.blockStreaming&&bits.push(`blockStreaming`),bits.length?bits.join(` `):`none`}function summarizeDiscordTarget(raw){if(!raw)return;let target=parseDiscordTarget(raw,{defaultKind:`channel`});return target?target.kind===`channel`?{raw,normalized:target.normalized,kind:`channel`,channelId:target.id}:target.kind===`user`?{raw,normalized:target.normalized,kind:`user`}:{raw,normalized:target.normalized}:{raw}}function formatDiscordIntents(intents){return intents?[`messageContent=${intents.messageContent??`unknown`}`,`guildMembers=${intents.guildMembers??`unknown`}`,`presence=${intents.presence??`unknown`}`].join(` `):`unknown`}function formatProbeLines(channelId,probe){let lines=[];if(!probe||typeof probe!=`object`)return lines;let probeObj=probe;if(channelId===`discord`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let app=probeObj.application;app?.intents&&lines.push(`Intents: ${formatDiscordIntents(app.intents)}`)}if(channelId===`telegram`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let flags=[],canJoinGroups=bot?.canJoinGroups,canReadAll=bot?.canReadAllGroupMessages,inlineQueries=bot?.supportsInlineQueries;typeof canJoinGroups==`boolean`&&flags.push(`joinGroups=${canJoinGroups}`),typeof canReadAll==`boolean`&&flags.push(`readAllGroupMessages=${canReadAll}`),typeof inlineQueries==`boolean`&&flags.push(`inlineQueries=${inlineQueries}`),flags.length>0&&lines.push(`Flags: ${flags.join(` `)}`);let webhook=probeObj.webhook;webhook?.url!==void 0&&lines.push(`Webhook: ${webhook.url||`none`}`)}if(channelId===`slack`){let bot=probeObj.bot,team=probeObj.team;if(bot?.name&&lines.push(`Bot: ${theme.accent(`@${bot.name}`)}`),team?.name||team?.id){let id=team?.id?` (${team.id})`:``;lines.push(`Team: ${team?.name??`unknown`}${id}`)}}if(channelId===`signal`){let version=probeObj.version;version&&lines.push(`Signal daemon: ${version}`)}if(channelId===`msteams`){let appId=typeof probeObj.appId==`string`?probeObj.appId.trim():``;appId&&lines.push(`App: ${theme.accent(appId)}`);let graph=probeObj.graph;if(graph){let roles=Array.isArray(graph.roles)?graph.roles.map(role=>String(role).trim()).filter(Boolean):[],scopes=typeof graph.scopes==`string`?graph.scopes.split(/\s+/).map(scope=>scope.trim()).filter(Boolean):Array.isArray(graph.scopes)?graph.scopes.map(scope=>String(scope).trim()).filter(Boolean):[];if(graph.ok===!1)lines.push(`Graph: ${theme.error(graph.error??`failed`)}`);else if(roles.length>0||scopes.length>0){let formatPermission=permission=>{let hint=TEAMS_GRAPH_PERMISSION_HINTS[permission];return hint?`${permission} (${hint})`:permission};roles.length>0&&lines.push(`Graph roles: ${roles.map(formatPermission).join(`, `)}`),scopes.length>0&&lines.push(`Graph scopes: ${scopes.map(formatPermission).join(`, `)}`)}else graph.ok===!0&&lines.push(`Graph: ok`)}}let ok=typeof probeObj.ok==`boolean`?probeObj.ok:void 0;if(ok===!0&&lines.length===0&&lines.push(`Probe: ok`),ok===!1){let error=typeof probeObj.error==`string`&&probeObj.error?` (${probeObj.error})`:``;lines.push(`Probe: ${theme.error(`failed${error}`)}`)}return lines}async function buildDiscordPermissions(params){let target=summarizeDiscordTarget(params.target?.trim());if(!target)return{};if(target.kind!==`channel`||!target.channelId)return{target,report:{error:`Target looks like a DM user; pass channel:<id> to audit channel permissions.`}};let token=params.account.token?.trim();if(!token)return{target,report:{channelId:target.channelId,error:`Discord bot token missing for permission audit.`}};try{let perms=await fetchChannelPermissionsDiscord(target.channelId,{token,accountId:params.account.accountId??void 0}),missing=REQUIRED_DISCORD_PERMISSIONS.filter(permission=>!perms.permissions.includes(permission));return{target,report:{channelId:perms.channelId,guildId:perms.guildId,isDm:perms.isDm,channelType:perms.channelType,permissions:perms.permissions,missingRequired:missing.length?missing:[],raw:perms.raw}}}catch(err){return{target,report:{channelId:target.channelId,error:err instanceof Error?err.message:String(err)}}}}async function resolveChannelReports(params){let{plugin,cfg,timeoutMs}=params,accountIds=params.accountOverride?[params.accountOverride]:(()=>{let ids=plugin.config.listAccountIds(cfg);return ids.length>0?ids:[resolveChannelDefaultAccountId({plugin,cfg,accountIds:ids})]})(),reports=[],listedActions=plugin.actions?.listActions?.({cfg})??[],actions=Array.from(new Set([`send`,`broadcast`,...listedActions.map(action=>String(action))]));for(let accountId of accountIds){let resolvedAccount=plugin.config.resolveAccount(cfg,accountId),configured=plugin.config.isConfigured?await plugin.config.isConfigured(resolvedAccount,cfg):!!resolvedAccount,enabled=plugin.config.isEnabled?plugin.config.isEnabled(resolvedAccount,cfg):resolvedAccount.enabled!==!1,probe;if(configured&&enabled&&plugin.status?.probeAccount)try{probe=await plugin.status.probeAccount({account:resolvedAccount,timeoutMs,cfg})}catch(err){probe={ok:!1,error:err instanceof Error?err.message:String(err)}}let slackScopes;if(plugin.id===`slack`&&configured&&enabled){let botToken=resolvedAccount.botToken?.trim(),userToken=resolvedAccount.config?.userToken?.trim(),scopeReports=[];botToken?scopeReports.push({tokenType:`bot`,result:await fetchSlackScopes(botToken,timeoutMs)}):scopeReports.push({tokenType:`bot`,result:{ok:!1,error:`Slack bot token missing.`}}),userToken&&scopeReports.push({tokenType:`user`,result:await fetchSlackScopes(userToken,timeoutMs)}),slackScopes=scopeReports}let discordTarget,discordPermissions;if(plugin.id===`discord`&&params.target){let perms=await buildDiscordPermissions({account:resolvedAccount,target:params.target});discordTarget=perms.target,discordPermissions=perms.report}reports.push({channel:plugin.id,accountId,accountName:typeof resolvedAccount.name==`string`&&resolvedAccount.name?.trim()||void 0,configured,enabled,support:plugin.capabilities,probe,target:discordTarget,channelPermissions:discordPermissions,actions,slackScopes})}return reports}async function channelsCapabilitiesCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let timeoutMs=normalizeTimeout(opts.timeout,1e4),rawChannel=typeof opts.channel==`string`?opts.channel.trim().toLowerCase():``,rawTarget=typeof opts.target==`string`?opts.target.trim():``;if(opts.account&&(!rawChannel||rawChannel===`all`)){runtime.error(danger(`--account requires a specific --channel.`)),runtime.exit(1);return}if(rawTarget&&rawChannel!==`discord`){runtime.error(danger(`--target requires --channel discord.`)),runtime.exit(1);return}let plugins=listChannelPlugins(),selected=!rawChannel||rawChannel===`all`?plugins:(()=>{let plugin=getChannelPlugin(rawChannel);return plugin?[plugin]:null})();if(!selected||selected.length===0){runtime.error(danger(`Unknown channel "${rawChannel}".`)),runtime.exit(1);return}let reports=[];for(let plugin of selected){let accountOverride=opts.account?.trim()||void 0;reports.push(...await resolveChannelReports({plugin,cfg,timeoutMs,accountOverride,target:rawTarget&&plugin.id===`discord`?rawTarget:void 0}))}if(opts.json){runtime.log(JSON.stringify({channels:reports},null,2));return}let lines=[];for(let report of reports){let label=formatChannelAccountLabel({channel:report.channel,accountId:report.accountId,name:report.accountName,channelStyle:theme.accent,accountStyle:theme.heading});if(lines.push(theme.heading(label)),lines.push(`Support: ${formatSupport(report.support)}`),report.actions&&report.actions.length>0&&lines.push(`Actions: ${report.actions.join(`, `)}`),report.configured===!1||report.enabled===!1){let configuredLabel=report.configured===!1?`not configured`:`configured`,enabledLabel=report.enabled===!1?`disabled`:`enabled`;lines.push(`Status: ${configuredLabel}, ${enabledLabel}`)}let probeLines=formatProbeLines(report.channel,report.probe);if(probeLines.length>0?lines.push(...probeLines):report.configured&&report.enabled&&lines.push(theme.muted(`Probe: unavailable`)),report.channel===`slack`&&report.slackScopes)for(let entry of report.slackScopes){let source=entry.result.source?` (${entry.result.source})`:``,label=entry.tokenType===`user`?`User scopes`:`Bot scopes`;entry.result.ok&&entry.result.scopes?.length?lines.push(`${label}${source}: ${entry.result.scopes.join(`, `)}`):entry.result.error&&lines.push(`${label}: ${theme.error(entry.result.error)}`)}if(report.channel===`discord`&&report.channelPermissions){let perms=report.channelPermissions;if(perms.error)lines.push(`Permissions: ${theme.error(perms.error)}`);else{let list=perms.permissions?.length?perms.permissions.join(`, `):`none`,label=perms.channelId?` (${perms.channelId})`:``;lines.push(`Permissions${label}: ${list}`),perms.missingRequired&&perms.missingRequired.length>0?lines.push(`${theme.warn(`Missing required:`)} ${perms.missingRequired.join(`, `)}`):lines.push(theme.success(`Missing required: none`))}}else report.channel===`discord`&&rawTarget&&!report.channelPermissions&&lines.push(theme.muted(`Permissions: skipped (no target).`));lines.push(``)}runtime.log(lines.join(`
1
+ import"./paths-BHg-VHB4.js";import{r as DEFAULT_CHAT_CHANNEL}from"./registry-Cv7CoWAs.js";import{D as danger,N as setVerbose,W as getResolvedLoggerSettings,d as isRecord,z as theme}from"./utils-BP60e80M.js";import{p as defaultRuntime}from"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./warning-filter-nSTjpMIH.js";import{x as loadAuthProfileStore}from"./auth-profiles-CuAFgjuQ.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import{n as DEFAULT_ACCOUNT_ID,u as normalizeAccountId}from"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import{c as resolveAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-CufEmNj_.js";import"./env-file-DeS6x2OL.js";import"./src-C8c9naq-.js";import{a as readConfigFileSnapshot,c as writeConfigFile,r as loadConfig}from"./io-CsCa3_1Z.js";import"./manifest-registry-009gLJ4l.js";import"./config-DmxNxDRW.js";import"./model-discovery-RTHjxEvZ.js";import"./model-catalog-D8OQ7p7I.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./refresh-C4vwneXT.js";import"./client-CGgp3zkQ.js";import{n as callGateway}from"./call-O-iC_P5t.js";import"./message-channel-z5YRpR2d.js";import{T as deleteTelegramUpdateOffset}from"./subagent-registry-m_x-JRkR.js";import"./sessions-CmJXMlLP.js";import"./project-context-store-BNXYrLJz.js";import"./tokens-CFKkpUIu.js";import{l as resolveTelegramAccount,n as listChannelPlugins,r as normalizeChannelId,t as getChannelPlugin}from"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import{r as createSlackWebClient}from"./send-CGcNbbV7.js";import{Q as fetchChannelPermissionsDiscord,tt as parseDiscordTarget}from"./send-DPRTlcZh.js";import"./with-timeout-CBXVw0An.js";import"./deliver--eLCRJc2.js";import"./accounts-Cx82nj4E.js";import"./send-DfHAMPcD.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-BZGiFZlP.js";import"./sandbox-C-Owvt1-.js";import"./chrome-BfwLDcFc.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-BjYYSEVE.js";import"./routes-Dnfsevhw.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./workspace-waBqRxiy.js";import"./reply-prefix-Cg7AqaK0.js";import"./sqlite-CIGM1WKg.js";import"./memory-cli-CiwWAhp5.js";import"./manager-Bjb9ptCz.js";import"./gemini-auth-KBXMhaRQ.js";import"./retry-B151Hej5.js";import"./common-BfwMxpLu.js";import"./runner-DwPaM8kz.js";import"./tool-display-Cs4hDP1f.js";import"./chunk-Dly7lM4r.js";import"./markdown-tables-B1Rx8hv6.js";import"./fetch-guard-DnXqPKae.js";import"./fetch-Cn_THzz8.js";import"./ir-CSdQJPqu.js";import"./render-DlHYsbvQ.js";import"./builderforcellm-syscheck-tquUDu_7.js";import{n as formatTimeAgo}from"./format-relative-CruqE52s.js";import"./session-utils-D2_j4c6U.js";import"./coding-tools.policy-BwdtwuXY.js";import"./pairing-store-BCsvhT6-.js";import"./fetch-DnWD6ydH.js";import"./exec-approvals-D7ZPAZpt.js";import"./nodes-screen-D6GHv_S0.js";import"./session-cost-usage-S0nkbPoW.js";import"./usage-format-5sp5AMSu.js";import{n as formatUsageReportLines,t as loadProviderUsageSummary}from"./provider-usage-DsI3qJRy.js";import"./send-BOSlm5fG.js";import"./outbound-attachment-BaTYE4qp.js";import"./delivery-queue-Cp3t4Upn.js";import"./project-context-BdK18hVI.js";import"./control-service-Ca0CBlhO.js";import"./stagger-CRe77dWL.js";import{n as resolveMessageChannelSelection}from"./channel-selection-BLwXhb9t.js";import"./send-BOBan2eG.js";import"./resolve-route-DEIW5uKy.js";import"./channel-activity-DX36RadH.js";import"./tables-CojSfTth.js";import{t as formatDocsLink}from"./links-BKzP7VVP.js";import{n as runCommandWithRuntime}from"./cli-utils-C9pW69LF.js";import{t as formatHelpExamples}from"./help-format-CfFf-w62.js";import{n as withProgress}from"./progress-Cqb-jAjT.js";import"./replies-DATdLu15.js";import"./onboard-helpers-D2vxAtv8.js";import"./prompt-style-BMWmaqSC.js";import"./pairing-labels-BUXpRejW.js";import"./active-listener-Di9e1YAD.js";import"./mamba-state-engine-DJt_RpLC.js";import"./transformers-stream-Buj40qHl.js";import{t as hasExplicitOptions}from"./command-options-DbMbMxM2.js";import{r as listChannelPluginCatalogEntries}from"./catalog-li4bSIE2.js";import"./note-DgDXuE0F.js";import{t as createClackPrompter}from"./clack-prompter-B52CP7eY.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DPPVplyk.js";import"./plugin-auto-enable-DT7HMdAA.js";import"./install-safe-path-ObPl6zIf.js";import"./npm-registry-spec-BV1VDmuN.js";import"./skill-scanner-C2gXLVti.js";import"./installs-C7X7CT9a.js";import{i as reloadOnboardingPluginRegistry,n as setupChannels,r as ensureOnboardingPluginInstalled}from"./onboard-channels-ZI4QC9WU.js";import{t as requireValidConfigSnapshot}from"./config-validation-DZ_PL8zv.js";import{t as buildChannelAccountSnapshot}from"./status-BXI_BTqV.js";import{t as parseLogLine}from"./parse-log-line-Xw9Ui348.js";import{t as collectChannelStatusIssues}from"./channels-status-issues-NLYb8w9i.js";import"./plugin-registry-DdFb5usc.js";import{t as formatCliChannelOptions}from"./channel-options-D5kOIN7b.js";import fs from"node:fs/promises";function applyAccountName(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountName;return apply?apply({cfg:params.cfg,accountId,name:params.name}):params.cfg}function applyChannelAccountConfig(params){let accountId=normalizeAccountId(params.accountId),apply=getChannelPlugin(params.channel)?.setup?.applyAccountConfig;return apply?apply({cfg:params.cfg,accountId,input:params.input}):params.cfg}async function requireValidConfig(runtime=defaultRuntime){return await requireValidConfigSnapshot(runtime)}function formatAccountLabel(params){let base=params.accountId||DEFAULT_ACCOUNT_ID;return params.name?.trim()?`${base} (${params.name.trim()})`:base}const channelLabel=channel=>getChannelPlugin(channel)?.meta.label??channel;function formatChannelAccountLabel(params){let channelText=channelLabel(params.channel),accountText=formatAccountLabel({accountId:params.accountId,name:params.name});return`${params.channelStyle?params.channelStyle(channelText):channelText} ${params.accountStyle?params.accountStyle(accountText):accountText}`}function shouldUseWizard(params){return params?.hasFlags===!1}function parseList(value){if(!value?.trim())return;let parsed=value.split(/[\n,;]+/g).map(entry=>entry.trim()).filter(Boolean);return parsed.length>0?parsed:void 0}function resolveCatalogChannelEntry(raw,cfg){let trimmed=raw.trim().toLowerCase();if(trimmed)return listChannelPluginCatalogEntries({workspaceDir:cfg?resolveAgentWorkspaceDir(cfg,resolveDefaultAgentId(cfg)):void 0}).find(entry=>entry.id.toLowerCase()===trimmed?!0:(entry.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===trimmed))}async function channelsAddCommand(opts,runtime=defaultRuntime,params){let cfg=await requireValidConfig(runtime);if(!cfg)return;let nextConfig=cfg;if(shouldUseWizard(params)){let prompter=createClackPrompter(),selection=[],accountIds={};await prompter.intro(`Channel setup`);let nextConfig=await setupChannels(cfg,runtime,prompter,{allowDisable:!1,allowSignalInstall:!0,promptAccountIds:!0,onSelection:value=>{selection=value},onAccountId:(channel,accountId)=>{accountIds[channel]=accountId}});if(selection.length===0){await prompter.outro(`No channels selected.`);return}if(await prompter.confirm({message:`Add display names for these accounts? (optional)`,initialValue:!1}))for(let channel of selection){let accountId=accountIds[channel]??DEFAULT_ACCOUNT_ID,plugin=getChannelPlugin(channel),account=plugin?.config.resolveAccount(nextConfig,accountId),existingName=plugin?.config.describeAccount?.(account,nextConfig)?.name??account?.name,name=await prompter.text({message:`${channel} account name (${accountId})`,initialValue:existingName});name?.trim()&&(nextConfig=applyAccountName({cfg:nextConfig,channel,accountId,name}))}await writeConfigFile(nextConfig),await prompter.outro(`Channels updated.`);return}let rawChannel=String(opts.channel??``),channel=normalizeChannelId(rawChannel),catalogEntry=channel?void 0:resolveCatalogChannelEntry(rawChannel,nextConfig);if(!channel&&catalogEntry){let prompter=createClackPrompter(),workspaceDir=resolveAgentWorkspaceDir(nextConfig,resolveDefaultAgentId(nextConfig)),result=await ensureOnboardingPluginInstalled({cfg:nextConfig,entry:catalogEntry,prompter,runtime,workspaceDir});if(nextConfig=result.cfg,!result.installed)return;reloadOnboardingPluginRegistry({cfg:nextConfig,runtime,workspaceDir}),channel=normalizeChannelId(catalogEntry.id)??catalogEntry.id}if(!channel){let hint=catalogEntry?`Plugin ${catalogEntry.meta.label} could not be loaded after install.`:`Unknown channel: ${String(opts.channel??``)}`;runtime.error(hint),runtime.exit(1);return}let plugin=getChannelPlugin(channel);if(!plugin?.setup?.applyAccountConfig){runtime.error(`Channel ${channel} does not support add.`),runtime.exit(1);return}let accountId=plugin.setup.resolveAccountId?.({cfg:nextConfig,accountId:opts.account})??normalizeAccountId(opts.account),useEnv=opts.useEnv===!0,initialSyncLimit=typeof opts.initialSyncLimit==`number`?opts.initialSyncLimit:typeof opts.initialSyncLimit==`string`&&opts.initialSyncLimit.trim()?Number.parseInt(opts.initialSyncLimit,10):void 0,groupChannels=parseList(opts.groupChannels),dmAllowlist=parseList(opts.dmAllowlist),input={name:opts.name,token:opts.token,tokenFile:opts.tokenFile,botToken:opts.botToken,appToken:opts.appToken,signalNumber:opts.signalNumber,cliPath:opts.cliPath,dbPath:opts.dbPath,service:opts.service,region:opts.region,authDir:opts.authDir,httpUrl:opts.httpUrl,httpHost:opts.httpHost,httpPort:opts.httpPort,webhookPath:opts.webhookPath,webhookUrl:opts.webhookUrl,audienceType:opts.audienceType,audience:opts.audience,homeserver:opts.homeserver,userId:opts.userId,accessToken:opts.accessToken,password:opts.password,deviceName:opts.deviceName,initialSyncLimit,useEnv,ship:opts.ship,url:opts.url,code:opts.code,groupChannels,dmAllowlist,autoDiscoverChannels:opts.autoDiscoverChannels},validationError=plugin.setup.validateInput?.({cfg:nextConfig,accountId,input});if(validationError){runtime.error(validationError),runtime.exit(1);return}let previousTelegramToken=channel===`telegram`?resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim():``;nextConfig=applyChannelAccountConfig({cfg:nextConfig,channel,accountId,input}),channel===`telegram`&&previousTelegramToken!==resolveTelegramAccount({cfg:nextConfig,accountId}).token.trim()&&await deleteTelegramUpdateOffset({accountId}),await writeConfigFile(nextConfig),runtime.log(`Added ${channelLabel(channel)} account "${accountId}".`)}function collectScopes(value,into){if(value){if(Array.isArray(value)){for(let entry of value)typeof entry==`string`&&entry.trim()&&into.push(entry.trim());return}if(typeof value==`string`){let raw=value.trim();if(!raw)return;let parts=raw.split(/[,\s]+/).map(part=>part.trim());for(let part of parts)part&&into.push(part);return}if(isRecord(value))for(let entry of Object.values(value))(Array.isArray(entry)||typeof entry==`string`)&&collectScopes(entry,into)}}function normalizeScopes(scopes){return Array.from(new Set(scopes.map(scope=>scope.trim()).filter(Boolean))).toSorted()}function extractScopes(payload){if(!isRecord(payload))return[];let scopes=[];return collectScopes(payload.scopes,scopes),collectScopes(payload.scope,scopes),isRecord(payload.info)&&(collectScopes(payload.info.scopes,scopes),collectScopes(payload.info.scope,scopes),collectScopes(payload.info.user_scopes,scopes),collectScopes(payload.info.bot_scopes,scopes)),normalizeScopes(scopes)}function readError(payload){if(!isRecord(payload))return;let error=payload.error;return typeof error==`string`&&error.trim()?error.trim():void 0}async function callSlack(client,method){try{let result=await client.apiCall(method);return isRecord(result)?result:null}catch(err){return{ok:!1,error:err instanceof Error?err.message:String(err)}}}async function fetchSlackScopes(token,timeoutMs){let client=createSlackWebClient(token,{timeout:timeoutMs}),attempts=[`auth.scopes`,`apps.permissions.info`],errors=[];for(let method of attempts){let result=await callSlack(client,method),scopes=extractScopes(result);if(scopes.length>0)return{ok:!0,scopes,source:method};let error=readError(result);error&&errors.push(`${method}: ${error}`)}return{ok:!1,error:errors.length>0?errors.join(` | `):`no scopes returned`}}const REQUIRED_DISCORD_PERMISSIONS=[`ViewChannel`,`SendMessages`],TEAMS_GRAPH_PERMISSION_HINTS={"ChannelMessage.Read.All":`channel history`,"Chat.Read.All":`chat history`,"Channel.ReadBasic.All":`channel list`,"Team.ReadBasic.All":`team list`,"TeamsActivity.Read.All":`teams activity`,"Sites.Read.All":`files (SharePoint)`,"Files.Read.All":`files (OneDrive)`};function normalizeTimeout(raw,fallback=1e4){let value=Number(raw);return!Number.isFinite(value)||value<=0?fallback:value}function formatSupport(capabilities){if(!capabilities)return`unknown`;let bits=[];return capabilities.chatTypes?.length&&bits.push(`chatTypes=${capabilities.chatTypes.join(`,`)}`),capabilities.polls&&bits.push(`polls`),capabilities.reactions&&bits.push(`reactions`),capabilities.edit&&bits.push(`edit`),capabilities.unsend&&bits.push(`unsend`),capabilities.reply&&bits.push(`reply`),capabilities.effects&&bits.push(`effects`),capabilities.groupManagement&&bits.push(`groupManagement`),capabilities.threads&&bits.push(`threads`),capabilities.media&&bits.push(`media`),capabilities.nativeCommands&&bits.push(`nativeCommands`),capabilities.blockStreaming&&bits.push(`blockStreaming`),bits.length?bits.join(` `):`none`}function summarizeDiscordTarget(raw){if(!raw)return;let target=parseDiscordTarget(raw,{defaultKind:`channel`});return target?target.kind===`channel`?{raw,normalized:target.normalized,kind:`channel`,channelId:target.id}:target.kind===`user`?{raw,normalized:target.normalized,kind:`user`}:{raw,normalized:target.normalized}:{raw}}function formatDiscordIntents(intents){return intents?[`messageContent=${intents.messageContent??`unknown`}`,`guildMembers=${intents.guildMembers??`unknown`}`,`presence=${intents.presence??`unknown`}`].join(` `):`unknown`}function formatProbeLines(channelId,probe){let lines=[];if(!probe||typeof probe!=`object`)return lines;let probeObj=probe;if(channelId===`discord`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let app=probeObj.application;app?.intents&&lines.push(`Intents: ${formatDiscordIntents(app.intents)}`)}if(channelId===`telegram`){let bot=probeObj.bot;if(bot?.username){let botId=bot.id?` (${bot.id})`:``;lines.push(`Bot: ${theme.accent(`@${bot.username}`)}${botId}`)}let flags=[],canJoinGroups=bot?.canJoinGroups,canReadAll=bot?.canReadAllGroupMessages,inlineQueries=bot?.supportsInlineQueries;typeof canJoinGroups==`boolean`&&flags.push(`joinGroups=${canJoinGroups}`),typeof canReadAll==`boolean`&&flags.push(`readAllGroupMessages=${canReadAll}`),typeof inlineQueries==`boolean`&&flags.push(`inlineQueries=${inlineQueries}`),flags.length>0&&lines.push(`Flags: ${flags.join(` `)}`);let webhook=probeObj.webhook;webhook?.url!==void 0&&lines.push(`Webhook: ${webhook.url||`none`}`)}if(channelId===`slack`){let bot=probeObj.bot,team=probeObj.team;if(bot?.name&&lines.push(`Bot: ${theme.accent(`@${bot.name}`)}`),team?.name||team?.id){let id=team?.id?` (${team.id})`:``;lines.push(`Team: ${team?.name??`unknown`}${id}`)}}if(channelId===`signal`){let version=probeObj.version;version&&lines.push(`Signal daemon: ${version}`)}if(channelId===`msteams`){let appId=typeof probeObj.appId==`string`?probeObj.appId.trim():``;appId&&lines.push(`App: ${theme.accent(appId)}`);let graph=probeObj.graph;if(graph){let roles=Array.isArray(graph.roles)?graph.roles.map(role=>String(role).trim()).filter(Boolean):[],scopes=typeof graph.scopes==`string`?graph.scopes.split(/\s+/).map(scope=>scope.trim()).filter(Boolean):Array.isArray(graph.scopes)?graph.scopes.map(scope=>String(scope).trim()).filter(Boolean):[];if(graph.ok===!1)lines.push(`Graph: ${theme.error(graph.error??`failed`)}`);else if(roles.length>0||scopes.length>0){let formatPermission=permission=>{let hint=TEAMS_GRAPH_PERMISSION_HINTS[permission];return hint?`${permission} (${hint})`:permission};roles.length>0&&lines.push(`Graph roles: ${roles.map(formatPermission).join(`, `)}`),scopes.length>0&&lines.push(`Graph scopes: ${scopes.map(formatPermission).join(`, `)}`)}else graph.ok===!0&&lines.push(`Graph: ok`)}}let ok=typeof probeObj.ok==`boolean`?probeObj.ok:void 0;if(ok===!0&&lines.length===0&&lines.push(`Probe: ok`),ok===!1){let error=typeof probeObj.error==`string`&&probeObj.error?` (${probeObj.error})`:``;lines.push(`Probe: ${theme.error(`failed${error}`)}`)}return lines}async function buildDiscordPermissions(params){let target=summarizeDiscordTarget(params.target?.trim());if(!target)return{};if(target.kind!==`channel`||!target.channelId)return{target,report:{error:`Target looks like a DM user; pass channel:<id> to audit channel permissions.`}};let token=params.account.token?.trim();if(!token)return{target,report:{channelId:target.channelId,error:`Discord bot token missing for permission audit.`}};try{let perms=await fetchChannelPermissionsDiscord(target.channelId,{token,accountId:params.account.accountId??void 0}),missing=REQUIRED_DISCORD_PERMISSIONS.filter(permission=>!perms.permissions.includes(permission));return{target,report:{channelId:perms.channelId,guildId:perms.guildId,isDm:perms.isDm,channelType:perms.channelType,permissions:perms.permissions,missingRequired:missing.length?missing:[],raw:perms.raw}}}catch(err){return{target,report:{channelId:target.channelId,error:err instanceof Error?err.message:String(err)}}}}async function resolveChannelReports(params){let{plugin,cfg,timeoutMs}=params,accountIds=params.accountOverride?[params.accountOverride]:(()=>{let ids=plugin.config.listAccountIds(cfg);return ids.length>0?ids:[resolveChannelDefaultAccountId({plugin,cfg,accountIds:ids})]})(),reports=[],listedActions=plugin.actions?.listActions?.({cfg})??[],actions=Array.from(new Set([`send`,`broadcast`,...listedActions.map(action=>String(action))]));for(let accountId of accountIds){let resolvedAccount=plugin.config.resolveAccount(cfg,accountId),configured=plugin.config.isConfigured?await plugin.config.isConfigured(resolvedAccount,cfg):!!resolvedAccount,enabled=plugin.config.isEnabled?plugin.config.isEnabled(resolvedAccount,cfg):resolvedAccount.enabled!==!1,probe;if(configured&&enabled&&plugin.status?.probeAccount)try{probe=await plugin.status.probeAccount({account:resolvedAccount,timeoutMs,cfg})}catch(err){probe={ok:!1,error:err instanceof Error?err.message:String(err)}}let slackScopes;if(plugin.id===`slack`&&configured&&enabled){let botToken=resolvedAccount.botToken?.trim(),userToken=resolvedAccount.config?.userToken?.trim(),scopeReports=[];botToken?scopeReports.push({tokenType:`bot`,result:await fetchSlackScopes(botToken,timeoutMs)}):scopeReports.push({tokenType:`bot`,result:{ok:!1,error:`Slack bot token missing.`}}),userToken&&scopeReports.push({tokenType:`user`,result:await fetchSlackScopes(userToken,timeoutMs)}),slackScopes=scopeReports}let discordTarget,discordPermissions;if(plugin.id===`discord`&&params.target){let perms=await buildDiscordPermissions({account:resolvedAccount,target:params.target});discordTarget=perms.target,discordPermissions=perms.report}reports.push({channel:plugin.id,accountId,accountName:typeof resolvedAccount.name==`string`&&resolvedAccount.name?.trim()||void 0,configured,enabled,support:plugin.capabilities,probe,target:discordTarget,channelPermissions:discordPermissions,actions,slackScopes})}return reports}async function channelsCapabilitiesCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let timeoutMs=normalizeTimeout(opts.timeout,1e4),rawChannel=typeof opts.channel==`string`?opts.channel.trim().toLowerCase():``,rawTarget=typeof opts.target==`string`?opts.target.trim():``;if(opts.account&&(!rawChannel||rawChannel===`all`)){runtime.error(danger(`--account requires a specific --channel.`)),runtime.exit(1);return}if(rawTarget&&rawChannel!==`discord`){runtime.error(danger(`--target requires --channel discord.`)),runtime.exit(1);return}let plugins=listChannelPlugins(),selected=!rawChannel||rawChannel===`all`?plugins:(()=>{let plugin=getChannelPlugin(rawChannel);return plugin?[plugin]:null})();if(!selected||selected.length===0){runtime.error(danger(`Unknown channel "${rawChannel}".`)),runtime.exit(1);return}let reports=[];for(let plugin of selected){let accountOverride=opts.account?.trim()||void 0;reports.push(...await resolveChannelReports({plugin,cfg,timeoutMs,accountOverride,target:rawTarget&&plugin.id===`discord`?rawTarget:void 0}))}if(opts.json){runtime.log(JSON.stringify({channels:reports},null,2));return}let lines=[];for(let report of reports){let label=formatChannelAccountLabel({channel:report.channel,accountId:report.accountId,name:report.accountName,channelStyle:theme.accent,accountStyle:theme.heading});if(lines.push(theme.heading(label)),lines.push(`Support: ${formatSupport(report.support)}`),report.actions&&report.actions.length>0&&lines.push(`Actions: ${report.actions.join(`, `)}`),report.configured===!1||report.enabled===!1){let configuredLabel=report.configured===!1?`not configured`:`configured`,enabledLabel=report.enabled===!1?`disabled`:`enabled`;lines.push(`Status: ${configuredLabel}, ${enabledLabel}`)}let probeLines=formatProbeLines(report.channel,report.probe);if(probeLines.length>0?lines.push(...probeLines):report.configured&&report.enabled&&lines.push(theme.muted(`Probe: unavailable`)),report.channel===`slack`&&report.slackScopes)for(let entry of report.slackScopes){let source=entry.result.source?` (${entry.result.source})`:``,label=entry.tokenType===`user`?`User scopes`:`Bot scopes`;entry.result.ok&&entry.result.scopes?.length?lines.push(`${label}${source}: ${entry.result.scopes.join(`, `)}`):entry.result.error&&lines.push(`${label}: ${theme.error(entry.result.error)}`)}if(report.channel===`discord`&&report.channelPermissions){let perms=report.channelPermissions;if(perms.error)lines.push(`Permissions: ${theme.error(perms.error)}`);else{let list=perms.permissions?.length?perms.permissions.join(`, `):`none`,label=perms.channelId?` (${perms.channelId})`:``;lines.push(`Permissions${label}: ${list}`),perms.missingRequired&&perms.missingRequired.length>0?lines.push(`${theme.warn(`Missing required:`)} ${perms.missingRequired.join(`, `)}`):lines.push(theme.success(`Missing required: none`))}}else report.channel===`discord`&&rawTarget&&!report.channelPermissions&&lines.push(theme.muted(`Permissions: skipped (no target).`));lines.push(``)}runtime.log(lines.join(`
2
2
  `).trimEnd())}const colorValue=value=>value===`none`?theme.error(value):value===`env`?theme.accent(value):theme.success(value);function formatEnabled(value){return value===!1?theme.error(`disabled`):theme.success(`enabled`)}function formatConfigured(value){return value?theme.success(`configured`):theme.warn(`not configured`)}function formatTokenSource(source){return`token=${colorValue(source||`none`)}`}function formatSource(label,source){return`${label}=${colorValue(source||`none`)}`}function formatLinked(value){return value?theme.success(`linked`):theme.warn(`not linked`)}function shouldShowConfigured(channel){return channel.meta.showConfigured!==!1}function formatAccountLine(params){let{channel,snapshot}=params,label=formatChannelAccountLabel({channel:channel.id,accountId:snapshot.accountId,name:snapshot.name,channelStyle:theme.accent,accountStyle:theme.heading}),bits=[];return snapshot.linked!==void 0&&bits.push(formatLinked(snapshot.linked)),shouldShowConfigured(channel)&&typeof snapshot.configured==`boolean`&&bits.push(formatConfigured(snapshot.configured)),snapshot.tokenSource&&bits.push(formatTokenSource(snapshot.tokenSource)),snapshot.botTokenSource&&bits.push(formatSource(`bot`,snapshot.botTokenSource)),snapshot.appTokenSource&&bits.push(formatSource(`app`,snapshot.appTokenSource)),snapshot.baseUrl&&bits.push(`base=${theme.muted(snapshot.baseUrl)}`),typeof snapshot.enabled==`boolean`&&bits.push(formatEnabled(snapshot.enabled)),`- ${label}: ${bits.join(`, `)}`}async function loadUsageWithProgress(runtime){try{return await withProgress({label:`Fetching usage snapshot…`,indeterminate:!0,enabled:!0},async()=>await loadProviderUsageSummary())}catch(err){return runtime.error(String(err)),null}}async function channelsListCommand(opts,runtime=defaultRuntime){let cfg=await requireValidConfig(runtime);if(!cfg)return;let includeUsage=opts.usage!==!1,plugins=listChannelPlugins(),authStore=await loadAuthProfileStore(),authProfiles=Object.entries(authStore.profiles).map(([profileId,profile])=>({id:profileId,provider:profile.provider,type:profile.type,isExternal:!1}));if(opts.json){let usage=includeUsage?await loadProviderUsageSummary():void 0,chat={};for(let plugin of plugins)chat[plugin.id]=plugin.config.listAccountIds(cfg);let payload={chat,auth:authProfiles,...usage?{usage}:{}};runtime.log(JSON.stringify(payload,null,2));return}let lines=[];lines.push(theme.heading(`Chat channels:`));for(let plugin of plugins){let accounts=plugin.config.listAccountIds(cfg);if(!(!accounts||accounts.length===0))for(let accountId of accounts){let snapshot=await buildChannelAccountSnapshot({plugin,cfg,accountId});lines.push(formatAccountLine({channel:plugin,snapshot}))}}if(lines.push(``),lines.push(theme.heading(`Auth providers (OAuth + API keys):`)),authProfiles.length===0)lines.push(theme.muted(`- none`));else for(let profile of authProfiles){let external=profile.isExternal?theme.muted(` (synced)`):``;lines.push(`- ${theme.accent(profile.id)} (${theme.success(profile.type)}${external})`)}if(runtime.log(lines.join(`
3
3
  `)),includeUsage){runtime.log(``);let usage=await loadUsageWithProgress(runtime);if(usage){let usageLines=formatUsageReportLines(usage);usageLines.length>0&&(usageLines[0]=theme.accent(usageLines[0]),runtime.log(usageLines.join(`
4
4
  `)))}}runtime.log(``),runtime.log(`Docs: ${formatDocsLink(`/gateway/configuration`,`gateway/configuration`)}`)}const getChannelSet=()=>new Set([...listChannelPlugins().map(plugin=>plugin.id),`all`]);function parseChannelFilter(raw){let trimmed=raw?.trim().toLowerCase();return trimmed&&getChannelSet().has(trimmed)?trimmed:`all`}function matchesChannel(line,channel){if(channel===`all`)return!0;let needle=`gateway/channels/${channel}`;return!!(line.subsystem?.includes(needle)||line.module?.includes(channel))}async function readTailLines(file,limit){let stat=await fs.stat(file).catch(()=>null);if(!stat)return[];let size=stat.size,start=Math.max(0,size-1e6),handle=await fs.open(file,`r`);try{let length=Math.max(0,size-start);if(length===0)return[];let buffer=Buffer.alloc(length),readResult=await handle.read(buffer,0,length,start),lines=buffer.toString(`utf8`,0,readResult.bytesRead).split(`
@@ -0,0 +1,4 @@
1
+ import{y as CONFIG_DIR}from"./registry-j1UKIotU.js";import{t as createSubsystemLogger}from"./subsystem-ykSbyaud.js";import{i as isErrno}from"./errors-CguQr0Ja.js";import{n as loadConfig}from"./config-utlbrOec.js";import path from"node:path";import fs from"node:fs";import os from"node:os";import{createHash,randomBytes}from"node:crypto";import"node:fs/promises";import{execFileSync,spawn}from"node:child_process";import net from"node:net";import{createServer}from"node:http";import WebSocket,{WebSocketServer}from"ws";import{Buffer as Buffer$1}from"node:buffer";const DEFAULT_BUILDERFORCE_AGENTS_BROWSER_ENABLED=!0,DEFAULT_BROWSER_EVALUATE_ENABLED=!0,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR=`#FF4500`,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME=`builderforce`,DEFAULT_BROWSER_DEFAULT_PROFILE_NAME=`chrome`,DEFAULT_AI_SNAPSHOT_MAX_CHARS=8e4,DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS=1e4,DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH=6;function isTailnetIPv4(address){let parts=address.split(`.`);if(parts.length!==4)return!1;let octets=parts.map(p=>Number.parseInt(p,10));if(octets.some(n=>!Number.isFinite(n)||n<0||n>255))return!1;let[a,b]=octets;return a===100&&b>=64&&b<=127}function isTailnetIPv6(address){return address.trim().toLowerCase().startsWith(`fd7a:115c:a1e0:`)}function listTailnetAddresses(){let ipv4=[],ipv6=[],ifaces=os.networkInterfaces();for(let entries of Object.values(ifaces))if(entries)for(let e of entries){if(!e||e.internal)continue;let address=e.address?.trim();address&&(isTailnetIPv4(address)&&ipv4.push(address),isTailnetIPv6(address)&&ipv6.push(address))}return{ipv4:[...new Set(ipv4)],ipv6:[...new Set(ipv6)]}}function pickPrimaryTailnetIPv4(){return listTailnetAddresses().ipv4[0]}function pickPrimaryLanIPv4(){let nets=os.networkInterfaces();for(let name of[`en0`,`eth0`]){let entry=nets[name]?.find(n=>n.family===`IPv4`&&!n.internal);if(entry?.address)return entry.address}for(let list of Object.values(nets)){let entry=list?.find(n=>n.family===`IPv4`&&!n.internal);if(entry?.address)return entry.address}}function isLoopbackAddress(ip){return ip?!!(ip===`127.0.0.1`||ip.startsWith(`127.`)||ip===`::1`||ip.startsWith(`::ffff:127.`)):!1}function isLoopbackHost(host){if(!host)return!1;let h=host.trim().toLowerCase();return h===`localhost`?!0:isLoopbackAddress(h.startsWith(`[`)&&h.endsWith(`]`)?h.slice(1,-1):h)}const POSIX_BUILDERFORCE_AGENTS_TMP_DIR=`/tmp/builderforce`;function isNodeErrorWithCode(err,code){return typeof err==`object`&&!!err&&`code`in err&&err.code===code}function resolvePreferredBuilderForceAgentsTmpDir(options={}){let accessSync=options.accessSync??fs.accessSync,lstatSync=options.lstatSync??fs.lstatSync,mkdirSync=options.mkdirSync??fs.mkdirSync,getuid=options.getuid??(()=>{try{return typeof process.getuid==`function`?process.getuid():void 0}catch{return}}),tmpdir=options.tmpdir??os.tmpdir,uid=getuid(),isSecureDirForUser=st=>uid===void 0?!0:!(typeof st.uid==`number`&&st.uid!==uid||typeof st.mode==`number`&&st.mode&18),fallback=()=>{let base=tmpdir(),suffix=uid===void 0?`builderforce`:`builderforce-${uid}`;return path.join(base,suffix)};try{let preferred=lstatSync(POSIX_BUILDERFORCE_AGENTS_TMP_DIR);return!preferred.isDirectory()||preferred.isSymbolicLink()||(accessSync(POSIX_BUILDERFORCE_AGENTS_TMP_DIR,fs.constants.W_OK|fs.constants.X_OK),!isSecureDirForUser(preferred))?fallback():POSIX_BUILDERFORCE_AGENTS_TMP_DIR}catch(err){if(!isNodeErrorWithCode(err,`ENOENT`))return fallback()}try{accessSync(`/tmp`,fs.constants.W_OK|fs.constants.X_OK),mkdirSync(POSIX_BUILDERFORCE_AGENTS_TMP_DIR,{recursive:!0,mode:448});try{let preferred=lstatSync(POSIX_BUILDERFORCE_AGENTS_TMP_DIR);if(!preferred.isDirectory()||preferred.isSymbolicLink()||!isSecureDirForUser(preferred))return fallback()}catch{return fallback()}return POSIX_BUILDERFORCE_AGENTS_TMP_DIR}catch{return fallback()}}function rawDataToString(data,encoding=`utf8`){return typeof data==`string`?data:Buffer$1.isBuffer(data)?data.toString(encoding):Array.isArray(data)?Buffer$1.concat(data).toString(encoding):data instanceof ArrayBuffer?Buffer$1.from(data).toString(encoding):Buffer$1.from(String(data)).toString(encoding)}const RELAY_AUTH_HEADER=`x-builderforce-relay-token`;function headerValue(value){if(value)return Array.isArray(value)?value[0]:value}function getHeader(req,name){return headerValue(req.headers[name.toLowerCase()])}function parseBaseUrl(raw){let parsed=new URL(raw.trim().replace(/\/$/,``));if(parsed.protocol!==`http:`&&parsed.protocol!==`https:`)throw Error(`extension relay cdpUrl must be http(s), got ${parsed.protocol}`);let host=parsed.hostname,port=parsed.port?.trim()===``?parsed.protocol===`https:`?443:80:Number(parsed.port);if(!Number.isFinite(port)||port<=0||port>65535)throw Error(`extension relay cdpUrl has invalid port: ${parsed.port||`(empty)`}`);return{host,port,baseUrl:parsed.toString().replace(/\/$/,``)}}function text(res,status,bodyText){let body=Buffer.from(bodyText);res.write(`HTTP/1.1 ${status} ${status===200?`OK`:`ERR`}\r\nContent-Type: text/plain; charset=utf-8\r
2
+ Content-Length: ${body.length}\r\nConnection: close\r
3
+ \r
4
+ `),res.write(body),res.end()}function rejectUpgrade(socket,status,bodyText){text(socket,status,bodyText);try{socket.destroy()}catch{}}const serversByPort=new Map,relayAuthByPort=new Map;function resolveGatewayAuthToken(){let envToken=process.env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim()||process.env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim();if(envToken)return envToken;try{let configToken=loadConfig().gateway?.auth?.token?.trim();if(configToken)return configToken}catch{}return null}function deriveDeterministicRelayAuthToken(port){let gatewayToken=resolveGatewayAuthToken();return gatewayToken?createHash(`sha256`).update(`builderforce-relay:${port}:`).update(gatewayToken).digest(`base64url`):null}function resolveRelayAuthToken(port){return deriveDeterministicRelayAuthToken(port)??randomBytes(32).toString(`base64url`)}function isAddrInUseError(err){return typeof err==`object`&&!!err&&`code`in err&&err.code===`EADDRINUSE`}async function looksLikeBuilderForceAgentsRelay(baseUrl){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),500);try{let statusUrl=new URL(`/extension/status`,`${baseUrl}/`).toString(),res=await fetch(statusUrl,{signal:ctrl.signal});return res.ok?typeof(await res.json()).connected==`boolean`:!1}catch{return!1}finally{clearTimeout(timer)}}function relayAuthTokenForUrl(url){try{let parsed=new URL(url);if(!isLoopbackHost(parsed.hostname))return null;let port=parsed.port?.trim()===``?parsed.protocol===`https:`||parsed.protocol===`wss:`?443:80:Number(parsed.port);return Number.isFinite(port)?relayAuthByPort.get(port)??deriveDeterministicRelayAuthToken(port):null}catch{return null}}function getChromeExtensionRelayAuthHeaders(url){let token=relayAuthTokenForUrl(url);return token?{[RELAY_AUTH_HEADER]:token}:{}}async function ensureChromeExtensionRelayServer(opts){let info=parseBaseUrl(opts.cdpUrl);if(!isLoopbackHost(info.host))throw Error(`extension relay requires loopback cdpUrl host (got ${info.host})`);let existing=serversByPort.get(info.port);if(existing)return existing;let relayAuthToken=resolveRelayAuthToken(info.port),extensionWs=null,cdpClients=new Set,connectedTargets=new Map,pendingExtension=new Map,nextExtensionId=1,sendToExtension=async payload=>{let ws=extensionWs;if(!ws||ws.readyState!==WebSocket.OPEN)throw Error(`Chrome extension not connected`);return ws.send(JSON.stringify(payload)),await new Promise((resolve,reject)=>{let timer=setTimeout(()=>{pendingExtension.delete(payload.id),reject(Error(`extension request timeout: ${payload.params.method}`))},3e4);pendingExtension.set(payload.id,{resolve,reject,timer})})},broadcastToCdpClients=evt=>{let msg=JSON.stringify(evt);for(let ws of cdpClients)ws.readyState===WebSocket.OPEN&&ws.send(msg)},sendResponseToCdp=(ws,res)=>{ws.readyState===WebSocket.OPEN&&ws.send(JSON.stringify(res))},ensureTargetEventsForClient=(ws,mode)=>{for(let target of connectedTargets.values())mode===`autoAttach`?ws.send(JSON.stringify({method:`Target.attachedToTarget`,params:{sessionId:target.sessionId,targetInfo:{...target.targetInfo,attached:!0},waitingForDebugger:!1}})):ws.send(JSON.stringify({method:`Target.targetCreated`,params:{targetInfo:{...target.targetInfo,attached:!0}}}))},routeCdpCommand=async cmd=>{switch(cmd.method){case`Browser.getVersion`:return{protocolVersion:`1.3`,product:`Chrome/BuilderForceAgents-Extension-Relay`,revision:`0`,userAgent:`BuilderForceAgents-Extension-Relay`,jsVersion:`V8`};case`Browser.setDownloadBehavior`:return{};case`Target.setAutoAttach`:case`Target.setDiscoverTargets`:return{};case`Target.getTargets`:return{targetInfos:Array.from(connectedTargets.values()).map(t=>({...t.targetInfo,attached:!0}))};case`Target.getTargetInfo`:{let params=cmd.params??{},targetId=typeof params.targetId==`string`?params.targetId:void 0;if(targetId){for(let t of connectedTargets.values())if(t.targetId===targetId)return{targetInfo:t.targetInfo}}if(cmd.sessionId&&connectedTargets.has(cmd.sessionId)){let t=connectedTargets.get(cmd.sessionId);if(t)return{targetInfo:t.targetInfo}}return{targetInfo:Array.from(connectedTargets.values())[0]?.targetInfo}}case`Target.attachToTarget`:{let params=cmd.params??{},targetId=typeof params.targetId==`string`?params.targetId:void 0;if(!targetId)throw Error(`targetId required`);for(let t of connectedTargets.values())if(t.targetId===targetId)return{sessionId:t.sessionId};throw Error(`target not found`)}default:return await sendToExtension({id:nextExtensionId++,method:`forwardCDPCommand`,params:{method:cmd.method,sessionId:cmd.sessionId,params:cmd.params}})}},server=createServer((req,res)=>{let path=new URL(req.url??`/`,info.baseUrl).pathname;if(path.startsWith(`/json`)){let token=getHeader(req,RELAY_AUTH_HEADER);if(!token||token!==relayAuthToken){res.writeHead(401),res.end(`Unauthorized`);return}}if(req.method===`HEAD`&&path===`/`){res.writeHead(200),res.end();return}if(path===`/`){res.writeHead(200,{"Content-Type":`text/plain; charset=utf-8`}),res.end(`OK`);return}if(path===`/extension/status`){res.writeHead(200,{"Content-Type":`application/json`}),res.end(JSON.stringify({connected:!!extensionWs}));return}let cdpWsUrl=`${`ws://${req.headers.host?.trim()||`${info.host}:${info.port}`}`}/cdp`;if((path===`/json/version`||path===`/json/version/`)&&(req.method===`GET`||req.method===`PUT`)){let payload={Browser:`BuilderForceAgents/extension-relay`,"Protocol-Version":`1.3`};extensionWs&&(payload.webSocketDebuggerUrl=cdpWsUrl),res.writeHead(200,{"Content-Type":`application/json`}),res.end(JSON.stringify(payload));return}if(new Set([`/json`,`/json/`,`/json/list`,`/json/list/`]).has(path)&&(req.method===`GET`||req.method===`PUT`)){let list=Array.from(connectedTargets.values()).map(t=>({id:t.targetId,type:t.targetInfo.type??`page`,title:t.targetInfo.title??``,description:t.targetInfo.title??``,url:t.targetInfo.url??``,webSocketDebuggerUrl:cdpWsUrl,devtoolsFrontendUrl:`/devtools/inspector.html?ws=${cdpWsUrl.replace(`ws://`,``)}`}));res.writeHead(200,{"Content-Type":`application/json`}),res.end(JSON.stringify(list));return}let activateMatch=path.match(/^\/json\/activate\/(.+)$/);if(activateMatch&&(req.method===`GET`||req.method===`PUT`)){let targetId=decodeURIComponent(activateMatch[1]??``).trim();if(!targetId){res.writeHead(400),res.end(`targetId required`);return}(async()=>{try{await sendToExtension({id:nextExtensionId++,method:`forwardCDPCommand`,params:{method:`Target.activateTarget`,params:{targetId}}})}catch{}})(),res.writeHead(200),res.end(`OK`);return}let closeMatch=path.match(/^\/json\/close\/(.+)$/);if(closeMatch&&(req.method===`GET`||req.method===`PUT`)){let targetId=decodeURIComponent(closeMatch[1]??``).trim();if(!targetId){res.writeHead(400),res.end(`targetId required`);return}(async()=>{try{await sendToExtension({id:nextExtensionId++,method:`forwardCDPCommand`,params:{method:`Target.closeTarget`,params:{targetId}}})}catch{}})(),res.writeHead(200),res.end(`OK`);return}res.writeHead(404),res.end(`not found`)}),wssExtension=new WebSocketServer({noServer:!0}),wssCdp=new WebSocketServer({noServer:!0});server.on(`upgrade`,(req,socket,head)=>{let pathname=new URL(req.url??`/`,info.baseUrl).pathname,remote=req.socket.remoteAddress;if(!isLoopbackAddress(remote)){rejectUpgrade(socket,403,`Forbidden`);return}let origin=headerValue(req.headers.origin);if(origin&&!origin.startsWith(`chrome-extension://`)){rejectUpgrade(socket,403,`Forbidden: invalid origin`);return}if(pathname===`/extension`){if(extensionWs){rejectUpgrade(socket,409,`Extension already connected`);return}wssExtension.handleUpgrade(req,socket,head,ws=>{wssExtension.emit(`connection`,ws,req)});return}if(pathname===`/cdp`){let token=getHeader(req,RELAY_AUTH_HEADER);if(!token||token!==relayAuthToken){rejectUpgrade(socket,401,`Unauthorized`);return}if(!extensionWs){rejectUpgrade(socket,503,`Extension not connected`);return}wssCdp.handleUpgrade(req,socket,head,ws=>{wssCdp.emit(`connection`,ws,req)});return}rejectUpgrade(socket,404,`Not Found`)}),wssExtension.on(`connection`,ws=>{extensionWs=ws;let ping=setInterval(()=>{ws.readyState===WebSocket.OPEN&&ws.send(JSON.stringify({method:`ping`}))},5e3);ws.on(`message`,data=>{let parsed=null;try{parsed=JSON.parse(rawDataToString(data))}catch{return}if(parsed&&typeof parsed==`object`&&`id`in parsed&&typeof parsed.id==`number`){let pending=pendingExtension.get(parsed.id);if(!pending)return;pendingExtension.delete(parsed.id),clearTimeout(pending.timer),`error`in parsed&&typeof parsed.error==`string`&&parsed.error.trim()?pending.reject(Error(parsed.error)):pending.resolve(parsed.result);return}if(parsed&&typeof parsed==`object`&&`method`in parsed){if(parsed.method===`pong`||parsed.method!==`forwardCDPEvent`)return;let evt=parsed,method=evt.params?.method,params=evt.params?.params,sessionId=evt.params?.sessionId;if(!method||typeof method!=`string`)return;if(method===`Target.attachedToTarget`){let attached=params??{};if((attached?.targetInfo?.type??`page`)!==`page`)return;if(attached?.sessionId&&attached?.targetInfo?.targetId){let prev=connectedTargets.get(attached.sessionId),nextTargetId=attached.targetInfo.targetId,prevTargetId=prev?.targetId,changedTarget=!!(prev&&prevTargetId&&prevTargetId!==nextTargetId);connectedTargets.set(attached.sessionId,{sessionId:attached.sessionId,targetId:nextTargetId,targetInfo:attached.targetInfo}),changedTarget&&prevTargetId&&broadcastToCdpClients({method:`Target.detachedFromTarget`,params:{sessionId:attached.sessionId,targetId:prevTargetId},sessionId:attached.sessionId}),(!prev||changedTarget)&&broadcastToCdpClients({method,params,sessionId});return}}if(method===`Target.detachedFromTarget`){let detached=params??{};detached?.sessionId&&connectedTargets.delete(detached.sessionId),broadcastToCdpClients({method,params,sessionId});return}if(method===`Target.targetInfoChanged`){let targetInfo=(params??{})?.targetInfo,targetId=targetInfo?.targetId;if(targetId&&(targetInfo?.type??`page`)===`page`)for(let[sid,target]of connectedTargets)target.targetId===targetId&&connectedTargets.set(sid,{...target,targetInfo:{...target.targetInfo,...targetInfo}})}broadcastToCdpClients({method,params,sessionId})}}),ws.on(`close`,()=>{clearInterval(ping),extensionWs=null;for(let[,pending]of pendingExtension)clearTimeout(pending.timer),pending.reject(Error(`extension disconnected`));pendingExtension.clear(),connectedTargets.clear();for(let client of cdpClients)try{client.close(1011,`extension disconnected`)}catch{}cdpClients.clear()})}),wssCdp.on(`connection`,ws=>{cdpClients.add(ws),ws.on(`message`,async data=>{let cmd=null;try{cmd=JSON.parse(rawDataToString(data))}catch{return}if(!(!cmd||typeof cmd!=`object`)&&!(typeof cmd.id!=`number`||typeof cmd.method!=`string`)){if(!extensionWs){sendResponseToCdp(ws,{id:cmd.id,sessionId:cmd.sessionId,error:{message:`Extension not connected`}});return}try{let result=await routeCdpCommand(cmd);if(cmd.method===`Target.setAutoAttach`&&!cmd.sessionId&&ensureTargetEventsForClient(ws,`autoAttach`),cmd.method===`Target.setDiscoverTargets`&&(cmd.params??{}).discover===!0&&ensureTargetEventsForClient(ws,`discover`),cmd.method===`Target.attachToTarget`){let params=cmd.params??{},targetId=typeof params.targetId==`string`?params.targetId:void 0;if(targetId){let target=Array.from(connectedTargets.values()).find(t=>t.targetId===targetId);target&&ws.send(JSON.stringify({method:`Target.attachedToTarget`,params:{sessionId:target.sessionId,targetInfo:{...target.targetInfo,attached:!0},waitingForDebugger:!1}}))}}sendResponseToCdp(ws,{id:cmd.id,sessionId:cmd.sessionId,result})}catch(err){sendResponseToCdp(ws,{id:cmd.id,sessionId:cmd.sessionId,error:{message:err instanceof Error?err.message:String(err)}})}}}),ws.on(`close`,()=>{cdpClients.delete(ws)})});try{await new Promise((resolve,reject)=>{server.listen(info.port,info.host,()=>resolve()),server.once(`error`,reject)})}catch(err){if(isAddrInUseError(err)&&await looksLikeBuilderForceAgentsRelay(info.baseUrl)){let existingRelay={host:info.host,port:info.port,baseUrl:info.baseUrl,cdpWsUrl:`ws://${info.host}:${info.port}/cdp`,extensionConnected:()=>!1,stop:async()=>{serversByPort.delete(info.port),relayAuthByPort.delete(info.port)}};return relayAuthByPort.set(info.port,relayAuthToken),serversByPort.set(info.port,existingRelay),existingRelay}throw err}let port=server.address()?.port??info.port,host=info.host,relay={host,port,baseUrl:`${new URL(info.baseUrl).protocol}//${host}:${port}`,cdpWsUrl:`ws://${host}:${port}/cdp`,extensionConnected:()=>!!extensionWs,stop:async()=>{serversByPort.delete(port),relayAuthByPort.delete(port);try{extensionWs?.close(1001,`server stopping`)}catch{}for(let ws of cdpClients)try{ws.close(1001,`server stopping`)}catch{}await new Promise(resolve=>{server.close(()=>resolve())}),wssExtension.close(),wssCdp.close()}};return relayAuthByPort.set(port,relayAuthToken),serversByPort.set(port,relay),relay}async function stopChromeExtensionRelayServer(opts){let info=parseBaseUrl(opts.cdpUrl),existing=serversByPort.get(info.port);return existing?(await existing.stop(),relayAuthByPort.delete(info.port),!0):!1}function getHeadersWithAuth(url,headers={}){let mergedHeaders={...getChromeExtensionRelayAuthHeaders(url),...headers};try{let parsed=new URL(url);if(Object.keys(mergedHeaders).some(key=>key.toLowerCase()===`authorization`))return mergedHeaders;if(parsed.username||parsed.password){let auth=Buffer.from(`${parsed.username}:${parsed.password}`).toString(`base64`);return{...mergedHeaders,Authorization:`Basic ${auth}`}}}catch{}return mergedHeaders}function appendCdpPath(cdpUrl,path){let url=new URL(cdpUrl);return url.pathname=`${url.pathname.replace(/\/$/,``)}${path.startsWith(`/`)?path:`/${path}`}`,url.toString()}function createCdpSender(ws){let nextId=1,pending=new Map,send=(method,params,sessionId)=>{let id=nextId++,msg={id,method,params,sessionId};return ws.send(JSON.stringify(msg)),new Promise((resolve,reject)=>{pending.set(id,{resolve,reject})})},closeWithError=err=>{for(let[,p]of pending)p.reject(err);pending.clear();try{ws.close()}catch{}};return ws.on(`error`,err=>{closeWithError(err instanceof Error?err:Error(String(err)))}),ws.on(`message`,data=>{try{let parsed=JSON.parse(rawDataToString(data));if(typeof parsed.id!=`number`)return;let p=pending.get(parsed.id);if(!p)return;if(pending.delete(parsed.id),parsed.error?.message){p.reject(Error(parsed.error.message));return}p.resolve(parsed.result)}catch{}}),ws.on(`close`,()=>{closeWithError(Error(`CDP socket closed`))}),{send,closeWithError}}async function fetchJson(url,timeoutMs=1500,init){return await(await fetchChecked(url,timeoutMs,init)).json()}async function fetchChecked(url,timeoutMs=1500,init){let ctrl=new AbortController,t=setTimeout(ctrl.abort.bind(ctrl),timeoutMs);try{let headers=getHeadersWithAuth(url,init?.headers||{}),res=await fetch(url,{...init,headers,signal:ctrl.signal});if(!res.ok)throw Error(`HTTP ${res.status}`);return res}finally{clearTimeout(t)}}async function fetchOk(url,timeoutMs=1500,init){await fetchChecked(url,timeoutMs,init)}async function withCdpSocket(wsUrl,fn,opts){let headers=getHeadersWithAuth(wsUrl,opts?.headers??{}),ws=new WebSocket(wsUrl,{handshakeTimeout:typeof opts?.handshakeTimeoutMs==`number`&&Number.isFinite(opts.handshakeTimeoutMs)?Math.max(1,Math.floor(opts.handshakeTimeoutMs)):5e3,...Object.keys(headers).length?{headers}:{}}),{send,closeWithError}=createCdpSender(ws),openPromise=new Promise((resolve,reject)=>{ws.once(`open`,()=>resolve()),ws.once(`error`,err=>reject(err)),ws.once(`close`,()=>reject(Error(`CDP socket closed`)))});try{await openPromise}catch(err){throw closeWithError(err instanceof Error?err:Error(String(err))),err}try{return await fn(send)}catch(err){throw closeWithError(err instanceof Error?err:Error(String(err))),err}finally{try{ws.close()}catch{}}}function normalizeCdpWsUrl(wsUrl,cdpUrl){let ws=new URL(wsUrl),cdp=new URL(cdpUrl);if(isLoopbackHost(ws.hostname)&&!isLoopbackHost(cdp.hostname)){ws.hostname=cdp.hostname;let cdpPort=cdp.port||(cdp.protocol===`https:`?`443`:`80`);cdpPort&&(ws.port=cdpPort),ws.protocol=cdp.protocol===`https:`?`wss:`:`ws:`}cdp.protocol===`https:`&&ws.protocol===`ws:`&&(ws.protocol=`wss:`),!ws.username&&!ws.password&&(cdp.username||cdp.password)&&(ws.username=cdp.username,ws.password=cdp.password);for(let[key,value]of cdp.searchParams.entries())ws.searchParams.has(key)||ws.searchParams.append(key,value);return ws.toString()}async function captureScreenshot(opts){return await withCdpSocket(opts.wsUrl,async send=>{await send(`Page.enable`);let clip;if(opts.fullPage){let metrics=await send(`Page.getLayoutMetrics`),size=metrics?.cssContentSize??metrics?.contentSize,width=Number(size?.width??0),height=Number(size?.height??0);width>0&&height>0&&(clip={x:0,y:0,width,height,scale:1})}let format=opts.format??`png`,quality=format===`jpeg`?Math.max(0,Math.min(100,Math.round(opts.quality??85))):void 0,base64=(await send(`Page.captureScreenshot`,{format,...quality===void 0?{}:{quality},fromSurface:!0,captureBeyondViewport:!0,...clip?{clip}:{}}))?.data;if(!base64)throw Error(`Screenshot failed: missing data`);return Buffer.from(base64,`base64`)})}async function createTargetViaCdp(opts){let version=await fetchJson(appendCdpPath(opts.cdpUrl,`/json/version`),1500),wsUrlRaw=String(version?.webSocketDebuggerUrl??``).trim(),wsUrl=wsUrlRaw?normalizeCdpWsUrl(wsUrlRaw,opts.cdpUrl):``;if(!wsUrl)throw Error(`CDP /json/version missing webSocketDebuggerUrl`);return await withCdpSocket(wsUrl,async send=>{let created=await send(`Target.createTarget`,{url:opts.url}),targetId=String(created?.targetId??``).trim();if(!targetId)throw Error(`CDP Target.createTarget returned no targetId`);return{targetId}})}function axValue(v){if(!v||typeof v!=`object`)return``;let value=v.value;return typeof value==`string`?value:typeof value==`number`||typeof value==`boolean`?String(value):``}function formatAriaSnapshot(nodes,limit){let byId=new Map;for(let n of nodes)n.nodeId&&byId.set(n.nodeId,n);let referenced=new Set;for(let n of nodes)for(let c of n.childIds??[])referenced.add(c);let root=nodes.find(n=>n.nodeId&&!referenced.has(n.nodeId))??nodes[0];if(!root?.nodeId)return[];let out=[],stack=[{id:root.nodeId,depth:0}];for(;stack.length&&out.length<limit;){let popped=stack.pop();if(!popped)break;let{id,depth}=popped,n=byId.get(id);if(!n)continue;let role=axValue(n.role),name=axValue(n.name),value=axValue(n.value),description=axValue(n.description),ref=`ax${out.length+1}`;out.push({ref,role:role||`unknown`,name:name||``,...value?{value}:{},...description?{description}:{},...typeof n.backendDOMNodeId==`number`?{backendDOMNodeId:n.backendDOMNodeId}:{},depth});let children=(n.childIds??[]).filter(c=>byId.has(c));for(let i=children.length-1;i>=0;i--){let child=children[i];child&&stack.push({id:child,depth:depth+1})}}return out}async function snapshotAria(opts){let limit=Math.max(1,Math.min(2e3,Math.floor(opts.limit??500)));return await withCdpSocket(opts.wsUrl,async send=>{await send(`Accessibility.enable`).catch(()=>{});let res=await send(`Accessibility.getFullAXTree`);return{nodes:formatAriaSnapshot(Array.isArray(res?.nodes)?res.nodes:[],limit)}})}const CHROMIUM_BUNDLE_IDS=new Set([`com.google.Chrome`,`com.google.Chrome.beta`,`com.google.Chrome.canary`,`com.google.Chrome.dev`,`com.brave.Browser`,`com.brave.Browser.beta`,`com.brave.Browser.nightly`,`com.microsoft.Edge`,`com.microsoft.EdgeBeta`,`com.microsoft.EdgeDev`,`com.microsoft.EdgeCanary`,`org.chromium.Chromium`,`com.vivaldi.Vivaldi`,`com.operasoftware.Opera`,`com.operasoftware.OperaGX`,`com.yandex.desktop.yandex-browser`,`company.thebrowser.Browser`]),CHROMIUM_DESKTOP_IDS=new Set([`google-chrome.desktop`,`google-chrome-beta.desktop`,`google-chrome-unstable.desktop`,`brave-browser.desktop`,`microsoft-edge.desktop`,`microsoft-edge-beta.desktop`,`microsoft-edge-dev.desktop`,`microsoft-edge-canary.desktop`,`chromium.desktop`,`chromium-browser.desktop`,`vivaldi.desktop`,`vivaldi-stable.desktop`,`opera.desktop`,`opera-gx.desktop`,`yandex-browser.desktop`,`org.chromium.Chromium.desktop`]),CHROMIUM_EXE_NAMES=new Set(`chrome.exe,msedge.exe,brave.exe,brave-browser.exe,chromium.exe,vivaldi.exe,opera.exe,launcher.exe,yandex.exe,yandexbrowser.exe,google chrome,google chrome canary,brave browser,microsoft edge,chromium,chrome,brave,msedge,brave-browser,google-chrome,google-chrome-stable,google-chrome-beta,google-chrome-unstable,microsoft-edge,microsoft-edge-beta,microsoft-edge-dev,microsoft-edge-canary,chromium-browser,vivaldi,vivaldi-stable,opera,opera-stable,opera-gx,yandex-browser`.split(`,`));function exists$1(filePath){try{return fs.existsSync(filePath)}catch{return!1}}function execText(command,args,timeoutMs=1200,maxBuffer=1024*1024){try{let output=execFileSync(command,args,{timeout:timeoutMs,encoding:`utf8`,maxBuffer});return String(output??``).trim()||null}catch{return null}}function inferKindFromIdentifier(identifier){let id=identifier.toLowerCase();return id.includes(`brave`)?`brave`:id.includes(`edge`)?`edge`:id.includes(`chromium`)?`chromium`:id.includes(`canary`)?`canary`:id.includes(`opera`)||id.includes(`vivaldi`)||id.includes(`yandex`)||id.includes(`thebrowser`)?`chromium`:`chrome`}function inferKindFromExecutableName(name){let lower=name.toLowerCase();return lower.includes(`brave`)?`brave`:lower.includes(`edge`)||lower.includes(`msedge`)?`edge`:lower.includes(`chromium`)?`chromium`:lower.includes(`canary`)||lower.includes(`sxs`)?`canary`:lower.includes(`opera`)||lower.includes(`vivaldi`)||lower.includes(`yandex`)?`chromium`:`chrome`}function detectDefaultChromiumExecutable(platform){return platform===`darwin`?detectDefaultChromiumExecutableMac():platform===`linux`?detectDefaultChromiumExecutableLinux():platform===`win32`?detectDefaultChromiumExecutableWindows():null}function detectDefaultChromiumExecutableMac(){let bundleId=detectDefaultBrowserBundleIdMac();if(!bundleId||!CHROMIUM_BUNDLE_IDS.has(bundleId))return null;let appPathRaw=execText(`/usr/bin/osascript`,[`-e`,`POSIX path of (path to application id "${bundleId}")`]);if(!appPathRaw)return null;let appPath=appPathRaw.trim().replace(/\/$/,``),exeName=execText(`/usr/bin/defaults`,[`read`,path.join(appPath,`Contents`,`Info`),`CFBundleExecutable`]);if(!exeName)return null;let exePath=path.join(appPath,`Contents`,`MacOS`,exeName.trim());return exists$1(exePath)?{kind:inferKindFromIdentifier(bundleId),path:exePath}:null}function detectDefaultBrowserBundleIdMac(){let plistPath=path.join(os.homedir(),`Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`);if(!exists$1(plistPath))return null;let handlersRaw=execText(`/usr/bin/plutil`,[`-extract`,`LSHandlers`,`json`,`-o`,`-`,`--`,plistPath],2e3,5*1024*1024);if(!handlersRaw)return null;let handlers;try{handlers=JSON.parse(handlersRaw)}catch{return null}if(!Array.isArray(handlers))return null;let resolveScheme=scheme=>{let candidate=null;for(let entry of handlers){if(!entry||typeof entry!=`object`)continue;let record=entry;if(record.LSHandlerURLScheme!==scheme)continue;let role=typeof record.LSHandlerRoleAll==`string`&&record.LSHandlerRoleAll||typeof record.LSHandlerRoleViewer==`string`&&record.LSHandlerRoleViewer||null;role&&(candidate=role)}return candidate};return resolveScheme(`http`)??resolveScheme(`https`)}function detectDefaultChromiumExecutableLinux(){let desktopId=execText(`xdg-settings`,[`get`,`default-web-browser`])||execText(`xdg-mime`,[`query`,`default`,`x-scheme-handler/http`]);if(!desktopId)return null;let trimmed=desktopId.trim();if(!CHROMIUM_DESKTOP_IDS.has(trimmed))return null;let desktopPath=findDesktopFilePath(trimmed);if(!desktopPath)return null;let execLine=readDesktopExecLine(desktopPath);if(!execLine)return null;let command=extractExecutableFromExecLine(execLine);if(!command)return null;let resolved=resolveLinuxExecutablePath(command);if(!resolved)return null;let exeName=path.posix.basename(resolved).toLowerCase();return CHROMIUM_EXE_NAMES.has(exeName)?{kind:inferKindFromExecutableName(exeName),path:resolved}:null}function detectDefaultChromiumExecutableWindows(){let progId=readWindowsProgId(),command=(progId?readWindowsCommandForProgId(progId):null)||readWindowsCommandForProgId(`http`);if(!command)return null;let exePath=extractWindowsExecutablePath(expandWindowsEnvVars(command));if(!exePath||!exists$1(exePath))return null;let exeName=path.win32.basename(exePath).toLowerCase();return CHROMIUM_EXE_NAMES.has(exeName)?{kind:inferKindFromExecutableName(exeName),path:exePath}:null}function findDesktopFilePath(desktopId){let candidates=[path.join(os.homedir(),`.local`,`share`,`applications`,desktopId),path.join(`/usr/local/share/applications`,desktopId),path.join(`/usr/share/applications`,desktopId),path.join(`/var/lib/snapd/desktop/applications`,desktopId)];for(let candidate of candidates)if(exists$1(candidate))return candidate;return null}function readDesktopExecLine(desktopPath){try{let lines=fs.readFileSync(desktopPath,`utf8`).split(/\r?\n/);for(let line of lines)if(line.startsWith(`Exec=`))return line.slice(5).trim()}catch{}return null}function extractExecutableFromExecLine(execLine){let tokens=splitExecLine(execLine);for(let token of tokens)if(token&&token!==`env`&&!(token.includes(`=`)&&!token.startsWith(`/`)&&!token.includes(`\\`)))return token.replace(/^["']|["']$/g,``);return null}function splitExecLine(line){let tokens=[],current=``,inQuotes=!1,quoteChar=``;for(let i=0;i<line.length;i+=1){let ch=line[i];if((ch===`"`||ch===`'`)&&(!inQuotes||ch===quoteChar)){inQuotes?(inQuotes=!1,quoteChar=``):(inQuotes=!0,quoteChar=ch);continue}if(!inQuotes&&/\s/.test(ch)){current&&=(tokens.push(current),``);continue}current+=ch}return current&&tokens.push(current),tokens}function resolveLinuxExecutablePath(command){let cleaned=command.trim().replace(/%[a-zA-Z]/g,``);if(!cleaned)return null;if(cleaned.startsWith(`/`))return cleaned;let resolved=execText(`which`,[cleaned],800);return resolved?resolved.trim():null}function readWindowsProgId(){let output=execText(`reg`,[`query`,`HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice`,`/v`,`ProgId`]);return output&&output.match(/ProgId\s+REG_\w+\s+(.+)$/im)?.[1]?.trim()||null}function readWindowsCommandForProgId(progId){let output=execText(`reg`,[`query`,progId===`http`?`HKCR\\http\\shell\\open\\command`:`HKCR\\${progId}\\shell\\open\\command`,`/ve`]);return output&&output.match(/REG_\w+\s+(.+)$/im)?.[1]?.trim()||null}function expandWindowsEnvVars(value){return value.replace(/%([^%]+)%/g,(_match,name)=>{let key=String(name??``).trim();return key?process.env[key]??`%${key}%`:_match})}function extractWindowsExecutablePath(command){let quoted=command.match(/"([^"]+\\.exe)"/i);if(quoted?.[1])return quoted[1];let unquoted=command.match(/([^\\s]+\\.exe)/i);return unquoted?.[1]?unquoted[1]:null}function findFirstExecutable(candidates){for(let candidate of candidates)if(exists$1(candidate.path))return candidate;return null}function findChromeExecutableMac(){return findFirstExecutable([{kind:`chrome`,path:`/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`},{kind:`chrome`,path:path.join(os.homedir(),`Applications/Google Chrome.app/Contents/MacOS/Google Chrome`)},{kind:`brave`,path:`/Applications/Brave Browser.app/Contents/MacOS/Brave Browser`},{kind:`brave`,path:path.join(os.homedir(),`Applications/Brave Browser.app/Contents/MacOS/Brave Browser`)},{kind:`edge`,path:`/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge`},{kind:`edge`,path:path.join(os.homedir(),`Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge`)},{kind:`chromium`,path:`/Applications/Chromium.app/Contents/MacOS/Chromium`},{kind:`chromium`,path:path.join(os.homedir(),`Applications/Chromium.app/Contents/MacOS/Chromium`)},{kind:`canary`,path:`/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary`},{kind:`canary`,path:path.join(os.homedir(),`Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary`)}])}function findChromeExecutableLinux(){return findFirstExecutable([{kind:`chrome`,path:`/usr/bin/google-chrome`},{kind:`chrome`,path:`/usr/bin/google-chrome-stable`},{kind:`chrome`,path:`/usr/bin/chrome`},{kind:`brave`,path:`/usr/bin/brave-browser`},{kind:`brave`,path:`/usr/bin/brave-browser-stable`},{kind:`brave`,path:`/usr/bin/brave`},{kind:`brave`,path:`/snap/bin/brave`},{kind:`edge`,path:`/usr/bin/microsoft-edge`},{kind:`edge`,path:`/usr/bin/microsoft-edge-stable`},{kind:`chromium`,path:`/usr/bin/chromium`},{kind:`chromium`,path:`/usr/bin/chromium-browser`},{kind:`chromium`,path:`/snap/bin/chromium`}])}function findChromeExecutableWindows(){let localAppData=process.env.LOCALAPPDATA??``,programFiles=process.env.ProgramFiles??`C:\\Program Files`,programFilesX86=process.env[`ProgramFiles(x86)`]??`C:\\Program Files (x86)`,joinWin=path.win32.join,candidates=[];return localAppData&&(candidates.push({kind:`chrome`,path:joinWin(localAppData,`Google`,`Chrome`,`Application`,`chrome.exe`)}),candidates.push({kind:`brave`,path:joinWin(localAppData,`BraveSoftware`,`Brave-Browser`,`Application`,`brave.exe`)}),candidates.push({kind:`edge`,path:joinWin(localAppData,`Microsoft`,`Edge`,`Application`,`msedge.exe`)}),candidates.push({kind:`chromium`,path:joinWin(localAppData,`Chromium`,`Application`,`chrome.exe`)}),candidates.push({kind:`canary`,path:joinWin(localAppData,`Google`,`Chrome SxS`,`Application`,`chrome.exe`)})),candidates.push({kind:`chrome`,path:joinWin(programFiles,`Google`,`Chrome`,`Application`,`chrome.exe`)}),candidates.push({kind:`chrome`,path:joinWin(programFilesX86,`Google`,`Chrome`,`Application`,`chrome.exe`)}),candidates.push({kind:`brave`,path:joinWin(programFiles,`BraveSoftware`,`Brave-Browser`,`Application`,`brave.exe`)}),candidates.push({kind:`brave`,path:joinWin(programFilesX86,`BraveSoftware`,`Brave-Browser`,`Application`,`brave.exe`)}),candidates.push({kind:`edge`,path:joinWin(programFiles,`Microsoft`,`Edge`,`Application`,`msedge.exe`)}),candidates.push({kind:`edge`,path:joinWin(programFilesX86,`Microsoft`,`Edge`,`Application`,`msedge.exe`)}),findFirstExecutable(candidates)}function resolveBrowserExecutableForPlatform(resolved,platform){if(resolved.executablePath){if(!exists$1(resolved.executablePath))throw Error(`browser.executablePath not found: ${resolved.executablePath}`);return{kind:`custom`,path:resolved.executablePath}}return detectDefaultChromiumExecutable(platform)||(platform===`darwin`?findChromeExecutableMac():platform===`linux`?findChromeExecutableLinux():platform===`win32`?findChromeExecutableWindows():null)}process.platform;var PortInUseError=class extends Error{constructor(port,details){super(`Port ${port} is already in use.`),this.name=`PortInUseError`,this.port=port,this.details=details}};async function ensurePortAvailable(port){try{await new Promise((resolve,reject)=>{let tester=net.createServer().once(`error`,err=>reject(err)).once(`listening`,()=>{tester.close(()=>resolve())}).listen(port)})}catch(err){throw isErrno(err)&&err.code===`EADDRINUSE`?new PortInUseError(port):err}}function decoratedMarkerPath(userDataDir){return path.join(userDataDir,`.builderforce-profile-decorated`)}function safeReadJson(filePath){try{if(!fs.existsSync(filePath))return null;let raw=fs.readFileSync(filePath,`utf-8`),parsed=JSON.parse(raw);return typeof parsed!=`object`||!parsed||Array.isArray(parsed)?null:parsed}catch{return null}}function safeWriteJson(filePath,data){fs.mkdirSync(path.dirname(filePath),{recursive:!0}),fs.writeFileSync(filePath,JSON.stringify(data,null,2))}function setDeep(obj,keys,value){let node=obj;for(let key of keys.slice(0,-1)){let next=node[key];(typeof next!=`object`||!next||Array.isArray(next))&&(node[key]={}),node=node[key]}node[keys[keys.length-1]??``]=value}function parseHexRgbToSignedArgbInt(hex){let cleaned=hex.trim().replace(/^#/,``);if(!/^[0-9a-fA-F]{6}$/.test(cleaned))return null;let argbUnsigned=255<<24|Number.parseInt(cleaned,16);return argbUnsigned>2147483647?argbUnsigned-4294967296:argbUnsigned}function isProfileDecorated(userDataDir,desiredName,desiredColorHex){let desiredColorInt=parseHexRgbToSignedArgbInt(desiredColorHex),localStatePath=path.join(userDataDir,`Local State`),preferencesPath=path.join(userDataDir,`Default`,`Preferences`),profile=safeReadJson(localStatePath)?.profile,infoCache=typeof profile==`object`&&profile&&!Array.isArray(profile)?profile.info_cache:null,info=typeof infoCache==`object`&&infoCache&&!Array.isArray(infoCache)&&typeof infoCache.Default==`object`&&infoCache.Default!==null&&!Array.isArray(infoCache.Default)?infoCache.Default:null,prefs=safeReadJson(preferencesPath),browserTheme=(()=>{let browser=prefs?.browser,theme=typeof browser==`object`&&browser&&!Array.isArray(browser)?browser.theme:null;return typeof theme==`object`&&theme&&!Array.isArray(theme)?theme:null})(),autogeneratedTheme=(()=>{let autogenerated=prefs?.autogenerated,theme=typeof autogenerated==`object`&&autogenerated&&!Array.isArray(autogenerated)?autogenerated.theme:null;return typeof theme==`object`&&theme&&!Array.isArray(theme)?theme:null})(),nameOk=typeof info?.name==`string`?info.name===desiredName:!0;if(desiredColorInt==null)return nameOk;let localSeedOk=typeof info?.profile_color_seed==`number`?info.profile_color_seed===desiredColorInt:!1,prefOk=typeof browserTheme?.user_color2==`number`&&browserTheme.user_color2===desiredColorInt||typeof autogeneratedTheme?.color==`number`&&autogeneratedTheme.color===desiredColorInt;return nameOk&&localSeedOk&&prefOk}function decorateBuilderForceAgentsProfile(userDataDir,opts){let desiredName=opts?.name??DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME,desiredColor=(opts?.color??DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR).toUpperCase(),desiredColorInt=parseHexRgbToSignedArgbInt(desiredColor),localStatePath=path.join(userDataDir,`Local State`),preferencesPath=path.join(userDataDir,`Default`,`Preferences`),localState=safeReadJson(localStatePath)??{};setDeep(localState,[`profile`,`info_cache`,`Default`,`name`],desiredName),setDeep(localState,[`profile`,`info_cache`,`Default`,`shortcut_name`],desiredName),setDeep(localState,[`profile`,`info_cache`,`Default`,`user_name`],desiredName),setDeep(localState,[`profile`,`info_cache`,`Default`,`profile_color`],desiredColor),setDeep(localState,[`profile`,`info_cache`,`Default`,`user_color`],desiredColor),desiredColorInt!=null&&(setDeep(localState,[`profile`,`info_cache`,`Default`,`profile_color_seed`],desiredColorInt),setDeep(localState,[`profile`,`info_cache`,`Default`,`profile_highlight_color`],desiredColorInt),setDeep(localState,[`profile`,`info_cache`,`Default`,`default_avatar_fill_color`],desiredColorInt),setDeep(localState,[`profile`,`info_cache`,`Default`,`default_avatar_stroke_color`],desiredColorInt)),safeWriteJson(localStatePath,localState);let prefs=safeReadJson(preferencesPath)??{};setDeep(prefs,[`profile`,`name`],desiredName),setDeep(prefs,[`profile`,`profile_color`],desiredColor),setDeep(prefs,[`profile`,`user_color`],desiredColor),desiredColorInt!=null&&(setDeep(prefs,[`autogenerated`,`theme`,`color`],desiredColorInt),setDeep(prefs,[`browser`,`theme`,`user_color2`],desiredColorInt)),safeWriteJson(preferencesPath,prefs);try{fs.writeFileSync(decoratedMarkerPath(userDataDir),`${Date.now()}\n`,`utf-8`)}catch{}}function ensureProfileCleanExit(userDataDir){let preferencesPath=path.join(userDataDir,`Default`,`Preferences`),prefs=safeReadJson(preferencesPath)??{};setDeep(prefs,[`exit_type`],`Normal`),setDeep(prefs,[`exited_cleanly`],!0),safeWriteJson(preferencesPath,prefs)}const log=createSubsystemLogger(`browser`).child(`chrome`);function exists(filePath){try{return fs.existsSync(filePath)}catch{return!1}}function resolveBrowserExecutable(resolved){return resolveBrowserExecutableForPlatform(resolved,process.platform)}function resolveBuilderForceAgentsUserDataDir(profileName=DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME){return path.join(CONFIG_DIR,`browser`,profileName,`user-data`)}function cdpUrlForPort(cdpPort){return`http://127.0.0.1:${cdpPort}`}async function isChromeReachable(cdpUrl,timeoutMs=500){return!!await fetchChromeVersion(cdpUrl,timeoutMs)}async function fetchChromeVersion(cdpUrl,timeoutMs=500){let ctrl=new AbortController,t=setTimeout(ctrl.abort.bind(ctrl),timeoutMs);try{let versionUrl=appendCdpPath(cdpUrl,`/json/version`),res=await fetch(versionUrl,{signal:ctrl.signal,headers:getHeadersWithAuth(versionUrl)});if(!res.ok)return null;let data=await res.json();return!data||typeof data!=`object`?null:data}catch{return null}finally{clearTimeout(t)}}async function getChromeWebSocketUrl(cdpUrl,timeoutMs=500){let version=await fetchChromeVersion(cdpUrl,timeoutMs),wsUrl=String(version?.webSocketDebuggerUrl??``).trim();return wsUrl?normalizeCdpWsUrl(wsUrl,cdpUrl):null}async function canOpenWebSocket(wsUrl,timeoutMs=800){return await new Promise(resolve=>{let headers=getHeadersWithAuth(wsUrl),ws=new WebSocket(wsUrl,{handshakeTimeout:timeoutMs,...Object.keys(headers).length?{headers}:{}}),timer=setTimeout(()=>{try{ws.terminate()}catch{}resolve(!1)},Math.max(50,timeoutMs+25));ws.once(`open`,()=>{clearTimeout(timer);try{ws.close()}catch{}resolve(!0)}),ws.once(`error`,()=>{clearTimeout(timer),resolve(!1)})})}async function isChromeCdpReady(cdpUrl,timeoutMs=500,handshakeTimeoutMs=800){let wsUrl=await getChromeWebSocketUrl(cdpUrl,timeoutMs);return wsUrl?await canOpenWebSocket(wsUrl,handshakeTimeoutMs):!1}async function launchBuilderForceAgentsChrome(resolved,profile){if(!profile.cdpIsLoopback)throw Error(`Profile "${profile.name}" is remote; cannot launch local Chrome.`);await ensurePortAvailable(profile.cdpPort);let exe=resolveBrowserExecutable(resolved);if(!exe)throw Error(`No supported browser found (Chrome/Brave/Edge/Chromium on macOS, Linux, or Windows).`);let userDataDir=resolveBuilderForceAgentsUserDataDir(profile.name);fs.mkdirSync(userDataDir,{recursive:!0});let needsDecorate=!isProfileDecorated(userDataDir,profile.name,(profile.color??DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR).toUpperCase()),spawnOnce=()=>{let args=[`--remote-debugging-port=${profile.cdpPort}`,`--user-data-dir=${userDataDir}`,`--no-first-run`,`--no-default-browser-check`,`--disable-sync`,`--disable-background-networking`,`--disable-component-update`,`--disable-features=Translate,MediaRouter`,`--disable-session-crashed-bubble`,`--hide-crash-restore-bubble`,`--password-store=basic`];return resolved.headless&&(args.push(`--headless=new`),args.push(`--disable-gpu`)),resolved.noSandbox&&(args.push(`--no-sandbox`),args.push(`--disable-setuid-sandbox`)),process.platform===`linux`&&args.push(`--disable-dev-shm-usage`),args.push(`--disable-blink-features=AutomationControlled`),resolved.extraArgs.length>0&&args.push(...resolved.extraArgs),args.push(`about:blank`),spawn(exe.path,args,{stdio:`pipe`,env:{...process.env,HOME:os.homedir()}})},startedAt=Date.now(),localStatePath=path.join(userDataDir,`Local State`),preferencesPath=path.join(userDataDir,`Default`,`Preferences`);if(!exists(localStatePath)||!exists(preferencesPath)){let bootstrap=spawnOnce(),deadline=Date.now()+1e4;for(;Date.now()<deadline&&!(exists(localStatePath)&&exists(preferencesPath));)await new Promise(r=>setTimeout(r,100));try{bootstrap.kill(`SIGTERM`)}catch{}let exitDeadline=Date.now()+5e3;for(;Date.now()<exitDeadline&&bootstrap.exitCode==null;)await new Promise(r=>setTimeout(r,50))}if(needsDecorate)try{decorateBuilderForceAgentsProfile(userDataDir,{name:profile.name,color:profile.color}),log.info(`🤖 builderforce browser profile decorated (${profile.color})`)}catch(err){log.warn(`builderforce browser profile decoration failed: ${String(err)}`)}try{ensureProfileCleanExit(userDataDir)}catch(err){log.warn(`builderforce browser clean-exit prefs failed: ${String(err)}`)}let proc=spawnOnce(),readyDeadline=Date.now()+15e3;for(;Date.now()<readyDeadline&&!await isChromeReachable(profile.cdpUrl,500);)await new Promise(r=>setTimeout(r,200));if(!await isChromeReachable(profile.cdpUrl,500)){try{proc.kill(`SIGKILL`)}catch{}throw Error(`Failed to start Chrome CDP on port ${profile.cdpPort} for profile "${profile.name}".`)}let pid=proc.pid??-1;return log.info(`🤖 builderforce browser started (${exe.kind}) profile "${profile.name}" on 127.0.0.1:${profile.cdpPort} (pid ${pid})`),{pid,exe,userDataDir,cdpPort:profile.cdpPort,startedAt,proc}}async function stopBuilderForceAgentsChrome(running,timeoutMs=2500){let proc=running.proc;if(proc.killed)return;try{proc.kill(`SIGTERM`)}catch{}let start=Date.now();for(;Date.now()-start<timeoutMs&&!(!proc.exitCode&&proc.killed);){if(!await isChromeReachable(cdpUrlForPort(running.cdpPort),200))return;await new Promise(r=>setTimeout(r,100))}try{proc.kill(`SIGKILL`)}catch{}}export{DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR as A,pickPrimaryLanIPv4 as C,DEFAULT_AI_SNAPSHOT_MAX_CHARS as D,DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS as E,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME as M,DEFAULT_BROWSER_DEFAULT_PROFILE_NAME as O,isLoopbackHost as S,DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH as T,withCdpSocket as _,resolveBuilderForceAgentsUserDataDir as a,rawDataToString as b,captureScreenshot as c,normalizeCdpWsUrl as d,snapshotAria as f,getHeadersWithAuth as g,fetchOk as h,launchBuilderForceAgentsChrome as i,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_ENABLED as j,DEFAULT_BROWSER_EVALUATE_ENABLED as k,createTargetViaCdp as l,fetchJson as m,isChromeCdpReady as n,stopBuilderForceAgentsChrome as o,appendCdpPath as p,isChromeReachable as r,resolveBrowserExecutableForPlatform as s,getChromeWebSocketUrl as t,formatAriaSnapshot as u,ensureChromeExtensionRelayServer as v,pickPrimaryTailnetIPv4 as w,resolvePreferredBuilderForceAgentsTmpDir as x,stopChromeExtensionRelayServer as y};