@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.
- package/dist/{agent-DvDtjczG.js → agent-CeWx2EpQ.js} +1 -1
- package/dist/{agent-DiLX8OzY.js → agent-DrcnpqOF.js} +1 -1
- package/dist/{agents-BawpdEjP.js → agents-CRJM6qhK.js} +1 -1
- package/dist/{agents-COWLUJqm.js → agents-hATFRfwk.js} +1 -1
- package/dist/{audio-preflight-CYQiI74L.js → audio-preflight-B9CfGDD2.js} +1 -1
- package/dist/{audio-preflight-BN1u9Tpc.js → audio-preflight-DHHeocUj.js} +1 -1
- package/dist/{auth-choice-D9VN-WjA.js → auth-choice-CWbPLRN0.js} +1 -1
- package/dist/{auth-choice-3cdcHeim.js → auth-choice-CzhKgWJy.js} +1 -1
- package/dist/{auth-choice.apply-Cd0RR0Z-.js → auth-choice.apply-C0RTYtRN.js} +1 -1
- package/dist/{auth-choice.apply-CMDgoDNN.js → auth-choice.apply-ChrTTHkK.js} +1 -1
- package/dist/{auth-choice.apply-BAeGyEKW.js → auth-choice.apply-D4LYzI8l.js} +1 -1
- package/dist/{auth-choice.apply-CSXvPCea.js → auth-choice.apply-Dy4rVG6K.js} +1 -1
- package/dist/{auth-choice.apply.transformers-DkX2-OZa.js → auth-choice.apply.transformers-9v6HFzNs.js} +1 -1
- package/dist/{auth-choice.apply.transformers-CEVxl3ul.js → auth-choice.apply.transformers-Be8599JD.js} +1 -1
- package/dist/{auth-choice.apply.transformers-B2Nr9M7m.js → auth-choice.apply.transformers-CgfGlqy1.js} +1 -1
- package/dist/{auth-choice.apply.transformers-Dpy9gODo.js → auth-choice.apply.transformers-D9a8-sLS.js} +1 -1
- package/dist/{banner-C93QSUTe.js → banner-8F7-gU1V.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/{builderforce-Dl4bZ63C.js → builderforce-CCfM1c79.js} +1 -1
- package/dist/{builderforce-C_tuO46t.js → builderforce-CImLd8Zo.js} +1 -1
- package/dist/bundled/boot-md/handler.js +1 -1
- package/dist/bundled/session-memory/handler.js +1 -1
- package/dist/{channel-options-CiYpNR-1.js → channel-options-CRng-5hZ.js} +1 -1
- package/dist/{channel-options-Cziy0WDc.js → channel-options-D5kOIN7b.js} +1 -1
- package/dist/{channel-web-Ae15MleJ.js → channel-web-B5HSpL4k.js} +1 -1
- package/dist/{channels-cli-CZM033Me.js → channels-cli-COl9TDHT.js} +1 -1
- package/dist/{channels-cli-yi1vxpvO.js → channels-cli-bR8QwOv3.js} +1 -1
- package/dist/chrome-ChzFLAeJ.js +4 -0
- package/dist/chrome-CrqJ4Ijz.js +4 -0
- package/dist/{cli-Bwv_-VuS.js → cli-BqJMHFNK.js} +1 -1
- package/dist/{cli-D8fndSEi.js → cli-DBn0qbHS.js} +1 -1
- package/dist/{command-registry-Cjom5ab0.js → command-registry-BqhtXJa7.js} +1 -1
- package/dist/{command-registry-8uEx2JjY.js → command-registry-DVH79C3B.js} +1 -1
- package/dist/{completion-cli-PTFpWp8Q.js → completion-cli-BFR0u1Uh.js} +1 -1
- package/dist/{completion-cli-LUuqgvVQ.js → completion-cli-BuUAEqQw.js} +1 -1
- package/dist/{completion-cli-DRsz70D2.js → completion-cli-CwaIh4zw.js} +1 -1
- package/dist/{completion-cli-BsXDz7T2.js → completion-cli-Da3-oE7r.js} +1 -1
- package/dist/{config-cli-BIx0enD5.js → config-cli-Bhrj7H1i.js} +1 -1
- package/dist/{config-cli-BFhOXrua.js → config-cli-DOHKZ1lO.js} +1 -1
- package/dist/{configure-D96xLIb6.js → configure-B-Yta1X3.js} +1 -1
- package/dist/{configure-S7YE6hn1.js → configure-BHVk4Ax9.js} +1 -1
- package/dist/{configure-dDKfCq_g.js → configure-D9YZEK_D.js} +1 -1
- package/dist/{configure-C7xdw9Kq.js → configure-DPE2hDzY.js} +1 -1
- package/dist/{deps-CGiO_NDu.js → deps-CrAVOWsA.js} +1 -1
- package/dist/{doctor-completion-ChhIrLd3.js → doctor-completion-CkjrUmbI.js} +1 -1
- package/dist/{doctor-completion-BUZwWoWB.js → doctor-completion-Dh9ah5lH.js} +1 -1
- package/dist/{embedded-DJYMy81Q.js → embedded-BrqzM5oT.js} +12 -12
- package/dist/{embedded-DjDnQMNx.js → embedded-wYxo-ADm.js} +12 -12
- package/dist/entry.js +1 -1
- package/dist/extensionAPI.js +1 -1
- package/dist/{gateway-cli-CN114d5j.js → gateway-cli-C2nh9UyY.js} +2 -2
- package/dist/{gateway-cli-Dzl70YBF.js → gateway-cli-CGkTLhet.js} +2 -2
- package/dist/{health-Cf1YoTRN.js → health-CEz2-7et.js} +1 -1
- package/dist/{health-AlkF1nUa.js → health-CFVx21sO.js} +1 -1
- package/dist/{health-ySVOGGNu.js → health-aKuq4xwa.js} +1 -1
- package/dist/{hooks-cli-6jeFEGg3.js → hooks-cli-DPSrycwI.js} +1 -1
- package/dist/{hooks-cli-DVPMCXUq.js → hooks-cli-uPHs7qnC.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/llm-slug-generator.js +1 -1
- package/dist/{models-CGUxphfN.js → models--TwKHn8b.js} +1 -1
- package/dist/{models-CIMM_Z3u.js → models-BXJebxTU.js} +1 -1
- package/dist/{models-cli-Cijh2uON.js → models-cli-O1zCgeoA.js} +1 -1
- package/dist/{models-cli-Oys3e_I3.js → models-cli-iKu1IVeH.js} +1 -1
- package/dist/{onboard-DAEXNhNd.js → onboard--0I8pdee.js} +1 -1
- package/dist/{onboard-b2fWbf0Q.js → onboard-C40OvMZO.js} +1 -1
- package/dist/{onboard-channels-elaccQRE.js → onboard-channels-BbpyejX4.js} +1 -1
- package/dist/{onboard-channels-Bsd11scA.js → onboard-channels-CoJnsCfd.js} +1 -1
- package/dist/{onboard-channels-C_Q7OUow.js → onboard-channels-ZI4QC9WU.js} +1 -1
- package/dist/{onboard-channels-Tl1X4Pl_.js → onboard-channels-uvIeLPXK.js} +1 -1
- package/dist/{onboard-interactive-DyGNiYRI.js → onboard-interactive-B3Z0XLT6.js} +1 -1
- package/dist/{onboard-interactive-C0qmgHsH.js → onboard-interactive-CJdxqQ1b.js} +1 -1
- package/dist/{onboard-interactive-86s992_v.js → onboard-interactive-COnCCTTW.js} +1 -1
- package/dist/{onboard-interactive-CvMSTjPK.js → onboard-interactive-jss8R9r9.js} +1 -1
- package/dist/{onboarding-DzvbhsaR.js → onboarding-B1BmYWrs.js} +2 -2
- package/dist/{onboarding-B0tbaqZ7.js → onboarding-CdRbvLgp.js} +2 -2
- package/dist/{onboarding.finalize-D-Pi9Blv.js → onboarding.finalize-B0AjF6qZ.js} +1 -1
- package/dist/{onboarding.finalize-CERLBlRF.js → onboarding.finalize-WsL-ijTc.js} +1 -1
- package/dist/{outbound-send-deps-CzhBrVa7.js → outbound-send-deps-DuML6h7r.js} +1 -1
- package/dist/{plugin-registry-DtrHn5NR.js → plugin-registry-BjWNyeVY.js} +1 -1
- package/dist/{plugin-registry-Avx51RIY.js → plugin-registry-Cf_sv-ny.js} +1 -1
- package/dist/{plugin-registry-CFkQDTOt.js → plugin-registry-DdFb5usc.js} +1 -1
- package/dist/{plugin-registry-BEmyRfmb.js → plugin-registry-DrEpL5ac.js} +1 -1
- package/dist/plugin-sdk/{accounts-BwreSNAR.js → accounts-Cy3WCbWg.js} +1 -1
- package/dist/plugin-sdk/{active-listener-DpQ7aGYd.js → active-listener-DVWVNlT9.js} +1 -1
- package/dist/plugin-sdk/agent-runtime/src/agents/tool-retry.d.ts +40 -32
- package/dist/plugin-sdk/agent-runtime/src/builderforce/model/agent-types.d.ts +6 -0
- package/dist/plugin-sdk/{agent-scope-BQByW0cD.js → agent-scope-DgKN27hJ.js} +1 -1
- package/dist/plugin-sdk/{api-key-rotation-yqTCeKjV.js → api-key-rotation-D37jV9ZW.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-B6uTvVfA.js → audio-preflight-D4xyO8Zq.js} +1 -1
- package/dist/plugin-sdk/{auth-json-Dw6ij9Pa.js → auth-json-nASe57Uw.js} +1 -1
- package/dist/plugin-sdk/{bindings-CDEzl4kl.js → bindings-CH-YLOLC.js} +1 -1
- package/dist/plugin-sdk/{channel-web-DKbpA9xC.js → channel-web-huZSNTX3.js} +1 -1
- package/dist/plugin-sdk/{chrome-DriEqJRH.js → chrome-CRUzg3kA.js} +1 -1
- package/dist/plugin-sdk/{chunk-cW0POl22.js → chunk-C94IAOuf.js} +1 -1
- package/dist/plugin-sdk/{command-format-CAX9XFjI.js → command-format-B3XMq_73.js} +1 -1
- package/dist/plugin-sdk/{common-BxEWhN2X.js → common-n0l_XN-S.js} +1 -1
- package/dist/plugin-sdk/{config-3vPn_hmp.js → config--Ci8Y91R.js} +2 -2
- package/dist/plugin-sdk/{fetch-DH0Y8iyO.js → fetch-B-GxSYRO.js} +1 -1
- package/dist/plugin-sdk/index.js +1 -1
- package/dist/plugin-sdk/{login-Dhdx0bVL.js → login-DZliYZg8.js} +1 -1
- package/dist/plugin-sdk/{login-qr-DAjOuijP.js → login-qr-DKcGvAjv.js} +1 -1
- package/dist/plugin-sdk/{manager-i8psl2Er.js → manager-DioOqJm_.js} +1 -1
- package/dist/plugin-sdk/{markdown-tables-Epim9b-0.js → markdown-tables-BUfhHgfs.js} +1 -1
- package/dist/plugin-sdk/{message-channel-sBPQc_-T.js → message-channel-CuZ2xOAM.js} +1 -1
- package/dist/plugin-sdk/{model-catalog-COVRezOQ.js → model-catalog-DIQ5a-o4.js} +1 -1
- package/dist/plugin-sdk/{model-selection-Crz-xYNU.js → model-selection-_H_U9jWH.js} +1 -1
- package/dist/plugin-sdk/{outbound-CPutSvae.js → outbound-Djibdmi7.js} +1 -1
- package/dist/plugin-sdk/{plugins-CaUOZBVb.js → plugins-BdkC9v5E.js} +1 -1
- package/dist/plugin-sdk/{pw-ai-jI9AWvKe.js → pw-ai-Bbi8Us-p.js} +1 -1
- package/dist/plugin-sdk/{qmd-manager-BRe5fGZw.js → qmd-manager-Dxn0jCpE.js} +1 -1
- package/dist/plugin-sdk/{registry-DJq2Cvo9.js → registry-CZHRcH-q.js} +1 -1
- package/dist/plugin-sdk/{render-BUCRXPIk.js → render-CuA_WRX5.js} +1 -1
- package/dist/plugin-sdk/{replies-CYjI7bye.js → replies-Cf69aZLA.js} +1 -1
- package/dist/plugin-sdk/{reply-B5o-SSYy.js → reply-BOVC-7UD.js} +13 -13
- package/dist/plugin-sdk/{reply-prefix-CCymsmsP.js → reply-prefix-w7kAvH11.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-DN1J7Wyc.js → resolve-route-0sbvl4ZN.js} +1 -1
- package/dist/plugin-sdk/{runner-C2pDJlRw.js → runner-DKoKK09-.js} +4 -4
- package/dist/plugin-sdk/{session-BnleckVX.js → session-DGLuyt10.js} +1 -1
- package/dist/plugin-sdk/{sqlite-BlMLqMl8.js → sqlite-JjFgDV-H.js} +1 -1
- package/dist/plugin-sdk/{subsystem-COTa5Ly_.js → subsystem-D0Ril4rt.js} +1 -1
- package/dist/plugin-sdk/{tool-images-DSpchb4x.js → tool-images-WRTP95FT.js} +1 -1
- package/dist/plugin-sdk/{tool-loop-detection-16p7mJ8N.js → tool-loop-detection-g8gPTCgJ.js} +1 -1
- package/dist/plugin-sdk/web-Cdu8TkUy.js +1 -0
- package/dist/plugin-sdk/{whatsapp-actions-C2B3iw8n.js → whatsapp-actions-CsSzy7G0.js} +1 -1
- package/dist/{plugins-DAlgx58e.js → plugins-Dr1wmnAf.js} +1 -1
- package/dist/{plugins-De7aK3yK.js → plugins-JhEblShx.js} +1 -1
- package/dist/{plugins-cli-CwdUVWjG.js → plugins-cli-DW4hoeeV.js} +1 -1
- package/dist/{plugins-cli-CfVCrrhx.js → plugins-cli-GewV3E8e.js} +1 -1
- package/dist/{program-CFL6mW3l.js → program-bggmBKuL.js} +2 -2
- package/dist/{program-context-DP4Xq9zC.js → program-context-BCTE8zEF.js} +1 -1
- package/dist/{prompt-select-styled-NxrGT7OR.js → prompt-select-styled-BtjhlTEH.js} +1 -1
- package/dist/{prompt-select-styled-Csz9HlSx.js → prompt-select-styled-CaNl41mG.js} +1 -1
- package/dist/{provider-auth-helpers-BMBw21Tn.js → provider-auth-helpers-CWUfg9zf.js} +1 -1
- package/dist/{provider-auth-helpers-VWPvSXPH.js → provider-auth-helpers-y1X8xKVE.js} +1 -1
- package/dist/{provider-dispatcher-CSOHd9zJ.js → provider-dispatcher-CRsPmKhJ.js} +1 -1
- package/dist/{provider-dispatcher-Bg9orQPy.js → provider-dispatcher-D9GbE_Ce.js} +1 -1
- package/dist/{push-apns-rMu8MKXi.js → push-apns-Cb1sQEEa.js} +1 -1
- package/dist/{push-apns-ep5WkyGz.js → push-apns-Cr-6aD3y.js} +1 -1
- package/dist/{pw-ai-UXo3gDGy.js → pw-ai-CG-kY5NP.js} +1 -1
- package/dist/{pw-ai-CIN6tj0G.js → pw-ai-DcZPg2vm.js} +1 -1
- package/dist/{register.agent-BynXVz7v.js → register.agent-B33EZBoL.js} +1 -1
- package/dist/{register.agent-RNVNKBP3.js → register.agent-DfYqZls1.js} +1 -1
- package/dist/{register.configure-BdqREs1-.js → register.configure-CREcJhKA.js} +1 -1
- package/dist/{register.configure-DDrvpBnA.js → register.configure-D8an7wc5.js} +1 -1
- package/dist/{register.maintenance-DT6t7mD_.js → register.maintenance-D84M5XLR.js} +1 -1
- package/dist/{register.maintenance-BSKHOCTV.js → register.maintenance-Dnp_Ii2x.js} +1 -1
- package/dist/{register.message-7KIfSUxS.js → register.message-B6E0uAEu.js} +1 -1
- package/dist/{register.message-DDhEvcaX.js → register.message-WOWC4tyf.js} +1 -1
- package/dist/{register.onboard-CKhooa7L.js → register.onboard-AgVEhehS.js} +1 -1
- package/dist/{register.onboard-CswvuzLx.js → register.onboard-Cwozk0Tx.js} +1 -1
- package/dist/{register.setup-1BmR-qlh.js → register.setup-BKyCvo9_.js} +1 -1
- package/dist/{register.setup-CivwfXf_.js → register.setup-C9IeGiAd.js} +1 -1
- package/dist/{register.status-health-sessions-CLdHZiJm.js → register.status-health-sessions-CYZctjpx.js} +1 -1
- package/dist/{register.status-health-sessions-BXpljfv3.js → register.status-health-sessions-CcL6srRC.js} +1 -1
- package/dist/{register.subclis-D_fHb-Aj.js → register.subclis-AFsfDByV.js} +1 -1
- package/dist/{register.subclis-CTTxdHaJ.js → register.subclis-C0DxtuRO.js} +1 -1
- package/dist/{reply-D9wUWhMx.js → reply-BuUSdq2L.js} +9 -9
- package/dist/{run-main-DNyQhVQT.js → run-main-CgJMiKPV.js} +1 -1
- package/dist/{runner-BNnckkaT.js → runner-C8oNv-9y.js} +3 -3
- package/dist/{runner-EHybuAt7.js → runner-nDoIXX7n.js} +3 -3
- package/dist/{server-node-events-BGrnw4ZT.js → server-node-events-BMsKmU5S.js} +1 -1
- package/dist/{server-node-events-D4WVcVHy.js → server-node-events-fS8TluXq.js} +1 -1
- package/dist/{session-dirs-eNN7E3kA.js → session-dirs-Bkfs-7vN.js} +1 -1
- package/dist/{session-dirs-C-pVBwSV.js → session-dirs-rYDCA_mQ.js} +1 -1
- package/dist/{status-Demw1HZ7.js → status-Ad1eFPKR.js} +1 -1
- package/dist/{status-CBieo24v.js → status-BMzVz5KY.js} +1 -1
- package/dist/{status-rkFgCaBM.js → status-CXRyaGws.js} +1 -1
- package/dist/{status-wTMmjZ7M.js → status-DpEUFAMk.js} +1 -1
- package/dist/{status-BhJw9Htq.js → status-oaiZkYBt.js} +1 -1
- package/dist/{subagent-registry-Bje3RAgk.js → subagent-registry-gVTWLPpL.js} +1 -1
- package/dist/{subagent-registry-B0kpBIxD.js → subagent-registry-hM0OCDzv.js} +1 -1
- package/dist/{subagent-registry-Cj5yC7B4.js → subagent-registry-m_x-JRkR.js} +9 -9
- package/dist/{tui-BCtecmPL.js → tui-HTtOgZ_X.js} +2 -2
- package/dist/{tui-BqHLI73U.js → tui-LemSel3H.js} +2 -2
- package/dist/{tui-cli-2R0xjpqW.js → tui-cli-BpzicV5H.js} +1 -1
- package/dist/{tui-cli-Dvd8BwzD.js → tui-cli-CruoIP1K.js} +1 -1
- package/dist/{update-cli-DUObGvw1.js → update-cli-Wa-nZ_Lq.js} +1 -1
- package/dist/{update-cli-Bt7Vfi7c.js → update-cli-zv67YxK1.js} +1 -1
- package/dist/{web--KblE8ax.js → web-BrsbhB1i.js} +1 -1
- package/dist/{web-C-yTnRvS.js → web-BzkO4Pbe.js} +1 -1
- package/dist/{web-0VRcRcFj.js → web-D_QYY7Gt.js} +1 -1
- package/dist/{web-BcUIWAAJ.js → web-jPbmSTQm.js} +1 -1
- package/package.json +1 -1
- package/dist/chrome-CmCESKt9.js +0 -4
- package/dist/chrome-D6qk0wxW.js +0 -4
- package/dist/plugin-sdk/web-CzJYJZZs.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as resolveOAuthDir,c as expandHomePrefix,l as resolveEffectiveHomeDir,n as resolveConfigPath,s as resolveStateDir,u as resolveRequiredHomeDir}from"./paths-Cb8zTlyG.js";import{createRequire}from"node:module";import path from"node:path";import fs from"node:fs";import os from"node:os";import{Logger}from"tslog";import json5 from"json5";import chalk,{Chalk}from"chalk";function normalizePluginHttpPath(path,fallback){let trimmed=path?.trim();if(!trimmed){let fallbackTrimmed=fallback?.trim();return fallbackTrimmed?fallbackTrimmed.startsWith(`/`)?fallbackTrimmed:`/${fallbackTrimmed}`:null}return trimmed.startsWith(`/`)?trimmed:`/${trimmed}`}const handlers=new Map;function registerInternalHook(eventKey,handler){handlers.has(eventKey)||handlers.set(eventKey,[]),handlers.get(eventKey).push(handler)}async function triggerInternalHook(event){let typeHandlers=handlers.get(event.type)??[],specificHandlers=handlers.get(`${event.type}:${event.action}`)??[],allHandlers=[...typeHandlers,...specificHandlers];if(allHandlers.length!==0)for(let handler of allHandlers)try{await handler(event)}catch(err){console.error(`Hook error [${event.type}:${event.action}]:`,err instanceof Error?err.message:String(err))}}function createInternalHookEvent(type,action,sessionKey,context={}){return{type,action,sessionKey,context,timestamp:new Date,messages:[]}}function readLoggingConfig(){let configPath=resolveConfigPath();try{if(!fs.existsSync(configPath))return;let raw=fs.readFileSync(configPath,`utf-8`),logging=json5.parse(raw)?.logging;return!logging||typeof logging!=`object`||Array.isArray(logging)?void 0:logging}catch{return}}const ALLOWED_LOG_LEVELS=[`silent`,`fatal`,`error`,`warn`,`info`,`debug`,`trace`];function normalizeLogLevel(level,fallback=`info`){let candidate=(level??fallback).trim();return ALLOWED_LOG_LEVELS.includes(candidate)?candidate:fallback}function levelToMinLevel(level){return{fatal:0,error:1,warn:2,info:3,debug:4,trace:5,silent:1/0}[level]}const loggingState={cachedLogger:null,cachedSettings:null,cachedConsoleSettings:null,overrideSettings:null,consolePatched:!1,forceConsoleToStderr:!1,consoleTimestampPrefix:!1,consoleSubsystemFilter:null,resolvingConsoleSettings:!1,streamErrorHandlersInstalled:!1,rawConsole:null},DEFAULT_LOG_DIR=path.join(resolveStateDir(),`logs`);path.join(DEFAULT_LOG_DIR,`builderforce.log`);const LOG_PREFIX=`builderforce`,LOG_SUFFIX=`.log`,requireConfig=createRequire(import.meta.url),externalTransports=new Set;function attachExternalTransport(logger,transport){logger.attachTransport(logObj=>{if(externalTransports.has(transport))try{transport(logObj)}catch{}})}function resolveSettings(){let cfg=loggingState.overrideSettings??readLoggingConfig();if(!cfg)try{cfg=requireConfig(`../config/config.js`).loadConfig?.().logging}catch{cfg=void 0}let defaultLevel=process.env.VITEST===`true`&&process.env.BUILDERFORCE_AGENTS_TEST_FILE_LOG!==`1`?`silent`:`info`,enabled=cfg?.enabled!==!1;return{enabled,level:enabled?normalizeLogLevel(cfg?.level,defaultLevel):`silent`,file:cfg?.file??defaultRollingPathForToday(),format:cfg?.format===`text`?`text`:`json`}}function settingsChanged(a,b){return a?a.enabled!==b.enabled||a.level!==b.level||a.file!==b.file||a.format!==b.format:!0}function isFileLogLevelEnabled(level){let settings=loggingState.cachedSettings??resolveSettings();return loggingState.cachedSettings||=settings,!settings.enabled||settings.level===`silent`?!1:levelToMinLevel(level)<=levelToMinLevel(settings.level)}function buildLogger(settings){if(!settings.enabled)return new Logger({name:`builderforce`,minLevel:levelToMinLevel(`silent`),type:`hidden`});fs.mkdirSync(path.dirname(settings.file),{recursive:!0}),isRollingPath(settings.file)&&pruneOldRollingLogs(path.dirname(settings.file));let logger=new Logger({name:`builderforce`,minLevel:levelToMinLevel(settings.level),type:`hidden`});logger.attachTransport(logObj=>{try{let time=logObj.date?.toISOString?.()??new Date().toISOString();if(settings.format===`text`){let lvlVal=logObj._meta?.logLevelName,lvl=typeof lvlVal==`string`?lvlVal:``,part0=logObj[0]===void 0?``:String(logObj[0]),part1=logObj[1]===void 0?``:JSON.stringify(logObj[1]),suffix=part1&&part1!==`{}`?` ${part1}`:``,plain=`${time} ${lvl.toUpperCase()} ${part0}${suffix}`.trim();fs.appendFileSync(settings.file,`${plain}\n`,{encoding:`utf8`})}else{let line=JSON.stringify({...logObj,time});fs.appendFileSync(settings.file,`${line}\n`,{encoding:`utf8`})}}catch{}});for(let transport of externalTransports)attachExternalTransport(logger,transport);return logger}function getLogger(){let settings=resolveSettings(),cachedLogger=loggingState.cachedLogger,cachedSettings=loggingState.cachedSettings;return(!cachedLogger||settingsChanged(cachedSettings,settings))&&(loggingState.cachedLogger=buildLogger(settings),loggingState.cachedSettings=settings),loggingState.cachedLogger}function getChildLogger(bindings,opts){let base=getLogger(),minLevel=opts?.level?levelToMinLevel(opts.level):void 0,name=bindings?JSON.stringify(bindings):void 0;return base.getSubLogger({name,minLevel,prefix:bindings?[name??``]:[]})}function toPinoLikeLogger(logger,level){return{level,child:bindings=>toPinoLikeLogger(logger.getSubLogger({name:bindings?JSON.stringify(bindings):void 0}),level),trace:(...args)=>logger.trace(...args),debug:(...args)=>logger.debug(...args),info:(...args)=>logger.info(...args),warn:(...args)=>logger.warn(...args),error:(...args)=>logger.error(...args),fatal:(...args)=>logger.fatal(...args)}}const resetHooks=new Set;function onLoggerReset(hook){return resetHooks.add(hook),()=>{resetHooks.delete(hook)}}function registerLogTransport(transport){externalTransports.add(transport);let logger=loggingState.cachedLogger;return logger&&attachExternalTransport(logger,transport),()=>{externalTransports.delete(transport)}}function formatLocalDate(date){return`${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,`0`)}-${String(date.getDate()).padStart(2,`0`)}`}function defaultRollingPathForToday(){let today=formatLocalDate(new Date);return path.join(DEFAULT_LOG_DIR,`${LOG_PREFIX}-${today}${LOG_SUFFIX}`)}function isRollingPath(file){let base=path.basename(file);return base.startsWith(`${LOG_PREFIX}-`)&&base.endsWith(LOG_SUFFIX)&&base.length===`${LOG_PREFIX}-YYYY-MM-DD${LOG_SUFFIX}`.length}function pruneOldRollingLogs(dir){try{let entries=fs.readdirSync(dir,{withFileTypes:!0}),cutoff=Date.now()-864e5;for(let entry of entries){if(!entry.isFile()||!entry.name.startsWith(`${LOG_PREFIX}-`)||!entry.name.endsWith(LOG_SUFFIX))continue;let fullPath=path.join(dir,entry.name);try{fs.statSync(fullPath).mtimeMs<cutoff&&fs.rmSync(fullPath,{force:!0})}catch{}}}catch{}}const BRAND_PALETTE={brand:`#3B82F6`,accent:`#FF5A2D`,accentBright:`#FF7A3D`,accentDim:`#D14A22`,info:`#FF8A5B`,success:`#2FBF71`,warn:`#FFB020`,error:`#E23D2D`,muted:`#8B7F77`},hasForceColor=typeof process.env.FORCE_COLOR==`string`&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!==`0`,baseChalk=process.env.NO_COLOR&&!hasForceColor?new Chalk({level:0}):chalk,hex=value=>baseChalk.hex(value),theme={brand:baseChalk.bold.hex(BRAND_PALETTE.brand),accent:hex(BRAND_PALETTE.accent),accentBright:hex(BRAND_PALETTE.accentBright),accentDim:hex(BRAND_PALETTE.accentDim),info:hex(BRAND_PALETTE.info),success:hex(BRAND_PALETTE.success),warn:hex(BRAND_PALETTE.warn),error:hex(BRAND_PALETTE.error),muted:hex(BRAND_PALETTE.muted),heading:baseChalk.bold.hex(BRAND_PALETTE.brand),command:hex(BRAND_PALETTE.brand),option:hex(BRAND_PALETTE.warn)},isRich=()=>baseChalk.level>0,colorize=(rich,color,value)=>rich?color(value):value;let globalVerbose=!1;function setVerbose(v){globalVerbose=v}function isVerbose(){return globalVerbose}function shouldLogVerbose(){return globalVerbose||isFileLogLevelEnabled(`debug`)}function logVerbose(message){if(shouldLogVerbose()){try{getLogger().debug({message},`verbose`)}catch{}globalVerbose&&console.log(theme.muted(message))}}function logVerboseConsole(message){globalVerbose&&console.log(theme.muted(message))}const success=theme.success,warn=theme.warn,info=theme.info,danger=theme.error;async function ensureDir(dir){await fs.promises.mkdir(dir,{recursive:!0})}async function pathExists(targetPath){try{return await fs.promises.access(targetPath),!0}catch{return!1}}function clampNumber(value,min,max){return Math.max(min,Math.min(max,value))}function clampInt(value,min,max){return clampNumber(Math.floor(value),min,max)}const clamp=clampNumber;function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function safeParseJson(raw){try{return JSON.parse(raw)}catch{return null}}function isPlainObject(value){return typeof value==`object`&&!!value&&!Array.isArray(value)&&Object.prototype.toString.call(value)===`[object Object]`}function isRecord(value){return typeof value==`object`&&!!value&&!Array.isArray(value)}function normalizeE164(number){let digits=number.replace(/^whatsapp:/,``).trim().replace(/[^\d+]/g,``);return digits.startsWith(`+`)?`+${digits.slice(1)}`:`+${digits}`}function isSelfChatMode(selfE164,allowFrom){if(!selfE164||!Array.isArray(allowFrom)||allowFrom.length===0)return!1;let normalizedSelf=normalizeE164(selfE164);return allowFrom.some(n=>{if(n===`*`)return!1;try{return normalizeE164(String(n))===normalizedSelf}catch{return!1}})}function toWhatsappJid(number){let withoutPrefix=number.replace(/^whatsapp:/,``).trim();return withoutPrefix.includes(`@`)?withoutPrefix:`${normalizeE164(withoutPrefix).replace(/\D/g,``)}@s.whatsapp.net`}function resolveLidMappingDirs(opts){let dirs=new Set,addDir=dir=>{dir&&dirs.add(resolveUserPath(dir))};addDir(opts?.authDir);for(let dir of opts?.lidMappingDirs??[])addDir(dir);return addDir(resolveOAuthDir()),addDir(path.join(CONFIG_DIR,`credentials`)),[...dirs]}function readLidReverseMapping(lid,opts){let mappingFilename=`lid-mapping-${lid}_reverse.json`,mappingDirs=resolveLidMappingDirs(opts);for(let dir of mappingDirs){let mappingPath=path.join(dir,mappingFilename);try{let data=fs.readFileSync(mappingPath,`utf8`),phone=JSON.parse(data);if(phone==null)continue;return normalizeE164(String(phone))}catch{}}return null}function jidToE164(jid,opts){let match=jid.match(/^(\d+)(?::\d+)?@(s\.whatsapp\.net|hosted)$/);if(match)return`+${match[1]}`;let lidMatch=jid.match(/^(\d+)(?::\d+)?@(lid|hosted\.lid)$/);if(lidMatch){let lid=lidMatch[1],phone=readLidReverseMapping(lid,opts);if(phone)return phone;(opts?.logMissing??shouldLogVerbose())&&logVerbose(`LID mapping not found for ${lid}; skipping inbound message`)}return null}async function resolveJidToE164(jid,opts){if(!jid)return null;let direct=jidToE164(jid,opts);if(direct)return direct;if(!/(@lid|@hosted\.lid)$/.test(jid)||!opts?.lidLookup?.getPNForLID)return null;try{let pnJid=await opts.lidLookup.getPNForLID(jid);return pnJid?jidToE164(pnJid,opts):null}catch(err){return shouldLogVerbose()&&logVerbose(`LID mapping lookup failed for ${jid}: ${String(err)}`),null}}function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}function isHighSurrogate(codeUnit){return codeUnit>=55296&&codeUnit<=56319}function isLowSurrogate(codeUnit){return codeUnit>=56320&&codeUnit<=57343}function sliceUtf16Safe(input,start,end){let len=input.length,from=start<0?Math.max(len+start,0):Math.min(start,len),to=end===void 0?len:end<0?Math.max(len+end,0):Math.min(end,len);if(to<from){let tmp=from;from=to,to=tmp}return from>0&&from<len&&isLowSurrogate(input.charCodeAt(from))&&isHighSurrogate(input.charCodeAt(from-1))&&(from+=1),to>0&&to<len&&isHighSurrogate(input.charCodeAt(to-1))&&isLowSurrogate(input.charCodeAt(to))&&--to,input.slice(from,to)}function truncateUtf16Safe(input,maxLen){let limit=Math.max(0,Math.floor(maxLen));return input.length<=limit?input:sliceUtf16Safe(input,0,limit)}function resolveUserPath(input){let trimmed=input.trim();if(!trimmed)return trimmed;if(trimmed.startsWith(`~`)){let expanded=expandHomePrefix(trimmed,{home:resolveRequiredHomeDir(process.env,os.homedir),env:process.env,homedir:os.homedir});return path.resolve(expanded)}return path.resolve(trimmed)}function resolveConfigDir(env=process.env,homedir=os.homedir){let override=env.BUILDERFORCE_AGENTS_STATE_DIR?.trim();if(override)return resolveUserPath(override);let newDir=path.join(resolveRequiredHomeDir(env,homedir),`.builderforce`);try{if(fs.existsSync(newDir))return newDir}catch{}return newDir}function resolveHomeDir(){return resolveEffectiveHomeDir(process.env,os.homedir)}function resolveHomeDisplayPrefix(){let home=resolveHomeDir();if(home)return process.env.BUILDERFORCE_AGENTS_HOME?.trim()?{home,prefix:`$BUILDERFORCE_AGENTS_HOME`}:{home,prefix:`~`}}function shortenHomePath(input){if(!input)return input;let display=resolveHomeDisplayPrefix();if(!display)return input;let{home,prefix}=display;return input===home?prefix:input.startsWith(`${home}/`)||input.startsWith(`${home}\\`)?`${prefix}${input.slice(home.length)}`:input}function shortenHomeInString(input){if(!input)return input;let display=resolveHomeDisplayPrefix();return display?input.split(display.home).join(display.prefix):input}function formatTerminalLink(label,url,opts){let safeLabel=label.replaceAll(`\x1B`,``),safeUrl=url.replaceAll(`\x1B`,``);return opts?.force===!0||opts?.force!==!1&&process.stdout.isTTY?`\u001b]8;;${safeUrl}\u0007${safeLabel}\u001b]8;;\u0007`:opts?.fallback??`${safeLabel} (${safeUrl})`}const CONFIG_DIR=resolveConfigDir(),pluginCommands=new Map;let registryLocked=!1;const MAX_ARGS_LENGTH=4096,RESERVED_COMMANDS=new Set(`help.commands.status.whoami.context.stop.restart.reset.new.compact.config.debug.allowlist.activation.skill.subagents.kill.steer.tell.model.models.queue.send.bash.exec.think.verbose.reasoning.elevated.usage`.split(`.`));function validateCommandName(name){let trimmed=name.trim().toLowerCase();return trimmed?/^[a-z][a-z0-9_-]*$/.test(trimmed)?RESERVED_COMMANDS.has(trimmed)?`Command name "${trimmed}" is reserved by a built-in command`:null:`Command name must start with a letter and contain only letters, numbers, hyphens, and underscores`:`Command name cannot be empty`}function registerPluginCommand(pluginId,command){if(registryLocked)return{ok:!1,error:`Cannot register commands while processing is in progress`};if(typeof command.handler!=`function`)return{ok:!1,error:`Command handler must be a function`};let validationError=validateCommandName(command.name);if(validationError)return{ok:!1,error:validationError};let key=`/${command.name.toLowerCase()}`;if(pluginCommands.has(key)){let existing=pluginCommands.get(key);return{ok:!1,error:`Command "${command.name}" already registered by plugin "${existing.pluginId}"`}}return pluginCommands.set(key,{...command,pluginId}),logVerbose(`Registered plugin command: ${key} (plugin: ${pluginId})`),{ok:!0}}function clearPluginCommands(){pluginCommands.clear()}function matchPluginCommand(commandBody){let trimmed=commandBody.trim();if(!trimmed.startsWith(`/`))return null;let spaceIndex=trimmed.indexOf(` `),commandName=spaceIndex===-1?trimmed:trimmed.slice(0,spaceIndex),args=spaceIndex===-1?void 0:trimmed.slice(spaceIndex+1).trim(),key=commandName.toLowerCase(),command=pluginCommands.get(key);return!command||args&&!command.acceptsArgs?null:{command,args:args||void 0}}function sanitizeArgs(args){if(!args)return;if(args.length>MAX_ARGS_LENGTH)return args.slice(0,MAX_ARGS_LENGTH);let sanitized=``;for(let char of args){let code=char.charCodeAt(0);code<=31&&code!==9&&code!==10||code===127||(sanitized+=char)}return sanitized}async function executePluginCommand(params){let{command,args,senderId,channel,isAuthorizedSender,commandBody,config}=params;if(command.requireAuth!==!1&&!isAuthorizedSender)return logVerbose(`Plugin command /${command.name} blocked: unauthorized sender ${senderId||`<unknown>`}`),{text:`⚠️ This command requires authorization.`};let sanitizedArgs=sanitizeArgs(args),ctx={senderId,channel,channelId:params.channelId,isAuthorizedSender,args:sanitizedArgs,commandBody,config,from:params.from,to:params.to,accountId:params.accountId,messageThreadId:params.messageThreadId};registryLocked=!0;try{let result=await command.handler(ctx);return logVerbose(`Plugin command /${command.name} executed successfully for ${senderId||`unknown`}`),result}catch(err){let error=err;return logVerbose(`Plugin command /${command.name} error: ${error.message}`),{text:`⚠️ Command failed. Please try again later.`}}finally{registryLocked=!1}}function listPluginCommands(){return Array.from(pluginCommands.values()).map(cmd=>({name:cmd.name,description:cmd.description,pluginId:cmd.pluginId}))}function getPluginCommandSpecs(){return Array.from(pluginCommands.values()).map(cmd=>({name:cmd.name,description:cmd.description}))}function createEmptyPluginRegistry(){return{plugins:[],tools:[],hooks:[],typedHooks:[],channels:[],providers:[],gatewayHandlers:{},httpHandlers:[],httpRoutes:[],cliRegistrars:[],services:[],commands:[],diagnostics:[]}}function createPluginRegistry(registryParams){let registry=createEmptyPluginRegistry(),coreGatewayMethods=new Set(Object.keys(registryParams.coreGatewayHandlers??{})),pushDiagnostic=diag=>{registry.diagnostics.push(diag)},registerTool=(record,tool,opts)=>{let names=opts?.names??(opts?.name?[opts.name]:[]),optional=opts?.optional===!0,factory=typeof tool==`function`?tool:_ctx=>tool;typeof tool!=`function`&&names.push(tool.name);let normalized=names.map(name=>name.trim()).filter(Boolean);normalized.length>0&&record.toolNames.push(...normalized),registry.tools.push({pluginId:record.id,factory,names:normalized,optional,source:record.source})},registerHook=(record,events,handler,opts,config)=>{let normalizedEvents=(Array.isArray(events)?events:[events]).map(event=>event.trim()).filter(Boolean),entry=opts?.entry??null,name=entry?.hook.name??opts?.name?.trim();if(!name){pushDiagnostic({level:`warn`,pluginId:record.id,source:record.source,message:`hook registration missing name`});return}let description=entry?.hook.description??opts?.description??``,hookEntry=entry?{...entry,hook:{...entry.hook,name,description,source:`builderforce-plugin`,pluginId:record.id},metadata:{...entry.metadata,events:normalizedEvents}}:{hook:{name,description,source:`builderforce-plugin`,pluginId:record.id,filePath:record.source,baseDir:path.dirname(record.source),handlerPath:record.source},frontmatter:{},metadata:{events:normalizedEvents},invocation:{enabled:!0}};if(record.hookNames.push(name),registry.hooks.push({pluginId:record.id,entry:hookEntry,events:normalizedEvents,source:record.source}),!(config?.hooks?.internal?.enabled!==!0||opts?.register===!1))for(let event of normalizedEvents)registerInternalHook(event,handler)},registerGatewayMethod=(record,method,handler)=>{let trimmed=method.trim();if(trimmed){if(coreGatewayMethods.has(trimmed)||registry.gatewayHandlers[trimmed]){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`gateway method already registered: ${trimmed}`});return}registry.gatewayHandlers[trimmed]=handler,record.gatewayMethods.push(trimmed)}},registerHttpHandler=(record,handler)=>{record.httpHandlers+=1,registry.httpHandlers.push({pluginId:record.id,handler,source:record.source})},registerHttpRoute=(record,params)=>{let normalizedPath=normalizePluginHttpPath(params.path);if(!normalizedPath){pushDiagnostic({level:`warn`,pluginId:record.id,source:record.source,message:`http route registration missing path`});return}if(registry.httpRoutes.some(entry=>entry.path===normalizedPath)){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`http route already registered: ${normalizedPath}`});return}record.httpHandlers+=1,registry.httpRoutes.push({pluginId:record.id,path:normalizedPath,handler:params.handler,source:record.source})},registerChannel=(record,registration)=>{let normalized=typeof registration.plugin==`object`?registration:{plugin:registration},plugin=normalized.plugin,id=typeof plugin?.id==`string`?plugin.id.trim():String(plugin?.id??``).trim();if(!id){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`channel registration missing id`});return}record.channelIds.push(id),registry.channels.push({pluginId:record.id,plugin,dock:normalized.dock,source:record.source})},registerProvider=(record,provider)=>{let id=typeof provider?.id==`string`?provider.id.trim():``;if(!id){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`provider registration missing id`});return}let existing=registry.providers.find(entry=>entry.provider.id===id);if(existing){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`provider already registered: ${id} (${existing.pluginId})`});return}record.providerIds.push(id),registry.providers.push({pluginId:record.id,provider,source:record.source})},registerCli=(record,registrar,opts)=>{let commands=(opts?.commands??[]).map(cmd=>cmd.trim()).filter(Boolean);record.cliCommands.push(...commands),registry.cliRegistrars.push({pluginId:record.id,register:registrar,commands,source:record.source})},registerService=(record,service)=>{let id=service.id.trim();id&&(record.services.push(id),registry.services.push({pluginId:record.id,service,source:record.source}))},registerCommand=(record,command)=>{let name=command.name.trim();if(!name){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`command registration missing name`});return}let result=registerPluginCommand(record.id,command);if(!result.ok){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`command registration failed: ${result.error}`});return}record.commands.push(name),registry.commands.push({pluginId:record.id,command,source:record.source})},registerTypedHook=(record,hookName,handler,opts)=>{record.hookCount+=1,registry.typedHooks.push({pluginId:record.id,hookName,handler,priority:opts?.priority,source:record.source})},normalizeLogger=logger=>({info:logger.info,warn:logger.warn,error:logger.error,debug:logger.debug});return{registry,createApi:(record,params)=>({id:record.id,name:record.name,version:record.version,description:record.description,source:record.source,config:params.config,pluginConfig:params.pluginConfig,runtime:registryParams.runtime,logger:normalizeLogger(registryParams.logger),registerTool:(tool,opts)=>registerTool(record,tool,opts),registerHook:(events,handler,opts)=>registerHook(record,events,handler,opts,params.config),registerHttpHandler:handler=>registerHttpHandler(record,handler),registerHttpRoute:params=>registerHttpRoute(record,params),registerChannel:registration=>registerChannel(record,registration),registerProvider:provider=>registerProvider(record,provider),registerGatewayMethod:(method,handler)=>registerGatewayMethod(record,method,handler),registerCli:(registrar,opts)=>registerCli(record,registrar,opts),registerService:service=>registerService(record,service),registerCommand:command=>registerCommand(record,command),resolvePath:input=>resolveUserPath(input),on:(hookName,handler,opts)=>registerTypedHook(record,hookName,handler,opts)}),pushDiagnostic,registerTool,registerChannel,registerProvider,registerGatewayMethod,registerCli,registerService,registerCommand,registerHook,registerTypedHook}}const REGISTRY_STATE=Symbol.for(`builderforce.pluginRegistryState`),state=(()=>{let globalState=globalThis;return globalState[REGISTRY_STATE]||(globalState[REGISTRY_STATE]={registry:createEmptyPluginRegistry(),key:null}),globalState[REGISTRY_STATE]})();function setActivePluginRegistry(registry,cacheKey){state.registry=registry,state.key=cacheKey??null}function getActivePluginRegistry(){return state.registry}function requireActivePluginRegistry(){return state.registry||=createEmptyPluginRegistry(),state.registry}const CHAT_CHANNEL_ORDER=[`telegram`,`whatsapp`,`discord`,`irc`,`googlechat`,`slack`,`signal`,`imessage`],CHANNEL_IDS=[...CHAT_CHANNEL_ORDER],CHAT_CHANNEL_META={telegram:{id:`telegram`,label:`Telegram`,selectionLabel:`Telegram (Bot API)`,detailLabel:`Telegram Bot`,docsPath:`/channels/telegram`,docsLabel:`telegram`,blurb:`simplest way to get started — register a bot with @BotFather and get going.`,systemImage:`paperplane`,selectionDocsPrefix:``,selectionDocsOmitLabel:!0,selectionExtras:[`https://builderforce.ai`]},whatsapp:{id:`whatsapp`,label:`WhatsApp`,selectionLabel:`WhatsApp (QR link)`,detailLabel:`WhatsApp Web`,docsPath:`/channels/whatsapp`,docsLabel:`whatsapp`,blurb:`works with your own number; recommend a separate phone + eSIM.`,systemImage:`message`},discord:{id:`discord`,label:`Discord`,selectionLabel:`Discord (Bot API)`,detailLabel:`Discord Bot`,docsPath:`/channels/discord`,docsLabel:`discord`,blurb:`very well supported right now.`,systemImage:`bubble.left.and.bubble.right`},irc:{id:`irc`,label:`IRC`,selectionLabel:`IRC (Server + Nick)`,detailLabel:`IRC`,docsPath:`/channels/irc`,docsLabel:`irc`,blurb:`classic IRC networks with DM/channel routing and pairing controls.`,systemImage:`network`},googlechat:{id:`googlechat`,label:`Google Chat`,selectionLabel:`Google Chat (Chat API)`,detailLabel:`Google Chat`,docsPath:`/channels/googlechat`,docsLabel:`googlechat`,blurb:`Google Workspace Chat app with HTTP webhook.`,systemImage:`message.badge`},slack:{id:`slack`,label:`Slack`,selectionLabel:`Slack (Socket Mode)`,detailLabel:`Slack Bot`,docsPath:`/channels/slack`,docsLabel:`slack`,blurb:`supported (Socket Mode).`,systemImage:`number`},signal:{id:`signal`,label:`Signal`,selectionLabel:`Signal (signal-cli)`,detailLabel:`Signal REST`,docsPath:`/channels/signal`,docsLabel:`signal`,blurb:`signal-cli linked device; more setup (David Reagans: "Hop on Discord.").`,systemImage:`antenna.radiowaves.left.and.right`},imessage:{id:`imessage`,label:`iMessage`,selectionLabel:`iMessage (imsg)`,detailLabel:`iMessage`,docsPath:`/channels/imessage`,docsLabel:`imessage`,blurb:`this is still a work in progress.`,systemImage:`message.fill`}},CHAT_CHANNEL_ALIASES={imsg:`imessage`,"internet-relay-chat":`irc`,"google-chat":`googlechat`,gchat:`googlechat`},BUNDLED_CHANNEL_IDS=[`matrix`,`mattermost`,`msteams`,`line`,`feishu`,`nostr`,`twitch`,`bluebubbles`,`tlon`,`nextcloud-talk`,`zalo`,`zalouser`];[...CHAT_CHANNEL_ORDER,...BUNDLED_CHANNEL_IDS];const normalizeChannelKey=raw=>raw?.trim().toLowerCase()||void 0;function getChatChannelMeta(id){return CHAT_CHANNEL_META[id]}function normalizeChatChannelId(raw){let normalized=normalizeChannelKey(raw);if(!normalized)return null;let resolved=CHAT_CHANNEL_ALIASES[normalized]??normalized;return CHAT_CHANNEL_ORDER.includes(resolved)?resolved:null}function normalizeChannelId(raw){return normalizeChatChannelId(raw)}function normalizeAnyChannelId(raw){let key=normalizeChannelKey(raw);return key?requireActivePluginRegistry().channels.find(entry=>{let id=String(entry.plugin.id??``).trim().toLowerCase();return id&&id===key?!0:(entry.plugin.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===key)})?.plugin.id??null:null}export{isFileLogLevelEnabled as $,resolveJidToE164 as A,info as B,isPlainObject as C,normalizeE164 as D,jidToE164 as E,sleep as F,shouldLogVerbose as G,logVerbose as H,sliceUtf16Safe as I,colorize as J,success as K,toWhatsappJid as L,safeParseJson as M,shortenHomeInString as N,pathExists as O,shortenHomePath as P,getLogger as Q,truncateUtf16Safe as R,formatTerminalLink as S,isSelfChatMode as T,logVerboseConsole as U,isVerbose as V,setVerbose as W,theme as X,isRich as Y,getChildLogger as Z,clamp as _,normalizeChannelId as a,normalizeLogLevel as at,ensureDir as b,requireActivePluginRegistry as c,triggerInternalHook as ct,clearPluginCommands as d,onLoggerReset as et,executePluginCommand as f,CONFIG_DIR as g,matchPluginCommand as h,normalizeAnyChannelId as i,levelToMinLevel as it,resolveUserPath as j,resolveConfigDir as k,setActivePluginRegistry as l,normalizePluginHttpPath as lt,listPluginCommands as m,CHAT_CHANNEL_ORDER as n,toPinoLikeLogger as nt,normalizeChatChannelId as o,readLoggingConfig as ot,getPluginCommandSpecs as p,warn as q,getChatChannelMeta as r,loggingState as rt,getActivePluginRegistry as s,createInternalHookEvent as st,CHANNEL_IDS as t,registerLogTransport as tt,createPluginRegistry as u,clampInt as v,isRecord as w,escapeRegExp as x,clampNumber as y,danger as z};
|
|
1
|
+
import{a as resolveOAuthDir,c as expandHomePrefix,l as resolveEffectiveHomeDir,n as resolveConfigPath,s as resolveStateDir,u as resolveRequiredHomeDir}from"./paths-Cb8zTlyG.js";import{createRequire}from"node:module";import path from"node:path";import fs from"node:fs";import os from"node:os";import{Logger}from"tslog";import JSON5 from"json5";import chalk,{Chalk}from"chalk";function normalizePluginHttpPath(path,fallback){let trimmed=path?.trim();if(!trimmed){let fallbackTrimmed=fallback?.trim();return fallbackTrimmed?fallbackTrimmed.startsWith(`/`)?fallbackTrimmed:`/${fallbackTrimmed}`:null}return trimmed.startsWith(`/`)?trimmed:`/${trimmed}`}const handlers=new Map;function registerInternalHook(eventKey,handler){handlers.has(eventKey)||handlers.set(eventKey,[]),handlers.get(eventKey).push(handler)}async function triggerInternalHook(event){let typeHandlers=handlers.get(event.type)??[],specificHandlers=handlers.get(`${event.type}:${event.action}`)??[],allHandlers=[...typeHandlers,...specificHandlers];if(allHandlers.length!==0)for(let handler of allHandlers)try{await handler(event)}catch(err){console.error(`Hook error [${event.type}:${event.action}]:`,err instanceof Error?err.message:String(err))}}function createInternalHookEvent(type,action,sessionKey,context={}){return{type,action,sessionKey,context,timestamp:new Date,messages:[]}}function readLoggingConfig(){let configPath=resolveConfigPath();try{if(!fs.existsSync(configPath))return;let raw=fs.readFileSync(configPath,`utf-8`),logging=JSON5.parse(raw)?.logging;return!logging||typeof logging!=`object`||Array.isArray(logging)?void 0:logging}catch{return}}const ALLOWED_LOG_LEVELS=[`silent`,`fatal`,`error`,`warn`,`info`,`debug`,`trace`];function normalizeLogLevel(level,fallback=`info`){let candidate=(level??fallback).trim();return ALLOWED_LOG_LEVELS.includes(candidate)?candidate:fallback}function levelToMinLevel(level){return{fatal:0,error:1,warn:2,info:3,debug:4,trace:5,silent:1/0}[level]}const loggingState={cachedLogger:null,cachedSettings:null,cachedConsoleSettings:null,overrideSettings:null,consolePatched:!1,forceConsoleToStderr:!1,consoleTimestampPrefix:!1,consoleSubsystemFilter:null,resolvingConsoleSettings:!1,streamErrorHandlersInstalled:!1,rawConsole:null},DEFAULT_LOG_DIR=path.join(resolveStateDir(),`logs`);path.join(DEFAULT_LOG_DIR,`builderforce.log`);const LOG_PREFIX=`builderforce`,LOG_SUFFIX=`.log`,requireConfig=createRequire(import.meta.url),externalTransports=new Set;function attachExternalTransport(logger,transport){logger.attachTransport(logObj=>{if(externalTransports.has(transport))try{transport(logObj)}catch{}})}function resolveSettings(){let cfg=loggingState.overrideSettings??readLoggingConfig();if(!cfg)try{cfg=requireConfig(`../config/config.js`).loadConfig?.().logging}catch{cfg=void 0}let defaultLevel=process.env.VITEST===`true`&&process.env.BUILDERFORCE_AGENTS_TEST_FILE_LOG!==`1`?`silent`:`info`,enabled=cfg?.enabled!==!1;return{enabled,level:enabled?normalizeLogLevel(cfg?.level,defaultLevel):`silent`,file:cfg?.file??defaultRollingPathForToday(),format:cfg?.format===`text`?`text`:`json`}}function settingsChanged(a,b){return a?a.enabled!==b.enabled||a.level!==b.level||a.file!==b.file||a.format!==b.format:!0}function isFileLogLevelEnabled(level){let settings=loggingState.cachedSettings??resolveSettings();return loggingState.cachedSettings||=settings,!settings.enabled||settings.level===`silent`?!1:levelToMinLevel(level)<=levelToMinLevel(settings.level)}function buildLogger(settings){if(!settings.enabled)return new Logger({name:`builderforce`,minLevel:levelToMinLevel(`silent`),type:`hidden`});fs.mkdirSync(path.dirname(settings.file),{recursive:!0}),isRollingPath(settings.file)&&pruneOldRollingLogs(path.dirname(settings.file));let logger=new Logger({name:`builderforce`,minLevel:levelToMinLevel(settings.level),type:`hidden`});logger.attachTransport(logObj=>{try{let time=logObj.date?.toISOString?.()??new Date().toISOString();if(settings.format===`text`){let lvlVal=logObj._meta?.logLevelName,lvl=typeof lvlVal==`string`?lvlVal:``,part0=logObj[0]===void 0?``:String(logObj[0]),part1=logObj[1]===void 0?``:JSON.stringify(logObj[1]),suffix=part1&&part1!==`{}`?` ${part1}`:``,plain=`${time} ${lvl.toUpperCase()} ${part0}${suffix}`.trim();fs.appendFileSync(settings.file,`${plain}\n`,{encoding:`utf8`})}else{let line=JSON.stringify({...logObj,time});fs.appendFileSync(settings.file,`${line}\n`,{encoding:`utf8`})}}catch{}});for(let transport of externalTransports)attachExternalTransport(logger,transport);return logger}function getLogger(){let settings=resolveSettings(),cachedLogger=loggingState.cachedLogger,cachedSettings=loggingState.cachedSettings;return(!cachedLogger||settingsChanged(cachedSettings,settings))&&(loggingState.cachedLogger=buildLogger(settings),loggingState.cachedSettings=settings),loggingState.cachedLogger}function getChildLogger(bindings,opts){let base=getLogger(),minLevel=opts?.level?levelToMinLevel(opts.level):void 0,name=bindings?JSON.stringify(bindings):void 0;return base.getSubLogger({name,minLevel,prefix:bindings?[name??``]:[]})}function toPinoLikeLogger(logger,level){return{level,child:bindings=>toPinoLikeLogger(logger.getSubLogger({name:bindings?JSON.stringify(bindings):void 0}),level),trace:(...args)=>logger.trace(...args),debug:(...args)=>logger.debug(...args),info:(...args)=>logger.info(...args),warn:(...args)=>logger.warn(...args),error:(...args)=>logger.error(...args),fatal:(...args)=>logger.fatal(...args)}}const resetHooks=new Set;function onLoggerReset(hook){return resetHooks.add(hook),()=>{resetHooks.delete(hook)}}function registerLogTransport(transport){externalTransports.add(transport);let logger=loggingState.cachedLogger;return logger&&attachExternalTransport(logger,transport),()=>{externalTransports.delete(transport)}}function formatLocalDate(date){return`${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,`0`)}-${String(date.getDate()).padStart(2,`0`)}`}function defaultRollingPathForToday(){let today=formatLocalDate(new Date);return path.join(DEFAULT_LOG_DIR,`${LOG_PREFIX}-${today}${LOG_SUFFIX}`)}function isRollingPath(file){let base=path.basename(file);return base.startsWith(`${LOG_PREFIX}-`)&&base.endsWith(LOG_SUFFIX)&&base.length===`${LOG_PREFIX}-YYYY-MM-DD${LOG_SUFFIX}`.length}function pruneOldRollingLogs(dir){try{let entries=fs.readdirSync(dir,{withFileTypes:!0}),cutoff=Date.now()-864e5;for(let entry of entries){if(!entry.isFile()||!entry.name.startsWith(`${LOG_PREFIX}-`)||!entry.name.endsWith(LOG_SUFFIX))continue;let fullPath=path.join(dir,entry.name);try{fs.statSync(fullPath).mtimeMs<cutoff&&fs.rmSync(fullPath,{force:!0})}catch{}}}catch{}}const BRAND_PALETTE={brand:`#3B82F6`,accent:`#FF5A2D`,accentBright:`#FF7A3D`,accentDim:`#D14A22`,info:`#FF8A5B`,success:`#2FBF71`,warn:`#FFB020`,error:`#E23D2D`,muted:`#8B7F77`},hasForceColor=typeof process.env.FORCE_COLOR==`string`&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!==`0`,baseChalk=process.env.NO_COLOR&&!hasForceColor?new Chalk({level:0}):chalk,hex=value=>baseChalk.hex(value),theme={brand:baseChalk.bold.hex(BRAND_PALETTE.brand),accent:hex(BRAND_PALETTE.accent),accentBright:hex(BRAND_PALETTE.accentBright),accentDim:hex(BRAND_PALETTE.accentDim),info:hex(BRAND_PALETTE.info),success:hex(BRAND_PALETTE.success),warn:hex(BRAND_PALETTE.warn),error:hex(BRAND_PALETTE.error),muted:hex(BRAND_PALETTE.muted),heading:baseChalk.bold.hex(BRAND_PALETTE.brand),command:hex(BRAND_PALETTE.brand),option:hex(BRAND_PALETTE.warn)},isRich=()=>baseChalk.level>0,colorize=(rich,color,value)=>rich?color(value):value;let globalVerbose=!1;function setVerbose(v){globalVerbose=v}function isVerbose(){return globalVerbose}function shouldLogVerbose(){return globalVerbose||isFileLogLevelEnabled(`debug`)}function logVerbose(message){if(shouldLogVerbose()){try{getLogger().debug({message},`verbose`)}catch{}globalVerbose&&console.log(theme.muted(message))}}function logVerboseConsole(message){globalVerbose&&console.log(theme.muted(message))}const success=theme.success,warn=theme.warn,info=theme.info,danger=theme.error;async function ensureDir(dir){await fs.promises.mkdir(dir,{recursive:!0})}async function pathExists(targetPath){try{return await fs.promises.access(targetPath),!0}catch{return!1}}function clampNumber(value,min,max){return Math.max(min,Math.min(max,value))}function clampInt(value,min,max){return clampNumber(Math.floor(value),min,max)}const clamp=clampNumber;function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function safeParseJson(raw){try{return JSON.parse(raw)}catch{return null}}function isPlainObject(value){return typeof value==`object`&&!!value&&!Array.isArray(value)&&Object.prototype.toString.call(value)===`[object Object]`}function isRecord(value){return typeof value==`object`&&!!value&&!Array.isArray(value)}function normalizeE164(number){let digits=number.replace(/^whatsapp:/,``).trim().replace(/[^\d+]/g,``);return digits.startsWith(`+`)?`+${digits.slice(1)}`:`+${digits}`}function isSelfChatMode(selfE164,allowFrom){if(!selfE164||!Array.isArray(allowFrom)||allowFrom.length===0)return!1;let normalizedSelf=normalizeE164(selfE164);return allowFrom.some(n=>{if(n===`*`)return!1;try{return normalizeE164(String(n))===normalizedSelf}catch{return!1}})}function toWhatsappJid(number){let withoutPrefix=number.replace(/^whatsapp:/,``).trim();return withoutPrefix.includes(`@`)?withoutPrefix:`${normalizeE164(withoutPrefix).replace(/\D/g,``)}@s.whatsapp.net`}function resolveLidMappingDirs(opts){let dirs=new Set,addDir=dir=>{dir&&dirs.add(resolveUserPath(dir))};addDir(opts?.authDir);for(let dir of opts?.lidMappingDirs??[])addDir(dir);return addDir(resolveOAuthDir()),addDir(path.join(CONFIG_DIR,`credentials`)),[...dirs]}function readLidReverseMapping(lid,opts){let mappingFilename=`lid-mapping-${lid}_reverse.json`,mappingDirs=resolveLidMappingDirs(opts);for(let dir of mappingDirs){let mappingPath=path.join(dir,mappingFilename);try{let data=fs.readFileSync(mappingPath,`utf8`),phone=JSON.parse(data);if(phone==null)continue;return normalizeE164(String(phone))}catch{}}return null}function jidToE164(jid,opts){let match=jid.match(/^(\d+)(?::\d+)?@(s\.whatsapp\.net|hosted)$/);if(match)return`+${match[1]}`;let lidMatch=jid.match(/^(\d+)(?::\d+)?@(lid|hosted\.lid)$/);if(lidMatch){let lid=lidMatch[1],phone=readLidReverseMapping(lid,opts);if(phone)return phone;(opts?.logMissing??shouldLogVerbose())&&logVerbose(`LID mapping not found for ${lid}; skipping inbound message`)}return null}async function resolveJidToE164(jid,opts){if(!jid)return null;let direct=jidToE164(jid,opts);if(direct)return direct;if(!/(@lid|@hosted\.lid)$/.test(jid)||!opts?.lidLookup?.getPNForLID)return null;try{let pnJid=await opts.lidLookup.getPNForLID(jid);return pnJid?jidToE164(pnJid,opts):null}catch(err){return shouldLogVerbose()&&logVerbose(`LID mapping lookup failed for ${jid}: ${String(err)}`),null}}function sleep(ms){return new Promise(resolve=>setTimeout(resolve,ms))}function isHighSurrogate(codeUnit){return codeUnit>=55296&&codeUnit<=56319}function isLowSurrogate(codeUnit){return codeUnit>=56320&&codeUnit<=57343}function sliceUtf16Safe(input,start,end){let len=input.length,from=start<0?Math.max(len+start,0):Math.min(start,len),to=end===void 0?len:end<0?Math.max(len+end,0):Math.min(end,len);if(to<from){let tmp=from;from=to,to=tmp}return from>0&&from<len&&isLowSurrogate(input.charCodeAt(from))&&isHighSurrogate(input.charCodeAt(from-1))&&(from+=1),to>0&&to<len&&isHighSurrogate(input.charCodeAt(to-1))&&isLowSurrogate(input.charCodeAt(to))&&--to,input.slice(from,to)}function truncateUtf16Safe(input,maxLen){let limit=Math.max(0,Math.floor(maxLen));return input.length<=limit?input:sliceUtf16Safe(input,0,limit)}function resolveUserPath(input){let trimmed=input.trim();if(!trimmed)return trimmed;if(trimmed.startsWith(`~`)){let expanded=expandHomePrefix(trimmed,{home:resolveRequiredHomeDir(process.env,os.homedir),env:process.env,homedir:os.homedir});return path.resolve(expanded)}return path.resolve(trimmed)}function resolveConfigDir(env=process.env,homedir=os.homedir){let override=env.BUILDERFORCE_AGENTS_STATE_DIR?.trim();if(override)return resolveUserPath(override);let newDir=path.join(resolveRequiredHomeDir(env,homedir),`.builderforce`);try{if(fs.existsSync(newDir))return newDir}catch{}return newDir}function resolveHomeDir(){return resolveEffectiveHomeDir(process.env,os.homedir)}function resolveHomeDisplayPrefix(){let home=resolveHomeDir();if(home)return process.env.BUILDERFORCE_AGENTS_HOME?.trim()?{home,prefix:`$BUILDERFORCE_AGENTS_HOME`}:{home,prefix:`~`}}function shortenHomePath(input){if(!input)return input;let display=resolveHomeDisplayPrefix();if(!display)return input;let{home,prefix}=display;return input===home?prefix:input.startsWith(`${home}/`)||input.startsWith(`${home}\\`)?`${prefix}${input.slice(home.length)}`:input}function shortenHomeInString(input){if(!input)return input;let display=resolveHomeDisplayPrefix();return display?input.split(display.home).join(display.prefix):input}function formatTerminalLink(label,url,opts){let safeLabel=label.replaceAll(`\x1B`,``),safeUrl=url.replaceAll(`\x1B`,``);return opts?.force===!0||opts?.force!==!1&&process.stdout.isTTY?`\u001b]8;;${safeUrl}\u0007${safeLabel}\u001b]8;;\u0007`:opts?.fallback??`${safeLabel} (${safeUrl})`}const CONFIG_DIR=resolveConfigDir(),pluginCommands=new Map;let registryLocked=!1;const MAX_ARGS_LENGTH=4096,RESERVED_COMMANDS=new Set(`help.commands.status.whoami.context.stop.restart.reset.new.compact.config.debug.allowlist.activation.skill.subagents.kill.steer.tell.model.models.queue.send.bash.exec.think.verbose.reasoning.elevated.usage`.split(`.`));function validateCommandName(name){let trimmed=name.trim().toLowerCase();return trimmed?/^[a-z][a-z0-9_-]*$/.test(trimmed)?RESERVED_COMMANDS.has(trimmed)?`Command name "${trimmed}" is reserved by a built-in command`:null:`Command name must start with a letter and contain only letters, numbers, hyphens, and underscores`:`Command name cannot be empty`}function registerPluginCommand(pluginId,command){if(registryLocked)return{ok:!1,error:`Cannot register commands while processing is in progress`};if(typeof command.handler!=`function`)return{ok:!1,error:`Command handler must be a function`};let validationError=validateCommandName(command.name);if(validationError)return{ok:!1,error:validationError};let key=`/${command.name.toLowerCase()}`;if(pluginCommands.has(key)){let existing=pluginCommands.get(key);return{ok:!1,error:`Command "${command.name}" already registered by plugin "${existing.pluginId}"`}}return pluginCommands.set(key,{...command,pluginId}),logVerbose(`Registered plugin command: ${key} (plugin: ${pluginId})`),{ok:!0}}function clearPluginCommands(){pluginCommands.clear()}function matchPluginCommand(commandBody){let trimmed=commandBody.trim();if(!trimmed.startsWith(`/`))return null;let spaceIndex=trimmed.indexOf(` `),commandName=spaceIndex===-1?trimmed:trimmed.slice(0,spaceIndex),args=spaceIndex===-1?void 0:trimmed.slice(spaceIndex+1).trim(),key=commandName.toLowerCase(),command=pluginCommands.get(key);return!command||args&&!command.acceptsArgs?null:{command,args:args||void 0}}function sanitizeArgs(args){if(!args)return;if(args.length>MAX_ARGS_LENGTH)return args.slice(0,MAX_ARGS_LENGTH);let sanitized=``;for(let char of args){let code=char.charCodeAt(0);code<=31&&code!==9&&code!==10||code===127||(sanitized+=char)}return sanitized}async function executePluginCommand(params){let{command,args,senderId,channel,isAuthorizedSender,commandBody,config}=params;if(command.requireAuth!==!1&&!isAuthorizedSender)return logVerbose(`Plugin command /${command.name} blocked: unauthorized sender ${senderId||`<unknown>`}`),{text:`⚠️ This command requires authorization.`};let sanitizedArgs=sanitizeArgs(args),ctx={senderId,channel,channelId:params.channelId,isAuthorizedSender,args:sanitizedArgs,commandBody,config,from:params.from,to:params.to,accountId:params.accountId,messageThreadId:params.messageThreadId};registryLocked=!0;try{let result=await command.handler(ctx);return logVerbose(`Plugin command /${command.name} executed successfully for ${senderId||`unknown`}`),result}catch(err){let error=err;return logVerbose(`Plugin command /${command.name} error: ${error.message}`),{text:`⚠️ Command failed. Please try again later.`}}finally{registryLocked=!1}}function listPluginCommands(){return Array.from(pluginCommands.values()).map(cmd=>({name:cmd.name,description:cmd.description,pluginId:cmd.pluginId}))}function getPluginCommandSpecs(){return Array.from(pluginCommands.values()).map(cmd=>({name:cmd.name,description:cmd.description}))}function createEmptyPluginRegistry(){return{plugins:[],tools:[],hooks:[],typedHooks:[],channels:[],providers:[],gatewayHandlers:{},httpHandlers:[],httpRoutes:[],cliRegistrars:[],services:[],commands:[],diagnostics:[]}}function createPluginRegistry(registryParams){let registry=createEmptyPluginRegistry(),coreGatewayMethods=new Set(Object.keys(registryParams.coreGatewayHandlers??{})),pushDiagnostic=diag=>{registry.diagnostics.push(diag)},registerTool=(record,tool,opts)=>{let names=opts?.names??(opts?.name?[opts.name]:[]),optional=opts?.optional===!0,factory=typeof tool==`function`?tool:_ctx=>tool;typeof tool!=`function`&&names.push(tool.name);let normalized=names.map(name=>name.trim()).filter(Boolean);normalized.length>0&&record.toolNames.push(...normalized),registry.tools.push({pluginId:record.id,factory,names:normalized,optional,source:record.source})},registerHook=(record,events,handler,opts,config)=>{let normalizedEvents=(Array.isArray(events)?events:[events]).map(event=>event.trim()).filter(Boolean),entry=opts?.entry??null,name=entry?.hook.name??opts?.name?.trim();if(!name){pushDiagnostic({level:`warn`,pluginId:record.id,source:record.source,message:`hook registration missing name`});return}let description=entry?.hook.description??opts?.description??``,hookEntry=entry?{...entry,hook:{...entry.hook,name,description,source:`builderforce-plugin`,pluginId:record.id},metadata:{...entry.metadata,events:normalizedEvents}}:{hook:{name,description,source:`builderforce-plugin`,pluginId:record.id,filePath:record.source,baseDir:path.dirname(record.source),handlerPath:record.source},frontmatter:{},metadata:{events:normalizedEvents},invocation:{enabled:!0}};if(record.hookNames.push(name),registry.hooks.push({pluginId:record.id,entry:hookEntry,events:normalizedEvents,source:record.source}),!(config?.hooks?.internal?.enabled!==!0||opts?.register===!1))for(let event of normalizedEvents)registerInternalHook(event,handler)},registerGatewayMethod=(record,method,handler)=>{let trimmed=method.trim();if(trimmed){if(coreGatewayMethods.has(trimmed)||registry.gatewayHandlers[trimmed]){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`gateway method already registered: ${trimmed}`});return}registry.gatewayHandlers[trimmed]=handler,record.gatewayMethods.push(trimmed)}},registerHttpHandler=(record,handler)=>{record.httpHandlers+=1,registry.httpHandlers.push({pluginId:record.id,handler,source:record.source})},registerHttpRoute=(record,params)=>{let normalizedPath=normalizePluginHttpPath(params.path);if(!normalizedPath){pushDiagnostic({level:`warn`,pluginId:record.id,source:record.source,message:`http route registration missing path`});return}if(registry.httpRoutes.some(entry=>entry.path===normalizedPath)){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`http route already registered: ${normalizedPath}`});return}record.httpHandlers+=1,registry.httpRoutes.push({pluginId:record.id,path:normalizedPath,handler:params.handler,source:record.source})},registerChannel=(record,registration)=>{let normalized=typeof registration.plugin==`object`?registration:{plugin:registration},plugin=normalized.plugin,id=typeof plugin?.id==`string`?plugin.id.trim():String(plugin?.id??``).trim();if(!id){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`channel registration missing id`});return}record.channelIds.push(id),registry.channels.push({pluginId:record.id,plugin,dock:normalized.dock,source:record.source})},registerProvider=(record,provider)=>{let id=typeof provider?.id==`string`?provider.id.trim():``;if(!id){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`provider registration missing id`});return}let existing=registry.providers.find(entry=>entry.provider.id===id);if(existing){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`provider already registered: ${id} (${existing.pluginId})`});return}record.providerIds.push(id),registry.providers.push({pluginId:record.id,provider,source:record.source})},registerCli=(record,registrar,opts)=>{let commands=(opts?.commands??[]).map(cmd=>cmd.trim()).filter(Boolean);record.cliCommands.push(...commands),registry.cliRegistrars.push({pluginId:record.id,register:registrar,commands,source:record.source})},registerService=(record,service)=>{let id=service.id.trim();id&&(record.services.push(id),registry.services.push({pluginId:record.id,service,source:record.source}))},registerCommand=(record,command)=>{let name=command.name.trim();if(!name){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`command registration missing name`});return}let result=registerPluginCommand(record.id,command);if(!result.ok){pushDiagnostic({level:`error`,pluginId:record.id,source:record.source,message:`command registration failed: ${result.error}`});return}record.commands.push(name),registry.commands.push({pluginId:record.id,command,source:record.source})},registerTypedHook=(record,hookName,handler,opts)=>{record.hookCount+=1,registry.typedHooks.push({pluginId:record.id,hookName,handler,priority:opts?.priority,source:record.source})},normalizeLogger=logger=>({info:logger.info,warn:logger.warn,error:logger.error,debug:logger.debug});return{registry,createApi:(record,params)=>({id:record.id,name:record.name,version:record.version,description:record.description,source:record.source,config:params.config,pluginConfig:params.pluginConfig,runtime:registryParams.runtime,logger:normalizeLogger(registryParams.logger),registerTool:(tool,opts)=>registerTool(record,tool,opts),registerHook:(events,handler,opts)=>registerHook(record,events,handler,opts,params.config),registerHttpHandler:handler=>registerHttpHandler(record,handler),registerHttpRoute:params=>registerHttpRoute(record,params),registerChannel:registration=>registerChannel(record,registration),registerProvider:provider=>registerProvider(record,provider),registerGatewayMethod:(method,handler)=>registerGatewayMethod(record,method,handler),registerCli:(registrar,opts)=>registerCli(record,registrar,opts),registerService:service=>registerService(record,service),registerCommand:command=>registerCommand(record,command),resolvePath:input=>resolveUserPath(input),on:(hookName,handler,opts)=>registerTypedHook(record,hookName,handler,opts)}),pushDiagnostic,registerTool,registerChannel,registerProvider,registerGatewayMethod,registerCli,registerService,registerCommand,registerHook,registerTypedHook}}const REGISTRY_STATE=Symbol.for(`builderforce.pluginRegistryState`),state=(()=>{let globalState=globalThis;return globalState[REGISTRY_STATE]||(globalState[REGISTRY_STATE]={registry:createEmptyPluginRegistry(),key:null}),globalState[REGISTRY_STATE]})();function setActivePluginRegistry(registry,cacheKey){state.registry=registry,state.key=cacheKey??null}function getActivePluginRegistry(){return state.registry}function requireActivePluginRegistry(){return state.registry||=createEmptyPluginRegistry(),state.registry}const CHAT_CHANNEL_ORDER=[`telegram`,`whatsapp`,`discord`,`irc`,`googlechat`,`slack`,`signal`,`imessage`],CHANNEL_IDS=[...CHAT_CHANNEL_ORDER],CHAT_CHANNEL_META={telegram:{id:`telegram`,label:`Telegram`,selectionLabel:`Telegram (Bot API)`,detailLabel:`Telegram Bot`,docsPath:`/channels/telegram`,docsLabel:`telegram`,blurb:`simplest way to get started — register a bot with @BotFather and get going.`,systemImage:`paperplane`,selectionDocsPrefix:``,selectionDocsOmitLabel:!0,selectionExtras:[`https://builderforce.ai`]},whatsapp:{id:`whatsapp`,label:`WhatsApp`,selectionLabel:`WhatsApp (QR link)`,detailLabel:`WhatsApp Web`,docsPath:`/channels/whatsapp`,docsLabel:`whatsapp`,blurb:`works with your own number; recommend a separate phone + eSIM.`,systemImage:`message`},discord:{id:`discord`,label:`Discord`,selectionLabel:`Discord (Bot API)`,detailLabel:`Discord Bot`,docsPath:`/channels/discord`,docsLabel:`discord`,blurb:`very well supported right now.`,systemImage:`bubble.left.and.bubble.right`},irc:{id:`irc`,label:`IRC`,selectionLabel:`IRC (Server + Nick)`,detailLabel:`IRC`,docsPath:`/channels/irc`,docsLabel:`irc`,blurb:`classic IRC networks with DM/channel routing and pairing controls.`,systemImage:`network`},googlechat:{id:`googlechat`,label:`Google Chat`,selectionLabel:`Google Chat (Chat API)`,detailLabel:`Google Chat`,docsPath:`/channels/googlechat`,docsLabel:`googlechat`,blurb:`Google Workspace Chat app with HTTP webhook.`,systemImage:`message.badge`},slack:{id:`slack`,label:`Slack`,selectionLabel:`Slack (Socket Mode)`,detailLabel:`Slack Bot`,docsPath:`/channels/slack`,docsLabel:`slack`,blurb:`supported (Socket Mode).`,systemImage:`number`},signal:{id:`signal`,label:`Signal`,selectionLabel:`Signal (signal-cli)`,detailLabel:`Signal REST`,docsPath:`/channels/signal`,docsLabel:`signal`,blurb:`signal-cli linked device; more setup (David Reagans: "Hop on Discord.").`,systemImage:`antenna.radiowaves.left.and.right`},imessage:{id:`imessage`,label:`iMessage`,selectionLabel:`iMessage (imsg)`,detailLabel:`iMessage`,docsPath:`/channels/imessage`,docsLabel:`imessage`,blurb:`this is still a work in progress.`,systemImage:`message.fill`}},CHAT_CHANNEL_ALIASES={imsg:`imessage`,"internet-relay-chat":`irc`,"google-chat":`googlechat`,gchat:`googlechat`},BUNDLED_CHANNEL_IDS=[`matrix`,`mattermost`,`msteams`,`line`,`feishu`,`nostr`,`twitch`,`bluebubbles`,`tlon`,`nextcloud-talk`,`zalo`,`zalouser`];[...CHAT_CHANNEL_ORDER,...BUNDLED_CHANNEL_IDS];const normalizeChannelKey=raw=>raw?.trim().toLowerCase()||void 0;function getChatChannelMeta(id){return CHAT_CHANNEL_META[id]}function normalizeChatChannelId(raw){let normalized=normalizeChannelKey(raw);if(!normalized)return null;let resolved=CHAT_CHANNEL_ALIASES[normalized]??normalized;return CHAT_CHANNEL_ORDER.includes(resolved)?resolved:null}function normalizeChannelId(raw){return normalizeChatChannelId(raw)}function normalizeAnyChannelId(raw){let key=normalizeChannelKey(raw);return key?requireActivePluginRegistry().channels.find(entry=>{let id=String(entry.plugin.id??``).trim().toLowerCase();return id&&id===key?!0:(entry.plugin.meta.aliases??[]).some(alias=>alias.trim().toLowerCase()===key)})?.plugin.id??null:null}export{isFileLogLevelEnabled as $,resolveJidToE164 as A,info as B,isPlainObject as C,normalizeE164 as D,jidToE164 as E,sleep as F,shouldLogVerbose as G,logVerbose as H,sliceUtf16Safe as I,colorize as J,success as K,toWhatsappJid as L,safeParseJson as M,shortenHomeInString as N,pathExists as O,shortenHomePath as P,getLogger as Q,truncateUtf16Safe as R,formatTerminalLink as S,isSelfChatMode as T,logVerboseConsole as U,isVerbose as V,setVerbose as W,theme as X,isRich as Y,getChildLogger as Z,clamp as _,normalizeChannelId as a,normalizeLogLevel as at,ensureDir as b,requireActivePluginRegistry as c,triggerInternalHook as ct,clearPluginCommands as d,onLoggerReset as et,executePluginCommand as f,CONFIG_DIR as g,matchPluginCommand as h,normalizeAnyChannelId as i,levelToMinLevel as it,resolveUserPath as j,resolveConfigDir as k,setActivePluginRegistry as l,normalizePluginHttpPath as lt,listPluginCommands as m,CHAT_CHANNEL_ORDER as n,toPinoLikeLogger as nt,normalizeChatChannelId as o,readLoggingConfig as ot,getPluginCommandSpecs as p,warn as q,getChatChannelMeta as r,loggingState as rt,getActivePluginRegistry as s,createInternalHookEvent as st,CHANNEL_IDS as t,registerLogTransport as tt,createPluginRegistry as u,clampInt as v,isRecord as w,escapeRegExp as x,clampNumber as y,danger as z};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{G as shouldLogVerbose,H as logVerbose,j as resolveUserPath}from"./registry-DJq2Cvo9.js";import{s as resolveStateDir}from"./paths-Cb8zTlyG.js";import{D as maxBytesForKind,O as mediaKindFromMime,_ as resizeToJpeg,g as optimizeImageToPng,h as hasAlphaChannel,n as fetchRemoteMedia,p as convertHeicToJpeg,v as detectMime,y as extensionForMime}from"./fetch-DH0Y8iyO.js";import{s as resolveAgentWorkspaceDir}from"./agent-scope-BQByW0cD.js";import{a as chunkText}from"./chunk-cW0POl22.js";import path from"node:path";import os from"node:os";import{fileURLToPath}from"node:url";import fs from"node:fs/promises";import MarkdownIt from"markdown-it";function buildMediaLocalRoots(stateDir){let resolvedStateDir=path.resolve(stateDir);return[os.tmpdir(),path.join(resolvedStateDir,`media`),path.join(resolvedStateDir,`agents`),path.join(resolvedStateDir,`workspace`),path.join(resolvedStateDir,`sandboxes`)]}function getDefaultMediaLocalRoots(){return buildMediaLocalRoots(resolveStateDir())}function getAgentScopedMediaLocalRoots(cfg,agentId){let roots=buildMediaLocalRoots(resolveStateDir());if(!agentId?.trim())return roots;let workspaceDir=resolveAgentWorkspaceDir(cfg,agentId);if(!workspaceDir)return roots;let normalizedWorkspaceDir=path.resolve(workspaceDir);return roots.includes(normalizedWorkspaceDir)||roots.push(normalizedWorkspaceDir),roots}function getDefaultLocalRoots(){return getDefaultMediaLocalRoots()}async function assertLocalMediaAllowed(mediaPath,localRoots){if(localRoots===`any`)return;let roots=localRoots??getDefaultLocalRoots(),resolved;try{resolved=await fs.realpath(mediaPath)}catch{resolved=path.resolve(mediaPath)}if(localRoots===void 0){let workspaceRoot=roots.find(root=>path.basename(root)===`workspace`);if(workspaceRoot){let stateDir=path.dirname(workspaceRoot),rel=path.relative(stateDir,resolved);if(rel&&!rel.startsWith(`..`)&&!path.isAbsolute(rel)&&(rel.split(path.sep)[0]??``).startsWith(`workspace-`))throw Error(`Local media path is not under an allowed directory: ${mediaPath}`)}}for(let root of roots){let resolvedRoot;try{resolvedRoot=await fs.realpath(root)}catch{resolvedRoot=path.resolve(root)}if(resolvedRoot===path.parse(resolvedRoot).root)throw Error(`Invalid localRoots entry (refuses filesystem root): ${root}. Pass a narrower directory.`);if(resolved===resolvedRoot||resolved.startsWith(resolvedRoot+path.sep))return}throw Error(`Local media path is not under an allowed directory: ${mediaPath}`)}const HEIC_MIME_RE=/^image\/hei[cf]$/i,HEIC_EXT_RE=/\.(heic|heif)$/i;function formatMb(bytes,digits=2){return(bytes/1048576).toFixed(digits)}function formatCapLimit(label,cap,size){return`${label} exceeds ${formatMb(cap,0)}MB limit (got ${formatMb(size)}MB)`}function formatCapReduce(label,cap,size){return`${label} could not be reduced below ${formatMb(cap,0)}MB (got ${formatMb(size)}MB)`}function isHeicSource(opts){return!!(opts.contentType&&HEIC_MIME_RE.test(opts.contentType.trim())||opts.fileName&&HEIC_EXT_RE.test(opts.fileName.trim()))}function toJpegFileName(fileName){if(!fileName)return;let trimmed=fileName.trim();if(!trimmed)return fileName;let parsed=path.parse(trimmed);return!parsed.ext||HEIC_EXT_RE.test(parsed.ext)?path.format({dir:parsed.dir,name:parsed.name||trimmed,ext:`.jpg`}):path.format({dir:parsed.dir,name:parsed.name,ext:`.jpg`})}function logOptimizedImage(params){if(shouldLogVerbose()&&!(params.optimized.optimizedSize>=params.originalSize)){if(params.optimized.format===`png`){logVerbose(`Optimized PNG (preserving alpha) from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px)`);return}logVerbose(`Optimized media from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px, q=${params.optimized.quality})`)}}async function optimizeImageWithFallback(params){let{buffer,cap,meta}=params;if((meta?.contentType===`image/png`||meta?.fileName?.toLowerCase().endsWith(`.png`))&&await hasAlphaChannel(buffer)){let optimized=await optimizeImageToPng(buffer,cap);if(optimized.buffer.length<=cap)return{...optimized,format:`png`};shouldLogVerbose()&&logVerbose(`PNG with alpha still exceeds ${formatMb(cap,0)}MB after optimization; falling back to JPEG`)}return{...await optimizeImageToJpeg(buffer,cap,meta),format:`jpeg`}}async function loadWebMediaInternal(mediaUrl,options={}){let{maxBytes,optimizeImages=!0,ssrfPolicy,localRoots,sandboxValidated=!1,readFile:readFileOverride}=options;if(mediaUrl=mediaUrl.replace(/^\s*MEDIA\s*:\s*/i,``),mediaUrl.startsWith(`file://`))try{mediaUrl=fileURLToPath(mediaUrl)}catch{throw Error(`Invalid file:// URL: ${mediaUrl}`)}let optimizeAndClampImage=async(buffer,cap,meta)=>{let originalSize=buffer.length,optimized=await optimizeImageWithFallback({buffer,cap,meta});if(logOptimizedImage({originalSize,optimized}),optimized.buffer.length>cap)throw Error(formatCapReduce(`Media`,cap,optimized.buffer.length));let contentType=optimized.format===`png`?`image/png`:`image/jpeg`,fileName=optimized.format===`jpeg`&&meta&&isHeicSource(meta)?toJpegFileName(meta.fileName):meta?.fileName;return{buffer:optimized.buffer,contentType,kind:`image`,fileName}},clampAndFinalize=async params=>{let cap=maxBytes===void 0?maxBytesForKind(params.kind):maxBytes;if(params.kind===`image`){let isGif=params.contentType===`image/gif`;if(isGif||!optimizeImages){if(params.buffer.length>cap)throw Error(formatCapLimit(isGif?`GIF`:`Media`,cap,params.buffer.length));return{buffer:params.buffer,contentType:params.contentType,kind:params.kind,fileName:params.fileName}}return{...await optimizeAndClampImage(params.buffer,cap,{contentType:params.contentType,fileName:params.fileName})}}if(params.buffer.length>cap)throw Error(formatCapLimit(`Media`,cap,params.buffer.length));return{buffer:params.buffer,contentType:params.contentType??void 0,kind:params.kind,fileName:params.fileName}};if(/^https?:\/\//i.test(mediaUrl)){let defaultFetchCap=maxBytesForKind(`unknown`),{buffer,contentType,fileName}=await fetchRemoteMedia({url:mediaUrl,maxBytes:maxBytes===void 0?defaultFetchCap:optimizeImages?Math.max(maxBytes,defaultFetchCap):maxBytes,ssrfPolicy});return await clampAndFinalize({buffer,contentType,kind:mediaKindFromMime(contentType),fileName})}if(mediaUrl.startsWith(`~`)&&(mediaUrl=resolveUserPath(mediaUrl)),(sandboxValidated||localRoots===`any`)&&!readFileOverride)throw Error(`Refusing localRoots bypass without readFile override. Use sandboxValidated with readFile, or pass explicit localRoots.`);sandboxValidated||localRoots===`any`||await assertLocalMediaAllowed(mediaUrl,localRoots);let data=readFileOverride?await readFileOverride(mediaUrl):await fs.readFile(mediaUrl),mime=await detectMime({buffer:data,filePath:mediaUrl}),kind=mediaKindFromMime(mime),fileName=path.basename(mediaUrl)||void 0;if(fileName&&!path.extname(fileName)&&mime){let ext=extensionForMime(mime);ext&&(fileName=`${fileName}${ext}`)}return await clampAndFinalize({buffer:data,contentType:mime,kind,fileName})}async function loadWebMedia(mediaUrl,maxBytesOrOptions,options){return typeof maxBytesOrOptions==`number`||maxBytesOrOptions===void 0?await loadWebMediaInternal(mediaUrl,{maxBytes:maxBytesOrOptions,optimizeImages:!0,ssrfPolicy:options?.ssrfPolicy,localRoots:options?.localRoots}):await loadWebMediaInternal(mediaUrl,{...maxBytesOrOptions,optimizeImages:maxBytesOrOptions.optimizeImages??!0})}async function loadWebMediaRaw(mediaUrl,maxBytesOrOptions,options){return typeof maxBytesOrOptions==`number`||maxBytesOrOptions===void 0?await loadWebMediaInternal(mediaUrl,{maxBytes:maxBytesOrOptions,optimizeImages:!1,ssrfPolicy:options?.ssrfPolicy,localRoots:options?.localRoots}):await loadWebMediaInternal(mediaUrl,{...maxBytesOrOptions,optimizeImages:!1})}async function optimizeImageToJpeg(buffer,maxBytes,opts={}){let source=buffer;if(isHeicSource(opts))try{source=await convertHeicToJpeg(buffer)}catch(err){throw Error(`HEIC image conversion failed: ${String(err)}`,{cause:err})}let sides=[2048,1536,1280,1024,800],qualities=[80,70,60,50,40],smallest=null;for(let side of sides)for(let quality of qualities)try{let out=await resizeToJpeg({buffer:source,maxSide:side,quality,withoutEnlargement:!0}),size=out.length;if((!smallest||size<smallest.size)&&(smallest={buffer:out,size,resizeSide:side,quality}),size<=maxBytes)return{buffer:out,optimizedSize:size,resizeSide:side,quality}}catch{}if(smallest)return{buffer:smallest.buffer,optimizedSize:smallest.size,resizeSide:smallest.resizeSide,quality:smallest.quality};throw Error(`Failed to optimize image`)}function createMarkdownIt(options){let md=new MarkdownIt({html:!1,linkify:options.linkify??!0,breaks:!1,typographer:!1});return md.enable(`strikethrough`),options.tableMode&&options.tableMode!==`off`?md.enable(`table`):md.disable(`table`),options.autolink===!1&&md.disable(`autolink`),md}function getAttr(token,name){if(token.attrGet)return token.attrGet(name);if(token.attrs){for(let[key,value]of token.attrs)if(key===name)return value}return null}function createTextToken(base,content){return{...base,type:`text`,content,children:void 0}}function applySpoilerTokens(tokens){for(let token of tokens)token.children&&token.children.length>0&&(token.children=injectSpoilersIntoInline(token.children))}function injectSpoilersIntoInline(tokens){let result=[],state={spoilerOpen:!1};for(let token of tokens){if(token.type!==`text`){result.push(token);continue}let content=token.content??``;if(!content.includes(`||`)){result.push(token);continue}let index=0;for(;index<content.length;){let next=content.indexOf(`||`,index);if(next===-1){index<content.length&&result.push(createTextToken(token,content.slice(index)));break}next>index&&result.push(createTextToken(token,content.slice(index,next))),state.spoilerOpen=!state.spoilerOpen,result.push({type:state.spoilerOpen?`spoiler_open`:`spoiler_close`}),index=next+2}}return result}function initRenderTarget(){return{text:``,styles:[],openStyles:[],links:[],linkStack:[]}}function resolveRenderTarget(state){return state.table?.currentCell??state}function appendText(state,value){if(!value)return;let target=resolveRenderTarget(state);target.text+=value}function openStyle(state,style){let target=resolveRenderTarget(state);target.openStyles.push({style,start:target.text.length})}function closeStyle(state,style){let target=resolveRenderTarget(state);for(let i=target.openStyles.length-1;i>=0;--i)if(target.openStyles[i]?.style===style){let start=target.openStyles[i].start;target.openStyles.splice(i,1);let end=target.text.length;end>start&&target.styles.push({start,end,style});return}}function appendParagraphSeparator(state){state.env.listStack.length>0||state.table||(state.text+=`
|
|
1
|
+
import{G as shouldLogVerbose,H as logVerbose,j as resolveUserPath}from"./registry-CZHRcH-q.js";import{s as resolveStateDir}from"./paths-Cb8zTlyG.js";import{D as maxBytesForKind,O as mediaKindFromMime,_ as resizeToJpeg,g as optimizeImageToPng,h as hasAlphaChannel,n as fetchRemoteMedia,p as convertHeicToJpeg,v as detectMime,y as extensionForMime}from"./fetch-B-GxSYRO.js";import{s as resolveAgentWorkspaceDir}from"./agent-scope-DgKN27hJ.js";import{a as chunkText}from"./chunk-C94IAOuf.js";import path from"node:path";import os from"node:os";import{fileURLToPath}from"node:url";import fs from"node:fs/promises";import MarkdownIt from"markdown-it";function buildMediaLocalRoots(stateDir){let resolvedStateDir=path.resolve(stateDir);return[os.tmpdir(),path.join(resolvedStateDir,`media`),path.join(resolvedStateDir,`agents`),path.join(resolvedStateDir,`workspace`),path.join(resolvedStateDir,`sandboxes`)]}function getDefaultMediaLocalRoots(){return buildMediaLocalRoots(resolveStateDir())}function getAgentScopedMediaLocalRoots(cfg,agentId){let roots=buildMediaLocalRoots(resolveStateDir());if(!agentId?.trim())return roots;let workspaceDir=resolveAgentWorkspaceDir(cfg,agentId);if(!workspaceDir)return roots;let normalizedWorkspaceDir=path.resolve(workspaceDir);return roots.includes(normalizedWorkspaceDir)||roots.push(normalizedWorkspaceDir),roots}function getDefaultLocalRoots(){return getDefaultMediaLocalRoots()}async function assertLocalMediaAllowed(mediaPath,localRoots){if(localRoots===`any`)return;let roots=localRoots??getDefaultLocalRoots(),resolved;try{resolved=await fs.realpath(mediaPath)}catch{resolved=path.resolve(mediaPath)}if(localRoots===void 0){let workspaceRoot=roots.find(root=>path.basename(root)===`workspace`);if(workspaceRoot){let stateDir=path.dirname(workspaceRoot),rel=path.relative(stateDir,resolved);if(rel&&!rel.startsWith(`..`)&&!path.isAbsolute(rel)&&(rel.split(path.sep)[0]??``).startsWith(`workspace-`))throw Error(`Local media path is not under an allowed directory: ${mediaPath}`)}}for(let root of roots){let resolvedRoot;try{resolvedRoot=await fs.realpath(root)}catch{resolvedRoot=path.resolve(root)}if(resolvedRoot===path.parse(resolvedRoot).root)throw Error(`Invalid localRoots entry (refuses filesystem root): ${root}. Pass a narrower directory.`);if(resolved===resolvedRoot||resolved.startsWith(resolvedRoot+path.sep))return}throw Error(`Local media path is not under an allowed directory: ${mediaPath}`)}const HEIC_MIME_RE=/^image\/hei[cf]$/i,HEIC_EXT_RE=/\.(heic|heif)$/i;function formatMb(bytes,digits=2){return(bytes/1048576).toFixed(digits)}function formatCapLimit(label,cap,size){return`${label} exceeds ${formatMb(cap,0)}MB limit (got ${formatMb(size)}MB)`}function formatCapReduce(label,cap,size){return`${label} could not be reduced below ${formatMb(cap,0)}MB (got ${formatMb(size)}MB)`}function isHeicSource(opts){return!!(opts.contentType&&HEIC_MIME_RE.test(opts.contentType.trim())||opts.fileName&&HEIC_EXT_RE.test(opts.fileName.trim()))}function toJpegFileName(fileName){if(!fileName)return;let trimmed=fileName.trim();if(!trimmed)return fileName;let parsed=path.parse(trimmed);return!parsed.ext||HEIC_EXT_RE.test(parsed.ext)?path.format({dir:parsed.dir,name:parsed.name||trimmed,ext:`.jpg`}):path.format({dir:parsed.dir,name:parsed.name,ext:`.jpg`})}function logOptimizedImage(params){if(shouldLogVerbose()&&!(params.optimized.optimizedSize>=params.originalSize)){if(params.optimized.format===`png`){logVerbose(`Optimized PNG (preserving alpha) from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px)`);return}logVerbose(`Optimized media from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px, q=${params.optimized.quality})`)}}async function optimizeImageWithFallback(params){let{buffer,cap,meta}=params;if((meta?.contentType===`image/png`||meta?.fileName?.toLowerCase().endsWith(`.png`))&&await hasAlphaChannel(buffer)){let optimized=await optimizeImageToPng(buffer,cap);if(optimized.buffer.length<=cap)return{...optimized,format:`png`};shouldLogVerbose()&&logVerbose(`PNG with alpha still exceeds ${formatMb(cap,0)}MB after optimization; falling back to JPEG`)}return{...await optimizeImageToJpeg(buffer,cap,meta),format:`jpeg`}}async function loadWebMediaInternal(mediaUrl,options={}){let{maxBytes,optimizeImages=!0,ssrfPolicy,localRoots,sandboxValidated=!1,readFile:readFileOverride}=options;if(mediaUrl=mediaUrl.replace(/^\s*MEDIA\s*:\s*/i,``),mediaUrl.startsWith(`file://`))try{mediaUrl=fileURLToPath(mediaUrl)}catch{throw Error(`Invalid file:// URL: ${mediaUrl}`)}let optimizeAndClampImage=async(buffer,cap,meta)=>{let originalSize=buffer.length,optimized=await optimizeImageWithFallback({buffer,cap,meta});if(logOptimizedImage({originalSize,optimized}),optimized.buffer.length>cap)throw Error(formatCapReduce(`Media`,cap,optimized.buffer.length));let contentType=optimized.format===`png`?`image/png`:`image/jpeg`,fileName=optimized.format===`jpeg`&&meta&&isHeicSource(meta)?toJpegFileName(meta.fileName):meta?.fileName;return{buffer:optimized.buffer,contentType,kind:`image`,fileName}},clampAndFinalize=async params=>{let cap=maxBytes===void 0?maxBytesForKind(params.kind):maxBytes;if(params.kind===`image`){let isGif=params.contentType===`image/gif`;if(isGif||!optimizeImages){if(params.buffer.length>cap)throw Error(formatCapLimit(isGif?`GIF`:`Media`,cap,params.buffer.length));return{buffer:params.buffer,contentType:params.contentType,kind:params.kind,fileName:params.fileName}}return{...await optimizeAndClampImage(params.buffer,cap,{contentType:params.contentType,fileName:params.fileName})}}if(params.buffer.length>cap)throw Error(formatCapLimit(`Media`,cap,params.buffer.length));return{buffer:params.buffer,contentType:params.contentType??void 0,kind:params.kind,fileName:params.fileName}};if(/^https?:\/\//i.test(mediaUrl)){let defaultFetchCap=maxBytesForKind(`unknown`),{buffer,contentType,fileName}=await fetchRemoteMedia({url:mediaUrl,maxBytes:maxBytes===void 0?defaultFetchCap:optimizeImages?Math.max(maxBytes,defaultFetchCap):maxBytes,ssrfPolicy});return await clampAndFinalize({buffer,contentType,kind:mediaKindFromMime(contentType),fileName})}if(mediaUrl.startsWith(`~`)&&(mediaUrl=resolveUserPath(mediaUrl)),(sandboxValidated||localRoots===`any`)&&!readFileOverride)throw Error(`Refusing localRoots bypass without readFile override. Use sandboxValidated with readFile, or pass explicit localRoots.`);sandboxValidated||localRoots===`any`||await assertLocalMediaAllowed(mediaUrl,localRoots);let data=readFileOverride?await readFileOverride(mediaUrl):await fs.readFile(mediaUrl),mime=await detectMime({buffer:data,filePath:mediaUrl}),kind=mediaKindFromMime(mime),fileName=path.basename(mediaUrl)||void 0;if(fileName&&!path.extname(fileName)&&mime){let ext=extensionForMime(mime);ext&&(fileName=`${fileName}${ext}`)}return await clampAndFinalize({buffer:data,contentType:mime,kind,fileName})}async function loadWebMedia(mediaUrl,maxBytesOrOptions,options){return typeof maxBytesOrOptions==`number`||maxBytesOrOptions===void 0?await loadWebMediaInternal(mediaUrl,{maxBytes:maxBytesOrOptions,optimizeImages:!0,ssrfPolicy:options?.ssrfPolicy,localRoots:options?.localRoots}):await loadWebMediaInternal(mediaUrl,{...maxBytesOrOptions,optimizeImages:maxBytesOrOptions.optimizeImages??!0})}async function loadWebMediaRaw(mediaUrl,maxBytesOrOptions,options){return typeof maxBytesOrOptions==`number`||maxBytesOrOptions===void 0?await loadWebMediaInternal(mediaUrl,{maxBytes:maxBytesOrOptions,optimizeImages:!1,ssrfPolicy:options?.ssrfPolicy,localRoots:options?.localRoots}):await loadWebMediaInternal(mediaUrl,{...maxBytesOrOptions,optimizeImages:!1})}async function optimizeImageToJpeg(buffer,maxBytes,opts={}){let source=buffer;if(isHeicSource(opts))try{source=await convertHeicToJpeg(buffer)}catch(err){throw Error(`HEIC image conversion failed: ${String(err)}`,{cause:err})}let sides=[2048,1536,1280,1024,800],qualities=[80,70,60,50,40],smallest=null;for(let side of sides)for(let quality of qualities)try{let out=await resizeToJpeg({buffer:source,maxSide:side,quality,withoutEnlargement:!0}),size=out.length;if((!smallest||size<smallest.size)&&(smallest={buffer:out,size,resizeSide:side,quality}),size<=maxBytes)return{buffer:out,optimizedSize:size,resizeSide:side,quality}}catch{}if(smallest)return{buffer:smallest.buffer,optimizedSize:smallest.size,resizeSide:smallest.resizeSide,quality:smallest.quality};throw Error(`Failed to optimize image`)}function createMarkdownIt(options){let md=new MarkdownIt({html:!1,linkify:options.linkify??!0,breaks:!1,typographer:!1});return md.enable(`strikethrough`),options.tableMode&&options.tableMode!==`off`?md.enable(`table`):md.disable(`table`),options.autolink===!1&&md.disable(`autolink`),md}function getAttr(token,name){if(token.attrGet)return token.attrGet(name);if(token.attrs){for(let[key,value]of token.attrs)if(key===name)return value}return null}function createTextToken(base,content){return{...base,type:`text`,content,children:void 0}}function applySpoilerTokens(tokens){for(let token of tokens)token.children&&token.children.length>0&&(token.children=injectSpoilersIntoInline(token.children))}function injectSpoilersIntoInline(tokens){let result=[],state={spoilerOpen:!1};for(let token of tokens){if(token.type!==`text`){result.push(token);continue}let content=token.content??``;if(!content.includes(`||`)){result.push(token);continue}let index=0;for(;index<content.length;){let next=content.indexOf(`||`,index);if(next===-1){index<content.length&&result.push(createTextToken(token,content.slice(index)));break}next>index&&result.push(createTextToken(token,content.slice(index,next))),state.spoilerOpen=!state.spoilerOpen,result.push({type:state.spoilerOpen?`spoiler_open`:`spoiler_close`}),index=next+2}}return result}function initRenderTarget(){return{text:``,styles:[],openStyles:[],links:[],linkStack:[]}}function resolveRenderTarget(state){return state.table?.currentCell??state}function appendText(state,value){if(!value)return;let target=resolveRenderTarget(state);target.text+=value}function openStyle(state,style){let target=resolveRenderTarget(state);target.openStyles.push({style,start:target.text.length})}function closeStyle(state,style){let target=resolveRenderTarget(state);for(let i=target.openStyles.length-1;i>=0;--i)if(target.openStyles[i]?.style===style){let start=target.openStyles[i].start;target.openStyles.splice(i,1);let end=target.text.length;end>start&&target.styles.push({start,end,style});return}}function appendParagraphSeparator(state){state.env.listStack.length>0||state.table||(state.text+=`
|
|
2
2
|
|
|
3
3
|
`)}function appendListPrefix(state){let stack=state.env.listStack,top=stack[stack.length-1];if(!top)return;top.index+=1;let indent=` `.repeat(Math.max(0,stack.length-1)),prefix=top.type===`ordered`?`${top.index}. `:`• `;state.text+=`${indent}${prefix}`}function renderInlineCode(state,content){if(!content)return;let target=resolveRenderTarget(state),start=target.text.length;target.text+=content,target.styles.push({start,end:start+content.length,style:`code`})}function renderCodeBlock(state,content){let code=content??``;code.endsWith(`
|
|
4
4
|
`)||(code=`${code}\n`);let target=resolveRenderTarget(state),start=target.text.length;target.text+=code,target.styles.push({start,end:start+code.length,style:`code_block`}),state.env.listStack.length===0&&(target.text+=`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as __exportAll}from"./rolldown-runtime-BlRA8w72.js";import{H as logVerbose,x as escapeRegExp}from"./registry-
|
|
1
|
+
import{t as __exportAll}from"./rolldown-runtime-BlRA8w72.js";import{H as logVerbose,x as escapeRegExp}from"./registry-CZHRcH-q.js";import{n as loadConfig}from"./config--Ci8Y91R.js";import{F as resolveSlackBotToken,M as resolveSlackAccount,m as parseSlackTarget}from"./plugins-BdkC9v5E.js";import{n as chunkMarkdownIR,o as loadWebMedia,r as markdownToIR,t as renderMarkdownWithMarkers}from"./render-CuA_WRX5.js";import{c as resolveChunkMode,i as chunkMarkdownTextWithMode,l as resolveTextChunkLimit}from"./chunk-C94IAOuf.js";import{n as resolveMarkdownTableMode}from"./markdown-tables-BUfhHgfs.js";import{WebClient}from"@slack/web-api";function parseBlocksJson(raw){try{return JSON.parse(raw)}catch{throw Error(`blocks must be valid JSON`)}}function assertBlocksArray(raw){if(!Array.isArray(raw))throw Error(`blocks must be an array`);if(raw.length===0)throw Error(`blocks must contain at least one block`);if(raw.length>50)throw Error(`blocks cannot exceed 50 items`);for(let block of raw){if(!block||typeof block!=`object`||Array.isArray(block))throw Error(`each block must be an object`);let type=block.type;if(typeof type!=`string`||type.trim().length===0)throw Error(`each block must include a non-empty string type`)}}function validateSlackBlocksArray(raw){return assertBlocksArray(raw),raw}function parseSlackBlocksInput(raw){if(raw!=null)return validateSlackBlocksArray(typeof raw==`string`?parseBlocksJson(raw):raw)}const HEARTBEAT_TOKEN=`HEARTBEAT_OK`,SILENT_REPLY_TOKEN=`NO_REPLY`;function isSilentReplyText(text,token=SILENT_REPLY_TOKEN){if(!text)return!1;let escaped=escapeRegExp(token);return RegExp(`^\\s*${escaped}(?=$|\\W)`).test(text)?!0:RegExp(`\\b${escaped}\\b\\W*$`).test(text)}const SLACK_DEFAULT_RETRY_OPTIONS={retries:2,factor:2,minTimeout:500,maxTimeout:3e3,randomize:!0};function resolveSlackWebClientOptions(options={}){return{...options,retryConfig:options.retryConfig??SLACK_DEFAULT_RETRY_OPTIONS}}function createSlackWebClient(token,options={}){return new WebClient(token,resolveSlackWebClientOptions(options))}function cleanCandidate(value){if(typeof value!=`string`)return;let normalized=value.replace(/\s+/g,` `).trim();return normalized.length>0?normalized:void 0}function readSectionText(block){return cleanCandidate(block.text?.text)}function readHeaderText(block){return cleanCandidate(block.text?.text)}function readImageText(block){return cleanCandidate(block.alt_text)??cleanCandidate(block.title?.text)}function readVideoText(block){return cleanCandidate(block.title?.text)??cleanCandidate(block.alt_text)}function readContextText(block){if(!Array.isArray(block.elements))return;let textParts=block.elements.map(element=>cleanCandidate(element.text)).filter(value=>!!value);return textParts.length>0?textParts.join(` `):void 0}function buildSlackBlocksFallbackText(blocks){for(let raw of blocks){let block=raw;switch(block.type){case`header`:{let text=readHeaderText(block);if(text)return text;break}case`section`:{let text=readSectionText(block);if(text)return text;break}case`image`:return readImageText(block)||`Shared an image`;case`video`:return readVideoText(block)||`Shared a video`;case`file`:return`Shared a file`;case`context`:{let text=readContextText(block);if(text)return text;break}default:break}}return`Shared a Block Kit message`}function escapeSlackMrkdwnSegment(text){return text.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}const SLACK_ANGLE_TOKEN_RE=/<[^>\n]+>/g;function isAllowedSlackAngleToken(token){if(!token.startsWith(`<`)||!token.endsWith(`>`))return!1;let inner=token.slice(1,-1);return inner.startsWith(`@`)||inner.startsWith(`#`)||inner.startsWith(`!`)||inner.startsWith(`mailto:`)||inner.startsWith(`tel:`)||inner.startsWith(`http://`)||inner.startsWith(`https://`)||inner.startsWith(`slack://`)}function escapeSlackMrkdwnContent(text){if(!text.includes(`&`)&&!text.includes(`<`)&&!text.includes(`>`))return text;SLACK_ANGLE_TOKEN_RE.lastIndex=0;let out=[],lastIndex=0;for(let match=SLACK_ANGLE_TOKEN_RE.exec(text);match;match=SLACK_ANGLE_TOKEN_RE.exec(text)){let matchIndex=match.index??0;out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex,matchIndex)));let token=match[0]??``;out.push(isAllowedSlackAngleToken(token)?token:escapeSlackMrkdwnSegment(token)),lastIndex=matchIndex+token.length}return out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex))),out.join(``)}function escapeSlackMrkdwnText(text){return!text.includes(`&`)&&!text.includes(`<`)&&!text.includes(`>`)?text:text.split(`
|
|
2
2
|
`).map(line=>line.startsWith(`> `)?`> ${escapeSlackMrkdwnContent(line.slice(2))}`:escapeSlackMrkdwnContent(line)).join(`
|
|
3
3
|
`)}function buildSlackLink(link,text){let href=link.href.trim();if(!href)return null;let trimmedLabel=text.slice(link.start,link.end).trim(),comparableHref=href.startsWith(`mailto:`)?href.slice(7):href;if(!(trimmedLabel.length>0&&trimmedLabel!==href&&trimmedLabel!==comparableHref))return null;let safeHref=escapeSlackMrkdwnSegment(href);return{start:link.start,end:link.end,open:`<${safeHref}|`,close:`>`}}function buildSlackRenderOptions(){return{styleMarkers:{bold:{open:`*`,close:`*`},italic:{open:`_`,close:`_`},strikethrough:{open:`~`,close:`~`},code:{open:"`",close:"`"},code_block:{open:"```\n",close:"```"}},escapeText:escapeSlackMrkdwnText,buildLink:buildSlackLink}}function markdownToSlackMrkdwnChunks(markdown,limit,options={}){let chunks=chunkMarkdownIR(markdownToIR(markdown??``,{linkify:!1,autolink:!1,headingStyle:`bold`,blockquotePrefix:`> `,tableMode:options.tableMode}),limit),renderOptions=buildSlackRenderOptions();return chunks.map(chunk=>renderMarkdownWithMarkers(chunk,renderOptions))}function hasCustomIdentity(identity){return!!(identity?.username||identity?.iconUrl||identity?.iconEmoji)}function isSlackCustomizeScopeError(err){if(!(err instanceof Error))return!1;let maybeData=err;return maybeData.data?.error?.toLowerCase()===`missing_scope`?(maybeData.data?.needed?.toLowerCase())?.includes(`chat:write.customize`)?!0:[...maybeData.data?.response_metadata?.scopes??[],...maybeData.data?.response_metadata?.acceptedScopes??[]].map(scope=>scope.toLowerCase()).includes(`chat:write.customize`):!1}async function postSlackMessageBestEffort(params){let basePayload={channel:params.channelId,text:params.text,thread_ts:params.threadTs,...params.blocks?.length?{blocks:params.blocks}:{}};try{return params.identity?.iconUrl?await params.client.chat.postMessage({...basePayload,...params.identity.username?{username:params.identity.username}:{},icon_url:params.identity.iconUrl}):params.identity?.iconEmoji?await params.client.chat.postMessage({...basePayload,...params.identity.username?{username:params.identity.username}:{},icon_emoji:params.identity.iconEmoji}):await params.client.chat.postMessage({...basePayload,...params.identity?.username?{username:params.identity.username}:{}})}catch(err){if(!hasCustomIdentity(params.identity)||!isSlackCustomizeScopeError(err))throw err;return logVerbose(`slack send: missing chat:write.customize, retrying without custom identity`),params.client.chat.postMessage(basePayload)}}function resolveToken(params){let explicit=resolveSlackBotToken(params.explicit);if(explicit)return explicit;let fallback=resolveSlackBotToken(params.fallbackToken);if(!fallback)throw logVerbose(`slack send: missing bot token for account=${params.accountId} explicit=${!!params.explicit} source=${params.fallbackSource??`unknown`}`),Error(`Slack bot token missing for account "${params.accountId}" (set channels.slack.accounts.${params.accountId}.botToken or SLACK_BOT_TOKEN for default).`);return fallback}function parseRecipient(raw){let target=parseSlackTarget(raw);if(!target)throw Error(`Recipient is required for Slack sends`);return{kind:target.kind,id:target.id}}async function resolveChannelId(client,recipient){if(recipient.kind===`channel`)return{channelId:recipient.id};let channelId=(await client.conversations.open({users:recipient.id})).channel?.id;if(!channelId)throw Error(`Failed to open Slack DM channel`);return{channelId,isDm:!0}}async function uploadSlackFile(params){let{buffer,contentType:_contentType,fileName}=await loadWebMedia(params.mediaUrl,{maxBytes:params.maxBytes,localRoots:params.mediaLocalRoots}),basePayload={channel_id:params.channelId,file:buffer,filename:fileName,...params.caption?{initial_comment:params.caption}:{}},payload=params.threadTs?{...basePayload,thread_ts:params.threadTs}:basePayload,parsed=await params.client.files.uploadV2(payload);return parsed.files?.[0]?.id??parsed.file?.id??parsed.files?.[0]?.name??parsed.file?.name??`unknown`}async function sendMessageSlack(to,message,opts={}){let trimmedMessage=message?.trim()??``,blocks=opts.blocks==null?void 0:validateSlackBlocksArray(opts.blocks);if(!trimmedMessage&&!opts.mediaUrl&&!blocks)throw Error(`Slack send requires text, blocks, or media`);let cfg=loadConfig(),account=resolveSlackAccount({cfg,accountId:opts.accountId}),token=resolveToken({explicit:opts.token,accountId:account.accountId,fallbackToken:account.botToken,fallbackSource:account.botTokenSource}),client=opts.client??createSlackWebClient(token),{channelId}=await resolveChannelId(client,parseRecipient(to));if(blocks){if(opts.mediaUrl)throw Error(`Slack send does not support blocks with mediaUrl`);return{messageId:(await postSlackMessageBestEffort({client,channelId,text:trimmedMessage||buildSlackBlocksFallbackText(blocks),threadTs:opts.threadTs,identity:opts.identity,blocks})).ts??`unknown`,channelId}}let textLimit=resolveTextChunkLimit(cfg,`slack`,account.accountId),chunkLimit=Math.min(textLimit,4e3),tableMode=resolveMarkdownTableMode({cfg,channel:`slack`,accountId:account.accountId}),chunkMode=resolveChunkMode(cfg,`slack`,account.accountId),chunks=(chunkMode===`newline`?chunkMarkdownTextWithMode(trimmedMessage,chunkLimit,chunkMode):[trimmedMessage]).flatMap(markdown=>markdownToSlackMrkdwnChunks(markdown,chunkLimit,{tableMode}));!chunks.length&&trimmedMessage&&chunks.push(trimmedMessage);let mediaMaxBytes=typeof account.config.mediaMaxMb==`number`?account.config.mediaMaxMb*1024*1024:void 0,lastMessageId=``;if(opts.mediaUrl){let[firstChunk,...rest]=chunks;lastMessageId=await uploadSlackFile({client,channelId,mediaUrl:opts.mediaUrl,mediaLocalRoots:opts.mediaLocalRoots,caption:firstChunk,threadTs:opts.threadTs,maxBytes:mediaMaxBytes});for(let chunk of rest)lastMessageId=(await postSlackMessageBestEffort({client,channelId,text:chunk,threadTs:opts.threadTs,identity:opts.identity})).ts??lastMessageId}else for(let chunk of chunks.length?chunks:[``])lastMessageId=(await postSlackMessageBestEffort({client,channelId,text:chunk,threadTs:opts.threadTs,identity:opts.identity})).ts??lastMessageId;return{messageId:lastMessageId||`unknown`,channelId}}function createReplyReferencePlanner(options){let hasReplied=options.hasReplied??!1,allowReference=options.allowReference!==!1,existingId=options.existingId?.trim(),startId=options.startId?.trim();return{use:()=>{if(!allowReference||options.replyToMode===`off`)return;let id=existingId??startId;if(id&&(options.replyToMode===`all`||!hasReplied))return hasReplied=!0,id},markSent:()=>{hasReplied=!0},hasReplied:()=>hasReplied}}var replies_exports=__exportAll({createSlackReplyDeliveryPlan:()=>createSlackReplyDeliveryPlan,deliverReplies:()=>deliverReplies,deliverSlackSlashReplies:()=>deliverSlackSlashReplies,resolveSlackThreadTs:()=>resolveSlackThreadTs});async function deliverReplies(params){for(let payload of params.replies){let threadTs=payload.replyToId??params.replyThreadTs,mediaList=payload.mediaUrls??(payload.mediaUrl?[payload.mediaUrl]:[]),text=payload.text??``;if(!(!text&&mediaList.length===0)){if(mediaList.length===0){let trimmed=text.trim();if(!trimmed||isSilentReplyText(trimmed,SILENT_REPLY_TOKEN))continue;await sendMessageSlack(params.target,trimmed,{token:params.token,threadTs,accountId:params.accountId})}else{let first=!0;for(let mediaUrl of mediaList){let caption=first?text:``;first=!1,await sendMessageSlack(params.target,caption,{token:params.token,mediaUrl,threadTs,accountId:params.accountId})}}params.runtime.log?.(`delivered reply to ${params.target}`)}}}function resolveSlackThreadTs(params){return createSlackReplyReferencePlanner({replyToMode:params.replyToMode,incomingThreadTs:params.incomingThreadTs,messageTs:params.messageTs,hasReplied:params.hasReplied}).use()}function createSlackReplyReferencePlanner(params){return createReplyReferencePlanner({replyToMode:params.incomingThreadTs?`all`:params.replyToMode,existingId:params.incomingThreadTs,startId:params.messageTs,hasReplied:params.hasReplied})}function createSlackReplyDeliveryPlan(params){let replyReference=createSlackReplyReferencePlanner({replyToMode:params.replyToMode,incomingThreadTs:params.incomingThreadTs,messageTs:params.messageTs,hasReplied:params.hasRepliedRef.value});return{nextThreadTs:()=>replyReference.use(),markSent:()=>{replyReference.markSent(),params.hasRepliedRef.value=replyReference.hasReplied()}}}async function deliverSlackSlashReplies(params){let messages=[],chunkLimit=Math.min(params.textLimit,4e3);for(let payload of params.replies){let textRaw=payload.text?.trim()??``,text=textRaw&&!isSilentReplyText(textRaw,SILENT_REPLY_TOKEN)?textRaw:void 0,mediaList=payload.mediaUrls??(payload.mediaUrl?[payload.mediaUrl]:[]),combined=[text??``,...mediaList.map(url=>url.trim()).filter(Boolean)].filter(Boolean).join(`
|
|
4
4
|
`);if(!combined)continue;let chunkMode=params.chunkMode??`length`,chunks=(chunkMode===`newline`?chunkMarkdownTextWithMode(combined,chunkLimit,chunkMode):[combined]).flatMap(markdown=>markdownToSlackMrkdwnChunks(markdown,chunkLimit,{tableMode:params.tableMode}));!chunks.length&&combined&&chunks.push(combined);for(let chunk of chunks)messages.push(chunk)}if(messages.length===0)return;let responseType=params.ephemeral?`ephemeral`:`in_channel`;for(let text of messages)await params.respond({text,response_type:responseType})}export{createReplyReferencePlanner as a,createSlackWebClient as c,SILENT_REPLY_TOKEN as d,isSilentReplyText as f,resolveSlackThreadTs as i,resolveSlackWebClientOptions as l,validateSlackBlocksArray as m,deliverReplies as n,sendMessageSlack as o,parseSlackBlocksInput as p,replies_exports as r,buildSlackBlocksFallbackText as s,createSlackReplyDeliveryPlan as t,HEARTBEAT_TOKEN as u};
|