@agentrix/cli 0.24.0 → 0.27.0
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/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/logger-D1P9ig03.cjs +1 -0
- package/dist/logger-DnKC_QlD.mjs +1 -0
- package/dist/sandbox/node-proxy-boot.cjs +1 -1
- package/package.json +7 -5
- package/dist/logger-C8RJ_miF.cjs +0 -1
- package/dist/logger-Dq-ORk-l.mjs +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";const t=e(import.meta.url);import n,{tmpdir as s,homedir as a}from"node:os";import*as i from"node:fs";import o,{existsSync as r,readFileSync as c,createWriteStream as l,mkdirSync as p,statSync as d,writeFileSync as u,renameSync as m,rmSync as h,readdirSync as g,unlinkSync as f,cpSync as y,createReadStream as v,promises as x,accessSync as w,constants as b}from"node:fs";import*as k from"node:path";import I,{join as S,basename as T,extname as E,resolve as _,sep as C,dirname as A,isAbsolute as $,relative as M,normalize as P}from"node:path";import R from"yargs";import{hideBin as N}from"yargs/helpers";import D from"chalk";import{encodeBase64 as O,createKeyPairWithUit8Array as j,encryptMachineEncryptionKey as U,generateAESKey as q,decodeBase64 as L,decryptWithEphemeralKey as H,createEventId as G,encryptFileContent as B,splitRtcChunkFrame as F,RtcChunkFlags as W,buildRtcChunkFrame as z,decodeGitPath as K,workerAuth as V,decryptSdkMessage as X,isSDKUserMessage as J,isAskUserMessage as Y,isAskUserResponseMessage as Q,isSDKMessage as Z,encryptSdkMessage as ee,machineAuth as te,getAgentContext as ne,detectPreview as se,IGNORED_DIRECTORIES as ae,DEFAULT_WORKER_EXECUTION_MODE as ie,isCompanionHeartbeatMessage as oe,isCompanionReminderMessage as re}from"@agentrix/shared";import{randomBytes as ce,randomUUID as le,createHash as pe,createDecipheriv as de,createCipheriv as ue,createHmac as me,timingSafeEqual as he}from"node:crypto";import ge from"axios";import{m as fe,l as ye,p as ve,a as xe,c as we,g as be,b as ke}from"./logger-Dq-ORk-l.mjs";import{createInterface as Ie}from"node:readline";import*as Se from"fs";import Te,{readFileSync as Ee,existsSync as _e,promises as Ce}from"fs";import*as Ae from"path";import $e,{join as Me,dirname as Pe}from"path";import Re from"open";import{io as Ne}from"socket.io-client";import{EventEmitter as De}from"node:events";import{pipeline as Oe}from"node:stream/promises";import{GitServerLocalStore as je,validateGitLabPatToken as Ue,deriveLocalGitServerEncryptionKey as qe,replacePromptPlaceholders as Le,loadAgentConfig as He,getAgentContext as Ge,buildGitLabWebhookUrl as Be,buildGitLabWebhookEndpointPath as Fe}from"@agentrix/shared/node";import{createRequire as We}from"node:module";import{spawn as ze,execSync as Ke}from"child_process";import Ve from"ps-list";import Xe from"cross-spawn";import{getPlatform as Je}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import Ye from"fastify";import{z as Qe,toJSONSchema as Ze}from"zod";import{validatorCompiler as et,serializerCompiler as tt}from"fastify-type-provider-zod";import{spawnSync as nt,spawn as st,execSync as at,execFile as it}from"node:child_process";import{createSdkMcpServer as ot,query as rt,tool as ct,AbortError as lt}from"@anthropic-ai/claude-agent-sdk";import{promisify as pt}from"node:util";import dt from"simple-git";import{readFile as ut,writeFile as mt,mkdir as ht,access as gt}from"node:fs/promises";import{McpServer as ft}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as yt}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{EventEmitter as vt}from"events";import xt from"better-sqlite3";import{fileURLToPath as wt,pathToFileURL as bt}from"url";import{isSupportedPlatform as kt,NetworkManager as It,SandboxManager as St}from"@xmz-ai/sandbox-runtime";import{Cron as Tt}from"croner";import*as Et from"@larksuiteoapi/node-sdk";import{readFile as _t,stat as Ct}from"fs/promises";import{randomUUID as At}from"crypto";import{Codex as $t}from"@openai/codex-sdk";import{stdin as Mt,stdout as Pt}from"node:process";import{createInterface as Rt}from"node:readline/promises";import"winston";import"os";const Nt=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function Dt(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Ot(e,t,n){const s=t.toLowerCase();"http_proxy"===s?(e.HTTP_PROXY=n,e.http_proxy=n):"https_proxy"===s?(e.HTTPS_PROXY=n,e.https_proxy=n):"no_proxy"===s?(e.NO_PROXY=n,e.no_proxy=n):"all_proxy"===s?(e.ALL_PROXY=n,e.all_proxy=n):"global_agent_http_proxy"===s&&(e.GLOBAL_AGENT_HTTP_PROXY=n,e.global_agent_http_proxy=n)}function jt(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=Dt(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=Dt(s)))}async function Ut(e){return new Promise(t=>setTimeout(t,e))}function qt(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function Lt(e,t){const n=await fe.readDaemonState();if(!n?.port){const e="No daemon running, no state file found";return ye.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=qt(n,e),i=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t||{}),signal:AbortSignal.timeout(s)});if(!i.ok){const t=await i.json().catch(()=>null),n=("string"==typeof t?.error?t.error:"string"==typeof t?.message?t.message:void 0)||`Request failed: ${e}, HTTP ${i.status}`;return ye.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${qt(n,e)}, ${t instanceof Error?t.message:"Unknown error"}. Check that the Agentrix daemon is running and that ${n.host??"127.0.0.1"}:${n.port} is reachable.`;return ye.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function Ht(e,t){return await Lt("/session-started",{sessionId:e,metadata:t})}async function Gt(e,t,n){const s="string"==typeof t?{content:t}:t;return await Lt("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function Bt(){const e=await fe.readDaemonState();if(!e)return!1;try{return process.kill(e.pid,0),!0}catch{return ye.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await Wt(),!1}}async function Ft(){if(ye.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await Bt())return ye.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await fe.readDaemonState();if(!e)return ye.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=Me(ve(),"package.json"),n=JSON.parse(Ee(t,"utf-8")).version;return ye.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return ye.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function Wt(){try{await fe.clearDaemonState(),ye.debug("[DAEMON RUN] Daemon state file removed")}catch(e){ye.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function zt(){try{const e=await fe.readDaemonState();if(!e)return void ye.debug("No daemon state found");ye.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await Lt("/stop")}(),void await async function(e){const t=Date.now();for(;Date.now()-t<2e3;)try{process.kill(e,0),await new Promise(e=>setTimeout(e,100))}catch{return}throw new Error("Process did not die within timeout")}(e.pid)}catch(e){ye.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){ye.debug("Error stopping daemon",e)}}function Kt(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function Vt(e,t){if(ge.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?Kt(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?Kt(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?Kt(e.message):e instanceof Error?`${t}: ${e.message}`:t}function Xt(){return O(new Uint8Array(ce(32)))}async function Jt(){const e=await fe.readCredentials();if(e){if(await async function(e){try{await ge.get(`${fe.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})}catch(e){throw new Error(Vt(e,"Stored machine credentials are no longer valid"))}}(e),!e.secret){const t={...e,secret:Xt()};return await fe.writeCredentials(t),ye.info("[AUTH] Generated missing local auth secret"),t}return ye.info("[AUTH] Using existing credentials"),e}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=fe.generateMachineId();n={token:t,secret:Xt(),machineId:e},ye.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=fe.generateMachineId(),t=new Uint8Array(ce(32)),n=await j(t);try{console.log(`[AUTH] Sending auth request to: ${fe.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${O(n.publicKey).substring(0,20)}...`);const t={machineId:e};await ge.post(`${fe.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(Vt(e,"Failed to create authentication request, please try again later.")),{credentials:null,userPublicKey:null,keypair:n}}const s=await async function(e,t){console.clear(),console.log("\nWeb Authentication\n");const n=function(e,t){const n={key:O(e,"base64"),machineId:t},s=JSON.stringify(n),a=O((new TextEncoder).encode(s),"base64url");return`${fe.webappUrl}/terminal/connect?auth=${a}`}(e.publicKey,t);return console.log("Opening your browser..."),await async function(e){try{return!process.stdout.isTTY||process.env.CI||process.env.HEADLESS?(ye.debug("[browser] Headless environment detected, skipping browser open"),!1):(ye.debug(`[browser] Attempting to open URL: ${e}`),await Re(e),ye.debug("[browser] Browser opened successfully"),!0)}catch(e){return ye.debug("[browser] Failed to open browser:",e),!1}}(n)?(console.log("✓ Browser opened\n"),console.log("Complete authentication in your browser window.")):console.log("Could not open browser automatically."),console.log("\nIf the browser did not open, please copy and paste this URL:"),console.log(n),console.log(""),await async function(e,t){process.stdout.write("Waiting for authentication");let n=0,s=!1;const a=()=>{s=!0,console.log("\n\nAuthentication cancelled."),process.exit(0)};process.on("SIGINT",a);try{for(;!s;){try{const n=await ge.get(`${fe.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=H(L(s),e.secretKey);return a?{token:t,userPublicKey:JSON.parse((new TextDecoder).decode(a)).publicKey}:(console.log("\n\nFailed to decrypt authentication data. Please try again."),{token:null,userPublicKey:null})}}catch(e){return console.log(`\n\n${Vt(e,"Failed to check authentication status. Please try again.")}`),{token:null,userPublicKey:null}}process.stdout.write("\rWaiting for authentication"+".".repeat(n%3+1)+" "),n++,await Ut(1e3)}}finally{process.off("SIGINT",a)}return{token:null,userPublicKey:null}}(e,t)}(n,e);return s.token?{credentials:{token:s.token,secret:O(t),machineId:e},userPublicKey:s?.userPublicKey,keypair:n}:{credentials:null,userPublicKey:null,keypair:n}}();if(!e.credentials||!e.userPublicKey)throw new Error("Authentication failed or was cancelled");n=e.credentials,s=e.keypair,a=e.userPublicKey}return await fe.writeCredentials(n),await async function(e,t,n,s){try{const a={id:e.machineId,metadata:JSON.stringify(t)};s&&n&&(a.dataEncryptionKey=U(s.publicKey,q(),L(n))),await ge.post(`${fe.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(Vt(e,"Failed to sync machine data"))}}(n,fe.metadata(),a,s),ye.info("[AUTH] Machine setup completed"),n}!function(e=process.env){!function(e=process.env,t){if(!t?.variables)return e;const n=!0===t.enabled;for(const[s,a]of Object.entries(t.variables)){const t=s.trim();if(!t)continue;const i=String(a),o=Nt.has(t);(n||o)&&(e[t]=i,Ot(e,t,i),jt(e,t,i))}}(e,function(e=process.env){const t=S(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?Dt(t):S(n.homedir(),".agentrix")}(e),"settings.json");if(!r(t))return null;try{const e=c(t,"utf-8"),n=JSON.parse(e);return n?.daemonEnv||null}catch{return null}}(e))}();class Yt{interval=null;socket=null;config;constructor(e){this.config=e}start(e){this.interval&&this.stop(),this.socket=e,this.interval=setInterval(()=>{if(!this.socket)return void this.stop();const e=this.config.payloadGenerator?this.config.payloadGenerator():{};this.socket.emit(this.config.event,e)},this.config.intervalMs)}stop(){this.interval&&(clearInterval(this.interval),this.interval=null),this.socket=null}isRunning(){return null!==this.interval}}function Qt(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=[];return t.message&&n.push(t.message),t.type&&n.push(`type=${t.type}`),void 0!==t.description&&n.push(`description=${JSON.stringify(t.description)}`),void 0!==t.data&&n.push(`data=${JSON.stringify(t.data)}`),void 0!==t.context&&n.push(`context=${JSON.stringify(t.context)}`),n.filter(Boolean).join(" ")||"unknown socket error"}class Zt{socket=null;config;eventHandlers=new Map;eventEmitter=new De;KeepAliveManager=null;healthCheckInterval=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new Yt(e.keepAliveConfig))}connect(){if(this.socket)return void this.log("Already connected or connecting");const{serverUrl:e,path:t,auth:n={},options:s={}}=this.config,a={path:t,auth:n,transports:["websocket"],reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:5e3,reconnectionAttempts:1/0,...s};this.socket=Ne(e,a),this.setupSocketHandlers(),this.log(`Connecting to ${e}`)}disconnect(){this.socket&&(this.log("Disconnecting"),this.stopHealthCheck(),this.socket.close(),this.socket=null)}get connected(){return this.socket?.connected??!1}replaceSocketHandler(e,t,n){this.socket&&(t&&this.socket.off(e,t),this.socket.on(e,n))}onEvent(e,t){const n=async n=>(this.log(`received event ${e}, data: ${JSON.stringify(n)}`),t(n)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}onEventWithAck(e,t){const n=async(n,s)=>(this.log(`received event with ack ${e}, data: ${JSON.stringify(n)}`),t(n,s)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}unregisterHandler(e){this.eventHandlers.delete(e),this.socket&&this.socket.off(e)}send(e,t){this.socket?(this.log(`send event ${e}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.log("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.log(`send event ${e}, data: ${JSON.stringify(t)}`),this.socket.emitWithAck(e,t)}sendVolatile(e,t){this.socket&&(void 0!==t?this.socket.volatile.emit(e,t):this.socket.volatile.emit(e))}async flush(e=1e4){if(this.connected)return new Promise(t=>{const n=setTimeout(()=>t(),e);this.socket.emit("ping",()=>{clearTimeout(n),t()})})}updateAuth(e){this.socket&&(this.socket.auth=e),this.config.auth=e}onLifecycle(e,t){this.eventEmitter.on(`lifecycle:${e}`,t)}offLifecycle(e){this.eventEmitter.removeAllListeners(`lifecycle:${e}`)}setupSocketHandlers(){this.socket&&(this.socket.on("connect",()=>{this.log("Connected"),this.eventEmitter.emit("lifecycle:connect",this.socket);for(const[e,t]of this.eventHandlers.entries())this.socket.off(e,t),this.socket.on(e,t);this.KeepAliveManager?.start(this.socket),this.startHealthCheck()}),this.socket.on("disconnect",e=>{this.log(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck()}),this.socket.on("connect_error",e=>{this.log(`Connection error: ${Qt(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.log(`Socket error: ${Qt(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}startHealthCheck(){const e=this.config.healthCheckConfig;if(!1===e?.enabled)return;const t=e?.intervalMs??3e4,n=e?.timeoutMs??5e3;this.stopHealthCheck(),this.healthCheckInterval=setInterval(()=>{if(!this.socket||!this.connected)return;const e=setTimeout(()=>{this.log("Health check timeout - forcing reconnect"),this.socket&&(this.socket.disconnect(),this.socket.connect())},n);this.socket.once("pong",()=>{clearTimeout(e)}),this.socket.emit("ping")},t)}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null)}log(e,...t){this.config.logger&&this.config.logger(`[SocketClient] ${e}`,...t)}}const en="attachment",tn={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function nn(){const e=S(fe.agentrixHomeDir,"tmp","channel-files");return r(e)||p(e,{recursive:!0}),e}function sn(e){const t=function(e){if(!e)return;return T(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||en;return S(nn(),`${le()}-${t}`)}async function an(e,t){if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);if(!e.body)throw new Error("Response body is null");const n=function(e,t){if(!e){const e=rn(t);return e?`${en}${e}`:void 0}if(E(e))return e;const n=rn(t);return n?`${e}${n}`:e}(t||function(e){if(!e)return;const t=e.match(/filename\*=UTF-8''([^;]+)/i);if(t?.[1])return decodeURIComponent(t[1]);const n=e.match(/filename="?([^";]+)"?/i);return n?.[1]}(e.headers.get("content-disposition")),e.headers.get("content-type")),s=sn(n),a=l(s);return await Oe(e.body,a),s}async function on(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=T(new URL(e).pathname);return E(t)?t:void 0}catch{return}}(e);return an(s,t||a)}function rn(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?tn[t]:void 0}function cn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var n=function e(){var n=!1;try{n=this instanceof e}catch{}return n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}),n}var ln,pn,dn,un={},mn={"application/1d-interleaved-parityfec":{source:"iana"},"application/3gpdash-qoe-report+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/3gpp-ims+xml":{source:"iana",compressible:!0},"application/3gpphal+json":{source:"iana",compressible:!0},"application/3gpphalforms+json":{source:"iana",compressible:!0},"application/a2l":{source:"iana"},"application/ace+cbor":{source:"iana"},"application/activemessage":{source:"iana"},"application/activity+json":{source:"iana",compressible:!0},"application/alto-costmap+json":{source:"iana",compressible:!0},"application/alto-costmapfilter+json":{source:"iana",compressible:!0},"application/alto-directory+json":{source:"iana",compressible:!0},"application/alto-endpointcost+json":{source:"iana",compressible:!0},"application/alto-endpointcostparams+json":{source:"iana",compressible:!0},"application/alto-endpointprop+json":{source:"iana",compressible:!0},"application/alto-endpointpropparams+json":{source:"iana",compressible:!0},"application/alto-error+json":{source:"iana",compressible:!0},"application/alto-networkmap+json":{source:"iana",compressible:!0},"application/alto-networkmapfilter+json":{source:"iana",compressible:!0},"application/alto-updatestreamcontrol+json":{source:"iana",compressible:!0},"application/alto-updatestreamparams+json":{source:"iana",compressible:!0},"application/aml":{source:"iana"},"application/andrew-inset":{source:"iana",extensions:["ez"]},"application/applefile":{source:"iana"},"application/applixware":{source:"apache",extensions:["aw"]},"application/at+jwt":{source:"iana"},"application/atf":{source:"iana"},"application/atfx":{source:"iana"},"application/atom+xml":{source:"iana",compressible:!0,extensions:["atom"]},"application/atomcat+xml":{source:"iana",compressible:!0,extensions:["atomcat"]},"application/atomdeleted+xml":{source:"iana",compressible:!0,extensions:["atomdeleted"]},"application/atomicmail":{source:"iana"},"application/atomsvc+xml":{source:"iana",compressible:!0,extensions:["atomsvc"]},"application/atsc-dwd+xml":{source:"iana",compressible:!0,extensions:["dwd"]},"application/atsc-dynamic-event-message":{source:"iana"},"application/atsc-held+xml":{source:"iana",compressible:!0,extensions:["held"]},"application/atsc-rdt+json":{source:"iana",compressible:!0},"application/atsc-rsat+xml":{source:"iana",compressible:!0,extensions:["rsat"]},"application/atxml":{source:"iana"},"application/auth-policy+xml":{source:"iana",compressible:!0},"application/bacnet-xdd+zip":{source:"iana",compressible:!1},"application/batch-smtp":{source:"iana"},"application/bdoc":{compressible:!1,extensions:["bdoc"]},"application/beep+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/calendar+json":{source:"iana",compressible:!0},"application/calendar+xml":{source:"iana",compressible:!0,extensions:["xcs"]},"application/call-completion":{source:"iana"},"application/cals-1840":{source:"iana"},"application/captive+json":{source:"iana",compressible:!0},"application/cbor":{source:"iana"},"application/cbor-seq":{source:"iana"},"application/cccex":{source:"iana"},"application/ccmp+xml":{source:"iana",compressible:!0},"application/ccxml+xml":{source:"iana",compressible:!0,extensions:["ccxml"]},"application/cdfx+xml":{source:"iana",compressible:!0,extensions:["cdfx"]},"application/cdmi-capability":{source:"iana",extensions:["cdmia"]},"application/cdmi-container":{source:"iana",extensions:["cdmic"]},"application/cdmi-domain":{source:"iana",extensions:["cdmid"]},"application/cdmi-object":{source:"iana",extensions:["cdmio"]},"application/cdmi-queue":{source:"iana",extensions:["cdmiq"]},"application/cdni":{source:"iana"},"application/cea":{source:"iana"},"application/cea-2018+xml":{source:"iana",compressible:!0},"application/cellml+xml":{source:"iana",compressible:!0},"application/cfw":{source:"iana"},"application/city+json":{source:"iana",compressible:!0},"application/clr":{source:"iana"},"application/clue+xml":{source:"iana",compressible:!0},"application/clue_info+xml":{source:"iana",compressible:!0},"application/cms":{source:"iana"},"application/cnrp+xml":{source:"iana",compressible:!0},"application/coap-group+json":{source:"iana",compressible:!0},"application/coap-payload":{source:"iana"},"application/commonground":{source:"iana"},"application/conference-info+xml":{source:"iana",compressible:!0},"application/cose":{source:"iana"},"application/cose-key":{source:"iana"},"application/cose-key-set":{source:"iana"},"application/cpl+xml":{source:"iana",compressible:!0,extensions:["cpl"]},"application/csrattrs":{source:"iana"},"application/csta+xml":{source:"iana",compressible:!0},"application/cstadata+xml":{source:"iana",compressible:!0},"application/csvm+json":{source:"iana",compressible:!0},"application/cu-seeme":{source:"apache",extensions:["cu"]},"application/cwt":{source:"iana"},"application/cybercash":{source:"iana"},"application/dart":{compressible:!0},"application/dash+xml":{source:"iana",compressible:!0,extensions:["mpd"]},"application/dash-patch+xml":{source:"iana",compressible:!0,extensions:["mpp"]},"application/dashdelta":{source:"iana"},"application/davmount+xml":{source:"iana",compressible:!0,extensions:["davmount"]},"application/dca-rft":{source:"iana"},"application/dcd":{source:"iana"},"application/dec-dx":{source:"iana"},"application/dialog-info+xml":{source:"iana",compressible:!0},"application/dicom":{source:"iana"},"application/dicom+json":{source:"iana",compressible:!0},"application/dicom+xml":{source:"iana",compressible:!0},"application/dii":{source:"iana"},"application/dit":{source:"iana"},"application/dns":{source:"iana"},"application/dns+json":{source:"iana",compressible:!0},"application/dns-message":{source:"iana"},"application/docbook+xml":{source:"apache",compressible:!0,extensions:["dbk"]},"application/dots+cbor":{source:"iana"},"application/dskpp+xml":{source:"iana",compressible:!0},"application/dssc+der":{source:"iana",extensions:["dssc"]},"application/dssc+xml":{source:"iana",compressible:!0,extensions:["xdssc"]},"application/dvcs":{source:"iana"},"application/ecmascript":{source:"iana",compressible:!0,extensions:["es","ecma"]},"application/edi-consent":{source:"iana"},"application/edi-x12":{source:"iana",compressible:!1},"application/edifact":{source:"iana",compressible:!1},"application/efi":{source:"iana"},"application/elm+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/elm+xml":{source:"iana",compressible:!0},"application/emergencycalldata.cap+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/emergencycalldata.comment+xml":{source:"iana",compressible:!0},"application/emergencycalldata.control+xml":{source:"iana",compressible:!0},"application/emergencycalldata.deviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.ecall.msd":{source:"iana"},"application/emergencycalldata.providerinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.serviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.subscriberinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.veds+xml":{source:"iana",compressible:!0},"application/emma+xml":{source:"iana",compressible:!0,extensions:["emma"]},"application/emotionml+xml":{source:"iana",compressible:!0,extensions:["emotionml"]},"application/encaprtp":{source:"iana"},"application/epp+xml":{source:"iana",compressible:!0},"application/epub+zip":{source:"iana",compressible:!1,extensions:["epub"]},"application/eshop":{source:"iana"},"application/exi":{source:"iana",extensions:["exi"]},"application/expect-ct-report+json":{source:"iana",compressible:!0},"application/express":{source:"iana",extensions:["exp"]},"application/fastinfoset":{source:"iana"},"application/fastsoap":{source:"iana"},"application/fdt+xml":{source:"iana",compressible:!0,extensions:["fdt"]},"application/fhir+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/fhir+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/fido.trusted-apps+json":{compressible:!0},"application/fits":{source:"iana"},"application/flexfec":{source:"iana"},"application/font-sfnt":{source:"iana"},"application/font-tdpfr":{source:"iana",extensions:["pfr"]},"application/font-woff":{source:"iana",compressible:!1},"application/framework-attributes+xml":{source:"iana",compressible:!0},"application/geo+json":{source:"iana",compressible:!0,extensions:["geojson"]},"application/geo+json-seq":{source:"iana"},"application/geopackage+sqlite3":{source:"iana"},"application/geoxacml+xml":{source:"iana",compressible:!0},"application/gltf-buffer":{source:"iana"},"application/gml+xml":{source:"iana",compressible:!0,extensions:["gml"]},"application/gpx+xml":{source:"apache",compressible:!0,extensions:["gpx"]},"application/gxf":{source:"apache",extensions:["gxf"]},"application/gzip":{source:"iana",compressible:!1,extensions:["gz"]},"application/h224":{source:"iana"},"application/held+xml":{source:"iana",compressible:!0},"application/hjson":{extensions:["hjson"]},"application/http":{source:"iana"},"application/hyperstudio":{source:"iana",extensions:["stk"]},"application/ibe-key-request+xml":{source:"iana",compressible:!0},"application/ibe-pkg-reply+xml":{source:"iana",compressible:!0},"application/ibe-pp-data":{source:"iana"},"application/iges":{source:"iana"},"application/im-iscomposing+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/index":{source:"iana"},"application/index.cmd":{source:"iana"},"application/index.obj":{source:"iana"},"application/index.response":{source:"iana"},"application/index.vnd":{source:"iana"},"application/inkml+xml":{source:"iana",compressible:!0,extensions:["ink","inkml"]},"application/iotp":{source:"iana"},"application/ipfix":{source:"iana",extensions:["ipfix"]},"application/ipp":{source:"iana"},"application/isup":{source:"iana"},"application/its+xml":{source:"iana",compressible:!0,extensions:["its"]},"application/java-archive":{source:"apache",compressible:!1,extensions:["jar","war","ear"]},"application/java-serialized-object":{source:"apache",compressible:!1,extensions:["ser"]},"application/java-vm":{source:"apache",compressible:!1,extensions:["class"]},"application/javascript":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["js","mjs"]},"application/jf2feed+json":{source:"iana",compressible:!0},"application/jose":{source:"iana"},"application/jose+json":{source:"iana",compressible:!0},"application/jrd+json":{source:"iana",compressible:!0},"application/jscalendar+json":{source:"iana",compressible:!0},"application/json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["json","map"]},"application/json-patch+json":{source:"iana",compressible:!0},"application/json-seq":{source:"iana"},"application/json5":{extensions:["json5"]},"application/jsonml+json":{source:"apache",compressible:!0,extensions:["jsonml"]},"application/jwk+json":{source:"iana",compressible:!0},"application/jwk-set+json":{source:"iana",compressible:!0},"application/jwt":{source:"iana"},"application/kpml-request+xml":{source:"iana",compressible:!0},"application/kpml-response+xml":{source:"iana",compressible:!0},"application/ld+json":{source:"iana",compressible:!0,extensions:["jsonld"]},"application/lgr+xml":{source:"iana",compressible:!0,extensions:["lgr"]},"application/link-format":{source:"iana"},"application/load-control+xml":{source:"iana",compressible:!0},"application/lost+xml":{source:"iana",compressible:!0,extensions:["lostxml"]},"application/lostsync+xml":{source:"iana",compressible:!0},"application/lpf+zip":{source:"iana",compressible:!1},"application/lxf":{source:"iana"},"application/mac-binhex40":{source:"iana",extensions:["hqx"]},"application/mac-compactpro":{source:"apache",extensions:["cpt"]},"application/macwriteii":{source:"iana"},"application/mads+xml":{source:"iana",compressible:!0,extensions:["mads"]},"application/manifest+json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["webmanifest"]},"application/marc":{source:"iana",extensions:["mrc"]},"application/marcxml+xml":{source:"iana",compressible:!0,extensions:["mrcx"]},"application/mathematica":{source:"iana",extensions:["ma","nb","mb"]},"application/mathml+xml":{source:"iana",compressible:!0,extensions:["mathml"]},"application/mathml-content+xml":{source:"iana",compressible:!0},"application/mathml-presentation+xml":{source:"iana",compressible:!0},"application/mbms-associated-procedure-description+xml":{source:"iana",compressible:!0},"application/mbms-deregister+xml":{source:"iana",compressible:!0},"application/mbms-envelope+xml":{source:"iana",compressible:!0},"application/mbms-msk+xml":{source:"iana",compressible:!0},"application/mbms-msk-response+xml":{source:"iana",compressible:!0},"application/mbms-protection-description+xml":{source:"iana",compressible:!0},"application/mbms-reception-report+xml":{source:"iana",compressible:!0},"application/mbms-register+xml":{source:"iana",compressible:!0},"application/mbms-register-response+xml":{source:"iana",compressible:!0},"application/mbms-schedule+xml":{source:"iana",compressible:!0},"application/mbms-user-service-description+xml":{source:"iana",compressible:!0},"application/mbox":{source:"iana",extensions:["mbox"]},"application/media-policy-dataset+xml":{source:"iana",compressible:!0,extensions:["mpf"]},"application/media_control+xml":{source:"iana",compressible:!0},"application/mediaservercontrol+xml":{source:"iana",compressible:!0,extensions:["mscml"]},"application/merge-patch+json":{source:"iana",compressible:!0},"application/metalink+xml":{source:"apache",compressible:!0,extensions:["metalink"]},"application/metalink4+xml":{source:"iana",compressible:!0,extensions:["meta4"]},"application/mets+xml":{source:"iana",compressible:!0,extensions:["mets"]},"application/mf4":{source:"iana"},"application/mikey":{source:"iana"},"application/mipc":{source:"iana"},"application/missing-blocks+cbor-seq":{source:"iana"},"application/mmt-aei+xml":{source:"iana",compressible:!0,extensions:["maei"]},"application/mmt-usd+xml":{source:"iana",compressible:!0,extensions:["musd"]},"application/mods+xml":{source:"iana",compressible:!0,extensions:["mods"]},"application/moss-keys":{source:"iana"},"application/moss-signature":{source:"iana"},"application/mosskey-data":{source:"iana"},"application/mosskey-request":{source:"iana"},"application/mp21":{source:"iana",extensions:["m21","mp21"]},"application/mp4":{source:"iana",extensions:["mp4s","m4p"]},"application/mpeg4-generic":{source:"iana"},"application/mpeg4-iod":{source:"iana"},"application/mpeg4-iod-xmt":{source:"iana"},"application/mrb-consumer+xml":{source:"iana",compressible:!0},"application/mrb-publish+xml":{source:"iana",compressible:!0},"application/msc-ivr+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msc-mixer+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msword":{source:"iana",compressible:!1,extensions:["doc","dot"]},"application/mud+json":{source:"iana",compressible:!0},"application/multipart-core":{source:"iana"},"application/mxf":{source:"iana",extensions:["mxf"]},"application/n-quads":{source:"iana",extensions:["nq"]},"application/n-triples":{source:"iana",extensions:["nt"]},"application/nasdata":{source:"iana"},"application/news-checkgroups":{source:"iana",charset:"US-ASCII"},"application/news-groupinfo":{source:"iana",charset:"US-ASCII"},"application/news-transmission":{source:"iana"},"application/nlsml+xml":{source:"iana",compressible:!0},"application/node":{source:"iana",extensions:["cjs"]},"application/nss":{source:"iana"},"application/oauth-authz-req+jwt":{source:"iana"},"application/oblivious-dns-message":{source:"iana"},"application/ocsp-request":{source:"iana"},"application/ocsp-response":{source:"iana"},"application/octet-stream":{source:"iana",compressible:!1,extensions:["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{source:"iana",extensions:["oda"]},"application/odm+xml":{source:"iana",compressible:!0},"application/odx":{source:"iana"},"application/oebps-package+xml":{source:"iana",compressible:!0,extensions:["opf"]},"application/ogg":{source:"iana",compressible:!1,extensions:["ogx"]},"application/omdoc+xml":{source:"apache",compressible:!0,extensions:["omdoc"]},"application/onenote":{source:"apache",extensions:["onetoc","onetoc2","onetmp","onepkg"]},"application/opc-nodeset+xml":{source:"iana",compressible:!0},"application/oscore":{source:"iana"},"application/oxps":{source:"iana",extensions:["oxps"]},"application/p21":{source:"iana"},"application/p21+zip":{source:"iana",compressible:!1},"application/p2p-overlay+xml":{source:"iana",compressible:!0,extensions:["relo"]},"application/parityfec":{source:"iana"},"application/passport":{source:"iana"},"application/patch-ops-error+xml":{source:"iana",compressible:!0,extensions:["xer"]},"application/pdf":{source:"iana",compressible:!1,extensions:["pdf"]},"application/pdx":{source:"iana"},"application/pem-certificate-chain":{source:"iana"},"application/pgp-encrypted":{source:"iana",compressible:!1,extensions:["pgp"]},"application/pgp-keys":{source:"iana",extensions:["asc"]},"application/pgp-signature":{source:"iana",extensions:["asc","sig"]},"application/pics-rules":{source:"apache",extensions:["prf"]},"application/pidf+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pidf-diff+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pkcs10":{source:"iana",extensions:["p10"]},"application/pkcs12":{source:"iana"},"application/pkcs7-mime":{source:"iana",extensions:["p7m","p7c"]},"application/pkcs7-signature":{source:"iana",extensions:["p7s"]},"application/pkcs8":{source:"iana",extensions:["p8"]},"application/pkcs8-encrypted":{source:"iana"},"application/pkix-attr-cert":{source:"iana",extensions:["ac"]},"application/pkix-cert":{source:"iana",extensions:["cer"]},"application/pkix-crl":{source:"iana",extensions:["crl"]},"application/pkix-pkipath":{source:"iana",extensions:["pkipath"]},"application/pkixcmp":{source:"iana",extensions:["pki"]},"application/pls+xml":{source:"iana",compressible:!0,extensions:["pls"]},"application/poc-settings+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/postscript":{source:"iana",compressible:!0,extensions:["ai","eps","ps"]},"application/ppsp-tracker+json":{source:"iana",compressible:!0},"application/problem+json":{source:"iana",compressible:!0},"application/problem+xml":{source:"iana",compressible:!0},"application/provenance+xml":{source:"iana",compressible:!0,extensions:["provx"]},"application/prs.alvestrand.titrax-sheet":{source:"iana"},"application/prs.cww":{source:"iana",extensions:["cww"]},"application/prs.cyn":{source:"iana",charset:"7-BIT"},"application/prs.hpub+zip":{source:"iana",compressible:!1},"application/prs.nprend":{source:"iana"},"application/prs.plucker":{source:"iana"},"application/prs.rdf-xml-crypt":{source:"iana"},"application/prs.xsf+xml":{source:"iana",compressible:!0},"application/pskc+xml":{source:"iana",compressible:!0,extensions:["pskcxml"]},"application/pvd+json":{source:"iana",compressible:!0},"application/qsig":{source:"iana"},"application/raml+yaml":{compressible:!0,extensions:["raml"]},"application/raptorfec":{source:"iana"},"application/rdap+json":{source:"iana",compressible:!0},"application/rdf+xml":{source:"iana",compressible:!0,extensions:["rdf","owl"]},"application/reginfo+xml":{source:"iana",compressible:!0,extensions:["rif"]},"application/relax-ng-compact-syntax":{source:"iana",extensions:["rnc"]},"application/remote-printing":{source:"iana"},"application/reputon+json":{source:"iana",compressible:!0},"application/resource-lists+xml":{source:"iana",compressible:!0,extensions:["rl"]},"application/resource-lists-diff+xml":{source:"iana",compressible:!0,extensions:["rld"]},"application/rfc+xml":{source:"iana",compressible:!0},"application/riscos":{source:"iana"},"application/rlmi+xml":{source:"iana",compressible:!0},"application/rls-services+xml":{source:"iana",compressible:!0,extensions:["rs"]},"application/route-apd+xml":{source:"iana",compressible:!0,extensions:["rapd"]},"application/route-s-tsid+xml":{source:"iana",compressible:!0,extensions:["sls"]},"application/route-usd+xml":{source:"iana",compressible:!0,extensions:["rusd"]},"application/rpki-ghostbusters":{source:"iana",extensions:["gbr"]},"application/rpki-manifest":{source:"iana",extensions:["mft"]},"application/rpki-publication":{source:"iana"},"application/rpki-roa":{source:"iana",extensions:["roa"]},"application/rpki-updown":{source:"iana"},"application/rsd+xml":{source:"apache",compressible:!0,extensions:["rsd"]},"application/rss+xml":{source:"apache",compressible:!0,extensions:["rss"]},"application/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"application/rtploopback":{source:"iana"},"application/rtx":{source:"iana"},"application/samlassertion+xml":{source:"iana",compressible:!0},"application/samlmetadata+xml":{source:"iana",compressible:!0},"application/sarif+json":{source:"iana",compressible:!0},"application/sarif-external-properties+json":{source:"iana",compressible:!0},"application/sbe":{source:"iana"},"application/sbml+xml":{source:"iana",compressible:!0,extensions:["sbml"]},"application/scaip+xml":{source:"iana",compressible:!0},"application/scim+json":{source:"iana",compressible:!0},"application/scvp-cv-request":{source:"iana",extensions:["scq"]},"application/scvp-cv-response":{source:"iana",extensions:["scs"]},"application/scvp-vp-request":{source:"iana",extensions:["spq"]},"application/scvp-vp-response":{source:"iana",extensions:["spp"]},"application/sdp":{source:"iana",extensions:["sdp"]},"application/secevent+jwt":{source:"iana"},"application/senml+cbor":{source:"iana"},"application/senml+json":{source:"iana",compressible:!0},"application/senml+xml":{source:"iana",compressible:!0,extensions:["senmlx"]},"application/senml-etch+cbor":{source:"iana"},"application/senml-etch+json":{source:"iana",compressible:!0},"application/senml-exi":{source:"iana"},"application/sensml+cbor":{source:"iana"},"application/sensml+json":{source:"iana",compressible:!0},"application/sensml+xml":{source:"iana",compressible:!0,extensions:["sensmlx"]},"application/sensml-exi":{source:"iana"},"application/sep+xml":{source:"iana",compressible:!0},"application/sep-exi":{source:"iana"},"application/session-info":{source:"iana"},"application/set-payment":{source:"iana"},"application/set-payment-initiation":{source:"iana",extensions:["setpay"]},"application/set-registration":{source:"iana"},"application/set-registration-initiation":{source:"iana",extensions:["setreg"]},"application/sgml":{source:"iana"},"application/sgml-open-catalog":{source:"iana"},"application/shf+xml":{source:"iana",compressible:!0,extensions:["shf"]},"application/sieve":{source:"iana",extensions:["siv","sieve"]},"application/simple-filter+xml":{source:"iana",compressible:!0},"application/simple-message-summary":{source:"iana"},"application/simplesymbolcontainer":{source:"iana"},"application/sipc":{source:"iana"},"application/slate":{source:"iana"},"application/smil":{source:"iana"},"application/smil+xml":{source:"iana",compressible:!0,extensions:["smi","smil"]},"application/smpte336m":{source:"iana"},"application/soap+fastinfoset":{source:"iana"},"application/soap+xml":{source:"iana",compressible:!0},"application/sparql-query":{source:"iana",extensions:["rq"]},"application/sparql-results+xml":{source:"iana",compressible:!0,extensions:["srx"]},"application/spdx+json":{source:"iana",compressible:!0},"application/spirits-event+xml":{source:"iana",compressible:!0},"application/sql":{source:"iana"},"application/srgs":{source:"iana",extensions:["gram"]},"application/srgs+xml":{source:"iana",compressible:!0,extensions:["grxml"]},"application/sru+xml":{source:"iana",compressible:!0,extensions:["sru"]},"application/ssdl+xml":{source:"apache",compressible:!0,extensions:["ssdl"]},"application/ssml+xml":{source:"iana",compressible:!0,extensions:["ssml"]},"application/stix+json":{source:"iana",compressible:!0},"application/swid+xml":{source:"iana",compressible:!0,extensions:["swidtag"]},"application/tamp-apex-update":{source:"iana"},"application/tamp-apex-update-confirm":{source:"iana"},"application/tamp-community-update":{source:"iana"},"application/tamp-community-update-confirm":{source:"iana"},"application/tamp-error":{source:"iana"},"application/tamp-sequence-adjust":{source:"iana"},"application/tamp-sequence-adjust-confirm":{source:"iana"},"application/tamp-status-query":{source:"iana"},"application/tamp-status-response":{source:"iana"},"application/tamp-update":{source:"iana"},"application/tamp-update-confirm":{source:"iana"},"application/tar":{compressible:!0},"application/taxii+json":{source:"iana",compressible:!0},"application/td+json":{source:"iana",compressible:!0},"application/tei+xml":{source:"iana",compressible:!0,extensions:["tei","teicorpus"]},"application/tetra_isi":{source:"iana"},"application/thraud+xml":{source:"iana",compressible:!0,extensions:["tfi"]},"application/timestamp-query":{source:"iana"},"application/timestamp-reply":{source:"iana"},"application/timestamped-data":{source:"iana",extensions:["tsd"]},"application/tlsrpt+gzip":{source:"iana"},"application/tlsrpt+json":{source:"iana",compressible:!0},"application/tnauthlist":{source:"iana"},"application/token-introspection+jwt":{source:"iana"},"application/toml":{compressible:!0,extensions:["toml"]},"application/trickle-ice-sdpfrag":{source:"iana"},"application/trig":{source:"iana",extensions:["trig"]},"application/ttml+xml":{source:"iana",compressible:!0,extensions:["ttml"]},"application/tve-trigger":{source:"iana"},"application/tzif":{source:"iana"},"application/tzif-leap":{source:"iana"},"application/ubjson":{compressible:!1,extensions:["ubj"]},"application/ulpfec":{source:"iana"},"application/urc-grpsheet+xml":{source:"iana",compressible:!0},"application/urc-ressheet+xml":{source:"iana",compressible:!0,extensions:["rsheet"]},"application/urc-targetdesc+xml":{source:"iana",compressible:!0,extensions:["td"]},"application/urc-uisocketdesc+xml":{source:"iana",compressible:!0},"application/vcard+json":{source:"iana",compressible:!0},"application/vcard+xml":{source:"iana",compressible:!0},"application/vemmi":{source:"iana"},"application/vividence.scriptfile":{source:"apache"},"application/vnd.1000minds.decision-model+xml":{source:"iana",compressible:!0,extensions:["1km"]},"application/vnd.3gpp-prose+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc3ch+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-v2x-local-service-information":{source:"iana"},"application/vnd.3gpp.5gnas":{source:"iana"},"application/vnd.3gpp.access-transfer-events+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.bsf+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gmop+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gtpc":{source:"iana"},"application/vnd.3gpp.interworking-data":{source:"iana"},"application/vnd.3gpp.lpp":{source:"iana"},"application/vnd.3gpp.mc-signalling-ear":{source:"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-payload":{source:"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-signalling":{source:"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-floor-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-signed+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-init-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-transmission-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mid-call+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ngap":{source:"iana"},"application/vnd.3gpp.pfcp":{source:"iana"},"application/vnd.3gpp.pic-bw-large":{source:"iana",extensions:["plb"]},"application/vnd.3gpp.pic-bw-small":{source:"iana",extensions:["psb"]},"application/vnd.3gpp.pic-bw-var":{source:"iana",extensions:["pvb"]},"application/vnd.3gpp.s1ap":{source:"iana"},"application/vnd.3gpp.sms":{source:"iana"},"application/vnd.3gpp.sms+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-ext+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.state-and-event-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ussd+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.bcmcsinfo+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.sms":{source:"iana"},"application/vnd.3gpp2.tcap":{source:"iana",extensions:["tcap"]},"application/vnd.3lightssoftware.imagescal":{source:"iana"},"application/vnd.3m.post-it-notes":{source:"iana",extensions:["pwn"]},"application/vnd.accpac.simply.aso":{source:"iana",extensions:["aso"]},"application/vnd.accpac.simply.imp":{source:"iana",extensions:["imp"]},"application/vnd.acucobol":{source:"iana",extensions:["acu"]},"application/vnd.acucorp":{source:"iana",extensions:["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{source:"apache",compressible:!1,extensions:["air"]},"application/vnd.adobe.flash.movie":{source:"iana"},"application/vnd.adobe.formscentral.fcdt":{source:"iana",extensions:["fcdt"]},"application/vnd.adobe.fxp":{source:"iana",extensions:["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{source:"iana"},"application/vnd.adobe.xdp+xml":{source:"iana",compressible:!0,extensions:["xdp"]},"application/vnd.adobe.xfdf":{source:"iana",extensions:["xfdf"]},"application/vnd.aether.imp":{source:"iana"},"application/vnd.afpc.afplinedata":{source:"iana"},"application/vnd.afpc.afplinedata-pagedef":{source:"iana"},"application/vnd.afpc.cmoca-cmresource":{source:"iana"},"application/vnd.afpc.foca-charset":{source:"iana"},"application/vnd.afpc.foca-codedfont":{source:"iana"},"application/vnd.afpc.foca-codepage":{source:"iana"},"application/vnd.afpc.modca":{source:"iana"},"application/vnd.afpc.modca-cmtable":{source:"iana"},"application/vnd.afpc.modca-formdef":{source:"iana"},"application/vnd.afpc.modca-mediummap":{source:"iana"},"application/vnd.afpc.modca-objectcontainer":{source:"iana"},"application/vnd.afpc.modca-overlay":{source:"iana"},"application/vnd.afpc.modca-pagesegment":{source:"iana"},"application/vnd.age":{source:"iana",extensions:["age"]},"application/vnd.ah-barcode":{source:"iana"},"application/vnd.ahead.space":{source:"iana",extensions:["ahead"]},"application/vnd.airzip.filesecure.azf":{source:"iana",extensions:["azf"]},"application/vnd.airzip.filesecure.azs":{source:"iana",extensions:["azs"]},"application/vnd.amadeus+json":{source:"iana",compressible:!0},"application/vnd.amazon.ebook":{source:"apache",extensions:["azw"]},"application/vnd.amazon.mobi8-ebook":{source:"iana"},"application/vnd.americandynamics.acc":{source:"iana",extensions:["acc"]},"application/vnd.amiga.ami":{source:"iana",extensions:["ami"]},"application/vnd.amundsen.maze+xml":{source:"iana",compressible:!0},"application/vnd.android.ota":{source:"iana"},"application/vnd.android.package-archive":{source:"apache",compressible:!1,extensions:["apk"]},"application/vnd.anki":{source:"iana"},"application/vnd.anser-web-certificate-issue-initiation":{source:"iana",extensions:["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{source:"apache",extensions:["fti"]},"application/vnd.antix.game-component":{source:"iana",extensions:["atx"]},"application/vnd.apache.arrow.file":{source:"iana"},"application/vnd.apache.arrow.stream":{source:"iana"},"application/vnd.apache.thrift.binary":{source:"iana"},"application/vnd.apache.thrift.compact":{source:"iana"},"application/vnd.apache.thrift.json":{source:"iana"},"application/vnd.api+json":{source:"iana",compressible:!0},"application/vnd.aplextor.warrp+json":{source:"iana",compressible:!0},"application/vnd.apothekende.reservation+json":{source:"iana",compressible:!0},"application/vnd.apple.installer+xml":{source:"iana",compressible:!0,extensions:["mpkg"]},"application/vnd.apple.keynote":{source:"iana",extensions:["key"]},"application/vnd.apple.mpegurl":{source:"iana",extensions:["m3u8"]},"application/vnd.apple.numbers":{source:"iana",extensions:["numbers"]},"application/vnd.apple.pages":{source:"iana",extensions:["pages"]},"application/vnd.apple.pkpass":{compressible:!1,extensions:["pkpass"]},"application/vnd.arastra.swi":{source:"iana"},"application/vnd.aristanetworks.swi":{source:"iana",extensions:["swi"]},"application/vnd.artisan+json":{source:"iana",compressible:!0},"application/vnd.artsquare":{source:"iana"},"application/vnd.astraea-software.iota":{source:"iana",extensions:["iota"]},"application/vnd.audiograph":{source:"iana",extensions:["aep"]},"application/vnd.autopackage":{source:"iana"},"application/vnd.avalon+json":{source:"iana",compressible:!0},"application/vnd.avistar+xml":{source:"iana",compressible:!0},"application/vnd.balsamiq.bmml+xml":{source:"iana",compressible:!0,extensions:["bmml"]},"application/vnd.balsamiq.bmpr":{source:"iana"},"application/vnd.banana-accounting":{source:"iana"},"application/vnd.bbf.usp.error":{source:"iana"},"application/vnd.bbf.usp.msg":{source:"iana"},"application/vnd.bbf.usp.msg+json":{source:"iana",compressible:!0},"application/vnd.bekitzur-stech+json":{source:"iana",compressible:!0},"application/vnd.bint.med-content":{source:"iana"},"application/vnd.biopax.rdf+xml":{source:"iana",compressible:!0},"application/vnd.blink-idb-value-wrapper":{source:"iana"},"application/vnd.blueice.multipass":{source:"iana",extensions:["mpm"]},"application/vnd.bluetooth.ep.oob":{source:"iana"},"application/vnd.bluetooth.le.oob":{source:"iana"},"application/vnd.bmi":{source:"iana",extensions:["bmi"]},"application/vnd.bpf":{source:"iana"},"application/vnd.bpf3":{source:"iana"},"application/vnd.businessobjects":{source:"iana",extensions:["rep"]},"application/vnd.byu.uapi+json":{source:"iana",compressible:!0},"application/vnd.cab-jscript":{source:"iana"},"application/vnd.canon-cpdl":{source:"iana"},"application/vnd.canon-lips":{source:"iana"},"application/vnd.capasystems-pg+json":{source:"iana",compressible:!0},"application/vnd.cendio.thinlinc.clientconf":{source:"iana"},"application/vnd.century-systems.tcp_stream":{source:"iana"},"application/vnd.chemdraw+xml":{source:"iana",compressible:!0,extensions:["cdxml"]},"application/vnd.chess-pgn":{source:"iana"},"application/vnd.chipnuts.karaoke-mmd":{source:"iana",extensions:["mmd"]},"application/vnd.ciedi":{source:"iana"},"application/vnd.cinderella":{source:"iana",extensions:["cdy"]},"application/vnd.cirpack.isdn-ext":{source:"iana"},"application/vnd.citationstyles.style+xml":{source:"iana",compressible:!0,extensions:["csl"]},"application/vnd.claymore":{source:"iana",extensions:["cla"]},"application/vnd.cloanto.rp9":{source:"iana",extensions:["rp9"]},"application/vnd.clonk.c4group":{source:"iana",extensions:["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{source:"iana",extensions:["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{source:"iana",extensions:["c11amz"]},"application/vnd.coffeescript":{source:"iana"},"application/vnd.collabio.xodocuments.document":{source:"iana"},"application/vnd.collabio.xodocuments.document-template":{source:"iana"},"application/vnd.collabio.xodocuments.presentation":{source:"iana"},"application/vnd.collabio.xodocuments.presentation-template":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{source:"iana"},"application/vnd.collection+json":{source:"iana",compressible:!0},"application/vnd.collection.doc+json":{source:"iana",compressible:!0},"application/vnd.collection.next+json":{source:"iana",compressible:!0},"application/vnd.comicbook+zip":{source:"iana",compressible:!1},"application/vnd.comicbook-rar":{source:"iana"},"application/vnd.commerce-battelle":{source:"iana"},"application/vnd.commonspace":{source:"iana",extensions:["csp"]},"application/vnd.contact.cmsg":{source:"iana",extensions:["cdbcmsg"]},"application/vnd.coreos.ignition+json":{source:"iana",compressible:!0},"application/vnd.cosmocaller":{source:"iana",extensions:["cmc"]},"application/vnd.crick.clicker":{source:"iana",extensions:["clkx"]},"application/vnd.crick.clicker.keyboard":{source:"iana",extensions:["clkk"]},"application/vnd.crick.clicker.palette":{source:"iana",extensions:["clkp"]},"application/vnd.crick.clicker.template":{source:"iana",extensions:["clkt"]},"application/vnd.crick.clicker.wordbank":{source:"iana",extensions:["clkw"]},"application/vnd.criticaltools.wbs+xml":{source:"iana",compressible:!0,extensions:["wbs"]},"application/vnd.cryptii.pipe+json":{source:"iana",compressible:!0},"application/vnd.crypto-shade-file":{source:"iana"},"application/vnd.cryptomator.encrypted":{source:"iana"},"application/vnd.cryptomator.vault":{source:"iana"},"application/vnd.ctc-posml":{source:"iana",extensions:["pml"]},"application/vnd.ctct.ws+xml":{source:"iana",compressible:!0},"application/vnd.cups-pdf":{source:"iana"},"application/vnd.cups-postscript":{source:"iana"},"application/vnd.cups-ppd":{source:"iana",extensions:["ppd"]},"application/vnd.cups-raster":{source:"iana"},"application/vnd.cups-raw":{source:"iana"},"application/vnd.curl":{source:"iana"},"application/vnd.curl.car":{source:"apache",extensions:["car"]},"application/vnd.curl.pcurl":{source:"apache",extensions:["pcurl"]},"application/vnd.cyan.dean.root+xml":{source:"iana",compressible:!0},"application/vnd.cybank":{source:"iana"},"application/vnd.cyclonedx+json":{source:"iana",compressible:!0},"application/vnd.cyclonedx+xml":{source:"iana",compressible:!0},"application/vnd.d2l.coursepackage1p0+zip":{source:"iana",compressible:!1},"application/vnd.d3m-dataset":{source:"iana"},"application/vnd.d3m-problem":{source:"iana"},"application/vnd.dart":{source:"iana",compressible:!0,extensions:["dart"]},"application/vnd.data-vision.rdz":{source:"iana",extensions:["rdz"]},"application/vnd.datapackage+json":{source:"iana",compressible:!0},"application/vnd.dataresource+json":{source:"iana",compressible:!0},"application/vnd.dbf":{source:"iana",extensions:["dbf"]},"application/vnd.debian.binary-package":{source:"iana"},"application/vnd.dece.data":{source:"iana",extensions:["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{source:"iana",compressible:!0,extensions:["uvt","uvvt"]},"application/vnd.dece.unspecified":{source:"iana",extensions:["uvx","uvvx"]},"application/vnd.dece.zip":{source:"iana",extensions:["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{source:"iana",extensions:["fe_launch"]},"application/vnd.desmume.movie":{source:"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{source:"iana"},"application/vnd.dm.delegation+xml":{source:"iana",compressible:!0},"application/vnd.dna":{source:"iana",extensions:["dna"]},"application/vnd.document+json":{source:"iana",compressible:!0},"application/vnd.dolby.mlp":{source:"apache",extensions:["mlp"]},"application/vnd.dolby.mobile.1":{source:"iana"},"application/vnd.dolby.mobile.2":{source:"iana"},"application/vnd.doremir.scorecloud-binary-document":{source:"iana"},"application/vnd.dpgraph":{source:"iana",extensions:["dpg"]},"application/vnd.dreamfactory":{source:"iana",extensions:["dfac"]},"application/vnd.drive+json":{source:"iana",compressible:!0},"application/vnd.ds-keypoint":{source:"apache",extensions:["kpxx"]},"application/vnd.dtg.local":{source:"iana"},"application/vnd.dtg.local.flash":{source:"iana"},"application/vnd.dtg.local.html":{source:"iana"},"application/vnd.dvb.ait":{source:"iana",extensions:["ait"]},"application/vnd.dvb.dvbisl+xml":{source:"iana",compressible:!0},"application/vnd.dvb.dvbj":{source:"iana"},"application/vnd.dvb.esgcontainer":{source:"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess2":{source:"iana"},"application/vnd.dvb.ipdcesgpdd":{source:"iana"},"application/vnd.dvb.ipdcroaming":{source:"iana"},"application/vnd.dvb.iptv.alfec-base":{source:"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{source:"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-container+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-generic+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-msglist+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-request+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-response+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-init+xml":{source:"iana",compressible:!0},"application/vnd.dvb.pfr":{source:"iana"},"application/vnd.dvb.service":{source:"iana",extensions:["svc"]},"application/vnd.dxr":{source:"iana"},"application/vnd.dynageo":{source:"iana",extensions:["geo"]},"application/vnd.dzr":{source:"iana"},"application/vnd.easykaraoke.cdgdownload":{source:"iana"},"application/vnd.ecdis-update":{source:"iana"},"application/vnd.ecip.rlp":{source:"iana"},"application/vnd.eclipse.ditto+json":{source:"iana",compressible:!0},"application/vnd.ecowin.chart":{source:"iana",extensions:["mag"]},"application/vnd.ecowin.filerequest":{source:"iana"},"application/vnd.ecowin.fileupdate":{source:"iana"},"application/vnd.ecowin.series":{source:"iana"},"application/vnd.ecowin.seriesrequest":{source:"iana"},"application/vnd.ecowin.seriesupdate":{source:"iana"},"application/vnd.efi.img":{source:"iana"},"application/vnd.efi.iso":{source:"iana"},"application/vnd.emclient.accessrequest+xml":{source:"iana",compressible:!0},"application/vnd.enliven":{source:"iana",extensions:["nml"]},"application/vnd.enphase.envoy":{source:"iana"},"application/vnd.eprints.data+xml":{source:"iana",compressible:!0},"application/vnd.epson.esf":{source:"iana",extensions:["esf"]},"application/vnd.epson.msf":{source:"iana",extensions:["msf"]},"application/vnd.epson.quickanime":{source:"iana",extensions:["qam"]},"application/vnd.epson.salt":{source:"iana",extensions:["slt"]},"application/vnd.epson.ssf":{source:"iana",extensions:["ssf"]},"application/vnd.ericsson.quickcall":{source:"iana"},"application/vnd.espass-espass+zip":{source:"iana",compressible:!1},"application/vnd.eszigno3+xml":{source:"iana",compressible:!0,extensions:["es3","et3"]},"application/vnd.etsi.aoc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.asic-e+zip":{source:"iana",compressible:!1},"application/vnd.etsi.asic-s+zip":{source:"iana",compressible:!1},"application/vnd.etsi.cug+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvcommand+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-bc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-cod+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-npvr+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvservice+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsync+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvueprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mcid+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mheg5":{source:"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{source:"iana",compressible:!0},"application/vnd.etsi.pstn+xml":{source:"iana",compressible:!0},"application/vnd.etsi.sci+xml":{source:"iana",compressible:!0},"application/vnd.etsi.simservs+xml":{source:"iana",compressible:!0},"application/vnd.etsi.timestamp-token":{source:"iana"},"application/vnd.etsi.tsl+xml":{source:"iana",compressible:!0},"application/vnd.etsi.tsl.der":{source:"iana"},"application/vnd.eu.kasparian.car+json":{source:"iana",compressible:!0},"application/vnd.eudora.data":{source:"iana"},"application/vnd.evolv.ecig.profile":{source:"iana"},"application/vnd.evolv.ecig.settings":{source:"iana"},"application/vnd.evolv.ecig.theme":{source:"iana"},"application/vnd.exstream-empower+zip":{source:"iana",compressible:!1},"application/vnd.exstream-package":{source:"iana"},"application/vnd.ezpix-album":{source:"iana",extensions:["ez2"]},"application/vnd.ezpix-package":{source:"iana",extensions:["ez3"]},"application/vnd.f-secure.mobile":{source:"iana"},"application/vnd.familysearch.gedcom+zip":{source:"iana",compressible:!1},"application/vnd.fastcopy-disk-image":{source:"iana"},"application/vnd.fdf":{source:"iana",extensions:["fdf"]},"application/vnd.fdsn.mseed":{source:"iana",extensions:["mseed"]},"application/vnd.fdsn.seed":{source:"iana",extensions:["seed","dataless"]},"application/vnd.ffsns":{source:"iana"},"application/vnd.ficlab.flb+zip":{source:"iana",compressible:!1},"application/vnd.filmit.zfc":{source:"iana"},"application/vnd.fints":{source:"iana"},"application/vnd.firemonkeys.cloudcell":{source:"iana"},"application/vnd.flographit":{source:"iana",extensions:["gph"]},"application/vnd.fluxtime.clip":{source:"iana",extensions:["ftc"]},"application/vnd.font-fontforge-sfd":{source:"iana"},"application/vnd.framemaker":{source:"iana",extensions:["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{source:"iana",extensions:["fnc"]},"application/vnd.frogans.ltf":{source:"iana",extensions:["ltf"]},"application/vnd.fsc.weblaunch":{source:"iana",extensions:["fsc"]},"application/vnd.fujifilm.fb.docuworks":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.container":{source:"iana"},"application/vnd.fujifilm.fb.jfi+xml":{source:"iana",compressible:!0},"application/vnd.fujitsu.oasys":{source:"iana",extensions:["oas"]},"application/vnd.fujitsu.oasys2":{source:"iana",extensions:["oa2"]},"application/vnd.fujitsu.oasys3":{source:"iana",extensions:["oa3"]},"application/vnd.fujitsu.oasysgp":{source:"iana",extensions:["fg5"]},"application/vnd.fujitsu.oasysprs":{source:"iana",extensions:["bh2"]},"application/vnd.fujixerox.art-ex":{source:"iana"},"application/vnd.fujixerox.art4":{source:"iana"},"application/vnd.fujixerox.ddd":{source:"iana",extensions:["ddd"]},"application/vnd.fujixerox.docuworks":{source:"iana",extensions:["xdw"]},"application/vnd.fujixerox.docuworks.binder":{source:"iana",extensions:["xbd"]},"application/vnd.fujixerox.docuworks.container":{source:"iana"},"application/vnd.fujixerox.hbpl":{source:"iana"},"application/vnd.fut-misnet":{source:"iana"},"application/vnd.futoin+cbor":{source:"iana"},"application/vnd.futoin+json":{source:"iana",compressible:!0},"application/vnd.fuzzysheet":{source:"iana",extensions:["fzs"]},"application/vnd.genomatix.tuxedo":{source:"iana",extensions:["txd"]},"application/vnd.gentics.grd+json":{source:"iana",compressible:!0},"application/vnd.geo+json":{source:"iana",compressible:!0},"application/vnd.geocube+xml":{source:"iana",compressible:!0},"application/vnd.geogebra.file":{source:"iana",extensions:["ggb"]},"application/vnd.geogebra.slides":{source:"iana"},"application/vnd.geogebra.tool":{source:"iana",extensions:["ggt"]},"application/vnd.geometry-explorer":{source:"iana",extensions:["gex","gre"]},"application/vnd.geonext":{source:"iana",extensions:["gxt"]},"application/vnd.geoplan":{source:"iana",extensions:["g2w"]},"application/vnd.geospace":{source:"iana",extensions:["g3w"]},"application/vnd.gerber":{source:"iana"},"application/vnd.globalplatform.card-content-mgt":{source:"iana"},"application/vnd.globalplatform.card-content-mgt-response":{source:"iana"},"application/vnd.gmx":{source:"iana",extensions:["gmx"]},"application/vnd.google-apps.document":{compressible:!1,extensions:["gdoc"]},"application/vnd.google-apps.presentation":{compressible:!1,extensions:["gslides"]},"application/vnd.google-apps.spreadsheet":{compressible:!1,extensions:["gsheet"]},"application/vnd.google-earth.kml+xml":{source:"iana",compressible:!0,extensions:["kml"]},"application/vnd.google-earth.kmz":{source:"iana",compressible:!1,extensions:["kmz"]},"application/vnd.gov.sk.e-form+xml":{source:"iana",compressible:!0},"application/vnd.gov.sk.e-form+zip":{source:"iana",compressible:!1},"application/vnd.gov.sk.xmldatacontainer+xml":{source:"iana",compressible:!0},"application/vnd.grafeq":{source:"iana",extensions:["gqf","gqs"]},"application/vnd.gridmp":{source:"iana"},"application/vnd.groove-account":{source:"iana",extensions:["gac"]},"application/vnd.groove-help":{source:"iana",extensions:["ghf"]},"application/vnd.groove-identity-message":{source:"iana",extensions:["gim"]},"application/vnd.groove-injector":{source:"iana",extensions:["grv"]},"application/vnd.groove-tool-message":{source:"iana",extensions:["gtm"]},"application/vnd.groove-tool-template":{source:"iana",extensions:["tpl"]},"application/vnd.groove-vcard":{source:"iana",extensions:["vcg"]},"application/vnd.hal+json":{source:"iana",compressible:!0},"application/vnd.hal+xml":{source:"iana",compressible:!0,extensions:["hal"]},"application/vnd.handheld-entertainment+xml":{source:"iana",compressible:!0,extensions:["zmm"]},"application/vnd.hbci":{source:"iana",extensions:["hbci"]},"application/vnd.hc+json":{source:"iana",compressible:!0},"application/vnd.hcl-bireports":{source:"iana"},"application/vnd.hdt":{source:"iana"},"application/vnd.heroku+json":{source:"iana",compressible:!0},"application/vnd.hhe.lesson-player":{source:"iana",extensions:["les"]},"application/vnd.hl7cda+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.hl7v2+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.hp-hpgl":{source:"iana",extensions:["hpgl"]},"application/vnd.hp-hpid":{source:"iana",extensions:["hpid"]},"application/vnd.hp-hps":{source:"iana",extensions:["hps"]},"application/vnd.hp-jlyt":{source:"iana",extensions:["jlt"]},"application/vnd.hp-pcl":{source:"iana",extensions:["pcl"]},"application/vnd.hp-pclxl":{source:"iana",extensions:["pclxl"]},"application/vnd.httphone":{source:"iana"},"application/vnd.hydrostatix.sof-data":{source:"iana",extensions:["sfd-hdstx"]},"application/vnd.hyper+json":{source:"iana",compressible:!0},"application/vnd.hyper-item+json":{source:"iana",compressible:!0},"application/vnd.hyperdrive+json":{source:"iana",compressible:!0},"application/vnd.hzn-3d-crossword":{source:"iana"},"application/vnd.ibm.afplinedata":{source:"iana"},"application/vnd.ibm.electronic-media":{source:"iana"},"application/vnd.ibm.minipay":{source:"iana",extensions:["mpy"]},"application/vnd.ibm.modcap":{source:"iana",extensions:["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{source:"iana",extensions:["irm"]},"application/vnd.ibm.secure-container":{source:"iana",extensions:["sc"]},"application/vnd.iccprofile":{source:"iana",extensions:["icc","icm"]},"application/vnd.ieee.1905":{source:"iana"},"application/vnd.igloader":{source:"iana",extensions:["igl"]},"application/vnd.imagemeter.folder+zip":{source:"iana",compressible:!1},"application/vnd.imagemeter.image+zip":{source:"iana",compressible:!1},"application/vnd.immervision-ivp":{source:"iana",extensions:["ivp"]},"application/vnd.immervision-ivu":{source:"iana",extensions:["ivu"]},"application/vnd.ims.imsccv1p1":{source:"iana"},"application/vnd.ims.imsccv1p2":{source:"iana"},"application/vnd.ims.imsccv1p3":{source:"iana"},"application/vnd.ims.lis.v2.result+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy.id+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings.simple+json":{source:"iana",compressible:!0},"application/vnd.informedcontrol.rms+xml":{source:"iana",compressible:!0},"application/vnd.informix-visionary":{source:"iana"},"application/vnd.infotech.project":{source:"iana"},"application/vnd.infotech.project+xml":{source:"iana",compressible:!0},"application/vnd.innopath.wamp.notification":{source:"iana"},"application/vnd.insors.igm":{source:"iana",extensions:["igm"]},"application/vnd.intercon.formnet":{source:"iana",extensions:["xpw","xpx"]},"application/vnd.intergeo":{source:"iana",extensions:["i2g"]},"application/vnd.intertrust.digibox":{source:"iana"},"application/vnd.intertrust.nncp":{source:"iana"},"application/vnd.intu.qbo":{source:"iana",extensions:["qbo"]},"application/vnd.intu.qfx":{source:"iana",extensions:["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.conceptitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.knowledgeitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsmessage+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.packageitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.planningitem+xml":{source:"iana",compressible:!0},"application/vnd.ipunplugged.rcprofile":{source:"iana",extensions:["rcprofile"]},"application/vnd.irepository.package+xml":{source:"iana",compressible:!0,extensions:["irp"]},"application/vnd.is-xpr":{source:"iana",extensions:["xpr"]},"application/vnd.isac.fcs":{source:"iana",extensions:["fcs"]},"application/vnd.iso11783-10+zip":{source:"iana",compressible:!1},"application/vnd.jam":{source:"iana",extensions:["jam"]},"application/vnd.japannet-directory-service":{source:"iana"},"application/vnd.japannet-jpnstore-wakeup":{source:"iana"},"application/vnd.japannet-payment-wakeup":{source:"iana"},"application/vnd.japannet-registration":{source:"iana"},"application/vnd.japannet-registration-wakeup":{source:"iana"},"application/vnd.japannet-setstore-wakeup":{source:"iana"},"application/vnd.japannet-verification":{source:"iana"},"application/vnd.japannet-verification-wakeup":{source:"iana"},"application/vnd.jcp.javame.midlet-rms":{source:"iana",extensions:["rms"]},"application/vnd.jisp":{source:"iana",extensions:["jisp"]},"application/vnd.joost.joda-archive":{source:"iana",extensions:["joda"]},"application/vnd.jsk.isdn-ngn":{source:"iana"},"application/vnd.kahootz":{source:"iana",extensions:["ktz","ktr"]},"application/vnd.kde.karbon":{source:"iana",extensions:["karbon"]},"application/vnd.kde.kchart":{source:"iana",extensions:["chrt"]},"application/vnd.kde.kformula":{source:"iana",extensions:["kfo"]},"application/vnd.kde.kivio":{source:"iana",extensions:["flw"]},"application/vnd.kde.kontour":{source:"iana",extensions:["kon"]},"application/vnd.kde.kpresenter":{source:"iana",extensions:["kpr","kpt"]},"application/vnd.kde.kspread":{source:"iana",extensions:["ksp"]},"application/vnd.kde.kword":{source:"iana",extensions:["kwd","kwt"]},"application/vnd.kenameaapp":{source:"iana",extensions:["htke"]},"application/vnd.kidspiration":{source:"iana",extensions:["kia"]},"application/vnd.kinar":{source:"iana",extensions:["kne","knp"]},"application/vnd.koan":{source:"iana",extensions:["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{source:"iana",extensions:["sse"]},"application/vnd.las":{source:"iana"},"application/vnd.las.las+json":{source:"iana",compressible:!0},"application/vnd.las.las+xml":{source:"iana",compressible:!0,extensions:["lasxml"]},"application/vnd.laszip":{source:"iana"},"application/vnd.leap+json":{source:"iana",compressible:!0},"application/vnd.liberty-request+xml":{source:"iana",compressible:!0},"application/vnd.llamagraphics.life-balance.desktop":{source:"iana",extensions:["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{source:"iana",compressible:!0,extensions:["lbe"]},"application/vnd.logipipe.circuit+zip":{source:"iana",compressible:!1},"application/vnd.loom":{source:"iana"},"application/vnd.lotus-1-2-3":{source:"iana",extensions:["123"]},"application/vnd.lotus-approach":{source:"iana",extensions:["apr"]},"application/vnd.lotus-freelance":{source:"iana",extensions:["pre"]},"application/vnd.lotus-notes":{source:"iana",extensions:["nsf"]},"application/vnd.lotus-organizer":{source:"iana",extensions:["org"]},"application/vnd.lotus-screencam":{source:"iana",extensions:["scm"]},"application/vnd.lotus-wordpro":{source:"iana",extensions:["lwp"]},"application/vnd.macports.portpkg":{source:"iana",extensions:["portpkg"]},"application/vnd.mapbox-vector-tile":{source:"iana",extensions:["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.conftoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.license+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.mdcf":{source:"iana"},"application/vnd.mason+json":{source:"iana",compressible:!0},"application/vnd.maxar.archive.3tz+zip":{source:"iana",compressible:!1},"application/vnd.maxmind.maxmind-db":{source:"iana"},"application/vnd.mcd":{source:"iana",extensions:["mcd"]},"application/vnd.medcalcdata":{source:"iana",extensions:["mc1"]},"application/vnd.mediastation.cdkey":{source:"iana",extensions:["cdkey"]},"application/vnd.meridian-slingshot":{source:"iana"},"application/vnd.mfer":{source:"iana",extensions:["mwf"]},"application/vnd.mfmp":{source:"iana",extensions:["mfm"]},"application/vnd.micro+json":{source:"iana",compressible:!0},"application/vnd.micrografx.flo":{source:"iana",extensions:["flo"]},"application/vnd.micrografx.igx":{source:"iana",extensions:["igx"]},"application/vnd.microsoft.portable-executable":{source:"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{source:"iana"},"application/vnd.miele+json":{source:"iana",compressible:!0},"application/vnd.mif":{source:"iana",extensions:["mif"]},"application/vnd.minisoft-hp3000-save":{source:"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{source:"iana"},"application/vnd.mobius.daf":{source:"iana",extensions:["daf"]},"application/vnd.mobius.dis":{source:"iana",extensions:["dis"]},"application/vnd.mobius.mbk":{source:"iana",extensions:["mbk"]},"application/vnd.mobius.mqy":{source:"iana",extensions:["mqy"]},"application/vnd.mobius.msl":{source:"iana",extensions:["msl"]},"application/vnd.mobius.plc":{source:"iana",extensions:["plc"]},"application/vnd.mobius.txf":{source:"iana",extensions:["txf"]},"application/vnd.mophun.application":{source:"iana",extensions:["mpn"]},"application/vnd.mophun.certificate":{source:"iana",extensions:["mpc"]},"application/vnd.motorola.flexsuite":{source:"iana"},"application/vnd.motorola.flexsuite.adsi":{source:"iana"},"application/vnd.motorola.flexsuite.fis":{source:"iana"},"application/vnd.motorola.flexsuite.gotap":{source:"iana"},"application/vnd.motorola.flexsuite.kmr":{source:"iana"},"application/vnd.motorola.flexsuite.ttc":{source:"iana"},"application/vnd.motorola.flexsuite.wem":{source:"iana"},"application/vnd.motorola.iprm":{source:"iana"},"application/vnd.mozilla.xul+xml":{source:"iana",compressible:!0,extensions:["xul"]},"application/vnd.ms-3mfdocument":{source:"iana"},"application/vnd.ms-artgalry":{source:"iana",extensions:["cil"]},"application/vnd.ms-asf":{source:"iana"},"application/vnd.ms-cab-compressed":{source:"iana",extensions:["cab"]},"application/vnd.ms-color.iccprofile":{source:"apache"},"application/vnd.ms-excel":{source:"iana",compressible:!1,extensions:["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{source:"iana",extensions:["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{source:"iana",extensions:["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{source:"iana",extensions:["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{source:"iana",extensions:["xltm"]},"application/vnd.ms-fontobject":{source:"iana",compressible:!0,extensions:["eot"]},"application/vnd.ms-htmlhelp":{source:"iana",extensions:["chm"]},"application/vnd.ms-ims":{source:"iana",extensions:["ims"]},"application/vnd.ms-lrm":{source:"iana",extensions:["lrm"]},"application/vnd.ms-office.activex+xml":{source:"iana",compressible:!0},"application/vnd.ms-officetheme":{source:"iana",extensions:["thmx"]},"application/vnd.ms-opentype":{source:"apache",compressible:!0},"application/vnd.ms-outlook":{compressible:!1,extensions:["msg"]},"application/vnd.ms-package.obfuscated-opentype":{source:"apache"},"application/vnd.ms-pki.seccat":{source:"apache",extensions:["cat"]},"application/vnd.ms-pki.stl":{source:"apache",extensions:["stl"]},"application/vnd.ms-playready.initiator+xml":{source:"iana",compressible:!0},"application/vnd.ms-powerpoint":{source:"iana",compressible:!1,extensions:["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{source:"iana",extensions:["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{source:"iana",extensions:["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{source:"iana",extensions:["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{source:"iana",extensions:["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{source:"iana",extensions:["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{source:"iana",compressible:!0},"application/vnd.ms-printing.printticket+xml":{source:"apache",compressible:!0},"application/vnd.ms-printschematicket+xml":{source:"iana",compressible:!0},"application/vnd.ms-project":{source:"iana",extensions:["mpp","mpt"]},"application/vnd.ms-tnef":{source:"iana"},"application/vnd.ms-windows.devicepairing":{source:"iana"},"application/vnd.ms-windows.nwprinting.oob":{source:"iana"},"application/vnd.ms-windows.printerpairing":{source:"iana"},"application/vnd.ms-windows.wsd.oob":{source:"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.lic-resp":{source:"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.meter-resp":{source:"iana"},"application/vnd.ms-word.document.macroenabled.12":{source:"iana",extensions:["docm"]},"application/vnd.ms-word.template.macroenabled.12":{source:"iana",extensions:["dotm"]},"application/vnd.ms-works":{source:"iana",extensions:["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{source:"iana",extensions:["wpl"]},"application/vnd.ms-xpsdocument":{source:"iana",compressible:!1,extensions:["xps"]},"application/vnd.msa-disk-image":{source:"iana"},"application/vnd.mseq":{source:"iana",extensions:["mseq"]},"application/vnd.msign":{source:"iana"},"application/vnd.multiad.creator":{source:"iana"},"application/vnd.multiad.creator.cif":{source:"iana"},"application/vnd.music-niff":{source:"iana"},"application/vnd.musician":{source:"iana",extensions:["mus"]},"application/vnd.muvee.style":{source:"iana",extensions:["msty"]},"application/vnd.mynfc":{source:"iana",extensions:["taglet"]},"application/vnd.nacamar.ybrid+json":{source:"iana",compressible:!0},"application/vnd.ncd.control":{source:"iana"},"application/vnd.ncd.reference":{source:"iana"},"application/vnd.nearst.inv+json":{source:"iana",compressible:!0},"application/vnd.nebumind.line":{source:"iana"},"application/vnd.nervana":{source:"iana"},"application/vnd.netfpx":{source:"iana"},"application/vnd.neurolanguage.nlu":{source:"iana",extensions:["nlu"]},"application/vnd.nimn":{source:"iana"},"application/vnd.nintendo.nitro.rom":{source:"iana"},"application/vnd.nintendo.snes.rom":{source:"iana"},"application/vnd.nitf":{source:"iana",extensions:["ntf","nitf"]},"application/vnd.noblenet-directory":{source:"iana",extensions:["nnd"]},"application/vnd.noblenet-sealer":{source:"iana",extensions:["nns"]},"application/vnd.noblenet-web":{source:"iana",extensions:["nnw"]},"application/vnd.nokia.catalogs":{source:"iana"},"application/vnd.nokia.conml+wbxml":{source:"iana"},"application/vnd.nokia.conml+xml":{source:"iana",compressible:!0},"application/vnd.nokia.iptv.config+xml":{source:"iana",compressible:!0},"application/vnd.nokia.isds-radio-presets":{source:"iana"},"application/vnd.nokia.landmark+wbxml":{source:"iana"},"application/vnd.nokia.landmark+xml":{source:"iana",compressible:!0},"application/vnd.nokia.landmarkcollection+xml":{source:"iana",compressible:!0},"application/vnd.nokia.n-gage.ac+xml":{source:"iana",compressible:!0,extensions:["ac"]},"application/vnd.nokia.n-gage.data":{source:"iana",extensions:["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{source:"iana",extensions:["n-gage"]},"application/vnd.nokia.ncd":{source:"iana"},"application/vnd.nokia.pcd+wbxml":{source:"iana"},"application/vnd.nokia.pcd+xml":{source:"iana",compressible:!0},"application/vnd.nokia.radio-preset":{source:"iana",extensions:["rpst"]},"application/vnd.nokia.radio-presets":{source:"iana",extensions:["rpss"]},"application/vnd.novadigm.edm":{source:"iana",extensions:["edm"]},"application/vnd.novadigm.edx":{source:"iana",extensions:["edx"]},"application/vnd.novadigm.ext":{source:"iana",extensions:["ext"]},"application/vnd.ntt-local.content-share":{source:"iana"},"application/vnd.ntt-local.file-transfer":{source:"iana"},"application/vnd.ntt-local.ogw_remote-access":{source:"iana"},"application/vnd.ntt-local.sip-ta_remote":{source:"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{source:"iana"},"application/vnd.oasis.opendocument.chart":{source:"iana",extensions:["odc"]},"application/vnd.oasis.opendocument.chart-template":{source:"iana",extensions:["otc"]},"application/vnd.oasis.opendocument.database":{source:"iana",extensions:["odb"]},"application/vnd.oasis.opendocument.formula":{source:"iana",extensions:["odf"]},"application/vnd.oasis.opendocument.formula-template":{source:"iana",extensions:["odft"]},"application/vnd.oasis.opendocument.graphics":{source:"iana",compressible:!1,extensions:["odg"]},"application/vnd.oasis.opendocument.graphics-template":{source:"iana",extensions:["otg"]},"application/vnd.oasis.opendocument.image":{source:"iana",extensions:["odi"]},"application/vnd.oasis.opendocument.image-template":{source:"iana",extensions:["oti"]},"application/vnd.oasis.opendocument.presentation":{source:"iana",compressible:!1,extensions:["odp"]},"application/vnd.oasis.opendocument.presentation-template":{source:"iana",extensions:["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{source:"iana",compressible:!1,extensions:["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{source:"iana",extensions:["ots"]},"application/vnd.oasis.opendocument.text":{source:"iana",compressible:!1,extensions:["odt"]},"application/vnd.oasis.opendocument.text-master":{source:"iana",extensions:["odm"]},"application/vnd.oasis.opendocument.text-template":{source:"iana",extensions:["ott"]},"application/vnd.oasis.opendocument.text-web":{source:"iana",extensions:["oth"]},"application/vnd.obn":{source:"iana"},"application/vnd.ocf+cbor":{source:"iana"},"application/vnd.oci.image.manifest.v1+json":{source:"iana",compressible:!0},"application/vnd.oftn.l10n+json":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessdownload+xml":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessstreaming+xml":{source:"iana",compressible:!0},"application/vnd.oipf.cspg-hexbinary":{source:"iana"},"application/vnd.oipf.dae.svg+xml":{source:"iana",compressible:!0},"application/vnd.oipf.dae.xhtml+xml":{source:"iana",compressible:!0},"application/vnd.oipf.mippvcontrolmessage+xml":{source:"iana",compressible:!0},"application/vnd.oipf.pae.gem":{source:"iana"},"application/vnd.oipf.spdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.oipf.spdlist+xml":{source:"iana",compressible:!0},"application/vnd.oipf.ueprofile+xml":{source:"iana",compressible:!0},"application/vnd.oipf.userprofile+xml":{source:"iana",compressible:!0},"application/vnd.olpc-sugar":{source:"iana",extensions:["xo"]},"application/vnd.oma-scws-config":{source:"iana"},"application/vnd.oma-scws-http-request":{source:"iana"},"application/vnd.oma-scws-http-response":{source:"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.drm-trigger+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.imd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.ltkm":{source:"iana"},"application/vnd.oma.bcast.notification+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.provisioningtrigger":{source:"iana"},"application/vnd.oma.bcast.sgboot":{source:"iana"},"application/vnd.oma.bcast.sgdd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.sgdu":{source:"iana"},"application/vnd.oma.bcast.simple-symbol-container":{source:"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.sprov+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.stkm":{source:"iana"},"application/vnd.oma.cab-address-book+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-feature-handler+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-pcc+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-subs-invite+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-user-prefs+xml":{source:"iana",compressible:!0},"application/vnd.oma.dcd":{source:"iana"},"application/vnd.oma.dcdc":{source:"iana"},"application/vnd.oma.dd2+xml":{source:"iana",compressible:!0,extensions:["dd2"]},"application/vnd.oma.drm.risd+xml":{source:"iana",compressible:!0},"application/vnd.oma.group-usage-list+xml":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+cbor":{source:"iana"},"application/vnd.oma.lwm2m+json":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+tlv":{source:"iana"},"application/vnd.oma.pal+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.detailed-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.final-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.groups+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.invocation-descriptor+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.optimized-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.push":{source:"iana"},"application/vnd.oma.scidm.messages+xml":{source:"iana",compressible:!0},"application/vnd.oma.xcap-directory+xml":{source:"iana",compressible:!0},"application/vnd.omads-email+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-file+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-folder+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omaloc-supl-init":{source:"iana"},"application/vnd.onepager":{source:"iana"},"application/vnd.onepagertamp":{source:"iana"},"application/vnd.onepagertamx":{source:"iana"},"application/vnd.onepagertat":{source:"iana"},"application/vnd.onepagertatp":{source:"iana"},"application/vnd.onepagertatx":{source:"iana"},"application/vnd.openblox.game+xml":{source:"iana",compressible:!0,extensions:["obgx"]},"application/vnd.openblox.game-binary":{source:"iana"},"application/vnd.openeye.oeb":{source:"iana"},"application/vnd.openofficeorg.extension":{source:"apache",extensions:["oxt"]},"application/vnd.openstreetmap.data+xml":{source:"iana",compressible:!0,extensions:["osm"]},"application/vnd.opentimestamps.ots":{source:"iana"},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawing+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{source:"iana",compressible:!1,extensions:["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slide":{source:"iana",extensions:["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{source:"iana",extensions:["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.template":{source:"iana",extensions:["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{source:"iana",compressible:!1,extensions:["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{source:"iana",extensions:["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.theme+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.vmldrawing":{source:"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{source:"iana",compressible:!1,extensions:["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{source:"iana",extensions:["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.core-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.relationships+xml":{source:"iana",compressible:!0},"application/vnd.oracle.resource+json":{source:"iana",compressible:!0},"application/vnd.orange.indata":{source:"iana"},"application/vnd.osa.netdeploy":{source:"iana"},"application/vnd.osgeo.mapguide.package":{source:"iana",extensions:["mgp"]},"application/vnd.osgi.bundle":{source:"iana"},"application/vnd.osgi.dp":{source:"iana",extensions:["dp"]},"application/vnd.osgi.subsystem":{source:"iana",extensions:["esa"]},"application/vnd.otps.ct-kip+xml":{source:"iana",compressible:!0},"application/vnd.oxli.countgraph":{source:"iana"},"application/vnd.pagerduty+json":{source:"iana",compressible:!0},"application/vnd.palm":{source:"iana",extensions:["pdb","pqa","oprc"]},"application/vnd.panoply":{source:"iana"},"application/vnd.paos.xml":{source:"iana"},"application/vnd.patentdive":{source:"iana"},"application/vnd.patientecommsdoc":{source:"iana"},"application/vnd.pawaafile":{source:"iana",extensions:["paw"]},"application/vnd.pcos":{source:"iana"},"application/vnd.pg.format":{source:"iana",extensions:["str"]},"application/vnd.pg.osasli":{source:"iana",extensions:["ei6"]},"application/vnd.piaccess.application-licence":{source:"iana"},"application/vnd.picsel":{source:"iana",extensions:["efif"]},"application/vnd.pmi.widget":{source:"iana",extensions:["wg"]},"application/vnd.poc.group-advertisement+xml":{source:"iana",compressible:!0},"application/vnd.pocketlearn":{source:"iana",extensions:["plf"]},"application/vnd.powerbuilder6":{source:"iana",extensions:["pbd"]},"application/vnd.powerbuilder6-s":{source:"iana"},"application/vnd.powerbuilder7":{source:"iana"},"application/vnd.powerbuilder7-s":{source:"iana"},"application/vnd.powerbuilder75":{source:"iana"},"application/vnd.powerbuilder75-s":{source:"iana"},"application/vnd.preminet":{source:"iana"},"application/vnd.previewsystems.box":{source:"iana",extensions:["box"]},"application/vnd.proteus.magazine":{source:"iana",extensions:["mgz"]},"application/vnd.psfs":{source:"iana"},"application/vnd.publishare-delta-tree":{source:"iana",extensions:["qps"]},"application/vnd.pvi.ptid1":{source:"iana",extensions:["ptid"]},"application/vnd.pwg-multiplexed":{source:"iana"},"application/vnd.pwg-xhtml-print+xml":{source:"iana",compressible:!0},"application/vnd.qualcomm.brew-app-res":{source:"iana"},"application/vnd.quarantainenet":{source:"iana"},"application/vnd.quark.quarkxpress":{source:"iana",extensions:["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{source:"iana"},"application/vnd.radisys.moml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conn+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-stream+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-base+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-detect+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-group+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-speech+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-transform+xml":{source:"iana",compressible:!0},"application/vnd.rainstor.data":{source:"iana"},"application/vnd.rapid":{source:"iana"},"application/vnd.rar":{source:"iana",extensions:["rar"]},"application/vnd.realvnc.bed":{source:"iana",extensions:["bed"]},"application/vnd.recordare.musicxml":{source:"iana",extensions:["mxl"]},"application/vnd.recordare.musicxml+xml":{source:"iana",compressible:!0,extensions:["musicxml"]},"application/vnd.renlearn.rlprint":{source:"iana"},"application/vnd.resilient.logic":{source:"iana"},"application/vnd.restful+json":{source:"iana",compressible:!0},"application/vnd.rig.cryptonote":{source:"iana",extensions:["cryptonote"]},"application/vnd.rim.cod":{source:"apache",extensions:["cod"]},"application/vnd.rn-realmedia":{source:"apache",extensions:["rm"]},"application/vnd.rn-realmedia-vbr":{source:"apache",extensions:["rmvb"]},"application/vnd.route66.link66+xml":{source:"iana",compressible:!0,extensions:["link66"]},"application/vnd.rs-274x":{source:"iana"},"application/vnd.ruckus.download":{source:"iana"},"application/vnd.s3sms":{source:"iana"},"application/vnd.sailingtracker.track":{source:"iana",extensions:["st"]},"application/vnd.sar":{source:"iana"},"application/vnd.sbm.cid":{source:"iana"},"application/vnd.sbm.mid2":{source:"iana"},"application/vnd.scribus":{source:"iana"},"application/vnd.sealed.3df":{source:"iana"},"application/vnd.sealed.csf":{source:"iana"},"application/vnd.sealed.doc":{source:"iana"},"application/vnd.sealed.eml":{source:"iana"},"application/vnd.sealed.mht":{source:"iana"},"application/vnd.sealed.net":{source:"iana"},"application/vnd.sealed.ppt":{source:"iana"},"application/vnd.sealed.tiff":{source:"iana"},"application/vnd.sealed.xls":{source:"iana"},"application/vnd.sealedmedia.softseal.html":{source:"iana"},"application/vnd.sealedmedia.softseal.pdf":{source:"iana"},"application/vnd.seemail":{source:"iana",extensions:["see"]},"application/vnd.seis+json":{source:"iana",compressible:!0},"application/vnd.sema":{source:"iana",extensions:["sema"]},"application/vnd.semd":{source:"iana",extensions:["semd"]},"application/vnd.semf":{source:"iana",extensions:["semf"]},"application/vnd.shade-save-file":{source:"iana"},"application/vnd.shana.informed.formdata":{source:"iana",extensions:["ifm"]},"application/vnd.shana.informed.formtemplate":{source:"iana",extensions:["itp"]},"application/vnd.shana.informed.interchange":{source:"iana",extensions:["iif"]},"application/vnd.shana.informed.package":{source:"iana",extensions:["ipk"]},"application/vnd.shootproof+json":{source:"iana",compressible:!0},"application/vnd.shopkick+json":{source:"iana",compressible:!0},"application/vnd.shp":{source:"iana"},"application/vnd.shx":{source:"iana"},"application/vnd.sigrok.session":{source:"iana"},"application/vnd.simtech-mindmapper":{source:"iana",extensions:["twd","twds"]},"application/vnd.siren+json":{source:"iana",compressible:!0},"application/vnd.smaf":{source:"iana",extensions:["mmf"]},"application/vnd.smart.notebook":{source:"iana"},"application/vnd.smart.teacher":{source:"iana",extensions:["teacher"]},"application/vnd.snesdev-page-table":{source:"iana"},"application/vnd.software602.filler.form+xml":{source:"iana",compressible:!0,extensions:["fo"]},"application/vnd.software602.filler.form-xml-zip":{source:"iana"},"application/vnd.solent.sdkm+xml":{source:"iana",compressible:!0,extensions:["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{source:"iana",extensions:["dxp"]},"application/vnd.spotfire.sfs":{source:"iana",extensions:["sfs"]},"application/vnd.sqlite3":{source:"iana"},"application/vnd.sss-cod":{source:"iana"},"application/vnd.sss-dtf":{source:"iana"},"application/vnd.sss-ntf":{source:"iana"},"application/vnd.stardivision.calc":{source:"apache",extensions:["sdc"]},"application/vnd.stardivision.draw":{source:"apache",extensions:["sda"]},"application/vnd.stardivision.impress":{source:"apache",extensions:["sdd"]},"application/vnd.stardivision.math":{source:"apache",extensions:["smf"]},"application/vnd.stardivision.writer":{source:"apache",extensions:["sdw","vor"]},"application/vnd.stardivision.writer-global":{source:"apache",extensions:["sgl"]},"application/vnd.stepmania.package":{source:"iana",extensions:["smzip"]},"application/vnd.stepmania.stepchart":{source:"iana",extensions:["sm"]},"application/vnd.street-stream":{source:"iana"},"application/vnd.sun.wadl+xml":{source:"iana",compressible:!0,extensions:["wadl"]},"application/vnd.sun.xml.calc":{source:"apache",extensions:["sxc"]},"application/vnd.sun.xml.calc.template":{source:"apache",extensions:["stc"]},"application/vnd.sun.xml.draw":{source:"apache",extensions:["sxd"]},"application/vnd.sun.xml.draw.template":{source:"apache",extensions:["std"]},"application/vnd.sun.xml.impress":{source:"apache",extensions:["sxi"]},"application/vnd.sun.xml.impress.template":{source:"apache",extensions:["sti"]},"application/vnd.sun.xml.math":{source:"apache",extensions:["sxm"]},"application/vnd.sun.xml.writer":{source:"apache",extensions:["sxw"]},"application/vnd.sun.xml.writer.global":{source:"apache",extensions:["sxg"]},"application/vnd.sun.xml.writer.template":{source:"apache",extensions:["stw"]},"application/vnd.sus-calendar":{source:"iana",extensions:["sus","susp"]},"application/vnd.svd":{source:"iana",extensions:["svd"]},"application/vnd.swiftview-ics":{source:"iana"},"application/vnd.sycle+xml":{source:"iana",compressible:!0},"application/vnd.syft+json":{source:"iana",compressible:!0},"application/vnd.symbian.install":{source:"apache",extensions:["sis","sisx"]},"application/vnd.syncml+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xsm"]},"application/vnd.syncml.dm+wbxml":{source:"iana",charset:"UTF-8",extensions:["bdm"]},"application/vnd.syncml.dm+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xdm"]},"application/vnd.syncml.dm.notification":{source:"iana"},"application/vnd.syncml.dmddf+wbxml":{source:"iana"},"application/vnd.syncml.dmddf+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{source:"iana"},"application/vnd.syncml.dmtnds+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.syncml.ds.notification":{source:"iana"},"application/vnd.tableschema+json":{source:"iana",compressible:!0},"application/vnd.tao.intent-module-archive":{source:"iana",extensions:["tao"]},"application/vnd.tcpdump.pcap":{source:"iana",extensions:["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{source:"iana",compressible:!0},"application/vnd.tmd.mediaflex.api+xml":{source:"iana",compressible:!0},"application/vnd.tml":{source:"iana"},"application/vnd.tmobile-livetv":{source:"iana",extensions:["tmo"]},"application/vnd.tri.onesource":{source:"iana"},"application/vnd.trid.tpt":{source:"iana",extensions:["tpt"]},"application/vnd.triscape.mxs":{source:"iana",extensions:["mxs"]},"application/vnd.trueapp":{source:"iana",extensions:["tra"]},"application/vnd.truedoc":{source:"iana"},"application/vnd.ubisoft.webplayer":{source:"iana"},"application/vnd.ufdl":{source:"iana",extensions:["ufd","ufdl"]},"application/vnd.uiq.theme":{source:"iana",extensions:["utz"]},"application/vnd.umajin":{source:"iana",extensions:["umj"]},"application/vnd.unity":{source:"iana",extensions:["unityweb"]},"application/vnd.uoml+xml":{source:"iana",compressible:!0,extensions:["uoml"]},"application/vnd.uplanet.alert":{source:"iana"},"application/vnd.uplanet.alert-wbxml":{source:"iana"},"application/vnd.uplanet.bearer-choice":{source:"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{source:"iana"},"application/vnd.uplanet.cacheop":{source:"iana"},"application/vnd.uplanet.cacheop-wbxml":{source:"iana"},"application/vnd.uplanet.channel":{source:"iana"},"application/vnd.uplanet.channel-wbxml":{source:"iana"},"application/vnd.uplanet.list":{source:"iana"},"application/vnd.uplanet.list-wbxml":{source:"iana"},"application/vnd.uplanet.listcmd":{source:"iana"},"application/vnd.uplanet.listcmd-wbxml":{source:"iana"},"application/vnd.uplanet.signal":{source:"iana"},"application/vnd.uri-map":{source:"iana"},"application/vnd.valve.source.material":{source:"iana"},"application/vnd.vcx":{source:"iana",extensions:["vcx"]},"application/vnd.vd-study":{source:"iana"},"application/vnd.vectorworks":{source:"iana"},"application/vnd.vel+json":{source:"iana",compressible:!0},"application/vnd.verimatrix.vcas":{source:"iana"},"application/vnd.veritone.aion+json":{source:"iana",compressible:!0},"application/vnd.veryant.thin":{source:"iana"},"application/vnd.ves.encrypted":{source:"iana"},"application/vnd.vidsoft.vidconference":{source:"iana"},"application/vnd.visio":{source:"iana",extensions:["vsd","vst","vss","vsw"]},"application/vnd.visionary":{source:"iana",extensions:["vis"]},"application/vnd.vividence.scriptfile":{source:"iana"},"application/vnd.vsf":{source:"iana",extensions:["vsf"]},"application/vnd.wap.sic":{source:"iana"},"application/vnd.wap.slc":{source:"iana"},"application/vnd.wap.wbxml":{source:"iana",charset:"UTF-8",extensions:["wbxml"]},"application/vnd.wap.wmlc":{source:"iana",extensions:["wmlc"]},"application/vnd.wap.wmlscriptc":{source:"iana",extensions:["wmlsc"]},"application/vnd.webturbo":{source:"iana",extensions:["wtb"]},"application/vnd.wfa.dpp":{source:"iana"},"application/vnd.wfa.p2p":{source:"iana"},"application/vnd.wfa.wsc":{source:"iana"},"application/vnd.windows.devicepairing":{source:"iana"},"application/vnd.wmc":{source:"iana"},"application/vnd.wmf.bootstrap":{source:"iana"},"application/vnd.wolfram.mathematica":{source:"iana"},"application/vnd.wolfram.mathematica.package":{source:"iana"},"application/vnd.wolfram.player":{source:"iana",extensions:["nbp"]},"application/vnd.wordperfect":{source:"iana",extensions:["wpd"]},"application/vnd.wqd":{source:"iana",extensions:["wqd"]},"application/vnd.wrq-hp3000-labelled":{source:"iana"},"application/vnd.wt.stf":{source:"iana",extensions:["stf"]},"application/vnd.wv.csp+wbxml":{source:"iana"},"application/vnd.wv.csp+xml":{source:"iana",compressible:!0},"application/vnd.wv.ssp+xml":{source:"iana",compressible:!0},"application/vnd.xacml+json":{source:"iana",compressible:!0},"application/vnd.xara":{source:"iana",extensions:["xar"]},"application/vnd.xfdl":{source:"iana",extensions:["xfdl"]},"application/vnd.xfdl.webform":{source:"iana"},"application/vnd.xmi+xml":{source:"iana",compressible:!0},"application/vnd.xmpie.cpkg":{source:"iana"},"application/vnd.xmpie.dpkg":{source:"iana"},"application/vnd.xmpie.plan":{source:"iana"},"application/vnd.xmpie.ppkg":{source:"iana"},"application/vnd.xmpie.xlim":{source:"iana"},"application/vnd.yamaha.hv-dic":{source:"iana",extensions:["hvd"]},"application/vnd.yamaha.hv-script":{source:"iana",extensions:["hvs"]},"application/vnd.yamaha.hv-voice":{source:"iana",extensions:["hvp"]},"application/vnd.yamaha.openscoreformat":{source:"iana",extensions:["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{source:"iana",compressible:!0,extensions:["osfpvg"]},"application/vnd.yamaha.remote-setup":{source:"iana"},"application/vnd.yamaha.smaf-audio":{source:"iana",extensions:["saf"]},"application/vnd.yamaha.smaf-phrase":{source:"iana",extensions:["spf"]},"application/vnd.yamaha.through-ngn":{source:"iana"},"application/vnd.yamaha.tunnel-udpencap":{source:"iana"},"application/vnd.yaoweme":{source:"iana"},"application/vnd.yellowriver-custom-menu":{source:"iana",extensions:["cmp"]},"application/vnd.youtube.yt":{source:"iana"},"application/vnd.zul":{source:"iana",extensions:["zir","zirz"]},"application/vnd.zzazz.deck+xml":{source:"iana",compressible:!0,extensions:["zaz"]},"application/voicexml+xml":{source:"iana",compressible:!0,extensions:["vxml"]},"application/voucher-cms+json":{source:"iana",compressible:!0},"application/vq-rtcpxr":{source:"iana"},"application/wasm":{source:"iana",compressible:!0,extensions:["wasm"]},"application/watcherinfo+xml":{source:"iana",compressible:!0,extensions:["wif"]},"application/webpush-options+json":{source:"iana",compressible:!0},"application/whoispp-query":{source:"iana"},"application/whoispp-response":{source:"iana"},"application/widget":{source:"iana",extensions:["wgt"]},"application/winhlp":{source:"apache",extensions:["hlp"]},"application/wita":{source:"iana"},"application/wordperfect5.1":{source:"iana"},"application/wsdl+xml":{source:"iana",compressible:!0,extensions:["wsdl"]},"application/wspolicy+xml":{source:"iana",compressible:!0,extensions:["wspolicy"]},"application/x-7z-compressed":{source:"apache",compressible:!1,extensions:["7z"]},"application/x-abiword":{source:"apache",extensions:["abw"]},"application/x-ace-compressed":{source:"apache",extensions:["ace"]},"application/x-amf":{source:"apache"},"application/x-apple-diskimage":{source:"apache",extensions:["dmg"]},"application/x-arj":{compressible:!1,extensions:["arj"]},"application/x-authorware-bin":{source:"apache",extensions:["aab","x32","u32","vox"]},"application/x-authorware-map":{source:"apache",extensions:["aam"]},"application/x-authorware-seg":{source:"apache",extensions:["aas"]},"application/x-bcpio":{source:"apache",extensions:["bcpio"]},"application/x-bdoc":{compressible:!1,extensions:["bdoc"]},"application/x-bittorrent":{source:"apache",extensions:["torrent"]},"application/x-blorb":{source:"apache",extensions:["blb","blorb"]},"application/x-bzip":{source:"apache",compressible:!1,extensions:["bz"]},"application/x-bzip2":{source:"apache",compressible:!1,extensions:["bz2","boz"]},"application/x-cbr":{source:"apache",extensions:["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{source:"apache",extensions:["vcd"]},"application/x-cfs-compressed":{source:"apache",extensions:["cfs"]},"application/x-chat":{source:"apache",extensions:["chat"]},"application/x-chess-pgn":{source:"apache",extensions:["pgn"]},"application/x-chrome-extension":{extensions:["crx"]},"application/x-cocoa":{source:"nginx",extensions:["cco"]},"application/x-compress":{source:"apache"},"application/x-conference":{source:"apache",extensions:["nsc"]},"application/x-cpio":{source:"apache",extensions:["cpio"]},"application/x-csh":{source:"apache",extensions:["csh"]},"application/x-deb":{compressible:!1},"application/x-debian-package":{source:"apache",extensions:["deb","udeb"]},"application/x-dgc-compressed":{source:"apache",extensions:["dgc"]},"application/x-director":{source:"apache",extensions:["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{source:"apache",extensions:["wad"]},"application/x-dtbncx+xml":{source:"apache",compressible:!0,extensions:["ncx"]},"application/x-dtbook+xml":{source:"apache",compressible:!0,extensions:["dtb"]},"application/x-dtbresource+xml":{source:"apache",compressible:!0,extensions:["res"]},"application/x-dvi":{source:"apache",compressible:!1,extensions:["dvi"]},"application/x-envoy":{source:"apache",extensions:["evy"]},"application/x-eva":{source:"apache",extensions:["eva"]},"application/x-font-bdf":{source:"apache",extensions:["bdf"]},"application/x-font-dos":{source:"apache"},"application/x-font-framemaker":{source:"apache"},"application/x-font-ghostscript":{source:"apache",extensions:["gsf"]},"application/x-font-libgrx":{source:"apache"},"application/x-font-linux-psf":{source:"apache",extensions:["psf"]},"application/x-font-pcf":{source:"apache",extensions:["pcf"]},"application/x-font-snf":{source:"apache",extensions:["snf"]},"application/x-font-speedo":{source:"apache"},"application/x-font-sunos-news":{source:"apache"},"application/x-font-type1":{source:"apache",extensions:["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{source:"apache"},"application/x-freearc":{source:"apache",extensions:["arc"]},"application/x-futuresplash":{source:"apache",extensions:["spl"]},"application/x-gca-compressed":{source:"apache",extensions:["gca"]},"application/x-glulx":{source:"apache",extensions:["ulx"]},"application/x-gnumeric":{source:"apache",extensions:["gnumeric"]},"application/x-gramps-xml":{source:"apache",extensions:["gramps"]},"application/x-gtar":{source:"apache",extensions:["gtar"]},"application/x-gzip":{source:"apache"},"application/x-hdf":{source:"apache",extensions:["hdf"]},"application/x-httpd-php":{compressible:!0,extensions:["php"]},"application/x-install-instructions":{source:"apache",extensions:["install"]},"application/x-iso9660-image":{source:"apache",extensions:["iso"]},"application/x-iwork-keynote-sffkey":{extensions:["key"]},"application/x-iwork-numbers-sffnumbers":{extensions:["numbers"]},"application/x-iwork-pages-sffpages":{extensions:["pages"]},"application/x-java-archive-diff":{source:"nginx",extensions:["jardiff"]},"application/x-java-jnlp-file":{source:"apache",compressible:!1,extensions:["jnlp"]},"application/x-javascript":{compressible:!0},"application/x-keepass2":{extensions:["kdbx"]},"application/x-latex":{source:"apache",compressible:!1,extensions:["latex"]},"application/x-lua-bytecode":{extensions:["luac"]},"application/x-lzh-compressed":{source:"apache",extensions:["lzh","lha"]},"application/x-makeself":{source:"nginx",extensions:["run"]},"application/x-mie":{source:"apache",extensions:["mie"]},"application/x-mobipocket-ebook":{source:"apache",extensions:["prc","mobi"]},"application/x-mpegurl":{compressible:!1},"application/x-ms-application":{source:"apache",extensions:["application"]},"application/x-ms-shortcut":{source:"apache",extensions:["lnk"]},"application/x-ms-wmd":{source:"apache",extensions:["wmd"]},"application/x-ms-wmz":{source:"apache",extensions:["wmz"]},"application/x-ms-xbap":{source:"apache",extensions:["xbap"]},"application/x-msaccess":{source:"apache",extensions:["mdb"]},"application/x-msbinder":{source:"apache",extensions:["obd"]},"application/x-mscardfile":{source:"apache",extensions:["crd"]},"application/x-msclip":{source:"apache",extensions:["clp"]},"application/x-msdos-program":{extensions:["exe"]},"application/x-msdownload":{source:"apache",extensions:["exe","dll","com","bat","msi"]},"application/x-msmediaview":{source:"apache",extensions:["mvb","m13","m14"]},"application/x-msmetafile":{source:"apache",extensions:["wmf","wmz","emf","emz"]},"application/x-msmoney":{source:"apache",extensions:["mny"]},"application/x-mspublisher":{source:"apache",extensions:["pub"]},"application/x-msschedule":{source:"apache",extensions:["scd"]},"application/x-msterminal":{source:"apache",extensions:["trm"]},"application/x-mswrite":{source:"apache",extensions:["wri"]},"application/x-netcdf":{source:"apache",extensions:["nc","cdf"]},"application/x-ns-proxy-autoconfig":{compressible:!0,extensions:["pac"]},"application/x-nzb":{source:"apache",extensions:["nzb"]},"application/x-perl":{source:"nginx",extensions:["pl","pm"]},"application/x-pilot":{source:"nginx",extensions:["prc","pdb"]},"application/x-pkcs12":{source:"apache",compressible:!1,extensions:["p12","pfx"]},"application/x-pkcs7-certificates":{source:"apache",extensions:["p7b","spc"]},"application/x-pkcs7-certreqresp":{source:"apache",extensions:["p7r"]},"application/x-pki-message":{source:"iana"},"application/x-rar-compressed":{source:"apache",compressible:!1,extensions:["rar"]},"application/x-redhat-package-manager":{source:"nginx",extensions:["rpm"]},"application/x-research-info-systems":{source:"apache",extensions:["ris"]},"application/x-sea":{source:"nginx",extensions:["sea"]},"application/x-sh":{source:"apache",compressible:!0,extensions:["sh"]},"application/x-shar":{source:"apache",extensions:["shar"]},"application/x-shockwave-flash":{source:"apache",compressible:!1,extensions:["swf"]},"application/x-silverlight-app":{source:"apache",extensions:["xap"]},"application/x-sql":{source:"apache",extensions:["sql"]},"application/x-stuffit":{source:"apache",compressible:!1,extensions:["sit"]},"application/x-stuffitx":{source:"apache",extensions:["sitx"]},"application/x-subrip":{source:"apache",extensions:["srt"]},"application/x-sv4cpio":{source:"apache",extensions:["sv4cpio"]},"application/x-sv4crc":{source:"apache",extensions:["sv4crc"]},"application/x-t3vm-image":{source:"apache",extensions:["t3"]},"application/x-tads":{source:"apache",extensions:["gam"]},"application/x-tar":{source:"apache",compressible:!0,extensions:["tar"]},"application/x-tcl":{source:"apache",extensions:["tcl","tk"]},"application/x-tex":{source:"apache",extensions:["tex"]},"application/x-tex-tfm":{source:"apache",extensions:["tfm"]},"application/x-texinfo":{source:"apache",extensions:["texinfo","texi"]},"application/x-tgif":{source:"apache",extensions:["obj"]},"application/x-ustar":{source:"apache",extensions:["ustar"]},"application/x-virtualbox-hdd":{compressible:!0,extensions:["hdd"]},"application/x-virtualbox-ova":{compressible:!0,extensions:["ova"]},"application/x-virtualbox-ovf":{compressible:!0,extensions:["ovf"]},"application/x-virtualbox-vbox":{compressible:!0,extensions:["vbox"]},"application/x-virtualbox-vbox-extpack":{compressible:!1,extensions:["vbox-extpack"]},"application/x-virtualbox-vdi":{compressible:!0,extensions:["vdi"]},"application/x-virtualbox-vhd":{compressible:!0,extensions:["vhd"]},"application/x-virtualbox-vmdk":{compressible:!0,extensions:["vmdk"]},"application/x-wais-source":{source:"apache",extensions:["src"]},"application/x-web-app-manifest+json":{compressible:!0,extensions:["webapp"]},"application/x-www-form-urlencoded":{source:"iana",compressible:!0},"application/x-x509-ca-cert":{source:"iana",extensions:["der","crt","pem"]},"application/x-x509-ca-ra-cert":{source:"iana"},"application/x-x509-next-ca-cert":{source:"iana"},"application/x-xfig":{source:"apache",extensions:["fig"]},"application/x-xliff+xml":{source:"apache",compressible:!0,extensions:["xlf"]},"application/x-xpinstall":{source:"apache",compressible:!1,extensions:["xpi"]},"application/x-xz":{source:"apache",extensions:["xz"]},"application/x-zmachine":{source:"apache",extensions:["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{source:"iana"},"application/xacml+xml":{source:"iana",compressible:!0},"application/xaml+xml":{source:"apache",compressible:!0,extensions:["xaml"]},"application/xcap-att+xml":{source:"iana",compressible:!0,extensions:["xav"]},"application/xcap-caps+xml":{source:"iana",compressible:!0,extensions:["xca"]},"application/xcap-diff+xml":{source:"iana",compressible:!0,extensions:["xdf"]},"application/xcap-el+xml":{source:"iana",compressible:!0,extensions:["xel"]},"application/xcap-error+xml":{source:"iana",compressible:!0},"application/xcap-ns+xml":{source:"iana",compressible:!0,extensions:["xns"]},"application/xcon-conference-info+xml":{source:"iana",compressible:!0},"application/xcon-conference-info-diff+xml":{source:"iana",compressible:!0},"application/xenc+xml":{source:"iana",compressible:!0,extensions:["xenc"]},"application/xhtml+xml":{source:"iana",compressible:!0,extensions:["xhtml","xht"]},"application/xhtml-voice+xml":{source:"apache",compressible:!0},"application/xliff+xml":{source:"iana",compressible:!0,extensions:["xlf"]},"application/xml":{source:"iana",compressible:!0,extensions:["xml","xsl","xsd","rng"]},"application/xml-dtd":{source:"iana",compressible:!0,extensions:["dtd"]},"application/xml-external-parsed-entity":{source:"iana"},"application/xml-patch+xml":{source:"iana",compressible:!0},"application/xmpp+xml":{source:"iana",compressible:!0},"application/xop+xml":{source:"iana",compressible:!0,extensions:["xop"]},"application/xproc+xml":{source:"apache",compressible:!0,extensions:["xpl"]},"application/xslt+xml":{source:"iana",compressible:!0,extensions:["xsl","xslt"]},"application/xspf+xml":{source:"apache",compressible:!0,extensions:["xspf"]},"application/xv+xml":{source:"iana",compressible:!0,extensions:["mxml","xhvml","xvml","xvm"]},"application/yang":{source:"iana",extensions:["yang"]},"application/yang-data+json":{source:"iana",compressible:!0},"application/yang-data+xml":{source:"iana",compressible:!0},"application/yang-patch+json":{source:"iana",compressible:!0},"application/yang-patch+xml":{source:"iana",compressible:!0},"application/yin+xml":{source:"iana",compressible:!0,extensions:["yin"]},"application/zip":{source:"iana",compressible:!1,extensions:["zip"]},"application/zlib":{source:"iana"},"application/zstd":{source:"iana"},"audio/1d-interleaved-parityfec":{source:"iana"},"audio/32kadpcm":{source:"iana"},"audio/3gpp":{source:"iana",compressible:!1,extensions:["3gpp"]},"audio/3gpp2":{source:"iana"},"audio/aac":{source:"iana"},"audio/ac3":{source:"iana"},"audio/adpcm":{source:"apache",extensions:["adp"]},"audio/amr":{source:"iana",extensions:["amr"]},"audio/amr-wb":{source:"iana"},"audio/amr-wb+":{source:"iana"},"audio/aptx":{source:"iana"},"audio/asc":{source:"iana"},"audio/atrac-advanced-lossless":{source:"iana"},"audio/atrac-x":{source:"iana"},"audio/atrac3":{source:"iana"},"audio/basic":{source:"iana",compressible:!1,extensions:["au","snd"]},"audio/bv16":{source:"iana"},"audio/bv32":{source:"iana"},"audio/clearmode":{source:"iana"},"audio/cn":{source:"iana"},"audio/dat12":{source:"iana"},"audio/dls":{source:"iana"},"audio/dsr-es201108":{source:"iana"},"audio/dsr-es202050":{source:"iana"},"audio/dsr-es202211":{source:"iana"},"audio/dsr-es202212":{source:"iana"},"audio/dv":{source:"iana"},"audio/dvi4":{source:"iana"},"audio/eac3":{source:"iana"},"audio/encaprtp":{source:"iana"},"audio/evrc":{source:"iana"},"audio/evrc-qcp":{source:"iana"},"audio/evrc0":{source:"iana"},"audio/evrc1":{source:"iana"},"audio/evrcb":{source:"iana"},"audio/evrcb0":{source:"iana"},"audio/evrcb1":{source:"iana"},"audio/evrcnw":{source:"iana"},"audio/evrcnw0":{source:"iana"},"audio/evrcnw1":{source:"iana"},"audio/evrcwb":{source:"iana"},"audio/evrcwb0":{source:"iana"},"audio/evrcwb1":{source:"iana"},"audio/evs":{source:"iana"},"audio/flexfec":{source:"iana"},"audio/fwdred":{source:"iana"},"audio/g711-0":{source:"iana"},"audio/g719":{source:"iana"},"audio/g722":{source:"iana"},"audio/g7221":{source:"iana"},"audio/g723":{source:"iana"},"audio/g726-16":{source:"iana"},"audio/g726-24":{source:"iana"},"audio/g726-32":{source:"iana"},"audio/g726-40":{source:"iana"},"audio/g728":{source:"iana"},"audio/g729":{source:"iana"},"audio/g7291":{source:"iana"},"audio/g729d":{source:"iana"},"audio/g729e":{source:"iana"},"audio/gsm":{source:"iana"},"audio/gsm-efr":{source:"iana"},"audio/gsm-hr-08":{source:"iana"},"audio/ilbc":{source:"iana"},"audio/ip-mr_v2.5":{source:"iana"},"audio/isac":{source:"apache"},"audio/l16":{source:"iana"},"audio/l20":{source:"iana"},"audio/l24":{source:"iana",compressible:!1},"audio/l8":{source:"iana"},"audio/lpc":{source:"iana"},"audio/melp":{source:"iana"},"audio/melp1200":{source:"iana"},"audio/melp2400":{source:"iana"},"audio/melp600":{source:"iana"},"audio/mhas":{source:"iana"},"audio/midi":{source:"apache",extensions:["mid","midi","kar","rmi"]},"audio/mobile-xmf":{source:"iana",extensions:["mxmf"]},"audio/mp3":{compressible:!1,extensions:["mp3"]},"audio/mp4":{source:"iana",compressible:!1,extensions:["m4a","mp4a"]},"audio/mp4a-latm":{source:"iana"},"audio/mpa":{source:"iana"},"audio/mpa-robust":{source:"iana"},"audio/mpeg":{source:"iana",compressible:!1,extensions:["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{source:"iana"},"audio/musepack":{source:"apache"},"audio/ogg":{source:"iana",compressible:!1,extensions:["oga","ogg","spx","opus"]},"audio/opus":{source:"iana"},"audio/parityfec":{source:"iana"},"audio/pcma":{source:"iana"},"audio/pcma-wb":{source:"iana"},"audio/pcmu":{source:"iana"},"audio/pcmu-wb":{source:"iana"},"audio/prs.sid":{source:"iana"},"audio/qcelp":{source:"iana"},"audio/raptorfec":{source:"iana"},"audio/red":{source:"iana"},"audio/rtp-enc-aescm128":{source:"iana"},"audio/rtp-midi":{source:"iana"},"audio/rtploopback":{source:"iana"},"audio/rtx":{source:"iana"},"audio/s3m":{source:"apache",extensions:["s3m"]},"audio/scip":{source:"iana"},"audio/silk":{source:"apache",extensions:["sil"]},"audio/smv":{source:"iana"},"audio/smv-qcp":{source:"iana"},"audio/smv0":{source:"iana"},"audio/sofa":{source:"iana"},"audio/sp-midi":{source:"iana"},"audio/speex":{source:"iana"},"audio/t140c":{source:"iana"},"audio/t38":{source:"iana"},"audio/telephone-event":{source:"iana"},"audio/tetra_acelp":{source:"iana"},"audio/tetra_acelp_bb":{source:"iana"},"audio/tone":{source:"iana"},"audio/tsvcis":{source:"iana"},"audio/uemclip":{source:"iana"},"audio/ulpfec":{source:"iana"},"audio/usac":{source:"iana"},"audio/vdvi":{source:"iana"},"audio/vmr-wb":{source:"iana"},"audio/vnd.3gpp.iufp":{source:"iana"},"audio/vnd.4sb":{source:"iana"},"audio/vnd.audiokoz":{source:"iana"},"audio/vnd.celp":{source:"iana"},"audio/vnd.cisco.nse":{source:"iana"},"audio/vnd.cmles.radio-events":{source:"iana"},"audio/vnd.cns.anp1":{source:"iana"},"audio/vnd.cns.inf1":{source:"iana"},"audio/vnd.dece.audio":{source:"iana",extensions:["uva","uvva"]},"audio/vnd.digital-winds":{source:"iana",extensions:["eol"]},"audio/vnd.dlna.adts":{source:"iana"},"audio/vnd.dolby.heaac.1":{source:"iana"},"audio/vnd.dolby.heaac.2":{source:"iana"},"audio/vnd.dolby.mlp":{source:"iana"},"audio/vnd.dolby.mps":{source:"iana"},"audio/vnd.dolby.pl2":{source:"iana"},"audio/vnd.dolby.pl2x":{source:"iana"},"audio/vnd.dolby.pl2z":{source:"iana"},"audio/vnd.dolby.pulse.1":{source:"iana"},"audio/vnd.dra":{source:"iana",extensions:["dra"]},"audio/vnd.dts":{source:"iana",extensions:["dts"]},"audio/vnd.dts.hd":{source:"iana",extensions:["dtshd"]},"audio/vnd.dts.uhd":{source:"iana"},"audio/vnd.dvb.file":{source:"iana"},"audio/vnd.everad.plj":{source:"iana"},"audio/vnd.hns.audio":{source:"iana"},"audio/vnd.lucent.voice":{source:"iana",extensions:["lvp"]},"audio/vnd.ms-playready.media.pya":{source:"iana",extensions:["pya"]},"audio/vnd.nokia.mobile-xmf":{source:"iana"},"audio/vnd.nortel.vbk":{source:"iana"},"audio/vnd.nuera.ecelp4800":{source:"iana",extensions:["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{source:"iana",extensions:["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{source:"iana",extensions:["ecelp9600"]},"audio/vnd.octel.sbc":{source:"iana"},"audio/vnd.presonus.multitrack":{source:"iana"},"audio/vnd.qcelp":{source:"iana"},"audio/vnd.rhetorex.32kadpcm":{source:"iana"},"audio/vnd.rip":{source:"iana",extensions:["rip"]},"audio/vnd.rn-realaudio":{compressible:!1},"audio/vnd.sealedmedia.softseal.mpeg":{source:"iana"},"audio/vnd.vmx.cvsd":{source:"iana"},"audio/vnd.wave":{compressible:!1},"audio/vorbis":{source:"iana",compressible:!1},"audio/vorbis-config":{source:"iana"},"audio/wav":{compressible:!1,extensions:["wav"]},"audio/wave":{compressible:!1,extensions:["wav"]},"audio/webm":{source:"apache",compressible:!1,extensions:["weba"]},"audio/x-aac":{source:"apache",compressible:!1,extensions:["aac"]},"audio/x-aiff":{source:"apache",extensions:["aif","aiff","aifc"]},"audio/x-caf":{source:"apache",compressible:!1,extensions:["caf"]},"audio/x-flac":{source:"apache",extensions:["flac"]},"audio/x-m4a":{source:"nginx",extensions:["m4a"]},"audio/x-matroska":{source:"apache",extensions:["mka"]},"audio/x-mpegurl":{source:"apache",extensions:["m3u"]},"audio/x-ms-wax":{source:"apache",extensions:["wax"]},"audio/x-ms-wma":{source:"apache",extensions:["wma"]},"audio/x-pn-realaudio":{source:"apache",extensions:["ram","ra"]},"audio/x-pn-realaudio-plugin":{source:"apache",extensions:["rmp"]},"audio/x-realaudio":{source:"nginx",extensions:["ra"]},"audio/x-tta":{source:"apache"},"audio/x-wav":{source:"apache",extensions:["wav"]},"audio/xm":{source:"apache",extensions:["xm"]},"chemical/x-cdx":{source:"apache",extensions:["cdx"]},"chemical/x-cif":{source:"apache",extensions:["cif"]},"chemical/x-cmdf":{source:"apache",extensions:["cmdf"]},"chemical/x-cml":{source:"apache",extensions:["cml"]},"chemical/x-csml":{source:"apache",extensions:["csml"]},"chemical/x-pdb":{source:"apache"},"chemical/x-xyz":{source:"apache",extensions:["xyz"]},"font/collection":{source:"iana",extensions:["ttc"]},"font/otf":{source:"iana",compressible:!0,extensions:["otf"]},"font/sfnt":{source:"iana"},"font/ttf":{source:"iana",compressible:!0,extensions:["ttf"]},"font/woff":{source:"iana",extensions:["woff"]},"font/woff2":{source:"iana",extensions:["woff2"]},"image/aces":{source:"iana",extensions:["exr"]},"image/apng":{compressible:!1,extensions:["apng"]},"image/avci":{source:"iana",extensions:["avci"]},"image/avcs":{source:"iana",extensions:["avcs"]},"image/avif":{source:"iana",compressible:!1,extensions:["avif"]},"image/bmp":{source:"iana",compressible:!0,extensions:["bmp"]},"image/cgm":{source:"iana",extensions:["cgm"]},"image/dicom-rle":{source:"iana",extensions:["drle"]},"image/emf":{source:"iana",extensions:["emf"]},"image/fits":{source:"iana",extensions:["fits"]},"image/g3fax":{source:"iana",extensions:["g3"]},"image/gif":{source:"iana",compressible:!1,extensions:["gif"]},"image/heic":{source:"iana",extensions:["heic"]},"image/heic-sequence":{source:"iana",extensions:["heics"]},"image/heif":{source:"iana",extensions:["heif"]},"image/heif-sequence":{source:"iana",extensions:["heifs"]},"image/hej2k":{source:"iana",extensions:["hej2"]},"image/hsj2":{source:"iana",extensions:["hsj2"]},"image/ief":{source:"iana",extensions:["ief"]},"image/jls":{source:"iana",extensions:["jls"]},"image/jp2":{source:"iana",compressible:!1,extensions:["jp2","jpg2"]},"image/jpeg":{source:"iana",compressible:!1,extensions:["jpeg","jpg","jpe"]},"image/jph":{source:"iana",extensions:["jph"]},"image/jphc":{source:"iana",extensions:["jhc"]},"image/jpm":{source:"iana",compressible:!1,extensions:["jpm"]},"image/jpx":{source:"iana",compressible:!1,extensions:["jpx","jpf"]},"image/jxr":{source:"iana",extensions:["jxr"]},"image/jxra":{source:"iana",extensions:["jxra"]},"image/jxrs":{source:"iana",extensions:["jxrs"]},"image/jxs":{source:"iana",extensions:["jxs"]},"image/jxsc":{source:"iana",extensions:["jxsc"]},"image/jxsi":{source:"iana",extensions:["jxsi"]},"image/jxss":{source:"iana",extensions:["jxss"]},"image/ktx":{source:"iana",extensions:["ktx"]},"image/ktx2":{source:"iana",extensions:["ktx2"]},"image/naplps":{source:"iana"},"image/pjpeg":{compressible:!1},"image/png":{source:"iana",compressible:!1,extensions:["png"]},"image/prs.btif":{source:"iana",extensions:["btif"]},"image/prs.pti":{source:"iana",extensions:["pti"]},"image/pwg-raster":{source:"iana"},"image/sgi":{source:"apache",extensions:["sgi"]},"image/svg+xml":{source:"iana",compressible:!0,extensions:["svg","svgz"]},"image/t38":{source:"iana",extensions:["t38"]},"image/tiff":{source:"iana",compressible:!1,extensions:["tif","tiff"]},"image/tiff-fx":{source:"iana",extensions:["tfx"]},"image/vnd.adobe.photoshop":{source:"iana",compressible:!0,extensions:["psd"]},"image/vnd.airzip.accelerator.azv":{source:"iana",extensions:["azv"]},"image/vnd.cns.inf2":{source:"iana"},"image/vnd.dece.graphic":{source:"iana",extensions:["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{source:"iana",extensions:["djvu","djv"]},"image/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"image/vnd.dwg":{source:"iana",extensions:["dwg"]},"image/vnd.dxf":{source:"iana",extensions:["dxf"]},"image/vnd.fastbidsheet":{source:"iana",extensions:["fbs"]},"image/vnd.fpx":{source:"iana",extensions:["fpx"]},"image/vnd.fst":{source:"iana",extensions:["fst"]},"image/vnd.fujixerox.edmics-mmr":{source:"iana",extensions:["mmr"]},"image/vnd.fujixerox.edmics-rlc":{source:"iana",extensions:["rlc"]},"image/vnd.globalgraphics.pgb":{source:"iana"},"image/vnd.microsoft.icon":{source:"iana",compressible:!0,extensions:["ico"]},"image/vnd.mix":{source:"iana"},"image/vnd.mozilla.apng":{source:"iana"},"image/vnd.ms-dds":{compressible:!0,extensions:["dds"]},"image/vnd.ms-modi":{source:"iana",extensions:["mdi"]},"image/vnd.ms-photo":{source:"apache",extensions:["wdp"]},"image/vnd.net-fpx":{source:"iana",extensions:["npx"]},"image/vnd.pco.b16":{source:"iana",extensions:["b16"]},"image/vnd.radiance":{source:"iana"},"image/vnd.sealed.png":{source:"iana"},"image/vnd.sealedmedia.softseal.gif":{source:"iana"},"image/vnd.sealedmedia.softseal.jpg":{source:"iana"},"image/vnd.svf":{source:"iana"},"image/vnd.tencent.tap":{source:"iana",extensions:["tap"]},"image/vnd.valve.source.texture":{source:"iana",extensions:["vtf"]},"image/vnd.wap.wbmp":{source:"iana",extensions:["wbmp"]},"image/vnd.xiff":{source:"iana",extensions:["xif"]},"image/vnd.zbrush.pcx":{source:"iana",extensions:["pcx"]},"image/webp":{source:"apache",extensions:["webp"]},"image/wmf":{source:"iana",extensions:["wmf"]},"image/x-3ds":{source:"apache",extensions:["3ds"]},"image/x-cmu-raster":{source:"apache",extensions:["ras"]},"image/x-cmx":{source:"apache",extensions:["cmx"]},"image/x-freehand":{source:"apache",extensions:["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{source:"apache",compressible:!0,extensions:["ico"]},"image/x-jng":{source:"nginx",extensions:["jng"]},"image/x-mrsid-image":{source:"apache",extensions:["sid"]},"image/x-ms-bmp":{source:"nginx",compressible:!0,extensions:["bmp"]},"image/x-pcx":{source:"apache",extensions:["pcx"]},"image/x-pict":{source:"apache",extensions:["pic","pct"]},"image/x-portable-anymap":{source:"apache",extensions:["pnm"]},"image/x-portable-bitmap":{source:"apache",extensions:["pbm"]},"image/x-portable-graymap":{source:"apache",extensions:["pgm"]},"image/x-portable-pixmap":{source:"apache",extensions:["ppm"]},"image/x-rgb":{source:"apache",extensions:["rgb"]},"image/x-tga":{source:"apache",extensions:["tga"]},"image/x-xbitmap":{source:"apache",extensions:["xbm"]},"image/x-xcf":{compressible:!1},"image/x-xpixmap":{source:"apache",extensions:["xpm"]},"image/x-xwindowdump":{source:"apache",extensions:["xwd"]},"message/cpim":{source:"iana"},"message/delivery-status":{source:"iana"},"message/disposition-notification":{source:"iana",extensions:["disposition-notification"]},"message/external-body":{source:"iana"},"message/feedback-report":{source:"iana"},"message/global":{source:"iana",extensions:["u8msg"]},"message/global-delivery-status":{source:"iana",extensions:["u8dsn"]},"message/global-disposition-notification":{source:"iana",extensions:["u8mdn"]},"message/global-headers":{source:"iana",extensions:["u8hdr"]},"message/http":{source:"iana",compressible:!1},"message/imdn+xml":{source:"iana",compressible:!0},"message/news":{source:"iana"},"message/partial":{source:"iana",compressible:!1},"message/rfc822":{source:"iana",compressible:!0,extensions:["eml","mime"]},"message/s-http":{source:"iana"},"message/sip":{source:"iana"},"message/sipfrag":{source:"iana"},"message/tracking-status":{source:"iana"},"message/vnd.si.simp":{source:"iana"},"message/vnd.wfa.wsc":{source:"iana",extensions:["wsc"]},"model/3mf":{source:"iana",extensions:["3mf"]},"model/e57":{source:"iana"},"model/gltf+json":{source:"iana",compressible:!0,extensions:["gltf"]},"model/gltf-binary":{source:"iana",compressible:!0,extensions:["glb"]},"model/iges":{source:"iana",compressible:!1,extensions:["igs","iges"]},"model/mesh":{source:"iana",compressible:!1,extensions:["msh","mesh","silo"]},"model/mtl":{source:"iana",extensions:["mtl"]},"model/obj":{source:"iana",extensions:["obj"]},"model/step":{source:"iana"},"model/step+xml":{source:"iana",compressible:!0,extensions:["stpx"]},"model/step+zip":{source:"iana",compressible:!1,extensions:["stpz"]},"model/step-xml+zip":{source:"iana",compressible:!1,extensions:["stpxz"]},"model/stl":{source:"iana",extensions:["stl"]},"model/vnd.collada+xml":{source:"iana",compressible:!0,extensions:["dae"]},"model/vnd.dwf":{source:"iana",extensions:["dwf"]},"model/vnd.flatland.3dml":{source:"iana"},"model/vnd.gdl":{source:"iana",extensions:["gdl"]},"model/vnd.gs-gdl":{source:"apache"},"model/vnd.gs.gdl":{source:"iana"},"model/vnd.gtw":{source:"iana",extensions:["gtw"]},"model/vnd.moml+xml":{source:"iana",compressible:!0},"model/vnd.mts":{source:"iana",extensions:["mts"]},"model/vnd.opengex":{source:"iana",extensions:["ogex"]},"model/vnd.parasolid.transmit.binary":{source:"iana",extensions:["x_b"]},"model/vnd.parasolid.transmit.text":{source:"iana",extensions:["x_t"]},"model/vnd.pytha.pyox":{source:"iana"},"model/vnd.rosette.annotated-data-model":{source:"iana"},"model/vnd.sap.vds":{source:"iana",extensions:["vds"]},"model/vnd.usdz+zip":{source:"iana",compressible:!1,extensions:["usdz"]},"model/vnd.valve.source.compiled-map":{source:"iana",extensions:["bsp"]},"model/vnd.vtu":{source:"iana",extensions:["vtu"]},"model/vrml":{source:"iana",compressible:!1,extensions:["wrl","vrml"]},"model/x3d+binary":{source:"apache",compressible:!1,extensions:["x3db","x3dbz"]},"model/x3d+fastinfoset":{source:"iana",extensions:["x3db"]},"model/x3d+vrml":{source:"apache",compressible:!1,extensions:["x3dv","x3dvz"]},"model/x3d+xml":{source:"iana",compressible:!0,extensions:["x3d","x3dz"]},"model/x3d-vrml":{source:"iana",extensions:["x3dv"]},"multipart/alternative":{source:"iana",compressible:!1},"multipart/appledouble":{source:"iana"},"multipart/byteranges":{source:"iana"},"multipart/digest":{source:"iana"},"multipart/encrypted":{source:"iana",compressible:!1},"multipart/form-data":{source:"iana",compressible:!1},"multipart/header-set":{source:"iana"},"multipart/mixed":{source:"iana"},"multipart/multilingual":{source:"iana"},"multipart/parallel":{source:"iana"},"multipart/related":{source:"iana",compressible:!1},"multipart/report":{source:"iana"},"multipart/signed":{source:"iana",compressible:!1},"multipart/vnd.bint.med-plus":{source:"iana"},"multipart/voice-message":{source:"iana"},"multipart/x-mixed-replace":{source:"iana"},"text/1d-interleaved-parityfec":{source:"iana"},"text/cache-manifest":{source:"iana",compressible:!0,extensions:["appcache","manifest"]},"text/calendar":{source:"iana",extensions:["ics","ifb"]},"text/calender":{compressible:!0},"text/cmd":{compressible:!0},"text/coffeescript":{extensions:["coffee","litcoffee"]},"text/cql":{source:"iana"},"text/cql-expression":{source:"iana"},"text/cql-identifier":{source:"iana"},"text/css":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["css"]},"text/csv":{source:"iana",compressible:!0,extensions:["csv"]},"text/csv-schema":{source:"iana"},"text/directory":{source:"iana"},"text/dns":{source:"iana"},"text/ecmascript":{source:"iana"},"text/encaprtp":{source:"iana"},"text/enriched":{source:"iana"},"text/fhirpath":{source:"iana"},"text/flexfec":{source:"iana"},"text/fwdred":{source:"iana"},"text/gff3":{source:"iana"},"text/grammar-ref-list":{source:"iana"},"text/html":{source:"iana",compressible:!0,extensions:["html","htm","shtml"]},"text/jade":{extensions:["jade"]},"text/javascript":{source:"iana",compressible:!0},"text/jcr-cnd":{source:"iana"},"text/jsx":{compressible:!0,extensions:["jsx"]},"text/less":{compressible:!0,extensions:["less"]},"text/markdown":{source:"iana",compressible:!0,extensions:["markdown","md"]},"text/mathml":{source:"nginx",extensions:["mml"]},"text/mdx":{compressible:!0,extensions:["mdx"]},"text/mizar":{source:"iana"},"text/n3":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["n3"]},"text/parameters":{source:"iana",charset:"UTF-8"},"text/parityfec":{source:"iana"},"text/plain":{source:"iana",compressible:!0,extensions:["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{source:"iana",charset:"UTF-8"},"text/prs.fallenstein.rst":{source:"iana"},"text/prs.lines.tag":{source:"iana",extensions:["dsc"]},"text/prs.prop.logic":{source:"iana"},"text/raptorfec":{source:"iana"},"text/red":{source:"iana"},"text/rfc822-headers":{source:"iana"},"text/richtext":{source:"iana",compressible:!0,extensions:["rtx"]},"text/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"text/rtp-enc-aescm128":{source:"iana"},"text/rtploopback":{source:"iana"},"text/rtx":{source:"iana"},"text/sgml":{source:"iana",extensions:["sgml","sgm"]},"text/shaclc":{source:"iana"},"text/shex":{source:"iana",extensions:["shex"]},"text/slim":{extensions:["slim","slm"]},"text/spdx":{source:"iana",extensions:["spdx"]},"text/strings":{source:"iana"},"text/stylus":{extensions:["stylus","styl"]},"text/t140":{source:"iana"},"text/tab-separated-values":{source:"iana",compressible:!0,extensions:["tsv"]},"text/troff":{source:"iana",extensions:["t","tr","roff","man","me","ms"]},"text/turtle":{source:"iana",charset:"UTF-8",extensions:["ttl"]},"text/ulpfec":{source:"iana"},"text/uri-list":{source:"iana",compressible:!0,extensions:["uri","uris","urls"]},"text/vcard":{source:"iana",compressible:!0,extensions:["vcard"]},"text/vnd.a":{source:"iana"},"text/vnd.abc":{source:"iana"},"text/vnd.ascii-art":{source:"iana"},"text/vnd.curl":{source:"iana",extensions:["curl"]},"text/vnd.curl.dcurl":{source:"apache",extensions:["dcurl"]},"text/vnd.curl.mcurl":{source:"apache",extensions:["mcurl"]},"text/vnd.curl.scurl":{source:"apache",extensions:["scurl"]},"text/vnd.debian.copyright":{source:"iana",charset:"UTF-8"},"text/vnd.dmclientscript":{source:"iana"},"text/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"text/vnd.esmertec.theme-descriptor":{source:"iana",charset:"UTF-8"},"text/vnd.familysearch.gedcom":{source:"iana",extensions:["ged"]},"text/vnd.ficlab.flt":{source:"iana"},"text/vnd.fly":{source:"iana",extensions:["fly"]},"text/vnd.fmi.flexstor":{source:"iana",extensions:["flx"]},"text/vnd.gml":{source:"iana"},"text/vnd.graphviz":{source:"iana",extensions:["gv"]},"text/vnd.hans":{source:"iana"},"text/vnd.hgl":{source:"iana"},"text/vnd.in3d.3dml":{source:"iana",extensions:["3dml"]},"text/vnd.in3d.spot":{source:"iana",extensions:["spot"]},"text/vnd.iptc.newsml":{source:"iana"},"text/vnd.iptc.nitf":{source:"iana"},"text/vnd.latex-z":{source:"iana"},"text/vnd.motorola.reflex":{source:"iana"},"text/vnd.ms-mediapackage":{source:"iana"},"text/vnd.net2phone.commcenter.command":{source:"iana"},"text/vnd.radisys.msml-basic-layout":{source:"iana"},"text/vnd.senx.warpscript":{source:"iana"},"text/vnd.si.uricatalogue":{source:"iana"},"text/vnd.sosi":{source:"iana"},"text/vnd.sun.j2me.app-descriptor":{source:"iana",charset:"UTF-8",extensions:["jad"]},"text/vnd.trolltech.linguist":{source:"iana",charset:"UTF-8"},"text/vnd.wap.si":{source:"iana"},"text/vnd.wap.sl":{source:"iana"},"text/vnd.wap.wml":{source:"iana",extensions:["wml"]},"text/vnd.wap.wmlscript":{source:"iana",extensions:["wmls"]},"text/vtt":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["vtt"]},"text/x-asm":{source:"apache",extensions:["s","asm"]},"text/x-c":{source:"apache",extensions:["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{source:"nginx",extensions:["htc"]},"text/x-fortran":{source:"apache",extensions:["f","for","f77","f90"]},"text/x-gwt-rpc":{compressible:!0},"text/x-handlebars-template":{extensions:["hbs"]},"text/x-java-source":{source:"apache",extensions:["java"]},"text/x-jquery-tmpl":{compressible:!0},"text/x-lua":{extensions:["lua"]},"text/x-markdown":{compressible:!0,extensions:["mkd"]},"text/x-nfo":{source:"apache",extensions:["nfo"]},"text/x-opml":{source:"apache",extensions:["opml"]},"text/x-org":{compressible:!0,extensions:["org"]},"text/x-pascal":{source:"apache",extensions:["p","pas"]},"text/x-processing":{compressible:!0,extensions:["pde"]},"text/x-sass":{extensions:["sass"]},"text/x-scss":{extensions:["scss"]},"text/x-setext":{source:"apache",extensions:["etx"]},"text/x-sfv":{source:"apache",extensions:["sfv"]},"text/x-suse-ymp":{compressible:!0,extensions:["ymp"]},"text/x-uuencode":{source:"apache",extensions:["uu"]},"text/x-vcalendar":{source:"apache",extensions:["vcs"]},"text/x-vcard":{source:"apache",extensions:["vcf"]},"text/xml":{source:"iana",compressible:!0,extensions:["xml"]},"text/xml-external-parsed-entity":{source:"iana"},"text/yaml":{compressible:!0,extensions:["yaml","yml"]},"video/1d-interleaved-parityfec":{source:"iana"},"video/3gpp":{source:"iana",extensions:["3gp","3gpp"]},"video/3gpp-tt":{source:"iana"},"video/3gpp2":{source:"iana",extensions:["3g2"]},"video/av1":{source:"iana"},"video/bmpeg":{source:"iana"},"video/bt656":{source:"iana"},"video/celb":{source:"iana"},"video/dv":{source:"iana"},"video/encaprtp":{source:"iana"},"video/ffv1":{source:"iana"},"video/flexfec":{source:"iana"},"video/h261":{source:"iana",extensions:["h261"]},"video/h263":{source:"iana",extensions:["h263"]},"video/h263-1998":{source:"iana"},"video/h263-2000":{source:"iana"},"video/h264":{source:"iana",extensions:["h264"]},"video/h264-rcdo":{source:"iana"},"video/h264-svc":{source:"iana"},"video/h265":{source:"iana"},"video/iso.segment":{source:"iana",extensions:["m4s"]},"video/jpeg":{source:"iana",extensions:["jpgv"]},"video/jpeg2000":{source:"iana"},"video/jpm":{source:"apache",extensions:["jpm","jpgm"]},"video/jxsv":{source:"iana"},"video/mj2":{source:"iana",extensions:["mj2","mjp2"]},"video/mp1s":{source:"iana"},"video/mp2p":{source:"iana"},"video/mp2t":{source:"iana",extensions:["ts"]},"video/mp4":{source:"iana",compressible:!1,extensions:["mp4","mp4v","mpg4"]},"video/mp4v-es":{source:"iana"},"video/mpeg":{source:"iana",compressible:!1,extensions:["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{source:"iana"},"video/mpv":{source:"iana"},"video/nv":{source:"iana"},"video/ogg":{source:"iana",compressible:!1,extensions:["ogv"]},"video/parityfec":{source:"iana"},"video/pointer":{source:"iana"},"video/quicktime":{source:"iana",compressible:!1,extensions:["qt","mov"]},"video/raptorfec":{source:"iana"},"video/raw":{source:"iana"},"video/rtp-enc-aescm128":{source:"iana"},"video/rtploopback":{source:"iana"},"video/rtx":{source:"iana"},"video/scip":{source:"iana"},"video/smpte291":{source:"iana"},"video/smpte292m":{source:"iana"},"video/ulpfec":{source:"iana"},"video/vc1":{source:"iana"},"video/vc2":{source:"iana"},"video/vnd.cctv":{source:"iana"},"video/vnd.dece.hd":{source:"iana",extensions:["uvh","uvvh"]},"video/vnd.dece.mobile":{source:"iana",extensions:["uvm","uvvm"]},"video/vnd.dece.mp4":{source:"iana"},"video/vnd.dece.pd":{source:"iana",extensions:["uvp","uvvp"]},"video/vnd.dece.sd":{source:"iana",extensions:["uvs","uvvs"]},"video/vnd.dece.video":{source:"iana",extensions:["uvv","uvvv"]},"video/vnd.directv.mpeg":{source:"iana"},"video/vnd.directv.mpeg-tts":{source:"iana"},"video/vnd.dlna.mpeg-tts":{source:"iana"},"video/vnd.dvb.file":{source:"iana",extensions:["dvb"]},"video/vnd.fvt":{source:"iana",extensions:["fvt"]},"video/vnd.hns.video":{source:"iana"},"video/vnd.iptvforum.1dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.1dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.2dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.2dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.ttsavc":{source:"iana"},"video/vnd.iptvforum.ttsmpeg2":{source:"iana"},"video/vnd.motorola.video":{source:"iana"},"video/vnd.motorola.videop":{source:"iana"},"video/vnd.mpegurl":{source:"iana",extensions:["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{source:"iana",extensions:["pyv"]},"video/vnd.nokia.interleaved-multimedia":{source:"iana"},"video/vnd.nokia.mp4vr":{source:"iana"},"video/vnd.nokia.videovoip":{source:"iana"},"video/vnd.objectvideo":{source:"iana"},"video/vnd.radgamettools.bink":{source:"iana"},"video/vnd.radgamettools.smacker":{source:"iana"},"video/vnd.sealed.mpeg1":{source:"iana"},"video/vnd.sealed.mpeg4":{source:"iana"},"video/vnd.sealed.swf":{source:"iana"},"video/vnd.sealedmedia.softseal.mov":{source:"iana"},"video/vnd.uvvu.mp4":{source:"iana",extensions:["uvu","uvvu"]},"video/vnd.vivo":{source:"iana",extensions:["viv"]},"video/vnd.youtube.yt":{source:"iana"},"video/vp8":{source:"iana"},"video/vp9":{source:"iana"},"video/webm":{source:"apache",compressible:!1,extensions:["webm"]},"video/x-f4v":{source:"apache",extensions:["f4v"]},"video/x-fli":{source:"apache",extensions:["fli"]},"video/x-flv":{source:"apache",compressible:!1,extensions:["flv"]},"video/x-m4v":{source:"apache",extensions:["m4v"]},"video/x-matroska":{source:"apache",compressible:!1,extensions:["mkv","mk3d","mks"]},"video/x-mng":{source:"apache",extensions:["mng"]},"video/x-ms-asf":{source:"apache",extensions:["asf","asx"]},"video/x-ms-vob":{source:"apache",extensions:["vob"]},"video/x-ms-wm":{source:"apache",extensions:["wm"]},"video/x-ms-wmv":{source:"apache",compressible:!1,extensions:["wmv"]},"video/x-ms-wmx":{source:"apache",extensions:["wmx"]},"video/x-ms-wvx":{source:"apache",extensions:["wvx"]},"video/x-msvideo":{source:"apache",extensions:["avi"]},"video/x-sgi-movie":{source:"apache",extensions:["movie"]},"video/x-smv":{source:"apache",extensions:["smv"]},"x-conference/x-cooltalk":{source:"apache",extensions:["ice"]},"x-shader/x-fragment":{compressible:!0},"x-shader/x-vertex":{compressible:!0}},hn=(dn||(dn=1,function(e){var t,n,s,a=pn?ln:(pn=1,ln=mn),i=$e.extname,o=/^\s*([^;\s]*)(?:;|\s|$)/,r=/^text\//i;function c(e){if(!e||"string"!=typeof e)return!1;var t=o.exec(e),n=t&&a[t[1].toLowerCase()];return n&&n.charset?n.charset:!(!t||!r.test(t[1]))&&"UTF-8"}e.charset=c,e.charsets={lookup:c},e.contentType=function(t){if(!t||"string"!=typeof t)return!1;var n=-1===t.indexOf("/")?e.lookup(t):t;if(!n)return!1;if(-1===n.indexOf("charset")){var s=e.charset(n);s&&(n+="; charset="+s.toLowerCase())}return n},e.extension=function(t){if(!t||"string"!=typeof t)return!1;var n=o.exec(t),s=n&&e.extensions[n[1].toLowerCase()];return!(!s||!s.length)&&s[0]},e.extensions=Object.create(null),e.lookup=function(t){if(!t||"string"!=typeof t)return!1;var n=i("x."+t).toLowerCase().substr(1);return n&&e.types[n]||!1},e.types=Object.create(null),t=e.extensions,n=e.types,s=["nginx","apache",void 0,"iana"],Object.keys(a).forEach(function(e){var i=a[e],o=i.extensions;if(o&&o.length){t[e]=o;for(var r=0;r<o.length;r++){var c=o[r];if(n[c]){var l=s.indexOf(a[n[c]].source),p=s.indexOf(i.source);if("application/octet-stream"!==n[c]&&(l>p||l===p&&"application/"===n[c].substr(0,12)))continue}n[c]=e}}})}(un)),un);function gn(e,t){e?e.send("workspace-file-response",t):ye.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function fn(e,t,n,s){return{eventId:G(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function yn(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;ye.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,p=function(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return function(e){const t=_(nn()),n=_(e);if(n!==t&&!n.startsWith(`${t}${C}`))throw new Error("Access denied: channel attachment path is outside channel files directory");return n}(decodeURIComponent(e))}return fe.resolveWorkspaceFilePath(e,t,n)}(s,n,a);if(!i.existsSync(p))return ye.warn(`[WORKSPACE] File not found: ${p}`),void gn(e.client,fn(o,n,"file_not_found","File or directory not found"));const d=await i.promises.stat(p),u=d.mtime.toISOString();if(c&&u===c)return void function(e,t,n,s){ye.debug(`[WORKSPACE] File not modified: ${s}`),gn(e,{eventId:G(),requestId:t,taskId:n,success:!0,notModified:!0})}(e.client,o,n,p);if(d.isDirectory())return void await async function(e,t,n,s,a,o){const r=await i.promises.readdir(s,{withFileTypes:!0}),c=await Promise.all(r.map(async e=>{const t=k.join(s,e.name),n=await i.promises.stat(t);return{name:e.name,type:e.isDirectory()?"directory":"file",size:n.size,modifiedAt:n.mtime.toISOString(),accessDenied:n.size>o}}));gn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:{type:"directory",entries:c,metadata:{size:0,modifiedAt:a.mtime.toISOString()}}})}(e.client,o,n,p,d,t);{const s=hn.lookup(p)||"application/octet-stream";return d.size>t?void function(e,t,n,s,a,i,o){ye.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),gn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:{type:"file",metadata:{size:a.size,mimeType:i,modifiedAt:a.mtime.toISOString(),accessDenied:!0}}})}(e.client,o,n,p,d,s,t):void await async function(e,t,n,s,a,o){const r=hn.lookup(s)||"application/octet-stream",c=(await i.promises.readFile(s)).toString("base64");let l=null;o&&(l=await async function(e){try{const t=await fe.getSecretKey();if(!t)return ye.warn("[WORKSPACE] Machine secret key not available"),null;const n=L(e);return H(n,t)||(ye.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return ye.warn("[WORKSPACE] Error decrypting dataEncryptionKey:",e),null}}(o));const p={type:"file",metadata:{size:a.size,mimeType:r,modifiedAt:a.mtime.toISOString()}};l?p.encryptedContent=B(c,l):p.content=c,gn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:p})}(e.client,o,n,p,d,l)}}catch(t){ye.error(`[WORKSPACE] Failed to handle workspace-file-request: ${t.message}`,t);const s="ENOENT"===t.code?"file_not_found":"EACCES"===t.code?"permission_denied":"unknown_error";gn(e.client,fn(o,n,s,t.message))}}}const vn=new je({credentialsDir:S(fe.agentrixHomeDir,"credentials")});async function xn(){const e=await fe.readCredentials();return e?.secret?qe(e.secret):null}function wn(e){return vn.loadGitServerConfig(e)}function bn(e,t){return vn.loadGitLabWebhookBridgeSecrets(e,t)}function kn(e){return vn.loadPatMeta(e)}function In(e,t){return vn.loadPat(e,t)}const Sn=100,Tn=[{method:"GET",pattern:/^\/user$/},{method:"GET",pattern:/^\/projects$/},{method:"GET",pattern:/^\/projects\/[^/]+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/repository\/branches$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/issues\/\d+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions\/[^/]+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/changes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/approvals$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+\/notes$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/approve$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+\/notes\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/merge$/}];class En{apiUrl;pat;requestId;gitServerId;constructor(e,t,n){this.apiUrl=e,this.pat=t,this.requestId=n?.requestId,this.gitServerId=n?.gitServerId}logPrefix(){return`[GITLAB EXECUTOR] reqId=${this.requestId??"-"}, gitServer=${this.gitServerId??"-"}`}summarizeResult(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"id"in n&&"status"in n?`id=${String(n.id??"-")}, status=${String(n.status??"-")}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}truncateText(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}async requestWithResponse(e,t="GET",n){const s=`${this.apiUrl}${e}`,a={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/json"},i=Date.now();ye.debug(`${this.logPrefix()} request start: ${t} ${e}`);try{const o=await fetch(s,{method:t,headers:a,body:n?JSON.stringify(n):void 0}),r=Date.now()-i;if(!o.ok){const n=await o.text().catch(()=>"Unknown error"),s=this.truncateText(n);throw ye.warn(`${this.logPrefix()} request failed: ${t} ${e}, status=${o.status}, elapsedMs=${r}, detail=${s}`),{status:o.status,message:`GitLab API error: ${o.status} ${o.statusText}`,detail:s}}return ye.debug(`${this.logPrefix()} request success: ${t} ${e}, elapsedMs=${r}`),{data:await o.json(),headers:o.headers}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw ye.error(`${this.logPrefix()} request exception: ${t} ${e}, message=${s}`),{status:0,message:`GitLab request failed: ${s}`}}}async requestForm(e,t){const n=`${this.apiUrl}${e}`,s={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/x-www-form-urlencoded"},a=Date.now();ye.debug(`${this.logPrefix()} form request start: POST ${e}`);try{const i=await fetch(n,{method:"POST",headers:s,body:t}),o=Date.now()-a;if(!i.ok){const t=await i.text().catch(()=>"Unknown error"),n=this.truncateText(t);throw ye.warn(`${this.logPrefix()} form request failed: POST ${e}, status=${i.status}, elapsedMs=${o}, detail=${n}`),{status:i.status,message:`GitLab API error: ${i.status} ${i.statusText}`,detail:n}}return ye.debug(`${this.logPrefix()} form request success: POST ${e}, elapsedMs=${o}`),await i.json()}catch(t){if("object"==typeof t&&null!==t&&"status"in t)throw t;const n=t instanceof Error?t.message:"Unknown network error";throw ye.error(`${this.logPrefix()} form request exception: POST ${e}, message=${n}`),{status:0,message:`GitLab request failed: ${n}`}}}async request(e,t="GET",n){const{data:s}=await this.requestWithResponse(e,t,n);return s}withQueryParams(e,t){const[n,s=""]=e.split("?"),a=new URLSearchParams(s);for(const[e,n]of Object.entries(t))a.set(e,String(n));const i=a.toString();return i?`${n}?${i}`:n}parseTotalPages(e){const t=e.get("x-total-pages");if(!t)return null;const n=Number.parseInt(t,10);return!Number.isFinite(n)||n<=0?null:n}async fetchRemainingPagesInBatches(e,t){const n=[];for(let s=2;s<=e;s+=4){const a=Math.min(s+4-1,e),i=Array.from({length:a-s+1},(e,t)=>s+t),o=await Promise.all(i.map(e=>t(e)));for(const e of o)n.push(...e)}return n}async requestPaginated(e){const t=this.withQueryParams(e,{per_page:Sn,page:1}),n=await this.requestWithResponse(t),s=[...n.data],a=this.parseTotalPages(n.headers);if(a&&a>1){const t=await this.fetchRemainingPagesInBatches(a,async t=>{const n=this.withQueryParams(e,{per_page:Sn,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===Sn){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:Sn,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<Sn)break;t+=1}}return s}async executeOperation(e,t){ye.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let n;switch(e){case"listRepos":n=await this.listRepos();break;case"listBranches":n=await this.listBranches(t.owner,t.name);break;case"createMergeRequest":n=await this.createMergeRequest(t);break;case"getMergeRequest":n=await this.getMergeRequest(t.owner,t.name,t.iid);break;case"listMergeRequests":n=await this.listMergeRequests(t.owner,t.name);break;case"triggerPipeline":n=await this.triggerPipeline(t);break;case"ensurePipelineTriggerToken":n=await this.ensurePipelineTriggerToken(t);break;case"requestGitlabApi":n=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":n={authMode:"local_pat",hasPat:!0};break;default:throw{status:400,message:`Unknown operation: ${e}`}}return ye.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,n)}`),n}catch(t){const n=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw ye.error(`${this.logPrefix()} operation failed: op=${e}, message=${n}`),t}}async listRepos(){return(await this.requestPaginated("/projects?membership=true&order_by=updated_at&sort=desc")).map(e=>({id:e.id,owner:e.path_with_namespace.split("/").slice(0,-1).join("/")||e.namespace.path,name:e.path,fullName:e.path_with_namespace,defaultBranch:e.default_branch,isPrivate:"private"===e.visibility,description:e.description,url:e.web_url,createdAt:e.created_at,updatedAt:e.updated_at}))}async listBranches(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.requestPaginated(`/projects/${n}/repository/branches`)).map(e=>({name:e.name,commit:{sha:e.commit.id,url:""},protected:e.protected}))}async createMergeRequest(e){const t=encodeURIComponent(`${e.owner}/${e.repo}`),n=await this.request(`/projects/${t}/merge_requests`,"POST",{source_branch:e.head,target_branch:e.base,title:e.title,description:e.body||""});return{number:n.iid,title:n.title,body:n.description,state:"opened"===n.state?"open":n.state,url:n.web_url,head:n.source_branch,base:n.target_branch,createdAt:n.created_at,updatedAt:n.updated_at}}async getMergeRequest(e,t,n){const s=encodeURIComponent(`${e}/${t}`),a=await this.request(`/projects/${s}/merge_requests/${n}`);return{number:a.iid,title:a.title,body:a.description,state:"opened"===a.state?"open":a.state,url:a.web_url,head:a.source_branch,base:a.target_branch,createdAt:a.created_at,updatedAt:a.updated_at}}async listMergeRequests(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.request(`/projects/${n}/merge_requests?state=opened&per_page=20`)).map(e=>({number:e.iid,title:e.title,body:e.description,state:"opened"===e.state?"open":e.state,url:e.web_url,head:e.source_branch,base:e.target_branch,createdAt:e.created_at,updatedAt:e.updated_at}))}parseNonEmptyString(e,t){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} is required`};return e.trim()}parseOptionalString(e,t){if(null!=e){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} must be a non-empty string`};return e.trim()}}resolveProjectPath(e){if("number"==typeof e.projectId||"string"==typeof e.projectId){const t=String(e.projectId).trim();if(t.length>0)return encodeURIComponent(t)}const t=this.parseOptionalString(e.projectPath,"projectPath");if(t)return encodeURIComponent(t);const n=this.parseOptionalString(e.owner,"owner"),s=this.parseOptionalString(e.repo??e.name,"repo");if(!n||!s)throw{status:400,message:"projectId, projectPath, or owner + repo is required"};return encodeURIComponent(`${n}/${s}`)}parsePipelineVariables(e){if(null==e)return{};if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Pipeline variables must be an object"};const t={};for(const[n,s]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw{status:400,message:`Pipeline variable name is invalid: ${n}`};if(null!=s){if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Pipeline variable value for "${n}" is invalid`};t[n]=String(s)}}return t}isUsableTriggerToken(e){return"string"==typeof e&&e.length>=20&&!e.includes("*")}async resolvePipelineTriggerToken(e,t){const n=this.parseOptionalString(t.triggerToken,"triggerToken");if(n)return n;if(!0!==t.createTriggerIfMissing)throw{status:400,message:"triggerToken is required unless createTriggerIfMissing is true"};const s=this.parseOptionalString(t.triggerDescription,"triggerDescription")??"Agentrix webhook bridge",a=(await this.requestPaginated(`/projects/${e}/triggers`)).find(e=>e.description===s&&this.isUsableTriggerToken(e.token));if(a?.token)return a.token;const i=new URLSearchParams;i.set("description",s);const o=await this.requestForm(`/projects/${e}/triggers`,i);if(!this.isUsableTriggerToken(o.token))throw{status:502,message:"GitLab did not return a usable pipeline trigger token"};return o.token}async ensurePipelineTriggerToken(e){const t=this.resolveProjectPath(e);return{token:await this.resolvePipelineTriggerToken(t,{...e,createTriggerIfMissing:!0})}}async triggerPipeline(e){const t=this.resolveProjectPath(e),n=this.parseNonEmptyString(e.ref,"ref"),s=this.parsePipelineVariables(e.variables),a=await this.resolvePipelineTriggerToken(t,e),i=new URLSearchParams;i.set("token",a),i.set("ref",n);for(const[e,t]of Object.entries(s))i.set(`variables[${e}]`,t);const o=await this.requestForm(`/projects/${t}/trigger/pipeline`,i);return{id:o.id,iid:o.iid,projectId:o.project_id,ref:o.ref,sha:o.sha,status:o.status,source:o.source,url:o.web_url,createdAt:o.created_at,updatedAt:o.updated_at}}parseProxyMethod(e){const t="string"==typeof e?e.toUpperCase():"GET";if("GET"===t||"POST"===t||"PUT"===t||"PATCH"===t||"DELETE"===t)return t;throw{status:400,message:`Unsupported proxy method: ${String(e)}`}}parseProxyPath(e){if("string"!=typeof e||0===e.length)throw{status:400,message:"Proxy path is required"};if(!e.startsWith("/"))throw{status:400,message:'Proxy path must start with "/"'};if(e.includes("://")||e.includes(".."))throw{status:400,message:"Proxy path contains invalid segments"};if(e.includes("?"))throw{status:400,message:"Proxy path must not contain query string; use payload.query"};return e}buildProxyQueryString(e){if(null==e)return"";if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Proxy query must be an object"};const t=new URLSearchParams;for(const[n,s]of Object.entries(e))if(null!=s)if(Array.isArray(s))for(const e of s){if("string"!=typeof e&&"number"!=typeof e&&"boolean"!=typeof e)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(e))}else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(s))}return t.toString()}isProxyAllowed(e,t){return Tn.some(n=>n.method===e&&n.pattern.test(t))}async requestGitlabApi(e){const t=this.parseProxyMethod(e.method),n=this.parseProxyPath(e.path),s=this.buildProxyQueryString(e.query),a=s.length>0?`${n}?${s}`:n;if(!this.isProxyAllowed(t,n))throw{status:403,message:`Proxy path not allowed: ${t} ${n}`};return"GET"===t?await this.request(a,t):await this.request(a,t,e.body)}}function _n(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function Cn(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function An(e){return ge.isAxiosError(e)?{message:e.message,status:e.response?.status,code:e.code}:{message:e instanceof Error?e.message:String(e)}}async function $n(e,t){if(!e.apiKey)throw new Error("missing api key");const n="anthropic"===t?{"x-api-key":e.apiKey,"anthropic-version":"2023-06-01"}:{Authorization:`Bearer ${e.apiKey}`},s=await ge.get(_n(e.baseUrl),{headers:n,timeout:1e4});return(s.data?.data||[]).map(e=>e&&"object"==typeof e&&"id"in e?String(e.id):null).filter(e=>Boolean(e))}async function Mn(e){const t=function(e){try{const t=new URL(e).hostname.toLowerCase();if("api.anthropic.com"===t||t.endsWith(".anthropic.com"))return"anthropic";if("api.openai.com"===t||t.endsWith(".openai.com"))return"openai"}catch{return null}return null}(e.baseUrl),n=t?[t]:["anthropic","openai"];let s;for(const a of n){ye.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${Cn(_n(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await $n(e,a);return ye.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=An(t);ye.warn(`[MODELS] Models request failed: source=${e.source}, protocol=${a}, status=${n.status??"-"}, code=${n.code??"-"}, message=${n.message}`)}}throw s instanceof Error?s:new Error("failed to fetch models")}function Pn(e,t){const n=t.ANTHROPIC_MODEL||e?.model||process.env.ANTHROPIC_MODEL;if(!n)return;const s=n.toLowerCase();return"opus"===s?t.ANTHROPIC_DEFAULT_OPUS_MODEL||process.env.ANTHROPIC_DEFAULT_OPUS_MODEL||"claude-opus-4-6":"sonnet"===s?t.ANTHROPIC_DEFAULT_SONNET_MODEL||process.env.ANTHROPIC_DEFAULT_SONNET_MODEL||"claude-sonnet-4-6":"haiku"===s?t.ANTHROPIC_DEFAULT_HAIKU_MODEL||process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL||"claude-haiku-4-5":n}async function Rn(e){const t=[];if(!e||"claude"===e){const e=function(){const e=function(e){if(!r(e))return null;try{return JSON.parse(c(e,"utf-8"))}catch{return null}}(S(fe.claudeConfigDir,"settings.json")),t=e?.env||{},n=t.ANTHROPIC_BASE_URL||process.env.ANTHROPIC_BASE_URL||"https://api.anthropic.com",s=t.ANTHROPIC_AUTH_TOKEN||t.ANTHROPIC_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN||process.env.ANTHROPIC_API_KEY;return s?{baseUrl:n,apiKey:s,source:"claude",defaultModel:Pn(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=S(fe.codexHomeDir,"config.toml");if(!r(e))return process.env.OPENAI_API_KEY?{baseUrl:process.env.OPENAI_BASE_URL||"https://api.openai.com",apiKey:process.env.OPENAI_API_KEY,source:"codex",defaultModel:process.env.OPENAI_MODEL}:null;const t=c(e,"utf-8"),n=t.match(/^model_provider\s*=\s*"([^"]+)"/m)?.[1]||"openai",s=t.match(/^model\s*=\s*"([^"]+)"/m)?.[1],a=t.match(new RegExp(`\\[model_providers\\.${n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\]([\\s\\S]*?)(?=\\n\\[|$)`)),i=a?.[1]||"",o=i.match(/^\s*base_url\s*=\s*"([^"]+)"/m)?.[1]||process.env.OPENAI_BASE_URL||"https://api.openai.com",l=i.match(/^\s*env_key\s*=\s*"([^"]+)"/m)?.[1]||("agentrix"===n?"AGENTRIX_API_KEY":"OPENAI_API_KEY");return{baseUrl:o,apiKey:process.env[l],source:"codex",defaultModel:s}}();e&&t.push(e)}ye.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${Cn(e.baseUrl)}:hasKey=${Boolean(e.apiKey)}:defaultModel=${e.defaultModel??"-"}`).join(",")||"-"}`);const n=new Set,s=[],a=t.find(e=>e.defaultModel)?.defaultModel;for(const e of t)try{for(const t of await Mn(e))n.add(t)}catch(t){const n=An(t);s.push({source:e.source,baseUrl:Cn(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?ye.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):ye.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function Nn(e,t){return{eventId:G(),status:"failed",opCode:e,message:t}}function Dn(e){return async(t,n)=>{if(ye.info(`[EVENT HANDLER] create-task: ${t.taskId}, agentType=${t.agentType}, agentId=${t.agentId}`),"shadow"!==t.taskType&&e.onCompanionInteraction?.(t.chatId),"task-message"!==t.event)return ye.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(Nn(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&ye.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){ye.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function On(e){return async(t,n)=>{ye.debug(`[EVENT HANDLER] resume-task: ${t.taskId}, agentSessionId=${t.agentSessionId}`),"shadow"!==t.taskType&&e.onCompanionInteraction?.(t.chatId);try{const s=await e.workerManager.startWorker(t,"resume-task");"success"!==s.status&&ye.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){ye.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function jn(e){return async(t,n)=>{if(ye.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return ye.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(Nn(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await Rn(t.agentType);if(0===e.length&&!s)return ye.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(Nn(t.eventId,"No models available from configured endpoints"));ye.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:G(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){ye.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function Un(e){return async t=>{ye.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function qn(e){return async(t,n)=>{ye.info(`[EVENT HANDLER] deploy-agent received: taskId=${t.taskId}, draftAgentId=${t.draftAgentId}, targetAgentId=${t.targetAgentId}, sourcePath=${t.sourcePath}`);try{const s=await e.workerManager.startDeploymentWorker(t);"success"!==s.status&&ye.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){ye.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function Ln(e){return async(t,n)=>{ye.info(`[EVENT HANDLER] hive-publish received: taskId=${t.taskId}, name=${t.name}, repoDir=${t.repoDir}`);try{const s=await e.workerManager.startHivePublishWorker(t);"success"!==s.status&&ye.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){ye.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function Hn(e){return async(t,n)=>{ye.info(`[EVENT HANDLER] hive-install received: taskId=${t.taskId}, name=${t.name}, hiveListingId=${t.hiveListingId}`);try{const s=await e.workerManager.startHiveInstallWorker(t);"success"!==s.status&&ye.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){ye.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(Nn(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function Gn(e){return async t=>{ye.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||ye.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function Bn(e){return async t=>{ye.info(`[GITLAB PROXY] request received: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, ttlMs=${t.ttlMs}, payloadKeys=${function(e){const t=Object.keys(e||{});return t.length>0?t.join(","):"-"}(t.payload)}`);const n=Date.now(),s=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?(e.client.send("daemon-gitlab-response",s),ye.info(`[GITLAB PROXY] response sent: reqId=${t.requestId}, op=${t.operation}, success=${n.success}, executionMs=${n.executionTimeMs}`)):ye.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=await xn();if(!e)return ye.warn(`[GITLAB PROXY] git server encryption key unavailable: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"Git server encryption key not available",executionTimeMs:Date.now()-n});const a=In(t.gitServerId,e);if(!a)return ye.warn(`[GITLAB PROXY] PAT missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:`No PAT configured for git server ${t.gitServerId}`,executionTimeMs:Date.now()-n});const i=t.payload.apiUrl;if(!i)return ye.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:Date.now()-n});ye.info(`[GITLAB PROXY] executing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, apiHost=${function(e){try{return new URL(e).host}catch{return"invalid-url"}}(i)}`);const o=new En(i,a,{requestId:t.requestId,gitServerId:t.gitServerId}),r=await o.executeOperation(t.operation,t.payload);ye.info(`[GITLAB PROXY] execution succeeded: reqId=${t.requestId}, op=${t.operation}, summary=${function(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}(t.operation,r)}`),s({success:!0,data:r,executionTimeMs:Date.now()-n})}catch(e){const a=e;let i="GITLAB_CONNECTIVITY_FAILED";401===a.status?i="PAT_INVALID":403===a.status?i="PAT_SCOPE_INSUFFICIENT":404===a.status&&(i="RESOURCE_NOT_FOUND");const o="string"==typeof a.message?a.message:"Unknown error",r="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,c="number"==typeof a.status?String(a.status):"unknown";ye.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${i}, status=${c}, message=${o}${r?`, detail=${r}`:""}`),s({success:!1,errorCode:i,errorMessage:o,executionTimeMs:Date.now()-n})}}}const Fn=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function Wn(e,t){if(!e)return;if("string"==typeof t)return void(e.sendMessage?e.sendMessage(t):e.send&&e.send(t));const n=Buffer.from(t);e.sendMessageBinary?e.sendMessageBinary(n):e.send&&e.send(n)}class zn{client;machineId;iceServers=[];sessions=new Map;rtcModule;peerConstructor;constructor(e,t){this.client=e,this.machineId=t;const n=We(import.meta.url);var s;this.rtcModule=n("node-datachannel"),this.peerConstructor=(s=this.rtcModule).RTCPeerConnection||s.PeerConnection||s.RTCConnection||s.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}registerHandlers(){this.peerConstructor?(this.client.onLifecycle("connect",()=>{this.requestIceServers()}),this.client.onEvent("rtc-ice-servers-response",e=>this.handleIceServersResponse(e)),this.client.onEvent("machine-rtc-request",e=>this.handleRtcRequest(e)),this.client.onEvent("rtc-signal",e=>this.handleRtcSignal(e))):ye.warn("[RTC] node-datachannel RTCPeerConnection not available")}shutdown(){this.sessions.forEach(e=>{e.peerConnection.close?.()}),this.sessions.clear()}requestIceServers(){this.client.send("rtc-ice-servers-request",{eventId:G()})}handleIceServersResponse(e){this.iceServers=function(e){const t=[];return e.forEach(e=>{Array.isArray(e.urls)?t.push(...e.urls):t.push(e.urls)}),t}(e.iceServers),ye.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void ye.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId))return void this.sendMachineRtcResponse(e.sessionId,t,!0);const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),this.sendMachineRtcResponse(e.sessionId,t,!0)}sendMachineRtcResponse(e,t,n,s){this.client.send("machine-rtc-response",{eventId:G(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void ye.warn("[RTC] rtc-signal missing userId");const n=e.workspaceUserId||t,s=e.taskId;let a=this.sessions.get(e.sessionId);if(!a){const i=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers});a={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:i,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]},this.sessions.set(e.sessionId,a),this.registerPeerHandlers(a)}try{this.applyRemoteSignal(a,e.signal)}catch(e){ye.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{ye.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{ye.info(`[RTC] ICE gathering (${e.sessionId}): ${t}`)}),t.onLocalDescription?.((t,n)=>{const s=function(e,t){return e&&"object"==typeof e&&"string"==typeof e.sdp?{sdp:e.sdp,type:e.type||t}:{sdp:String(e||""),type:t}}(t,n);this.client.send("rtc-signal",{eventId:G(),machineId:this.machineId,sessionId:e.sessionId,from:"machine",signal:s,userId:e.userId})}),t.onLocalCandidate?.((t,n,s)=>{const a=function(e,t,n){return"string"==typeof e?{candidate:e,sdpMid:t||"0",sdpMLineIndex:n??0}:e&&"string"==typeof e.candidate?{candidate:e.candidate,sdpMid:e.sdpMid||e.mid||t||"0",sdpMLineIndex:"number"==typeof e.sdpMLineIndex?e.sdpMLineIndex:n??0}:null}(t,n,s);a&&this.client.send("rtc-signal",{eventId:G(),machineId:this.machineId,sessionId:e.sessionId,from:"machine",signal:{candidate:a},userId:e.userId})}),t.onDataChannel?.(t=>{e.dataChannel=t,this.registerDataChannel(e,t)})}registerDataChannel(e,t){t.onOpen?.(()=>{ye.info(`[RTC] Data channel open (${e.sessionId})`),e.lastActivity=Date.now(),Wn(t,JSON.stringify({v:1,type:"control.ready",channel:"control",requestId:`req-${e.sessionId}`,streamId:0,timestamp:(new Date).toISOString(),payload:{ok:!0}}))}),t.onClosed?.(()=>{ye.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{ye.error(`[RTC] Data channel error (${e.sessionId})`,t)}),t.onMessage?.(t=>{e.lastActivity=Date.now(),this.handleDataChannelMessage(e,t)})}handleDataChannelMessage(e,t){if(Buffer.isBuffer(t)||t instanceof Uint8Array){try{F(new Uint8Array(t))}catch(e){ye.warn("[RTC] Received binary payload without handler")}return}let n=null;if("string"==typeof t?n=t:t&&"string"==typeof t.text&&(n=t.text),!n)return;let s=null;try{s=JSON.parse(n)}catch(e){return void ye.warn("[RTC] Non-JSON message",n)}s&&"string"==typeof s.type&&"file.request"===s.type&&this.handleFileRequest(e,s).catch(e=>{ye.error("[RTC] Failed to handle file request",e)})}async handleFileRequest(e,t){const n=t.payload;if(!n)return;if(n.userId!==e.workspaceUserId)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"unauthorized",message:"Unauthorized workspace access"}});if(e.allowedTaskId&&n.taskId!==e.allowedTaskId)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"unauthorized",message:"Unauthorized task access"}});const s=(a=n.userId,o=n.taskId,r=n.relativePath,fe.resolveWorkspaceFilePath(a,o,r));var a,o,r;if(!i.existsSync(s))return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"file_not_found",message:"File or directory not found"}});const c=await i.promises.stat(s);if(!function(e,t){return!t||e.mtime.toISOString()!==t}(c,n.ifModifiedSince))return void this.sendControl(e,{v:1,type:"file.not_modified",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString()});if(c.isDirectory()||"directory"===n.entryType){const n=await i.promises.readdir(s,{withFileTypes:!0}),a={entries:await Promise.all(n.map(async e=>{const t=k.join(s,e.name),n=await i.promises.stat(t);return{name:e.name,type:e.isDirectory()?"directory":"file",size:n.size,modifiedAt:n.mtime.toISOString()}})),modifiedAt:c.mtime.toISOString()};return void this.sendControl(e,{v:1,type:"file.dir",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:a})}const l=1024*(n.maxFileSizeMB??Fn)*1024;if(c.size>l)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"file_too_large",message:"File exceeds size limit"}});const p=hn.lookup(s)||"application/octet-stream",d={size:c.size,mimeType:"string"==typeof p?p:"application/octet-stream",modifiedAt:c.mtime.toISOString()};this.sendControl(e,{v:1,type:"file.meta",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:d}),await this.sendFileChunks(e,t.streamId,s),this.sendControl(e,{v:1,type:"file.end",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{size:c.size}})}async sendFileChunks(e,t,n){const s=e.dataChannel;if(!s)return;const a=i.createReadStream(n,{highWaterMark:65536});let o=0;await new Promise((e,n)=>{a.on("data",e=>{const n=W.Binary|(0===o?W.Start:0),a=Buffer.isBuffer(e)?e:Buffer.from(e),i=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),r=z({streamId:t,seq:o,flags:n,payloadLength:i.length},i);Wn(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=z({streamId:t,seq:o,flags:W.End|W.Binary,payloadLength:0},new Uint8Array);Wn(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&Wn(n,JSON.stringify(t))}applyRemoteSignal(e,t){const{peerConnection:n}=e;if(t&&t.sdp&&t.type)return n.setRemoteDescription?.(t.sdp,t.type),e.remoteDescriptionSet=!0,e.pendingCandidates?.forEach(e=>{try{n.addRemoteCandidate?.(e.candidate,e.mid)}catch(e){ye.warn("[RTC] Failed to add queued candidate",e)}}),void(e.pendingCandidates=[]);if(t&&t.candidate){const s=t.candidate,a="string"==typeof s?s:s&&"string"==typeof s.candidate?s.candidate:null,i=t.sdpMid||s?.sdpMid||s?.mid||"0";if(a){if(!e.remoteDescriptionSet)return void e.pendingCandidates?.push({candidate:a,mid:i});n.addRemoteCandidate?.(a,i)}}}}class Kn{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new Zt(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client},this.rtcManager=new zn(this.client,s),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 30 seconds"))},3e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":Dn(t=this.context),"resume-task":On(t),"list-models":jn(t),"stop-task":Gn(t),"deploy-agent":qn(t),"hive-publish":Ln(t),"hive-install":Hn(t),"shutdown-machine":Un(t),"workspace-file-request":yn({client:t.client}),"daemon-gitlab-request":Bn(t)};var t;this.client.onEventWithAck("create-task",e["create-task"]),this.client.onEventWithAck("resume-task",e["resume-task"]),this.client.onEventWithAck("list-models",e["list-models"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEventWithAck("deploy-agent",e["deploy-agent"]),this.client.onEventWithAck("hive-publish",e["hive-publish"]),this.client.onEventWithAck("hive-install",e["hive-install"]),this.client.onEvent("shutdown-machine",e["shutdown-machine"]),this.client.onEvent("workspace-file-request",e["workspace-file-request"]),this.client.onEvent("daemon-gitlab-request",e["daemon-gitlab-request"])}}let Vn=null;let Xn=!1;async function Jn(){if(Xn)ye.info("[caffeinate] Already stopping, skipping");else if(Vn&&!Vn.killed){Xn=!0,ye.info(`[caffeinate] Stopping caffeinate process PID ${Vn.pid}`);try{Vn.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),Vn&&!Vn.killed&&Vn.kill("SIGKILL"),Vn=null,Xn=!1}catch(e){ye.info("[caffeinate] Error stopping caffeinate:",e),Xn=!1}}}let Yn=!1;function Qn(e){const{pid:t,name:n,cmd:s}=e;if(t===process.pid||t===process.ppid)return null;if(!(n.includes("agentrix")||"node"===n&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("dist\\index.mjs"))||("MainThread"===n||n.includes("MainThread"))&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("agentrix.mjs"))||s.includes("agentrix.mjs")||s.includes("agentrix-cli")||s.includes("tsx")&&s.includes("src/index.ts")&&s.includes("agentrix-cli")))return null;let a="unknown";const i=s.toLowerCase();return i.includes(" worker")?a="worker":i.includes(" upgrade-daemon")?a="upgrade-daemon":i.includes(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function Zn(){try{let e;e="win32"===process.platform?await async function(){try{const e=Ke("wmic process where \"name='node.exe'\" get ProcessId,CommandLine /format:csv",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}),t=[],n=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=1;e<n.length;e++){const s=n[e];if(!s)continue;const a=s.indexOf(",");if(-1===a)continue;const i=s.substring(a+1),o=i.lastIndexOf(",");if(-1===o)continue;const r=i.substring(0,o).trim(),c=i.substring(o+1).trim(),l=parseInt(c,10);isNaN(l)||t.push({pid:l,name:"node",cmd:r})}return t}catch(e){return[]}}():(await Ve()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=Qn(n);e&&t.push(e)}return t}catch(e){return[]}}function es(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:Ke(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function ts(){const e=Je(),t=function(){const e=es("git"),t=es("claude"),n=es("codex");return[{name:"git",installed:e.available,required:!0,description:"Version control system (required for all tasks)",installCommand:"https://git-scm.com/downloads",path:e.path},{name:"claude",installed:t.available,required:!0,description:"Claude Code CLI (required for most features)",installCommand:"npm install -g @anthropic-ai/claude-code",path:t.path},{name:"codex",installed:n.available,required:!1,description:"Codex CLI (optional, for Codex tasks)",installCommand:"npm install -g @codex-ai/codex-cli",path:n.path}]}(),n=function(e){if("macos"===e){const e=es("rg");return[{name:"ripgrep",installed:e.available,required:!0,description:"Fast code search tool (required by sandbox)",installCommand:"brew install ripgrep",path:e.path}]}if("linux"===e){const e=es("bwrap"),t=es("socat");return[{name:"bubblewrap",installed:e.available,required:!0,description:"Sandboxing tool for Linux",installCommand:"sudo apt install bubblewrap # Debian/Ubuntu\nsudo yum install bubblewrap # RHEL/CentOS\nsudo pacman -S bubblewrap # Arch",path:e.path},{name:"socat",installed:t.available,required:!0,description:"Socket communication tool (required by sandbox)",installCommand:"sudo apt install socat # Debian/Ubuntu\nsudo yum install socat # RHEL/CentOS\nsudo pacman -S socat # Arch",path:t.path}]}return[]}(e),s=t.filter(e=>e.required&&!e.installed),a=n.filter(e=>e.required&&!e.installed);return{cli:t,sandbox:n,allSatisfied:0===s.length&&0===a.length,missingSandbox:a,missingCli:s}}function ns(){const e=ts(),t=[],n=e.cli.find(e=>"git"===e.name);n&&!n.installed&&t.push("git");for(const n of e.missingSandbox)t.push(n.name);return{ok:0===t.length,missing:t}}function ss(){return{PWD:process.env.PWD,AGENTRIX_HOME_DIR:process.env.AGENTRIX_HOME_DIR,AGENTRIX_SERVER_URL:process.env.AGENTRIX_SERVER_URL,AGENTRIX_PROJECT_ROOT:process.env.AGENTRIX_PROJECT_ROOT,DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING:process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING,NODE_ENV:process.env.NODE_ENV,DEBUG:process.env.DEBUG,workingDirectory:process.cwd(),processArgv:process.argv,agentrixDir:fe.agentrixHomeDir,serverUrl:fe.serverUrl,logsDir:fe.getStatePaths().logsDir,processPid:process.pid,nodeVersion:process.version,platform:process.platform,arch:process.arch,user:process.env.USER,home:process.env.HOME,shell:process.env.SHELL,terminal:process.env.TERM}}async function as(e){if(e||(e="all"),console.log(D.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(D.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${D.green(xe.version)}`),console.log(`Platform: ${D.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${D.green(process.version)}`),console.log(""),console.log(D.bold("🔧 Daemon Spawn Diagnostics"));const e=ve(),t=S(e,"bin","agentrix.mjs"),n=S(e,"dist","index.mjs");console.log(`Project Root: ${D.blue(e)}`),console.log(`Wrapper Script: ${D.blue(t)}`),console.log(`CLI Entrypoint: ${D.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?D.green("✓ Yes"):D.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?D.green("✓ Yes"):D.red("❌ No")}`),console.log(""),console.log(D.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${D.blue(fe.agentrixHomeDir)}`),console.log(`Server URL: ${D.blue(fe.serverUrl)}`),console.log(`Logs Dir: ${D.blue(fe.getStatePaths().logsDir)}`),console.log(D.bold("\n🌍 Environment Variables"));const s=ss();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?D.green(s.AGENTRIX_HOME_DIR):D.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?D.green(s.AGENTRIX_SERVER_URL):D.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?D.yellow("ENABLED"):D.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?D.green(s.DEBUG):D.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?D.green(s.NODE_ENV):D.gray("not set")}`),console.log(D.bold("\n🔐 Authentication"));try{await fe.readCredentials()?console.log(D.green("✓ Authenticated (credentials found)")):console.log(D.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(D.red("❌ Error reading credentials"))}!function(e=!1){const t=ts(),n=Je();console.log(D.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(D.green(`✓ ${n.name}`),D.gray(`- ${n.description}`)),e&&n.path&&console.log(D.gray(` Location: ${n.path}`));else{const e=n.required?D.red("❌"):D.yellow("⚠️");console.log(`${e} ${n.name}`,D.gray(`- ${n.description}`)),n.installCommand&&console.log(D.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(D.bold("\n🔒 Sandbox Dependencies")),console.log(D.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(D.green(`✓ ${n.name}`),D.gray(`- ${n.description}`)),e&&n.path&&console.log(D.gray(` Location: ${n.path}`))):(console.log(D.red(`❌ ${n.name}`),D.gray(`- ${n.description}`)),n.installCommand&&console.log(D.blue(` Install: ${n.installCommand}`)))}else console.log(D.bold("\n🔒 Sandbox Dependencies")),console.log(D.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(D.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(D.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(D.red(` • ${t.name}`));console.log(D.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(D.bold("\n🤖 Daemon Status"));try{const t=await Bt(),n=await fe.readDaemonState();if(t&&n?(console.log(D.green("✓ Daemon is running")),console.log(` PID: ${n.pid}`),console.log(` Started: ${new Date(n.startTime).toLocaleString()}`),console.log(` CLI Version: ${n.cliVersion}`),n.port&&console.log(` HTTP Port: ${n.port}`)):n&&!t?console.log(D.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(D.red("❌ Daemon is not running")),n){console.log(D.bold("\n📄 Daemon State:"));const e=fe.getStatePaths();console.log(D.blue(`Location: ${e.daemonStateFile}`)),console.log(D.gray(JSON.stringify(n,null,2)))}const s=await Zn();if(s.length>0){console.log(D.bold("\n🔍 All Agentrix CLI Processes"));const e=s.reduce((e,t)=>(e[t.type]||(e[t.type]=[]),e[t.type].push(t),e),{});Object.entries(e).forEach(([e,t])=>{console.log(D.blue(`\n${{daemon:"🤖 Daemon","upgrade-daemon":"🔄 Upgrade Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?D.cyan:e.includes("daemon")?D.blue:D.gray;console.log(` ${s(`PID ${t}`)}: ${D.gray(n)}`)})})}else console.log(D.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(D.bold("\n💡 Process Management")),console.log(D.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(D.red("❌ Error checking daemon status"))}}let is=null;async function os(){const e=us(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(is&&is.expiresAt>Date.now()&&is.overridesSignature===t)return is.openers;const n=cs(e),s=[];for(const e of n){const t=e.isSupported();t&&s.push({id:e.id,label:e.label,kind:e.kind,method:e.method,urlTemplate:e.urlTemplate,supported:t})}return is={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function rs(e){const t=process.platform;if("darwin"===t)return function(e){const t=ls(e),n=[];if(t){const e=xs(t);n.push("-e",`set defaultLocation to POSIX file "${e}"`,"-e","set chosenFolder to choose folder default location defaultLocation")}else n.push("-e","set chosenFolder to choose folder");return n.push("-e","POSIX path of chosenFolder"),ps(fs("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=gs("powershell")?"powershell":gs("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=ls(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${vs(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return ps(fs(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=ls(e);if(gs("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return ps(fs("zenity",e,{captureOutput:!0}))}if(gs("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),ps(fs("kdialog",e,{captureOutput:!0}))}throw new Error("No supported directory picker is available")}(e);throw new Error("Directory picker is not supported on this platform")}function cs(e){const t=process.platform,n=["Visual Studio Code","Visual Studio Code - Insiders"],s=["Cursor"],a=["IntelliJ IDEA","IntelliJ IDEA CE","IntelliJ IDEA Ultimate"],i=["WebStorm"],o=["PyCharm","PyCharm CE","PyCharm Professional"],c=[{id:"vscode",label:"VS Code",kind:"editor",method:"scheme",urlTemplate:"vscode://file/{path}?windowId=_blank",scheme:"vscode",macAppNames:n,isSupported:()=>ms("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>ms("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>ms("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>ms("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>ms("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?gs("osascript")&&hs("Terminal"):"win32"===e?gs("wt")||gs("powershell")||gs("pwsh")||gs("cmd"):"linux"===e&&Boolean(ds())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(gs("wt"))return void ys("wt",["-d",e]);const t=gs("powershell")?"powershell":gs("pwsh")?"pwsh":null;return t?void ys(t,["-NoExit","-Command",`Set-Location -LiteralPath '${vs(e)}'`]):void ys("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=ds();if(!t)throw new Error("No supported terminal is available");return void ys(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!fs("osascript",["-e",'tell application "Terminal"',"-e",`do script "${xs(`cd ${ws(e)}`)}"`,"-e","activate","-e","end tell"]))throw new Error("Failed to open Terminal")}(e,t)},{id:"file-manager",label:"darwin"===t?"Finder":"win32"===t?"Explorer":"Files",kind:"file-manager",method:"cli",isSupported:()=>function(e){return"darwin"===e?gs("open"):"win32"===e||"linux"===e&&(gs("xdg-open")||gs("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return gs("xdg-open")?void fs("xdg-open",[e]):void fs("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}fs("explorer",[e])}else fs("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?gs("osascript"):"win32"===e?gs("powershell")||gs("pwsh"):"linux"===e&&gs("gio")}(t),open:e=>function(e,t){if("darwin"!==t)if("win32"!==t){if("linux"!==t)throw new Error("Open With is not supported on this platform");fs("gio",["open","--ask",e])}else fs(gs("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${vs(e)}'`]);else if(null===fs("osascript",["-e",`set targetPath to POSIX file "${xs(e)}"`,"-e","set appChoice to choose application","-e","tell appChoice to open targetPath"],{captureOutput:!0}))throw new Error("No application selected")}(e,t)}];return function(e,t,n){const s=n??us();return e.map(e=>{const n=s[e.id];if(!n)return e;if(!1===n.enabled)return{...e,isSupported:()=>!1};const a={...e,label:n.label??e.label,method:n.method??e.method,urlTemplate:n.urlTemplate??e.urlTemplate};if(n.command){const s=function(e){return e?Array.isArray(e)?e:[e]:[]}(n.appName??e.macAppNames);a.method="cli",a.isSupported=()=>function(e,t,n){return"darwin"===n&&t.length>0?t.some(e=>hs(e)):I.isAbsolute(e)||e.includes(I.sep)?r(e):gs(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!fs(e,(t&&t.length>0?t:["{path}"]).map(e=>e.split("{path}").join(n))))throw new Error(`Command failed: ${e}`)}(n.command,n.args,e)}return a})}(c,t,e)}function ls(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!d(t).isDirectory())return}catch{return}return t}}function ps(e){if(!e)return null;return e.trim()||null}function ds(){const e=ws(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&gs(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${ws(t)} && exec ${e}`]}:[{command:"gnome-terminal",args:e=>["--working-directory",e]},{command:"kgx",args:e=>["--working-directory",e]},{command:"konsole",args:e=>["--workdir",e]},{command:"xfce4-terminal",args:e=>["--working-directory",e]},{command:"mate-terminal",args:e=>["--working-directory",e]},{command:"lxterminal",args:e=>["--working-directory",e]},{command:"alacritty",args:e=>["--working-directory",e]},{command:"kitty",args:e=>["--directory",e]},{command:"xterm",args:t=>["-e","sh","-lc",`cd ${ws(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${ws(t)} && exec ${e}`]}].find(e=>gs(e.command))??null}function us(){try{const e=fe.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return ye.warn("[OPENERS] Failed to read opener overrides",e),{}}}function ms(e,t,s){return"darwin"===t?function(e,t){if(gs("mdfind")){const t=fs("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(gs("plutil")){const t=[I.join(n.homedir(),"Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"),"/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"];for(const n of t){if(!r(n))continue;const t=fs("plutil",["-extract","LSHandlers","json","-o","-",n],{captureOutput:!0});if(t)try{const n=JSON.parse(t);if(Array.isArray(n)&&n.some(t=>t.LSHandlerURLScheme?.toLowerCase()===e.toLowerCase()))return!0}catch(e){ye.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>hs(e))}(e,s):"win32"===t?function(e){return gs("reg")&&(Boolean(fs("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean(fs("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(gs("xdg-settings")){const t=fs("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(gs("gio")){const t=fs("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function hs(e){return"darwin"===process.platform&&Boolean(fs("open",["-Ra",e]))}function gs(e){return"win32"===process.platform?Boolean(fs("where",[e])):Boolean(fs("sh",["-c",`command -v ${e}`]))}function fs(e,t,n){const s=nt(e,t,{encoding:n?.captureOutput?"utf8":void 0,stdio:n?.captureOutput?"pipe":"ignore",windowsHide:!0});if(0!==s.status){if(n?.captureOutput){const n="string"==typeof s.stderr?s.stderr.trim():"";n&&ye.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function ys(e,t){st(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function vs(e){return e.replace(/'/g,"''")}function xs(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function ws(e){return`'${e.replace(/'/g,"'\\''")}'`}function bs(e,t){if(t){const n=e.startsWith(t)?e.slice(t.length).replace(/^\//,""):T(e);return S(t,"versions",n)}let n=A(e),s=0;for(;s<10;){if(r(S(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return S(n,"versions",t)}const t=A(n);if(t===n)break;n=t,s++}const a=A(e),i=T(e);return S(a,`.${i}.version`)}function ks(e,t){const n=bs(e,t);if(!r(n))return"0.0.0";try{return c(n,"utf-8").trim()}catch(e){return"0.0.0"}}function Is(e,t,n){try{const s=bs(e,n),a=A(s);if(!r(a)){const{mkdirSync:e}=o;e(a,{recursive:!0})}u(s,t,"utf-8")}catch(e){}}function Ss(e,t){const n=e.split(".").map(Number),s=t.split(".").map(Number);for(let e=0;e<3;e++){const t=n[e]||0,a=s[e]||0;if(t>a)return 1;if(t<a)return-1}return 0}function Ts(e,t,n){const s=ks(e,n),a=Ss(t.metadata.version,s);if(!r(e)){const s=A(e);if(!r(s)){const{mkdirSync:e}=o;e(s,{recursive:!0})}return u(e,t.content,"utf-8"),Is(e,t.metadata.version,n),{updated:!0,reason:"created"}}if(a<=0)return{updated:!1,reason:"up-to-date"};switch(t.metadata.updateStrategy){case"overwrite":return u(e,t.content,"utf-8"),Is(e,t.metadata.version,n),{updated:!0,reason:"overwritten"};case"create-only":return{updated:!1,reason:"create-only"};case"notify-user":return{updated:!1,reason:"requires-user-approval"};default:return{updated:!1,reason:"unknown-strategy"}}}async function Es(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=S(fe.agentrixAgentsHomeDir,t);if(r(i))return{agentDir:i};const o=`${i}.tmp-${Date.now()}`;try{const e=["git","clone","--depth=1"];if(s&&e.push("--branch",s),e.push(n,o),at(e.join(" "),{stdio:"pipe"}),a){const e=S(o,a);if(!r(e))throw new Error(`Sub-directory "${a}" not found in cloned repository`);m(e,i),h(o,{recursive:!0,force:!0})}else m(o,i);return _s(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function _s(e){const t=[],n=S(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=S(n,e);d(s).isDirectory()&&r(S(s,"package.json"))&&t.push(s)}const s=S(e,"claude","hooks");r(s)&&r(S(s,"package.json"))&&t.push(s);for(const e of t)at("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),at("yarn build",{cwd:e,stdio:"pipe"})}function Cs(e){const t=e.split("\n");for(;t.length>0&&""===t[0].trim();)t.shift();for(;t.length>0&&""===t[t.length-1].trim();)t.pop();const n=t.reduce((e,t)=>{if(""===t.trim())return e;const n=t.match(/^\s*/)[0].length;return Math.min(e,n)},1/0);return t.map(e=>e.slice(n)).join("\n")}const As=Cs("\n ## Title Setting Protocol:\n - MUST set a descriptive title using mcp__agentrix__change_title as your FIRST action when the user makes a request\n - This is mandatory, not optional - do this before any other work\n - Update the title if the conversation direction changes substantially\n"),$s=Cs("\n Important: If the content to be written to a file is too long, split it into chunks and write them to the file incrementally. Writing too much content at once can easily cause errors.\n");function Ms(e){const t="group"===e?.chatType?.toLowerCase();return Cs(`\n ## External Channel Context\n\n ${function(e){const t=function(e){const t=e?.trim();return t?{telegram:"Telegram",wechat:"WeChat",lark:"Lark"}[t.toLowerCase()]??t:null}(e?.platform),n=[e?.chatType?`chat type: ${e.chatType}`:void 0,e?.chatName?`chat name: ${e.chatName}`:void 0,e?.chatId?`chat id: ${e.chatId}`:void 0].filter(Boolean).join(", ");return Cs(t?`\n This task was started from an external messaging channel on ${t}.\n The user is interacting with you through ${t}.\n ${n?`Channel context: ${n}.`:""}\n `:"\n This task was started from an external messaging channel such as Telegram, WeChat, or Lark.\n The user is interacting with you through that external platform.\n ")}(e)}\n\n ${t?Cs("\n This external channel is a group chat. Recent group history may already be injected into the current input as `<external_group_history>` with `<msg>` entries and sender metadata.\n\n If you need more context from earlier group messages, use `mcp__agentrix__get_channel_group_history` to page older saved group history. That tool is read-only and is only for understanding context/history.\n "):""}\n\n Your normal final result is NOT automatically sent to the external channel. It is stored in Agentrix/task history.\n\n The external user is waiting on the external platform. If you do not call \`mcp__agentrix__send_channel_message\` during this turn, the user will see absolutely nothing from your model-directed channel response. Any runtime fallback is only an emergency safety net; do not rely on it.\n\n You MUST use \`mcp__agentrix__send_channel_message\` to send anything the external user should see: acknowledgements, progress updates, questions, results, and failures.\n\n Before ending the task, you MUST ensure the external user has received an appropriate user-facing message via \`mcp__agentrix__send_channel_message\`.\n\n Do not put user-facing content only in the final internal result; the system will NOT forward the normal success result when you have used the channel message tool.\n\n For multi-step tasks, at minimum call \`mcp__agentrix__send_channel_message\` once before ending with the final conclusion.\n\n If the user receives no message at all, the answer is considered a failure regardless of how complete the internal result is.\n\n ## What to send with send_channel_message\n\n Use \`mcp__agentrix__send_channel_message\` to send user-facing conversational messages to the external channel.\n The purpose is to help the user understand that you are working, what state the work is in, and what the final result is.\n\n You should send:\n - Acknowledgement/progress when the task is long-running, multi-step, or requires waiting, so the user knows work started or is ongoing.\n - Questions/choices/permission requests when user input is needed or you are blocked.\n - User-understandable results when done: conclusion, summary, next steps, and key deliverable notes.\n - Clear failure/limitation messages when the task cannot be completed, a platform does not support something, permission is missing, or an external service fails.\n\n Do not send:\n - Internal reasoning, verbose execution logs, stack traces, debug dumps.\n - Internal summaries that only matter to Agentrix/task history.\n - Excessive implementation detail unless the user is explicitly collaborating technically and needs it.\n - Temporary paths, environment variables, tokens, secrets, or private data.\n\n Style:\n - External channel messages should feel like natural conversation: short, clear, useful.\n - For simple tasks, usually send only the final answer.\n - For long tasks, send a brief start/progress message and a final result message.\n - If attachments are sent, briefly explain what they are and what the user can do next.\n\n ## What attachments to send\n\n Attachments are part of \`send_channel_message\` and are only for deliverables the user should consume, save, view, or forward.\n\n Send attachments for:\n - Files the user explicitly asked to generate, export, package, send, or share.\n - Final deliverables such as images, posters, charts, PDFs, spreadsheets, reports, slides, archives, audio, or video.\n - Artifacts without which the channel answer would be incomplete.\n\n Do not send attachments for:\n - Files that were merely created, edited, read, downloaded, or used while doing the work.\n - Logs, caches, temporary files, build artifacts, intermediate screenshots, debug outputs unless the user explicitly asked for them.\n - Files containing secrets, credentials, private data, or local environment details.\n - Any file that is only part of the work process rather than a user deliverable.\n\n Decision rules:\n - A file generated for the user to use/view/save is usually an attachment deliverable.\n - A file created or modified while completing work is not automatically a deliverable; decide based on user intent.\n - Do not decide based on file location or directory.\n - A file inside the workspace can be a deliverable.\n - A file outside the workspace can still be unsafe or inappropriate.\n - Decide based on semantics and user intent, not path location.\n - When modifying files, do not send them automatically; summarize changes in text unless the user asked to receive, export, package, or forward those files.\n - If uncertain or risky, ask for confirmation via \`send_channel_message\` first.\n\n Do NOT send files just because they were created, edited, read, downloaded, or used during the task.\n After sending the external response, your final result can briefly summarize what you sent for Agentrix history.\n If the platform does not support sending that attachment type, explain that and provide the best available alternative.\n`)}Ms();const Ps=Cs('\n ## Input Data Format (Conversation Stream)\n\n Messages come in this XML format. Pay attention to `seq` to understand the order.\n\n <msg seq="N" at="ISO_TIME" senderType="human|agent" senderId="id" senderName="name">\n content\n </msg>\n'),Rs=Cs('\n ## Orchestration Decision Framework\n\n **Core Principle**: Analyze dependencies FIRST to choose orchestration mode.\n\n **Decision Rule**:\n - **No dependencies** (agents work independently) → Direct execution\n - **Has dependencies** (sequential, turn-taking, coordination) → Plan-Execute-Replan loop\n\n ### Mode 1: Direct Execution (No Dependencies)\n\n When agents can work independently with no coordination:\n - Single agent request\n - Parallel opinions (no need to build on each other)\n - Independent work tasks\n\n **Examples**:\n - "Claude, explain X" → invoke(claude)\n - "What do you both think?" → invoke(claude), invoke(codex)\n - "Claude, write parser. Codex, write formatter." → assign both\n\n ### Mode 2: Plan-Execute-Replan Loop (Has Dependencies)\n\n When work has sequential dependencies or coordination:\n\n **The Loop**:\n 1. **PLAN**: TodoWrite defines structure/order\n 2. **EXECUTE**: invoke/assign first agent\n 3. **WAIT**: Agent responds in next message batch\n 4. **REPLAN**: Update TODO (mark done), identify next\n 5. **REPEAT**: Continue until complete\n\n **Dependency types**:\n - **Sequential**: Agent B needs Agent A\'s output\n - **Turn-taking**: Debate/conversation structure (A→B→A)\n - **Coordination**: Multiple agents with defined roles\n\n **Example - Debate** (turn-taking dependency):\n ```\n User: "4-round debate on REST vs GraphQL"\n\n PLAN (TodoWrite):\n - [ ] Claude: Opening argument FOR REST\n - [ ] Codex: Counter argument FOR GraphQL\n - [ ] Claude: Rebuttal\n - [ ] Codex: Final response\n\n EXECUTE: invoke(claude, hint="You argue FOR REST. Present your opening argument.")\n WAIT: Claude responds with REST argument\n REPLAN: Mark done, next is codex\n EXECUTE: invoke(codex, hint="You argue FOR GraphQL. Counter the REST arguments.")\n WAIT: Codex responds with GraphQL argument\n REPLAN: Mark done, next is claude rebuttal\n EXECUTE: invoke(claude) // No hint needed - role already established from history\n REPEAT...\n ```\n\n **hint usage**: Use hint to reduce agent\'s attention cost or provide meta-context:\n - ✅ Role assignment: first turn of debate (hint="You argue FOR REST")\n - ✅ Focus guidance: (hint="Focus only on performance aspects")\n - ✅ Long/busy chat: help agent locate relevant context (hint="Respond to Alice\'s question about caching")\n - ✅ Multi-topic: clarify which thread to address (hint="Re: the API design discussion")\n - ❌ Short, clear context: agent can easily find what to respond to\n - ❌ Role already established: agent knows their role from recent history\n\n **Why TodoWrite**: Planner is event-driven, can\'t "wait" for responses. TodoWrite provides persistent state across turns.\n\n ### Best Practices\n\n - Match agent to user intent by reviewing capabilities (get_task_agents)\n - Review history (get_task_history) when context is unclear\n\n ### Common Mistakes\n\n - ❌ Invoke just because an agent spoke; only act on unmet user requests\n - ❌ Repeated or cascading invokes on the same request\n - ❌ Invoke multiple agents with dependencies simultaneously\n - ❌ Use TodoWrite for independent requests (over-engineering)\n - ❌ Forget to update TODO after agent responds\n'),Ns=Cs('\n You are Planner, orchestrating a chat group where Users and Agents interact.\n Your goal is to observe the conversation stream, analyze context, and direct appropriate agents via tools.\n\n ## Visibility Rules\n\n - Your text output is NOT shown to users, but IS visible to developers for debugging\n - Keep brief reasoning/analysis in your output to help developers understand your decisions\n - NEVER attempt to answer user questions directly - let agents handle all user interaction\n\n ## Output Format\n\n 1. Brief reasoning (for developer debugging)\n 2. Tool calls if needed\n 3. Final output: ONLY "✅" on a new line (no other text after it)\n'),Ds=Cs("\n # Task Delegation\n\n ## When to Delegate (use create_task)\n\n - Implementation work: writing code, editing files, running tests\n - Investigation: multi-file analysis, tracing bugs, code archaeology\n - Code reviews, audits, or quality scans\n - Producing artifacts: reports, plans, configs\n - Any work where the user is waiting for you to finish before the conversation can continue\n\n ## When to Respond Directly\n\n - Answering questions, explaining concepts\n - Quick file lookups to answer a specific question (1-2 reads is fine)\n - Short code snippets or examples in conversation\n - Discussion, planning, decision-making with the user\n\n ## Your Role in Conversation\n\n The conversation is for **discussion, decisions, and summaries** — not for executing work.\n\n - Discuss approaches, trade-offs, and options with the user\n - Make decisions together (or present recommendations)\n - Summarize task results when they come back\n - Coordinate and plan — then delegate execution to tasks\n\n ## Anti-Patterns (Do NOT do these in conversation)\n\n - ❌ **Code editing**: Don't write/edit code directly in conversation — create a task\n - ❌ **Research rabbit holes**: Don't grep → read → grep → read in conversation — delegate the investigation\n - ❌ **Building artifacts**: Any output that produces files (code, reports, configs) belongs in a task\n - ❌ **Running tests/builds**: Don't run test suites or build commands in conversation — create a task\n\n **Rule of thumb**: If you're about to *change* something or *produce* something, it's a task. If you're about to *answer* something, respond directly.\n\n ## After Delegating\n\n - User sees task creation confirmation immediately\n - Continue responding to user's other questions\n - You'll receive <sub-task-result-updated> when task completes\n - Briefly summarize the result to user — no deep analysis needed\n - Do NOT create duplicate sub-tasks unless explicitly asked\n\n ## Using emit_to_task Effectively\n\n emit_to_task sends follow-up instructions to a running or completed sub-task. Use it for:\n\n - **User adds requirements**: User says \"also add tests\" → emit to the existing task, don't create a new one\n - **Passing decisions**: You discussed options with user, user chose option B → emit the decision to the task\n - **Course correction**: Task went in wrong direction → emit new guidance\n - **Providing context**: Task asks a question → get answer from user → emit answer to task\n - **Retry after failure**: Task failed → emit instructions to retry with fixes\n\n Do NOT use emit_to_task to:\n - Start a completely different task (create a new task instead)\n - Send very long instructions (if the scope changed drastically, create a new task)\n\n ## Task Granularity\n\n - **One task = one coherent unit of work** (e.g., \"implement login page\", \"investigate memory leak\")\n - Don't create a task for a single trivial operation (e.g., \"read one file\")\n - Don't cram unrelated work into one task — split them so they can run in parallel\n - Multiple independent tasks CAN run in parallel\n"),Os=Cs(`\n ${Ns}\n\n ${Ps}\n\n ${Rs}\n`),js=Cs('\n ## Message Format\n\n Messages in this group chat are formatted as XML:\n\n <msg seq="N" at="ISO_TIME" senderType="human|agent" senderId="id" senderName="name">\n content\n </msg>\n\n You may also receive a `<hint>` block at the start:\n\n <hint>\n context or instruction from the orchestrator\n </hint>\n\n The hint provides context for your response (e.g., debate role, focus area).\n Follow the hint\'s guidance while responding to the conversation.\n\n When responding, just reply naturally - the system will handle formatting.\n');function Us(e){const t=["# Available Agents",""];for(const n of e)n.description?t.push(`- **${n.name}** (${n.id}): ${n.description}`):t.push(`- **${n.name}** (${n.id})`);return t.join("\n")}function qs(e,t){const n=t.find(t=>t.id===e);if(!n)return Us(t);const s=t.filter(t=>t.id!==e),a=["# Group Context","",`You are \`${n.name}\`. `,"You are a member of this group chat."];if(n.description&&a.push(`Your role: ${n.description}`),s.length>0){a.push(""),a.push("## Other Agents in This Group"),a.push("");for(const e of s)e.description?a.push(`- **${e.name}**: ${e.description}`):a.push(`- **${e.name}**`)}return a.push(""),a.push(js),a.join("\n")}function Ls(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function Hs(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function Gs(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function Bs(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(Hs).map(e=>e.text).join("\n").trim():""}function Fs(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n={input_tokens:e.usage.input_tokens,output_tokens:e.usage.output_tokens,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:e.usage.cached_input_tokens,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"};return{type:"result",subtype:"success",duration_ms:0,duration_api_ms:0,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:n,modelUsage:{[e.model]:{inputTokens:t>0?t:0,outputTokens:e.usage.output_tokens,cacheReadInputTokens:e.usage.cached_input_tokens,cacheCreationInputTokens:0,webSearchRequests:0,costUSD:0,contextWindow:0,maxOutputTokens:0}},permission_denials:[],uuid:crypto.randomUUID(),session_id:e.sessionId,structured_output:e.structuredOutput}}function Ws(e,t){if(!t)return;const n=e?.trim();if(!n)throw new Error("Structured output was requested but the agent returned an empty response");try{return JSON.parse(n)}catch(e){const t=n.length>200?`${n.slice(0,200)}...`:n;throw new Error(`Structured output was requested but the agent returned invalid JSON: ${e instanceof Error?e.message:"unknown error"}; response=${JSON.stringify(t)}`)}}const zs="agentrix",Ks="1.0.0";async function*Vs(e){yield e}let Xs;const Js=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],Ys=["Glob","Grep","Read","Skill"],Qs=["Read","Glob","Grep"],Zs=["Read","Glob","Grep","TodoWrite"];function ea(e,t,n,s,a,i,o,c){const l=function(e){const{agentId:t,modeConfig:n,cwd:s,agentConfig:a,channelBound:i,channelContext:o,projectGuidance:r}=e,{mode:c,groupAgents:l}=n,p=a.customSystemPrompt,d=a.systemPromptMode??"append",u=function(e){const{mode:t,supportChangeTitle:n}=e,s=[$s];switch(t){case"work":case"group_work":n&&s.unshift(As);break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":s.unshift(Ds)}return s.join("\n\n")}(n);if("group_chat"===c||"group_work"===c){const e=[Os];return l&&l.length>0&&e.push(Us(l)),u&&e.push(u),i&&e.push(Ms(o)),r?.systemPromptAppend&&e.push(r.systemPromptAppend),e.join("\n\n")}const m="reply"===c&&l&&l.length>0?qs(t,l):void 0,h={},g=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE;g&&(h.COMPANION_HOME=g,h.COMPANION_MODE="companion_shadow"===c?"shadow":"chat");const f=Object.keys(h).length>0?h:void 0,y=p?Le(p,s,f):void 0;if("replace"===d&&y){const e=[y];return m&&e.push(m),u&&e.push(u),i&&e.push(Ms(o)),r?.systemPromptAppend&&e.push(r.systemPromptAppend),e.join("\n\n")}const v=[];return m&&v.push(m),u&&v.push(u),i&&v.push(Ms(o)),y&&v.push(y),r?.systemPromptAppend&&v.push(r.systemPromptAppend),{type:"preset",preset:"claude_code",append:v.length>0?v.join("\n\n"):void 0}}({agentId:e,modeConfig:n.modeConfig,cwd:n.cwd,agentConfig:s,channelBound:n.channelBound,channelContext:n.channelContext,projectGuidance:n.projectAgentrixGuidance}),p=function(e){switch(e){case"work":case"companion_shadow":return;case"chat":case"companion_chat":return[...Js];case"reply":return[...Ys];case"group_chat":return[...Qs];case"group_work":return[...Zs]}}(n.modeConfig.mode),d=function(e,t){const n={},s=e=>async(t,n,s)=>await e(t,n,s)??{},a=new Set([...Object.keys(e),...t?Object.keys(t):[]]);for(const i of a){const a=[],o=e[i];o&&a.push(s(o));const r=t?.[i];r&&a.push(s(r)),n[i]=[{hooks:a}]}return n}(n.hooks??{},a),u=function(){if(void 0!==Xs)return Xs??void 0;const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(e){const t=function(e){const t=e.trim();if(t){if(t.includes("/")||t.includes("\\")||t.startsWith(".")){const e=$(t)?t:_(t);return r(e)?e:void 0}return function(e){const t="win32"===process.platform?"where":"which",n=nt(t,[e],{encoding:"utf-8"});if(0===n.status)return n.stdout.split(/\r?\n/).map(e=>e.trim()).find(e=>e.length>0)}(t)}}(e);if(t)return Xs=t,t}Xs=null}(),m=o?function(e){const{modeConfig:t,tools:n,agentType:s,allowAskUser:a=!0,supportedFeatures:i,channelBound:o,channelGroupBound:r,visionModel:c,serverName:l=zs,serverVersion:p=Ks}=e,{mode:d,supportChangeTitle:u}=t,m=[];switch(d){case"work":i?.includes("sub-task")&&(m.push(n.createTask),m.push(n.replyToSubTask),m.push(n.listSubTask)),u&&m.push(n.changeTaskTitle),a&&m.push(n.askUser),m.push(n.getTaskHistory);break;case"chat":m.push(n.createTask),m.push(n.replyToSubTask),a&&m.push(n.askUser),m.push(n.getTaskHistory),m.push(n.listSubTask);break;case"group_chat":m.push(n.invoke),m.push(n.createSoloTask),m.push(n.createGroupTask),m.push(n.replyToSubTask),m.push(n.getTaskAgents),m.push(n.getTaskHistory);break;case"group_work":m.push(n.invoke),m.push(n.assign),u&&m.push(n.changeTaskTitle),m.push(n.getTaskAgents),m.push(n.getTaskHistory);break;case"reply":m.push(n.getTaskHistory),a&&m.push(n.askUser);break;case"companion_chat":m.push(n.createTask),m.push(n.replyToSubTask),a&&m.push(n.askUser),m.push(n.getTaskHistory),m.push(n.uploadFile),m.push(n.listAgents),m.push(n.scheduleTask);break;case"companion_shadow":m.push(n.getTaskHistory),m.push(n.readConversation),m.push(n.listAgents),m.push(n.scheduleTask)}("companion_chat"===d||"companion_shadow"===d)&&(m.push(n.listTasks),m.push(n.sendReminder),m.push(n.prepareHiveRepository),m.push(n.publishToHive),m.push(n.updateHiveListingVersion),m.push(n.recordHiveInstall),m.push(n.createHiveReview),m.push(n.createHiveComment)),"companion"===s&&m.push(n.updateAgentInfo),o&&"companion_shadow"!==d&&m.push(n.sendChannelMessage),r&&"companion_shadow"!==d&&m.push(n.getChannelGroupHistory),c&&"companion_shadow"!==d&&"reply"!==d&&m.push(n.analyzeImage);const h=ot({name:l,version:p,tools:m}),g=m.map(e=>((e,t)=>`mcp__${e}__${t}`)(l,e.name));return{server:h,toolNames:g}}({modeConfig:n.modeConfig,tools:o,agentType:t,allowAskUser:n.allowAskUser,supportedFeatures:n.supportedFeatures,channelBound:n.channelBound,channelGroupBound:n.channelGroupBound,visionModel:n.visionModel}):void 0,h={...m?.server?{agentrix:m.server}:{},...n.mcpServers??{},...i??{}};return{stderr:n.stderr,model:n.model||s.customModel,fallbackModel:s.customFallbackModel,cwd:n.cwd,resume:n.agentSessionId,permissionMode:n.initialPermissionMode??s.customPermissionMode??"bypassPermissions",settingSources:["user","project","local"],systemPrompt:l,tools:p,mcpServers:h,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?Ls(n.env):void 0,pathToClaudeCodeExecutable:u,maxTurns:s.customMaxTurns??n.maxTurns??c,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:d,outputFormat:n.structuredOutputSchema}}class ta{constructor(e,t,n,s,a){this.agentId=e,this.agentType=t,this.agentConfig=n,this.agentHooks=s,this.agentMcpServers=a}getAgentConfiguration(){return this.agentConfig}getHooks(){return this.agentHooks}getMcpServers(){return this.agentMcpServers}async executeHook(e,t,n){await async function(e,t,n,s){if(!e)return;const a=e[t];if(!a)return;const i=s||(e=>console.log(e));try{i(`[${t}] Executing hook...`);const e=new AbortController,s=setTimeout(()=>{e.abort()},6e4);try{await a(n,"",{signal:e.signal}),i(`[${t}] Hook executed successfully`)}finally{clearTimeout(s)}}catch(e){console.warn(`[${t}] Hook failed (non-fatal):`,e)}}(this.agentHooks,e,t,n)}async run(e,t){const n=this.agentConfig,s="string"==typeof e?Gs(e):e;let a=null;const i=rt({prompt:Vs(s),options:ea(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const e of i)if(console.log("ClaudeRunner.run: received message",JSON.stringify(e)),"result"===e.type){a=e;break}if(!a)throw new Error("ClaudeRunner.run: missing result message");return a}async*runStreamed(e,t){const n=this.agentConfig,s="string"==typeof e?Gs(e):e,a=rt({prompt:Vs(s),options:ea(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const e of a)if(yield e,"result"===e.type)break}loop(e){const t=e.abortController,n=this.agentConfig,s=ea(this.agentId,this.agentType,e,n,this.agentHooks,this.agentMcpServers,e.agentrixTools);let a=!1;const i=[];let o=null,r=null;const c=()=>{if(!a&&(a=!0,o)){const e=o;o=null,e(null)}},l=async function*(){for(;!a&&!t.signal.aborted;){if(i.length>0){yield i.shift();continue}const e=await new Promise(e=>{o=e});if(!e)break;yield e}},p=async function*(){try{const e=rt({prompt:l(),options:s});r=e;for await(const t of e)yield t}finally{r=null,c()}}();return t.signal.addEventListener("abort",c,{once:!0}),{push:e=>{if(console.log("ClaudeRunner.loop.push:",JSON.stringify(e,null,2)),a)return;const t="string"==typeof e?Gs(e):e;if(o){const e=o;return o=null,void e(t)}i.push(t)},events:p,stop:c,setPermissionMode:async e=>{r&&await r.setPermissionMode(e)}}}}function na(e,t,n){e&&e(t,"AGENT",n)}function sa(){return`Companion probe timed out after ${Math.round(45)}s`}function aa(e){return e instanceof Error&&e.message?e.message:String(e)}function ia(e){return"string"==typeof e.result&&e.result.trim()?e.result:Array.isArray(e.permission_denials)&&e.permission_denials.length>0?String(e.permission_denials[0]):"error_max_turns"===e.subtype?"Companion probe exceeded max turns":"Companion probe failed"}async function oa(){const e=S(fe.agentrixHomeDir,"tmp","companion-probe");p(e,{recursive:!0});const t=new ta("default","claude",{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}),n=new AbortController;let s=!1;const a=setTimeout(()=>{s=!0,n.abort()},45e3);try{const a=await t.run("hi",{cwd:e,abortController:n,modeConfig:{mode:"chat",supportChangeTitle:!1}});return a.is_error?{success:!1,error:s?sa():ia(a)}:{success:!0}}catch(e){return{success:!1,error:s?sa():aa(e)}}finally{clearTimeout(a)}}const ra=pt(it);function ca(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),dt(t)}async function la(e){try{const t=ca(e);return await t.checkIsRepo()}catch{return!1}}async function pa(e){const t=ca(e),n=(await t.raw(["worktree","list","--porcelain"])).trim().split("\n").filter(Boolean),s=[];let a=null;for(const e of n)if(e.startsWith("worktree "))a&&s.push(a),a={path:e.replace("worktree ","").trim(),branch:null,commit:"",isMain:0===s.length};else if(a)if(e.startsWith("HEAD "))a.commit=e.replace("HEAD ","").trim();else{if(e.startsWith("branch ")){const t=e.replace("branch ","").trim();a.branch=t.replace("refs/heads/","");continue}e.startsWith("detached")&&(a.branch=null)}return a&&s.push(a),s}async function da(e,t,n,s="HEAD"){const a=A(t);if(r(a)||p(a,{recursive:!0}),r(t)&&!wa(t))throw new Error(`Worktree directory already exists at ${t}`);const i=ca(e);await i.raw(["worktree","add","-b",n,t,s])}async function ua(e,t,n=!1){const s=ca(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function ma(e){const t=ca(e);await t.init()}async function ha(e){const t=ca(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function ga(e,t){const n=A(t);r(n)||p(n,{recursive:!0});const s=ca();await s.clone(e,t)}async function fa(e,t,n){const s=ca(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(n&&await s.checkout(n),await s.checkoutLocalBranch(t))}async function ya(e){const t=ca(e);return!(await t.status()).isClean()}async function va(e){const t=ca(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function xa(e){try{const t=ca(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function wa(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function ba(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function ka(e,t,n){const s=ca(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:ba(K(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function Ia(e,t){try{const{stdout:n}=await ra("git",t,{cwd:e,maxBuffer:10485760,windowsHide:!0});return n}catch(e){const t=e;if(1===t.code&&"string"==typeof t.stdout)return t.stdout;throw e}}function Sa(e){return e.split("\n").map(e=>e.trim()).filter(Boolean).map(e=>function(e){const[t,n,s]=e.split("\t");if(!t||!n||!s)return null;const a="-"===t?0:Number.parseInt(t,10),i="-"===n?0:Number.parseInt(n,10);if(Number.isNaN(a)||Number.isNaN(i))return null;const o=s.startsWith("/dev/null => ")?s.slice(13):s;return{path:ba(K(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function Ta(e,t){return pe("sha256").update(`${e}\n${t}`).digest("hex")}async function Ea(e,t){const n=await Ia(e,["diff","--binary","--find-renames",t,"--"]),s=Sa(await Ia(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await ra("git",["ls-files","--others","--exclude-standard","-z"],{cwd:e,maxBuffer:10485760,windowsHide:!0});return t.split("\0").filter(Boolean)}(e),i=await Promise.all(a.map(t=>Ia(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=Sa((await Promise.all(a.map(t=>Ia(e,["diff","--no-index","--numstat","--","/dev/null",t])))).join("\n")),r=function(e){const t=e.trim();return t?`${t}\n`:""}([n,...i].filter(Boolean).join("\n"));return r?{patch:r,stats:{totalInsertions:(c=[...s,...o]).reduce((e,t)=>e+t.insertions,0),totalDeletions:c.reduce((e,t)=>e+t.deletions,0),files:c},artifactVersion:Ta(t,r)}:null;var c}async function _a(e){const t=ca(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function Ca(e,t,n){const s=ca(e);await s.remote(["set-url",t,n])}function Aa(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function $a(e,t,n){const s=ca(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await Ca(e,t,n):await s.addRemote(t,n)}function Ma(e){const t=e.match(/^git@([^:]+):(.+)\/(.+?)(?:\.git)?$/);if(t){const[,n,s,a]=t;return{url:e,host:n.split("-")[0],owner:s,repo:a}}const n=e.match(/^https?:\/\/([^/]+)\/(.+)\/(.+?)(?:\.git)?$/);if(n){const[,t,s,a]=n;return{url:e,host:t,owner:s,repo:a}}return null}async function Pa(e){try{const t=ca(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?Ma(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const Ra="oauth2",Na="AGENTRIX_GIT_USERNAME",Da="AGENTRIX_GIT_PASSWORD";function Oa(){const e=S(s(),`git-askpass-${le()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${Na}:-${Ra}}" ;;\n *) printf '%s\\n' "\${${Da}:-}" ;;\nesac\n`,{mode:448}),e}function ja(e,t,n=Ra){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[Na]:n,[Da]:t}}const Ua=pt(it),qa="github",La="xmz-ai",Ha="agentrix-agent",Ga="https://github.com/xmz-ai/agentrix-agent.git",Ba="main";async function Fa(e,t,n){await Ua("git",["clone","--depth=1","--branch",t,e,n]),await $a(n,"origin",Aa(e))}async function Wa(e){const t=fe.resolveRepoStoreCheckoutDir(qa,La,Ha),n=S(t,"companion"),s=fe.resolveRepoStoreLockPath(qa,La,Ha),a=await fe.acquireFileLock(s);if(!a)throw new Error(`Timed out waiting for Companion template repository lock at ${s}`);try{const{gitUrl:s,branch:a}=await async function(e){if(e?.token){const t=await async function(e){const t=`${fe.serverUrl}/v1/agents/${encodeURIComponent("companion")}/git-url`;try{const n=await fetch(t,{headers:{Authorization:`Bearer ${e}`}});return n.ok?n.json():null}catch{return null}}(e.token);if(t?.gitUrl)return{gitUrl:t.gitUrl,branch:t.branch||Ba}}return{gitUrl:Ga,branch:Ba}}(e);if(!await la(t)){if(!wa(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await Fa(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(e){return{path:t,companionDir:n,pullSucceeded:!1,error:e instanceof Error?e.message:String(e)}}}try{return await async function(e,t,n){await Ua("git",["fetch","--depth=1",e,t],{cwd:n}),await Ua("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await $a(n,"origin",Aa(e))}(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(e){if(function(e){const t=e instanceof Error?e.message:String(e);return t.includes("refusing to merge unrelated histories")||t.includes("Not possible to fast-forward")||t.includes("non-fast-forward")}(e))try{return await async function(e,t,n){const s=S(A(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await Fa(e,t,s),h(n,{recursive:!0,force:!0}),m(s,n)}catch(e){throw h(s,{recursive:!0,force:!0}),e}}(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(s){return{path:t,companionDir:n,pullSucceeded:!1,error:`${e instanceof Error?e.message:String(e)}; failed to replace checkout: ${s instanceof Error?s.message:String(s)}`}}return{path:t,companionDir:n,pullSucceeded:!1,error:e instanceof Error?e.message:String(e)}}}finally{await fe.releaseFileLock(s,a)}}function za(e){return e.split("\\").join("/")}function Ka(e,t){const n=S(t,"template","versions",`${e}.json`);if(!r(n))return{};try{const e=c(n,"utf-8");return JSON.parse(e)}catch(e){return console.warn(`[Companion] Failed to parse ${n}:`,e),{}}}async function Va(e){const t=fe.agentrixAgentsHomeDir,n=S(t,"companion"),s=S(n,"claude"),a=!r(S(n,"agent.json")),i=await Wa(e?.credentials);let o=r(S(i.companionDir,"agent.json"))?i.companionDir:n;if(i.pullSucceeded||console.warn("[Companion] Template repository update failed:",i.error||"unknown error"),a){const e=await oa();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(S(o,"agent.json")))y(o,n,{recursive:!0}),_s(n),console.log("[Companion] Installed from template repository");else try{await Es({agentId:"companion",gitUrl:Ga,branch:"main",subDir:"companion"}),console.log("[Companion] Installed from git fallback")}catch(e){console.warn("[Companion] Git install failed, will retry next boot:",e instanceof Error?e.message:e)}r(S(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await Es({agentId:"companion",gitUrl:Ga,branch:"main",subDir:"companion"})),o=r(S(i.companionDir,"agent.json"))?i.companionDir:n}var l;l=S(s,"memory"),r(l)||p(l,{recursive:!0});const{language:m,templates:h}=function(e,t,n){const s=function(e){const t=[e,process.env.AGENTRIX_COMPANION_TEMPLATE_LANGUAGE,process.env.LC_ALL,process.env.LC_MESSAGES,process.env.LANG];for(const e of t){if(!e)continue;const t=e.trim().toLowerCase();if(t){if(t.startsWith("zh"))return"zh-Hans";if(t.startsWith("en"))return"en"}}return"en"}(e),a=Ka("common",t),i=Ka(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=S(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n})}const p=function(e){const t={};if(!r(e))return t;const n=s=>{const a=g(s).sort();for(const i of a){const a=S(s,i);if(d(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=za(M(e,a));t[o]=c(a,"utf-8")}};return n(e),t}(S(t,"template","languages",s));for(const[e,t]of Object.entries(p)){const s=i[e]||(n?l:void 0);s&&o.push({relativePath:e,content:t,metadata:s})}if(0===o.length)throw new Error(`Companion template files are missing in ${t}`);return{language:s,templates:o}}(e?.preferredLanguage,o,a),f=[];for(const e of h){const t=Ts(S(n,e.relativePath),e,n);if(f.push({path:e.relativePath,updated:t.updated,reason:t.reason}),t.updated){const n="created"===t.reason?"Created":"Updated";console.log(`[Companion] ${n}: ${e.relativePath}`)}}f.some(e=>e.updated&&(e.path.startsWith("claude/plugins/")||e.path.startsWith("claude/hooks/")))&&(_s(n),console.log("[Companion] Rebuilt plugins after template updates"));const v=function(e,t){const n=[];for(const s of e){if("notify-user"!==s.metadata.updateStrategy)continue;const e=S(t,s.relativePath);if(!r(e))continue;const a=ks(e,t);Ss(s.metadata.version,a)>0&&n.push({template:s,targetPath:e,currentVersion:a,newVersion:s.metadata.version})}return n}(h,n);if(v.length>0)try{const e=S(s,"UPGRADES.md"),t=function(e){return`# Upgrades Available\n\nThe following files have new versions available:\n\n${e.map(e=>`- **${e.template.metadata.description||e.template.relativePath}**: v${e.currentVersion} → v${e.newVersion}`).join("\n")}\n\n---\n\n**Shadow's Instructions:**\n\nWhen you detect this file:\n1. Send a reminder to the main companion using \`mcp__agentrix__send_reminder\`\n2. Content: "System upgrade detected. ${e.length} file(s) available."\n3. Reference this file path so main companion can read details\n4. Exit quietly\n\n**Main Companion's Instructions:**\n\nWhen you receive the upgrade reminder:\n1. Choose appropriate timing (don't interrupt user's work)\n2. Read this file to see what's new\n3. For each upgrade, read the corresponding \`.upgrade\` file\n4. Present to user naturally, explain benefits\n5. If user agrees: integrate the new content in your own voice\n6. Update version files using Write tool (write \`versions/<relative-path>\` with the new version number)\n7. Delete \`.upgrade\` files when done\n8. Delete this file when all upgrades are handled\n`}(v);u(e,t,"utf-8");for(const e of v){const t=`${e.targetPath}.upgrade`,n=`# Upgrade: ${e.template.metadata.description||e.template.relativePath}\n\n**Current Version**: v${e.currentVersion}\n**New Version**: v${e.newVersion}\n\n---\n\n## New Content\n\n${e.template.content}\n\n---\n\n## Integration Instructions\n\n1. Read the new content above\n2. Compare with your current \`${e.template.relativePath}\`\n3. Integrate the new features in your own voice\n4. Keep your existing customizations\n5. Use Write tool to update \`versions/${e.template.relativePath}\` with content: "${e.newVersion}"\n6. Delete this file when done\n`;u(t,n,"utf-8")}console.log(`[Companion] Created UPGRADES.md with ${v.length} pending upgrade(s)`),console.log("[Companion] Shadow will notify main companion on next heartbeat")}catch(e){console.warn("[Companion] Failed to create upgrade files (permission denied?):",e instanceof Error?e.message:e),console.warn("[Companion] Upgrade detection will be skipped. Please check sandbox permissions for agents directory.")}return console.log(`[Companion] Language: ${m}`),{agentDir:n,homeDir:s}}const Xa="https://ilinkai.weixin.qq.com",Ja="https://novac2c.cdn.weixin.qq.com/c2c",Ya=1e3,Qa=We(import.meta.url)("qrcode-terminal");function Za(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function ei(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function ti(e,t){if("number"==typeof e&&Number.isFinite(e)&&e>0)return e;if("string"==typeof e){const t=Number(e);if(Number.isFinite(t)&&t>0)return t}return t}function ni(e){if("number"==typeof e||"string"==typeof e){const t=Number(e);if(Number.isFinite(t))return new Date(t>1e10?t:1e3*t).toISOString();const n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return(new Date).toISOString()}function si(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function ai(e){if("string"==typeof e.text)return e.text;if("string"==typeof e.content)return e.content;if(e.text_item?.text)return e.text_item.text;for(const t of e.item_list??[]){if("string"==typeof t.text)return t.text;if("string"==typeof t.text_item?.text)return t.text_item.text}}function ii(e){const t=String(e.message_type??e.msg_type??"").toLowerCase();if(t.includes("image"))return"image";if(t.includes("file"))return"file";if(t.includes("voice")||t.includes("audio"))return"voice";if(e.image_item)return"image";if(e.file_item)return"file";for(const t of function(e){return e.item_list??[]}(e)){const e=String(t.type??"").toLowerCase();if(t.image_item||e.includes("image"))return"image";if(t.file_item||e.includes("file"))return"file";if(e.includes("voice")||e.includes("audio"))return"voice"}return"text"}function oi(e){if(e.image_item?.media?.full_url)return ri(e.image_item.media,e.image_item.aeskey,"image.jpg");if(e.image_item?.url)return e.image_item.url;if(e.image_item?.file_id)return e.image_item.file_id;if(e.image_item?.image_key)return e.image_item.image_key;for(const t of e.item_list??[]){if(t.image_item?.media?.full_url)return ri(t.image_item.media,t.image_item.aeskey,"image.jpg");if(t.image_item?.url)return t.image_item.url;if(t.image_item?.file_id)return t.image_item.file_id;if(t.image_item?.image_key)return t.image_item.image_key}}function ri(e,t,n){const s={url:e.full_url||"",aesKey:e.aes_key||t,fileName:n};return`wechat-media:${Buffer.from(JSON.stringify(s)).toString("base64url")}`}function ci(e){return e?Array.isArray(e.updates)?e.updates:Array.isArray(e.msgs)?e.msgs:Array.isArray(e.message_list)?e.message_list:Array.isArray(e.items)?e.items:[]:[]}function li(e){return e.retcode??e.ret??e.errcode}function pi(e,t){const n=li(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function di(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function ui(e){let t="";return Qa.generate(e,{small:!0},e=>{t=e}),t}class mi{id;platform="wechat";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;polling=!1;pollController=null;pollPromise=null;retryTimer=null;resolveRetrySleep=null;retryDelayMs=Ya;contextTokens=new Map;clientId=ce(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=ei(e.token)??ei(e.botToken)??ei(e.bot_token)??ei(e.apiKey)??ei(e.api_key);return{baseUrl:ei(e.baseUrl)??ei(e.base_url)??Xa,token:t||Za(t,"token"),routeTag:ei(e.routeTag)??ei(e.route_tag),getUpdatesBuf:ei(e.getUpdatesBuf)??ei(e.get_updates_buf)??"",channelVersion:ei(e.channelVersion)??ei(e.channel_version)??"1.0.0",pollTimeoutMs:ti(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:ti(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:ei(e.fileDownloadEndpoint)??ei(e.file_download_endpoint)??ei(e.downloadEndpoint)??ei(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||Xa,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${di(t,"get_bot_qrcode")}?bot_type=3`,{method:"GET",headers:n}),a=await s.json().catch(()=>({}));if(!s.ok)throw new Error(`HTTP ${s.status}: ${JSON.stringify(a)}`);const i=li(a);if(i&&0!==i)throw new Error(pi(a,"WeChat QR login failed"));if(!a.qrcode||!a.qrcode_img_content)throw new Error("WeChat QR login response is missing qrcode data");return{qrcode:a.qrcode,qrcodeContent:a.qrcode_img_content,qrcodeTerminal:ui(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||Xa,s=await fetch(`${di(n,"get_qrcode_status")}?qrcode=${encodeURIComponent(e)}`,{method:"GET",headers:{"iLink-App-ClientVersion":"1"}}),a=await s.json().catch(()=>({}));if(!s.ok)throw new Error(`HTTP ${s.status}: ${JSON.stringify(a)}`);const i=li(a);if(i&&0!==i)throw new Error(pi(a,"WeChat QR status failed"));return{status:a.status||"wait",token:a.bot_token,baseUrl:a.baseurl,ilinkBotId:a.ilink_bot_id,ilinkUserId:a.ilink_user_id}}get state(){return this.connectionState}async connect(){"connected"!==this.connectionState&&"connecting"!==this.connectionState&&(this.polling=!0,this.retryDelayMs=Ya,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),ye.info(`[CHANNEL][WECHAT] Connected: channel=${this.id}`))}async disconnect(){this.polling=!1,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null,this.resolveRetrySleep?.()),this.resolveRetrySleep=null,this.pollController?.abort(),this.pollController=null,await(this.pollPromise?.catch(()=>{})),this.pollPromise=null,this.setState("disconnected")}async sendMessage(e,t){const n=this.contextTokens.get(e);if(!n)throw new Error(`WeChat sendMessage requires an iLink context_token for chat ${e}; wait for this contact to send a message first`);const s=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${ce(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[{type:1,text_item:{text:t}}]}},{timeoutMs:this.credentials.requestTimeoutMs}),a=li(s);if(a&&0!==a)throw new Error(pi(s,"WeChat sendMessage failed"))}async sendChannelMessage(e,t){const n=t.content?.trim();n&&await this.sendMessage(e,n);for(const n of t.attachments??[])await this.sendAttachment(e,n)}async sendAttachment(e,t){const n=this.contextTokens.get(e);if(!n)throw new Error(`WeChat send attachment requires an iLink context_token for chat ${e}; wait for this contact to send a message first`);const s=t.fileName?.trim()||T(t.filePath),a=await ut(t.filePath),i=this.resolveOutgoingKind(t),o="image"===i?1:3,r="image"===i?2:4,c=await this.uploadWechatMedia(e,a,s,o),l={full_url:c.fullUrl,aes_key:c.aesKey,encrypt_query_param:c.encryptQueryParam,encrypt_type:1},p="image"===i?{type:r,image_item:{media:l,aeskey:c.aesKeyHex,mid_size:c.encryptedSize}}:{type:r,file_item:{file_name:s,name:s,md5:c.md5,media:l,len:String(a.length)}},d=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${ce(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[p]}},{timeoutMs:this.credentials.requestTimeoutMs}),u=li(d);if(u&&0!==u)throw new Error(pi(d,"WeChat send attachment failed"))}resolveOutgoingKind(e){return"image"===e.kind?"image":e.kind&&"auto"!==e.kind&&"file"!==e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}async uploadWechatMedia(e,t,n,s){const a=ce(16).toString("hex"),i=ce(16).toString("hex"),o=this.encryptWechatMedia(t,i),r=pe("md5").update(t).digest("hex"),c=await this.request("getuploadurl",{media_type:s,to_user_id:e,filekey:a,rawsize:t.length,rawfilemd5:r,filesize:o.length,no_need_thumb:!0,aeskey:i},{timeoutMs:this.credentials.requestTimeoutMs}),l=li(c);if(l&&0!==l)throw new Error(pi(c,"WeChat getuploadurl failed"));const p=this.extractUploadParam(c),d=await fetch(`${Ja}/upload?encrypted_query_param=${encodeURIComponent(p)}&filekey=${encodeURIComponent(a)}`,{method:"POST",headers:{"Content-Type":"application/octet-stream","Content-Length":String(o.length)},body:o});if(!d.ok){const e=await d.text().catch(()=>"");throw new Error(`WeChat CDN upload failed: HTTP ${d.status}: ${e||d.statusText}`)}const u=d.headers.get("x-encrypted-param");if(!u)throw new Error("WeChat CDN upload response missing x-encrypted-param");return{fullUrl:`${Ja}/download?encrypted_query_param=${encodeURIComponent(u)}`,aesKey:Buffer.from(i,"utf-8").toString("base64"),aesKeyHex:i,encryptQueryParam:u,md5:r,encryptedSize:o.length}}extractUploadParam(e){const t=e.upload_param;if("string"==typeof t&&t.trim())return t.trim();const n=e.data;if(n&&"object"==typeof n){const e=n.upload_param;if("string"==typeof e&&e.trim())return e.trim()}throw new Error("WeChat getuploadurl response missing upload_param")}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=function(e){if(!e.startsWith("wechat-media:"))return null;try{const t=JSON.parse(Buffer.from(e.slice(13),"base64url").toString("utf-8"));return"string"==typeof t?.url&&t.url?{url:t.url,aesKey:"string"==typeof t.aesKey?t.aesKey:void 0,fileName:"string"==typeof t.fileName?t.fileName:void 0}:null}catch{return null}}(e);if(n)return await this.downloadEncryptedMedia(n,t.fileName);if(/^https?:\/\//i.test(e))return await on(e,t.fileName);const s=await this.requestDownloadFile(e);return await an(s,t.fileName||e)}catch(t){return ye.warn(`[CHANNEL][WECHAT] Failed to download file: channel=${this.id}, fileKey=${e}`,t),null}}async getChatName(e){return e}async getUserName(e){return e}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async pollLoop(){for(;this.polling;)try{const e=await this.request("getupdates",{get_updates_buf:this.credentials.getUpdatesBuf},{timeoutMs:Math.max(this.credentials.requestTimeoutMs,this.credentials.pollTimeoutMs+5e3)}),t=li(e);if(t&&0!==t)throw new Error(pi(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=Ya,"connected"!==this.connectionState&&this.setState("connected");for(const e of ci(n)){const t=this.normalizeMessage(e);t&&await(this.messageHandler?.(t))}}catch(e){if(!this.polling)break;if(this.isAbortError(e))continue;const t=e instanceof Error?e:new Error(String(e));ye.warn(`[CHANNEL][WECHAT] Poll failed: channel=${this.id}, message=${t.message}`),this.setState("error",t),await this.sleepWithCancel(this.retryDelayMs),this.retryDelayMs=Math.min(2*this.retryDelayMs,3e4),this.polling&&this.setState("connecting")}}async request(e,t,n){const s=new AbortController;"getupdates"===e&&(this.pollController=s);const a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=this.buildHeaders(),a=await fetch(this.apiUrl(e),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,...t}),signal:s.signal}),i=await a.json().catch(()=>({}));if(!a.ok)throw new Error(`HTTP ${a.status}: ${JSON.stringify(i)}`);return i}finally{clearTimeout(a),"getupdates"===e&&this.pollController===s&&(this.pollController=null)}}async requestDownloadFile(e){const t=new AbortController,n=setTimeout(()=>t.abort(),this.credentials.requestTimeoutMs);try{const n=this.buildHeaders(),s=await fetch(this.apiUrl(this.credentials.fileDownloadEndpoint),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,file_id:e,file_key:e,image_key:e}),signal:t.signal});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`HTTP ${s.status}: ${e||s.statusText}`)}return s}finally{clearTimeout(n)}}async downloadEncryptedMedia(e,t){const n=await fetch(e.url);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=Buffer.from(await n.arrayBuffer()),a=e.aesKey?this.decryptWechatMedia(s,e.aesKey):s,i=sn(t||e.fileName||"attachment");return await mt(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=de("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=de("aes-128-ecb",n,null);return t.setAutoPadding(!1),Buffer.concat([t.update(e),t.final()])}}encryptWechatMedia(e,t){const n=Buffer.from(t,"hex");if(16!==n.length)throw new Error(`Invalid WeChat upload AES key length: ${n.length}`);const s=ue("aes-128-ecb",n,null);return Buffer.concat([s.update(e),s.final()])}decodeWechatAesKey(e){const t=Buffer.from(e,"base64").toString("utf-8"),n=/^[0-9a-f]{32}$/i.test(t)?t:e,s=/^[0-9a-f]{32}$/i.test(n)?Buffer.from(n,"hex"):Buffer.from(n,"utf-8");if(16!==s.length)throw new Error(`Invalid WeChat media AES key length: ${s.length}`);return s}buildHeaders(){const e={"Content-Type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${this.credentials.token}`,"X-WECHAT-UIN":this.generateWechatUin()};return this.credentials.routeTag&&(e.SKRouteTag=this.credentials.routeTag),e}apiUrl(e){return di(this.credentials.baseUrl,e)}generateWechatUin(){const e=ce(4).readUInt32BE(0).toString();return Buffer.from(e).toString("base64")}sleepWithCancel(e){return new Promise(t=>{this.resolveRetrySleep=t,this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.resolveRetrySleep=null,t()},e)})}isAbortError(e){return e instanceof Error&&"AbortError"===e.name}normalizeMessage(e){const t=e.chat_id??e.room_id??e.talker??e.from_user_id;if(!t)return ye.warn(`[CHANNEL][WECHAT] Ignoring malformed message event: channel=${this.id}`),null;e.context_token&&this.contextTokens.set(t,e.context_token);const n=e,s=function(e){if(e.file_item){const t=e.file_item.file_name??e.file_item.name;return{fileKey:e.file_item.media?.full_url?ri(e.file_item.media,void 0,t):e.file_item.file_id??e.file_item.file_key,fileName:t}}for(const t of e.item_list??[])if(t.file_item){const e=t.file_item.file_name??t.file_item.name;return{fileKey:t.file_item.media?.full_url?ri(t.file_item.media,void 0,e):t.file_item.file_id??t.file_item.file_key,fileName:e}}return{}}(e),a=e.from_user_id??e.sender??t,i=!0===n.is_at||!0===n.mentioned_bot||!0===n.at_bot,o=!0===n.reply_to_bot||!0===n.is_reply_to_bot;return{id:e.message_id??e.msg_id??String(e.id??e.seq??le()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:si(n,["sender_name","nickname","user_name"]),type:ii(e),text:ai(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:oi(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:ni(e.timestamp??e.create_time),raw:e}}}const hi=["telegram","wechat","lark"],gi=Qe.enum(hi),fi=Qe.enum(["connecting","connected","disconnected","error"]),yi=Qe.enum(["text","image","file","voice"]),vi=Qe.record(Qe.string(),Qe.unknown()),xi=Qe.object({id:Qe.string(),platform:gi,name:Qe.string().optional(),credentials:vi,enabled:Qe.boolean(),connectionState:fi,lastConnectedAt:Qe.string().optional(),lastDisconnectedAt:Qe.string().optional(),lastError:Qe.string().optional(),createdAt:Qe.string(),updatedAt:Qe.string()}),wi=Qe.object({platform:gi,name:Qe.string().optional(),credentials:vi,enabled:Qe.boolean().optional()}),bi=Qe.object({id:Qe.string(),channelId:Qe.string(),chatId:Qe.string(),taskId:Qe.string(),chatName:Qe.string().optional(),createdAt:Qe.string(),updatedAt:Qe.string()});Qe.object({id:Qe.string(),channelId:Qe.string(),platform:gi,chatId:Qe.string(),chatType:Qe.string().optional(),senderId:Qe.string().optional(),senderType:Qe.string().optional(),senderName:Qe.string().optional(),type:yi,text:Qe.string().optional(),fileKey:Qe.string().optional(),fileName:Qe.string().optional(),imageKey:Qe.string().optional(),attachmentPaths:Qe.array(Qe.string()).optional(),mentionedBot:Qe.boolean().optional(),replyToBot:Qe.boolean().optional(),triggered:Qe.boolean().optional(),rawContent:Qe.unknown().optional(),timestamp:Qe.string(),raw:Qe.unknown().optional()});const ki=Qe.object({id:Qe.string(),name:Qe.string(),avatar:Qe.string().optional(),description:Qe.string().optional(),chatStatus:Qe.string().optional(),external:Qe.boolean().optional()}),Ii=Qe.enum(["auto","image","file","audio","video"]),Si=Qe.object({filePath:Qe.string(),fileName:Qe.string().optional(),mimeType:Qe.string().optional(),kind:Ii.optional()});Qe.object({content:Qe.string().optional(),attachments:Qe.array(Si).optional()});const Ti=Qe.object({version:Qe.literal(1),channels:Qe.array(xi),bindings:Qe.array(bi),companionDataEncryptionKey:Qe.string().optional(),companionOwnerEncryptedDataKey:Qe.string().optional()});function Ei(e){return!e||"object"!=typeof e||Array.isArray(e)?null:e}function _i(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Ci(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function Ai(e){const t=e?.trim().toLowerCase();return"issue"===t?"issue":"mergerequest"===t||"merge_request"===t?"merge_request":void 0}function $i(e){const t=e.split("/").filter(Boolean);if(t.length<2)return{owner:"",name:e};const n=t[t.length-1];return{owner:t.slice(0,-1).join("/"),name:n}}function Mi(e){const t=Ei(e.project);return t?{id:Ci(t.id),path:_i(t.path),path_with_namespace:_i(t.path_with_namespace),default_branch:_i(t.default_branch),web_url:_i(t.web_url)}:null}function Pi(e){const t=Ei(e.object_attributes);return t?{iid:Ci(t.iid),title:_i(t.title),url:_i(t.url),action:_i(t.action),state:_i(t.state)}:null}function Ri(e){const t=Ei(e.object_attributes);return t?{iid:Ci(t.iid),title:_i(t.title),url:_i(t.url),action:_i(t.action),state:_i(t.state),source_branch:_i(t.source_branch),target_branch:_i(t.target_branch)}:null}function Ni(e){const t=Ei(e.object_attributes);return t?{id:Ci(t.id),note:_i(t.note),noteable_type:_i(t.noteable_type),url:_i(t.url),action:_i(t.action),system:(n=t.system,"boolean"==typeof n?n:void 0)}:null;var n}function Di(e){const t=Ei(e.object_attributes);return t?{id:Ci(t.id),iid:Ci(t.iid),status:_i(t.status),source:_i(t.source),ref:_i(t.ref),sha:_i(t.sha),url:_i(t.url)}:null}function Oi(e){return _i(e.event_type)||_i(e.object_kind)||"unknown"}function ji(e){return!!e&&/(?:^|[^A-Za-z0-9._-])(?:@agentrix|\/agentrix)(?=$|[^A-Za-z0-9._-])/i.test(e)}function Ui(e,t,n,s){const{owner:a,name:i}=$i(s.path_with_namespace??"");return{AGENTRIX_EVENT_NAME:t,AGENTRIX_EVENT_ACTION:n,AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:a,AGENTRIX_REPOSITORY_NAME:i,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"}}function qi(e,t,n,s){const a={ref:t,variables:n};return e.id?a.projectId=e.id:e.path_with_namespace&&(a.projectPath=e.path_with_namespace),s.triggerToken&&(a.triggerToken=s.triggerToken),void 0!==s.createTriggerIfMissing&&(a.createTriggerIfMissing=s.createTriggerIfMissing),a}function Li(e,t,n){switch(Oi(t)){case"issue":return function(e,t,n){if("issue"!==Oi(t))return null;const s=Mi(t),a=Pi(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes project.default_branch"};const{owner:o,name:r}=$i(s.path_with_namespace),c=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"close":case"closed":return"closed";case"update":case"updated":case"edit":case"edited":return"edited";default:return"opened"===t?"opened":"closed"===t?"closed":e||"unknown"}}(a.action,a.state),l={AGENTRIX_EVENT_NAME:"issue",AGENTRIX_EVENT_ACTION:c,AGENTRIX_ISSUE_NUMBER:String(a.iid),AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:o,AGENTRIX_REPOSITORY_NAME:r,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"};a.title&&(l.AGENTRIX_ISSUE_TITLE=a.title);const p=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/issues/${t.iid}`:void 0}(s,a);return p&&(l.AGENTRIX_ISSUE_URL=p),{operationPayload:qi(s,i,l,n),action:c}}(e,t,n);case"note":return function(e,t,n){const s=Mi(t),a=Ni(t);if(!s?.path_with_namespace||!a?.note||!0===a.system||!ji(a.note))return null;const i=Ai(a.noteable_type);if(!i)return null;const o=Ei("issue"===i?t.issue:t.merge_request),r=Ci(o?.iid);if(!r)return null;const c="merge_request"===i?_i(o?.source_branch):void 0,l="merge_request"===i?_i(o?.target_branch):void 0,p=n.ref||l||s.default_branch||c;if(!p)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes a usable ref"};const d=function(e){switch(e){case void 0:case"create":case"created":return"created";case"update":case"updated":return"updated";case"delete":case"deleted":return"deleted";default:return e||"unknown"}}(a.action),u=Ui(e,"note",d,s);return u.AGENTRIX_NOTEABLE_TYPE=i,u.AGENTRIX_NOTE_BODY=a.note,a.id&&(u.AGENTRIX_NOTE_ID=String(a.id)),a.url&&(u.AGENTRIX_NOTE_URL=a.url),"issue"===i?u.AGENTRIX_ISSUE_NUMBER=String(r):(u.AGENTRIX_PR_NUMBER=String(r),c&&(u.AGENTRIX_HEAD_REF=c),l&&(u.AGENTRIX_BASE_REF=l)),{operationPayload:qi(s,p,u,n),action:d}}(e,t,n);case"merge_request":return function(e,t,n){const s=Mi(t),a=Ri(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||a.target_branch||s.default_branch||a.source_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes target_branch or project.default_branch"};const o=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"update":case"updated":return"updated";case"merge":case"merged":return"merged";case"close":case"closed":return"closed";default:return"merged"===t?"merged":"closed"===t?"closed":"opened"===t?"opened":e||"unknown"}}(a.action,a.state),r=Ui(e,"merge_request",o,s);r.AGENTRIX_PR_NUMBER=String(a.iid),a.source_branch&&(r.AGENTRIX_HEAD_REF=a.source_branch),a.target_branch&&(r.AGENTRIX_BASE_REF=a.target_branch),a.title&&(r.AGENTRIX_MR_TITLE=a.title);const c=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/merge_requests/${t.iid}`:void 0}(s,a);return c&&(r.AGENTRIX_MR_URL=c),{operationPayload:qi(s,i,r,n),action:o}}(e,t,n);case"pipeline":return function(e,t,n){const s=Mi(t),a=Di(t);if(!s?.path_with_namespace||!a?.status||"failed"!==a.status||"trigger"===a.source)return null;const i=n.ref||a.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes object_attributes.ref or project.default_branch"};const o=Ui(e,"pipeline",a.status,s);o.AGENTRIX_PIPELINE_STATUS=a.status,o.AGENTRIX_REF=i,a.source&&(o.AGENTRIX_PIPELINE_SOURCE=a.source),a.id&&(o.AGENTRIX_PIPELINE_ID=String(a.id)),a.iid&&(o.AGENTRIX_PIPELINE_IID=String(a.iid)),a.sha&&(o.AGENTRIX_SHA=a.sha);const r=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.id?`${e.web_url}/-/pipelines/${t.id}`:void 0}(s,a);r&&(o.AGENTRIX_PIPELINE_URL=r);const c=function(e){const t=Ei(e.merge_request);return Ci(t?.iid)}(t);return c&&(o.AGENTRIX_PR_NUMBER=String(c)),{operationPayload:qi(s,i,o,n),action:a.status}}(e,t,n);default:return null}}function Hi(e){const t=Oi(e);if("note"===t){const t=Ni(e);return!0===t?.system?"system_note":ji(t?.note)?"unsupported_note":"note_command_missing"}if("pipeline"===t){const t=Di(e);return t?.status&&"failed"!==t.status?"pipeline_status_unsupported":"trigger"===t?.source?"pipeline_source_unsupported":"unsupported_pipeline"}return"issue"===t||"merge_request"===t?"missing_required_payload":"unsupported_event"}function Gi(e){return e.secret||e.token}function Bi(e,t){return me("sha256",t).update(e).digest("base64url")}function Fi(e,t){const[n,s,a]=t.split(".");if(!n||!s||void 0!==a)throw new Error("Invalid Agentrix event MCP token format");if(!function(e,t){const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&he(n,s)}(s,Bi(n,Gi(e))))throw new Error("Invalid Agentrix event MCP token signature");let i;try{i=JSON.parse((o=n,Buffer.from(o,"base64url").toString("utf8")))}catch{throw new Error("Invalid Agentrix event MCP token payload")}var o;if(!(i.taskId&&i.userId&&i.machineId&&i.nonce))throw new Error("Incomplete Agentrix event MCP token payload");if(i.machineId!==e.machineId)throw new Error("Agentrix event MCP token machine mismatch");return i}const Wi="agentrix_event_broker",zi="/mcp/agentrix-event-broker",Ki="change_title";async function Vi(e,t,n){const s=function(e){const t=e.headers.authorization;if(!t)throw new Error("Missing Agentrix event MCP bearer token");const n=/^Bearer\s+(.+)$/i.exec(t);if(!n?.[1])throw new Error("Invalid Agentrix event MCP authorization header");return n[1]}(e),a=function(e){const t=new ft({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(Ki,{title:"Change session title",description:["Emit an Agentrix event that changes the current session title.","Use this early in a task when the conversation has no user-provided title."].join(" "),inputSchema:{title:Qe.string().min(1).max(200).describe("New title for the current Agentrix task")}},async({title:t})=>{const n=await async function(e,t,n){const s=n.trim();if(!s)throw new Error("Title must not be empty");return await e.changeTitle(t,s),`Agentrix title change event emitted for task ${t.taskId}: ${s}`}(e.dispatcher,e.context,t);return{content:[{type:"text",text:n}]}}),t}({context:Fi(n.credentials,s),dispatcher:n.dispatcher}),i=new yt({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){ye.warn("[EVENT MCP] Failed to handle MCP request:",e),t.raw.headersSent||(t.raw.writeHead(500,{"Content-Type":"application/json"}),t.raw.end(JSON.stringify({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})))}finally{await i.close().catch(()=>{}),await a.close().catch(()=>{})}}function Xi(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=S(e,a.name),i=d(s),o=M(t,s);n.push({name:a.name,path:o,size:i.size,modifiedAt:i.mtimeMs,isDirectory:a.isDirectory()}),a.isDirectory()&&n.push(...Xi(s,t))}return n}function Ji(){return S(fe.agentrixAgentsHomeDir,"companion","claude")}const Yi=Qe.object({id:Qe.string(),type:Qe.string(),name:Qe.string(),baseUrl:Qe.string(),apiUrl:Qe.string(),oauthServerId:Qe.string().nullable().optional(),ownerId:Qe.string().nullable().optional(),authModeDefault:Qe.string().optional(),executionMode:Qe.string().optional(),syncMode:Qe.string().optional(),networkMode:Qe.string().optional(),githubAppName:Qe.string().nullable().optional(),enabled:Qe.boolean().optional(),createdAt:Qe.string().optional(),updatedAt:Qe.string().optional()}).passthrough();async function Qi(e,t,n){let s;try{return await Promise.race([e,new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)})])}finally{s&&clearTimeout(s)}}function Zi(e){return Array.isArray(e)?e[0]:e}function eo(e){return e instanceof Error?e.message:"Unknown error"}async function to(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:G(),method:t,path:n,body:s},o=await Qi(e.sendWithAck("machine-rpc-call",i),a,`Timed out waiting for machine RPC ${t} ${n}`);if(!o.success){const e=o.error?.message||`Machine RPC failed: ${t} ${n}`;throw new Error(e)}return o.data}function no(e){const{getChildren:t,stopSession:n,requestShutdown:s,registerSession:a,credentials:i,getSocketClient:o}=e;return new Promise(l=>{const m=fe.getDaemonControlHost(),h=fe.getDaemonWebhookHost(),g=Ye({logger:!1});g.removeContentTypeParser("application/json"),g.addContentTypeParser("application/json",{parseAs:"string"},(e,t,n)=>{const s="string"==typeof t?t:t.toString("utf8");if(0!==s.trim().length)try{n(null,JSON.parse(s))}catch(e){const t=e instanceof Error?e:new Error("Invalid JSON body");t.statusCode=400,n(t,void 0)}else n(null,{})}),g.setValidatorCompiler(et),g.setSerializerCompiler(tt);const f=g.withTypeProvider();!function(e,t){const n={credentials:t.credentials,dispatcher:t.dispatcher??(s=t.credentials,{changeTitle:(e,t)=>async function(e,t,n){const s=new Zt({serverUrl:fe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(e.token,e.machineId,t.taskId),options:{reconnection:!1,timeout:1e4},logger:(e,...t)=>{ye.debug(`[EVENT MCP] ${e}`,...t)}});try{await async function(e){await new Promise((t,n)=>{const s=setTimeout(()=>{e.offLifecycle("connect"),e.offLifecycle("connect_error"),n(new Error("Agentrix event broker worker socket connection timeout"))},1e4);e.onLifecycle("connect",()=>{clearTimeout(s),e.offLifecycle("connect_error"),t()}),e.onLifecycle("connect_error",t=>{clearTimeout(s),e.offLifecycle("connect"),n(t instanceof Error?t:new Error(String(t)))}),e.connect()})}(s),s.send("change-task-title",{eventId:G(),taskId:t.taskId,title:n}),await s.flush(5e3)}finally{s.disconnect()}}(s,e,t)})};var s;e.post(zi,async(e,t)=>{try{await Vi(e,t,n)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return ye.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(zi,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(zi,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(g,{credentials:i});const y=e=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),e.header("Access-Control-Allow-Private-Network","true")};f.post("/session-started",{schema:{body:Qe.object({sessionId:Qe.string(),metadata:Qe.any()}),response:{200:Qe.object({status:Qe.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return ye.debug(`[CONTROL SERVER] Session started: ${t}`),a(t,n),{status:"ok"}}),f.options("/ping",async(e,t)=>(y(t),t.send())),f.get("/ping",{schema:{response:{200:Qe.object({status:Qe.literal("ok"),machineId:Qe.string(),timestamp:Qe.string(),controlHost:Qe.string(),webhookHost:Qe.string()})}}},async(e,t)=>(y(t),{status:"ok",machineId:i.machineId,timestamp:(new Date).toISOString(),controlHost:m,webhookHost:h})),f.options("/openers",async(e,t)=>(y(t),t.send())),f.get("/openers",{schema:{response:{200:Qe.object({openers:Qe.array(Qe.object({id:Qe.string(),label:Qe.string(),kind:Qe.enum(["system","file-manager","terminal","editor","ide"]),method:Qe.enum(["scheme","cli"]),urlTemplate:Qe.string().optional(),supported:Qe.boolean()}))})}}},async(e,t)=>(y(t),{openers:await os()})),f.options("/open",async(e,t)=>(y(t),t.send())),f.options("/pick-directory",async(e,t)=>(y(t),t.send())),f.post("/open",{schema:{body:Qe.object({path:Qe.string(),openerId:Qe.string(),userId:Qe.string().optional(),taskId:Qe.string().optional()}),response:{200:Qe.object({success:Qe.boolean(),error:Qe.string().optional()})}}},async(e,t)=>{y(t);const{path:n,openerId:s,userId:a,taskId:i}=e.body;return await async function({openerId:e,targetPath:t,userId:n,taskId:s}){const a=cs(us()).find(t=>t.id===e);if(!a)return{success:!1,error:"Unknown openerId"};if("cli"!==a.method||!a.open)return{success:!1,error:"Opener is not executable by CLI"};if(!a.isSupported())return{success:!1,error:"Opener is not supported on this system"};let i;try{i=function(e,t,n){const s=I.resolve(e);if(!I.isAbsolute(s))throw new Error("Path must be absolute");if(!d(s).isDirectory())throw new Error("Path must be a directory");if(t&&n){const e=fe.getTaskCwd(t,n);if(e&&!function(e,t){const n=I.relative(t,e);return""===n||!n.startsWith("..")&&!I.isAbsolute(n)}(s,I.resolve(e)))throw new Error("Path is outside the task workspace")}return s}(t,n,s)}catch(e){return{success:!1,error:e instanceof Error?e.message:"Invalid path"}}try{return a.open(i),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Failed to open path";return ye.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),f.post("/pick-directory",{schema:{body:Qe.object({defaultPath:Qe.string().optional()}),response:{200:Qe.object({path:Qe.string().nullable(),error:Qe.string().optional()})}}},async(e,t)=>{y(t);try{return{path:rs(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),f.post("/companion/ensure",{schema:{body:Qe.object({preferredLanguage:Qe.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:Qe.object({agentDir:Qe.string()})}}},async e=>await Va({preferredLanguage:e.body?.preferredLanguage,credentials:i})),f.post("/companion/probe",{schema:{response:{200:Qe.object({success:Qe.boolean(),error:Qe.string().optional()})}}},async()=>await oa()),f.get("/companion/workspace/status",{schema:{response:{200:Qe.object({exists:Qe.boolean()})}}},async()=>{const e=Ji();return{exists:r(e)}}),f.get("/companion/workspace",{schema:{response:{200:Qe.object({files:Qe.array(Qe.object({name:Qe.string(),path:Qe.string(),size:Qe.number(),modifiedAt:Qe.number(),isDirectory:Qe.boolean()}))})}}},async()=>{const e=Ji();return r(e)?{files:Xi(e,e)}:{files:[]}}),f.get("/companion/file",{schema:{querystring:Qe.object({path:Qe.string()}),response:{200:Qe.object({content:Qe.string()}),404:Qe.object({error:Qe.string()})}}},async(e,t)=>{const n=Ji(),s=P(S(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),f.put("/companion/file",{schema:{body:Qe.object({path:Qe.string(),content:Qe.string()}),response:{200:Qe.object({success:Qe.boolean()}),400:Qe.object({error:Qe.string()})}}},async(e,t)=>{const n=Ji(),s=P(S(n,e.body.path));return s.startsWith(n)?(p(A(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),f.get("/companion/config",{schema:{response:{200:Qe.object({heartbeatIntervalMs:Qe.number(),heartbeatEnabled:Qe.boolean(),lastHeartbeatTimestamp:Qe.string().nullable(),lastHeartbeatDate:Qe.string().nullable(),lastInteractionTimestamp:Qe.string().nullable()})}}},async()=>{const e=Ji(),t=S(e,"state.json");let n=9e5,s=!1,a=null,i=null,o=null;if(r(t))try{const e=JSON.parse(c(t,"utf-8"));"number"==typeof e.heartbeatIntervalMs&&(n=e.heartbeatIntervalMs),"boolean"==typeof e.heartbeatEnabled&&(s=e.heartbeatEnabled),"string"==typeof e.lastHeartbeatTimestamp&&(a=e.lastHeartbeatTimestamp),"string"==typeof e.lastHeartbeatDate&&(i=e.lastHeartbeatDate),"string"==typeof e.lastInteractionTimestamp&&(o=e.lastInteractionTimestamp)}catch{}return{heartbeatIntervalMs:n,heartbeatEnabled:s,lastHeartbeatTimestamp:a,lastHeartbeatDate:i,lastInteractionTimestamp:o}}),f.put("/companion/config",{schema:{body:Qe.object({heartbeatIntervalMs:Qe.number().optional(),heartbeatEnabled:Qe.boolean().optional()}),response:{200:Qe.object({success:Qe.boolean()})}}},async e=>{const t=Ji(),n=S(t,"state.json");let s={};if(r(n))try{s=JSON.parse(c(n,"utf-8"))}catch{}const{heartbeatIntervalMs:a,heartbeatEnabled:i}=e.body;return void 0!==a&&(s.heartbeatIntervalMs=a),void 0!==i&&(s.heartbeatEnabled=i),p(A(n),{recursive:!0}),u(n,JSON.stringify(s,null,2),"utf-8"),{success:!0}}),f.post("/agent/install",{schema:{body:Qe.object({agentId:Qe.string(),gitUrl:Qe.string(),branch:Qe.string().optional(),subDir:Qe.string().optional()}),response:{200:Qe.object({agentDir:Qe.string()}),500:Qe.object({error:Qe.string()})}}},async(e,t)=>{try{return await Es(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),f.post("/git-server/register",{schema:{body:Qe.object({name:Qe.string().min(1),baseUrl:Qe.string().url(),apiUrl:Qe.string().url()}),response:{200:Qe.object({gitServer:Qe.object({id:Qe.string(),type:Qe.string(),name:Qe.string(),baseUrl:Qe.string(),apiUrl:Qe.string()}),machineId:Qe.string()}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{try{const n=await to(o?.(),"POST","/v1/git-servers/machine-register",{...e.body,machineId:i.machineId});return t.send(n)}catch(n){const s=eo(n);return ye.warn(`[GIT SERVER] register failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),f.post("/git-server/complete",{schema:{body:Qe.object({gitServerId:Qe.string().min(1)}),response:{200:Qe.object({success:Qe.boolean(),machineId:Qe.string()}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{try{const n=await to(o?.(),"POST",`/v1/git-servers/${encodeURIComponent(e.body.gitServerId)}/machine-complete`,{machineId:i.machineId});return t.send(n)}catch(n){const s=eo(n);return ye.warn(`[GIT SERVER] complete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),f.post("/git-server/list",{schema:{response:{200:Qe.object({gitServers:Qe.array(Yi)}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{try{const e=await to(o?.(),"POST","/v1/git-servers/machine-list",{machineId:i.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=eo(e);return ye.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),f.post("/git-server/delete",{schema:{body:Qe.object({gitServerId:Qe.string().min(1)}),response:{200:Qe.object({success:Qe.boolean(),machineId:Qe.string()}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{try{const n=await to(o?.(),"POST",`/v1/git-servers/${encodeURIComponent(e.body.gitServerId)}/machine-unlink`,{machineId:i.machineId});return t.send({success:!0,machineId:i.machineId,...n&&"object"==typeof n?n:{}})}catch(n){const s=eo(n);return ye.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),f.post("/webhooks/gitlab/:gitServerId",{schema:{params:Qe.object({gitServerId:Qe.string()}),body:Qe.record(Qe.string(),Qe.unknown()),response:{200:Qe.object({status:Qe.enum(["triggered","ignored","failed"]),eventType:Qe.string(),action:Qe.string().optional(),pipeline:Qe.unknown().optional(),reason:Qe.string().optional(),errorMessage:Qe.string().optional(),errorDetail:Qe.string().optional(),upstreamStatus:Qe.number().optional()}),400:Qe.object({error:Qe.string()}),401:Qe.object({error:Qe.string()}),403:Qe.object({error:Qe.string()}),404:Qe.object({error:Qe.string()}),502:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()})}}},async(e,t)=>{const n=le(),s=Date.now(),a=function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body),i=function(e){const t=Oi(e);if("issue"===t){const t=Pi(e);if(!t?.iid)return null}else if("merge_request"===t){const t=Ri(e);if(!t?.iid)return null}else if("note"===t){const t=Ni(e);if(!0===t?.system||!ji(t?.note))return null;const n=Ai(t?.noteable_type),s="issue"===n?Ei(e.issue):"merge_request"===n?Ei(e.merge_request):null;if(!Ci(s?.iid))return null}else if("pipeline"===t){const t=Di(e);if("failed"!==t?.status||"trigger"===t.source)return null}else if("issue"!==t&&"merge_request"!==t)return null;return function(e){const t=Mi(e);return t?.id?String(t.id):t?.path_with_namespace??null}(e)}(e.body),r=e.ip||"-",c="string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-",l=(a,i)=>{const o=Date.now()-s,r=function(e){if(!e||"object"!=typeof e)return"type="+typeof e;const t=e;if("string"==typeof t.error)return`error=${t.error}`;const n=String(t.status??"-"),s=String(t.eventType??"-"),a=String(t.action??"-"),i=String(t.reason??"-"),o=String(t.upstreamStatus??"-"),r=String(t.errorMessage??"-"),c=function(e){if(!e||"object"!=typeof e)return"-";const t=e,n=t.id??t.iid??"-",s=t.status??"-",a=t.ref??"-",i=t.web_url??t.webUrl??"-";return`id=${String(n)}, status=${String(s)}, ref=${String(a)}, webUrl=${String(i)}`}(t.pipeline);return`status=${n}, eventType=${s}, action=${a}, reason=${i}, upstreamStatus=${o}, errorMessage=${r}, pipeline=${c}`}(i);return ye[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};ye.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}, remote=${r}, userAgent=${c}`);const p=await xn();if(!p)return l(500,{error:"Git server encryption key not available"});const d=bn(e.params.gitServerId,p),u=d?.webhookSecret;if(!u)return l(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});if(!function(e,t){if("string"!=typeof e)return!1;const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&he(n,s)}(e.headers["x-gitlab-token"],u))return l(401,{error:"Invalid GitLab webhook token"});const m=Zi(e.headers["x-gitlab-event-uuid"])??Zi(e.headers["x-gitlab-delivery"]),h=a;(async function(e,t,n,s,a){if(!a?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:G(),provider:"gitlab",gitServerId:e,deliveryId:n,eventType:s,payload:t},o=await Qi(a.sendWithAck("repository-inbox-webhook",i),5e3,"Timed out waiting for repository inbox webhook ack");if("success"!==o.status)throw new Error(o.message||"API failed to process repository inbox webhook")})(e.params.gitServerId,e.body,m,h,o?.()).catch(t=>{const s=t instanceof Error?t.message:String(t);ye.warn(`[GITLAB WEBHOOK] inbox side-channel failed: hookId=${n}, gitServer=${e.params.gitServerId}, message=${s}`)});const g=In(e.params.gitServerId,p);if(!g)return l(403,{error:`No PAT configured for git server ${e.params.gitServerId}`});try{const t=wn(e.params.gitServerId),s=t?.apiUrl;if(!s)return l(400,{error:`GitLab API URL is not configured for git server ${e.params.gitServerId}`});let o;if(i)if(o=d.projectTriggerTokens?.[i],o)ye.info(`[GITLAB WEBHOOK] pipeline trigger token reused: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`);else{const t=function(e){const t=Mi(e);return t?.path_with_namespace?t.id?{projectId:t.id}:{projectPath:t.path_with_namespace}:null}(e.body);if(!t)return l(400,{error:"GitLab webhook payload is missing project information"});ye.info(`[GITLAB WEBHOOK] ensuring pipeline trigger token: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}, mode=create_or_reuse`);const a=new En(s,g,{gitServerId:e.params.gitServerId}),r=await a.executeOperation("ensurePipelineTriggerToken",t);if(!r||"object"!=typeof r||"string"!=typeof r.token)return l(502,{error:"Failed to create GitLab pipeline trigger token"});o=r.token,function(e,t,n){vn.saveGitLabWebhookBridgeSecrets(e,t,n)}(e.params.gitServerId,{webhookSecret:u,projectTriggerTokens:{...d.projectTriggerTokens??{},[i]:o}},p),ye.info(`[GITLAB WEBHOOK] pipeline trigger token stored: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`)}return ye.info(`[GITLAB WEBHOOK] triggering pipeline: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}`),l(200,await async function({gitServerId:e,payload:t,config:n,pat:s}){const a=Oi(t),i=Li(e,t,n);if(!i)return{status:"ignored",eventType:a,reason:Hi(t)};if(!n.apiUrl)throw{status:400,message:"GitLab API URL is required"};const o=new En(n.apiUrl,s,{gitServerId:e});let r;try{r=await o.executeOperation("triggerPipeline",i.operationPayload)}catch(e){const t=function(e){const t=e;return{message:"string"==typeof t?.message?t.message:e instanceof Error?e.message:"Failed to trigger GitLab pipeline",detail:"string"==typeof t?.detail?t.detail:void 0,upstreamStatus:"number"==typeof t?.status?t.status:void 0}}(e);return{status:"failed",eventType:a,action:i.action,reason:"pipeline_trigger_failed",errorMessage:t.message,errorDetail:t.detail,upstreamStatus:t.upstreamStatus}}return{status:"triggered",eventType:a,action:i.action,pipeline:r}}({gitServerId:e.params.gitServerId,payload:e.body,pat:g,config:{apiUrl:s,triggerToken:o}}))}catch(t){const s=t,a="number"==typeof s.status&&s.status>=400&&s.status<600?s.status:500,i="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return ye.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, message=${i}`),l(a,{error:i})}}),f.post("/schedule",{schema:{body:Qe.object({task:Qe.string(),type:Qe.enum(["once","recurring"]),due:Qe.string().optional(),cron:Qe.string().optional(),timezone:Qe.string().optional(),timeType:Qe.enum(["utc","local"]).optional()}),response:{200:Qe.object({id:Qe.string(),task:Qe.string(),type:Qe.enum(["once","recurring"]),due:Qe.string().optional(),cron:Qe.string().optional(),timezone:Qe.string().optional(),timeType:Qe.enum(["utc","local"]).optional(),createdAt:Qe.string()}),400:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(t,n)=>{const s=e.companionScheduler;if(!s)return n.code(503).send({error:"Companion scheduler not available"});const{task:a,type:i,due:o,cron:r,timezone:c,timeType:l}=t.body;return"once"!==i||o?"recurring"!==i||r?s.addScheduledTask({task:a,type:i,due:o,cron:r,timezone:c,timeType:l}):n.code(400).send({error:'"cron" is required for recurring tasks'}):n.code(400).send({error:'"due" is required for one-time tasks'})}),f.get("/schedule",{schema:{response:{200:Qe.object({tasks:Qe.array(Qe.object({id:Qe.string(),task:Qe.string(),type:Qe.enum(["once","recurring"]),due:Qe.string().optional(),cron:Qe.string().optional(),timezone:Qe.string().optional(),timeType:Qe.enum(["utc","local"]).optional(),createdAt:Qe.string()}))}),503:Qe.object({error:Qe.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),f.delete("/schedule/:id",{schema:{params:Qe.object({id:Qe.string()}),response:{200:Qe.object({success:Qe.boolean()}),404:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?s.deleteScheduledTask(t.params.id)?{success:!0}:n.code(404).send({error:`Task ${t.params.id} not found`}):n.code(503).send({error:"Companion scheduler not available"})});const v=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);f.options("/channels",async(e,t)=>(y(t),t.send())),f.options("/channels/platforms",async(e,t)=>(y(t),t.send())),f.options("/channels/wechat/login/qrcode",async(e,t)=>(y(t),t.send())),f.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(y(t),t.send())),f.options("/channels/:id",async(e,t)=>(y(t),t.send())),f.options("/channels/:id/connect",async(e,t)=>(y(t),t.send())),f.options("/channels/:id/disconnect",async(e,t)=>(y(t),t.send())),f.options("/channels/:id/contacts",async(e,t)=>(y(t),t.send())),f.options("/channels/:id/bindings",async(e,t)=>(y(t),t.send())),f.options("/channels/:id/bindings/:bindingId",async(e,t)=>(y(t),t.send())),f.options("/channels/task-message",async(e,t)=>(y(t),t.send())),f.options("/channels/group-history",async(e,t)=>(y(t),t.send())),f.get("/channels",{schema:{response:{200:Qe.object({channels:Qe.array(xi)}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)return{channels:n.getChannels()}}),f.get("/channels/platforms",{schema:{response:{200:Qe.object({platforms:Qe.array(Qe.enum(hi))})}}},async(e,t)=>(y(t),{platforms:[...hi]})),f.get("/channels/wechat/login/qrcode",{schema:{response:{200:Qe.object({qrcode:Qe.string(),qrcodeContent:Qe.string(),qrcodeTerminal:Qe.string(),baseUrl:Qe.string()}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);try{return await mi.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return ye.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),f.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:Qe.object({qrcode:Qe.string()}),response:{200:Qe.object({status:Qe.string(),token:Qe.string().optional(),baseUrl:Qe.string().optional(),ilinkBotId:Qe.string().optional(),ilinkUserId:Qe.string().optional()}),502:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);try{return await mi.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return ye.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),f.post("/channels",{schema:{body:wi,response:{200:xi,503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)return n.addChannel(e.body)}),f.delete("/channels/:id",{schema:{params:Qe.object({id:Qe.string()}),response:{200:Qe.object({success:Qe.boolean()}),404:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),f.post("/channels/:id/connect",{schema:{params:Qe.object({id:Qe.string()}),response:{200:xi,404:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return await n.connectChannel(e.params.id)}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),f.post("/channels/:id/disconnect",{schema:{params:Qe.object({id:Qe.string()}),response:{200:xi,404:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return await n.disconnectChannel(e.params.id,{disable:!0})}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),f.get("/channels/:id/contacts",{schema:{params:Qe.object({id:Qe.string()}),response:{200:Qe.object({contacts:Qe.array(ki)}),404:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return{contacts:await n.getContacts(e.params.id)}}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),f.get("/channels/:id/bindings",{schema:{params:Qe.object({id:Qe.string()}),response:{200:Qe.object({bindings:Qe.array(bi)}),404:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return{bindings:n.getBindings(e.params.id)}}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(404).send({error:n})}}),f.post("/channels/task-message",{schema:{body:Qe.object({taskId:Qe.string(),content:Qe.string().optional(),attachments:Qe.array(Qe.object({filePath:Qe.string(),fileName:Qe.string().optional(),mimeType:Qe.string().optional(),kind:Qe.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:Qe.object({channelId:Qe.string(),chatId:Qe.string()}).optional()}),response:{200:Qe.object({success:Qe.boolean()}),404:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{const s={content:e.body.content,attachments:e.body.attachments};return e.body.target?(await n.sendMessageToChannel(e.body.target,s),{success:!0}):await n.sendMessageToTaskChannel(e.body.taskId,s)?{success:!0}:t.code(404).send({error:`No channel binding for task ${e.body.taskId}`})}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),f.post("/channels/group-history",{schema:{body:Qe.object({taskId:Qe.string(),limit:Qe.number().int().positive().max(100).optional(),beforeSeq:Qe.number().int().positive().optional(),afterSeq:Qe.number().int().nonnegative().optional(),target:Qe.object({channelId:Qe.string(),chatId:Qe.string(),platform:Qe.string().optional(),chatType:Qe.string().optional(),chatName:Qe.string().optional()})}),response:{200:Qe.object({historyXml:Qe.string(),hasMoreBefore:Qe.boolean(),hasMoreAfter:Qe.boolean()}),400:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()}),500:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return void 0!==e.body.beforeSeq&&void 0!==e.body.afterSeq?t.code(400).send({error:"Use beforeSeq or afterSeq, not both"}):n.getChannelGroupHistory(e.body.target,{limit:e.body.limit,beforeSeq:e.body.beforeSeq,afterSeq:e.body.afterSeq})}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("only available")?400:500;return t.code(s).send({error:n})}}),f.delete("/channels/:id/bindings/:bindingId",{schema:{params:Qe.object({id:Qe.string(),bindingId:Qe.string()}),response:{200:Qe.object({success:Qe.boolean()}),404:Qe.object({error:Qe.string()}),503:Qe.object({error:Qe.string()})}}},async(e,t)=>{y(t);const n=v(t);if(n)try{return n.removeBinding(e.params.id,e.params.bindingId)?{success:!0}:t.code(404).send({error:`Binding ${e.params.bindingId} not found`})}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(404).send({error:n})}}),f.post("/list",{schema:{response:{200:Qe.object({children:Qe.array(Qe.object({startedBy:Qe.string(),taskId:Qe.string(),pid:Qe.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),f.post("/stop-session",{schema:{body:Qe.object({sessionId:Qe.string()}),response:{200:Qe.object({success:Qe.boolean()})}}},async e=>{const{sessionId:t}=e.body;return ye.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),f.post("/stop",{schema:{response:{200:Qe.object({status:Qe.string()})}}},async()=>(ye.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{ye.debug("[CONTROL SERVER] Triggering daemon shutdown"),s()},50),{status:"stopping"})),"127.0.0.1"!==m&&ye.warn(`[CONTROL SERVER] Listening on ${m}; ensure daemon control endpoints are protected by network policy`);const x=e=>new Promise((t,n)=>{g.listen({port:e,host:m},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{e=await x(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw ye.info("[CONTROL SERVER] Failed to start:",t),t;ye.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await x(0)}const t=parseInt(e.split(":").pop());ye.info(`[CONTROL SERVER] Started on port ${t}`),l({port:t,host:m,webhookHost:h,stop:async()=>{await g.close(),ye.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw ye.info("[CONTROL SERVER] Failed to start:",e),e})})}function so(e,t={}){const n=ve(),s=S(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw ye.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return ze(process.execPath,a,t)}const ao=[{version:1,fileName:"001_init.sql"}];function io(e){var t;return function(e,t){const n=new xt(e),s=new vt;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=Pe(wt(import.meta.url)),t=[Me(e,"migrations"),Me(process.cwd(),"dist","migrations"),Me(process.cwd(),"src","worker","history","migrations")];for(const e of t)if(_e(e))return e;throw new Error(`Task history migrations directory not found at ${t[0]}`)}(),n=e.pragma("user_version",{simple:!0}),s=function(e,t){const n=Me(e,t);return Ee(n,"utf8")}(t,ao[0].fileName);e.exec(s),n<ao[0].version&&e.pragma(`user_version = ${ao[0].version}`)}(n);const a=n.prepare("\n INSERT OR IGNORE INTO task_message (\n event_id,\n task_id,\n sender_type,\n sender_id,\n sender_name,\n message,\n created_at\n ) VALUES (\n @eventId,\n @taskId,\n @senderType,\n @senderId,\n @senderName,\n @message,\n @createdAt\n );\n "),i=n.prepare("SELECT local_sequence FROM task_message WHERE event_id = ?"),o=n.prepare("\n INSERT OR IGNORE INTO task_event (\n event_id,\n task_id,\n chat_id,\n sequence,\n event_type,\n event_data,\n created_at\n ) VALUES (\n @eventId,\n @taskId,\n @chatId,\n @sequence,\n @eventType,\n @eventData,\n @createdAt\n );\n "),r=n.prepare("\n UPDATE task_event\n SET sequence = ?\n WHERE event_id = ? AND (sequence IS NULL OR sequence < ?)\n "),c=n.prepare("\n SELECT * FROM task_event\n WHERE sequence > ? AND event_type = 'task-message'\n ORDER BY sequence ASC\n LIMIT ?\n "),l=n.prepare("\n SELECT 1 as has_row\n FROM task_event\n WHERE sequence > ? AND event_type = 'task-message'\n LIMIT 1\n "),p=n.prepare("\n SELECT * FROM task_message\n ORDER BY local_sequence DESC\n LIMIT ?\n "),d=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence ASC\n LIMIT ?\n "),u=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence < ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),m=n.prepare("\n SELECT 1 as has_row\n FROM task_message\n WHERE local_sequence < ?\n LIMIT 1\n "),h=n.prepare("\n SELECT 1 as has_row\n FROM task_message\n WHERE local_sequence > ?\n LIMIT 1\n "),g=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),f=n.prepare("\n SELECT agent_id, session_id, last_sequence\n FROM task_agent_session\n "),y=n.prepare("\n INSERT INTO task_agent_session (agent_id, task_id, session_id, last_sequence, updated_at)\n VALUES (?, ?, ?, NULL, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n session_id = excluded.session_id,\n updated_at = excluded.updated_at\n "),v=n.prepare("\n INSERT INTO task_agent_session (agent_id, task_id, session_id, last_sequence, updated_at)\n VALUES (?, ?, '__pending__', ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n last_sequence = CASE\n WHEN task_agent_session.last_sequence IS NULL OR task_agent_session.last_sequence < excluded.last_sequence\n THEN excluded.last_sequence\n ELSE task_agent_session.last_sequence\n END,\n updated_at = excluded.updated_at\n ");return{saveMessage:e=>{const n=e.eventId??G(),o=(new Date).toISOString(),r=a.run({eventId:n,taskId:t,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,message:JSON.stringify(e.message),createdAt:o}).changes>0,c=i.get(n),l=c?.local_sequence??null;return r&&null!==l&&s.emit("message-saved",{eventId:n}),{eventId:n,localSequence:l,inserted:r}},saveTaskEvent:e=>{const t=e.eventId??G(),n=(new Date).toISOString(),s={...e.eventData,eventId:t};return o.run({eventId:t,taskId:e.taskId,chatId:e.chatId,sequence:e.sequence,eventType:e.eventType,eventData:JSON.stringify(s),createdAt:n}),t},updateTaskEventSequence:(e,t)=>{r.run(t,e,t)},pageTaskEventsAfter:(e,t)=>{const n=c.all(e,t).map(ro),s=n.at(-1)?.sequence??null;return{data:n,hasMore:null!==s&&Boolean(l.get(s))}},getLatestTaskEvent:e=>{if(0===e.length)return null;const t=e.map(()=>"?").join(","),s=n.prepare(`\n SELECT * FROM task_event\n WHERE event_type IN (${t})\n ORDER BY created_at DESC, rowid DESC\n LIMIT 1\n `).get(...e);return s?ro(s):null},pageRecentMessages:e=>{const t=p.all(e).map(oo).reverse(),n=t[0]?.localSequence??null;return{data:t,hasMore:!!n&&Boolean(m.get(n))}},pageMessagesAfter:(e,t)=>{const n=d.all(e,t).map(oo),s=n.at(-1)?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},pageMessagesBefore:(e,t)=>{const n=u.all(e,t).map(oo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(m.get(s))}},pageRecentMessagesAfter:(e,t)=>{const n=g.all(e,t).map(oo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(m.get(s))}},getAgentSessions:()=>{const e=f.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.session_id);return t},getAgentLastSequences:()=>{const e=f.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.last_sequence);return t},upsertAgentSession:(e,n)=>{y.run(e,t,n,(new Date).toISOString())},updateAgentLastSequence:(e,n)=>{v.run(e,t,n,(new Date).toISOString())},on:(e,t)=>{s.on(e,t)},off:(e,t)=>{s.off(e,t)},close:()=>{s.removeAllListeners(),n.close()}}}((t=e.dataDir,Me(t,"data.bin")),e.taskId)}function oo(e){const t=JSON.parse(e.message);return{localSequence:e.local_sequence,eventId:e.event_id,senderType:e.sender_type,senderId:e.sender_id,senderName:e.sender_name,message:t,createdAt:e.created_at}}function ro(e){const t=JSON.parse(e.event_data);return{eventId:e.event_id,taskId:e.task_id,chatId:e.chat_id,sequence:e.sequence??null,eventType:e.event_type,eventData:t,createdAt:e.created_at}}const co={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".svg":"image/svg+xml",".ico":"image/x-icon",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".md":"text/markdown",".csv":"text/csv",".json":"application/json",".xml":"application/xml",".html":"text/html",".css":"text/css",".js":"application/javascript",".ts":"application/typescript",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".rar":"application/vnd.rar",".mp3":"audio/mpeg",".mp4":"video/mp4",".wav":"audio/wav",".avi":"video/x-msvideo"},lo={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/bmp":".bmp","image/svg+xml":".svg","image/x-icon":".ico","application/pdf":".pdf","text/plain":".txt","text/html":".html","text/csv":".csv","application/json":".json","video/mp4":".mp4","audio/mpeg":".mp3"};async function po(e,t,n=!1){try{const s=await fetch(e);if(!s.ok)throw new Error(`Failed to download file: ${s.status} ${s.statusText}`);if(!s.body)throw new Error("Response body is null");const a=function(e){try{const t=new URL(e),n=E(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=E(s);if(e)return e}return""}catch{return""}}(e),i=s.headers.get("content-type"),o=i?.split(";")[0].trim()||function(e){const t=e.toLowerCase();return co[t]||"application/octet-stream"}(a),r=a||function(e){return lo[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=T(t);c=n&&E(n)?n:`${le()}${r||".dat"}`}catch{c=`${le()}${r||".dat"}`}else c=`${le()}${r||".dat"}`;const p=S(t,c),d=s.body,u=l(p);return await Oe(d,u),{filePath:p,mimeType:o,filename:c}}catch(t){throw new Error(`Failed to download file from ${e}: ${t instanceof Error?t.message:String(t)}`)}}async function uo(e,t){const{attachmentsDir:n,log:s}=t;if(!Array.isArray(e.message.content))return e;const a=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","IMAGE",`Downloading image to local attachment: ${s}`);const{filePath:a,mimeType:i}=await po(s,t,!0);return n?.("info","IMAGE",`Image saved to: ${a}`),{type:"text",text:`Image file: ${a}\nType: ${i}`}}catch(t){return n?.("error","IMAGE",`Error downloading image to file: ${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n,s):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","DOCUMENT",`Downloading document from: ${s}`);const{filePath:a,mimeType:i,filename:o}=await po(s,t,!0);return n?.("info","DOCUMENT",`Document downloaded to: ${a}`),{type:"text",text:`Document: ${a}\nTitle: ${e.title||o}\nType: ${i}`}}catch(t){return n?.("error","DOCUMENT",`Error processing document: ${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n,s):e));return{...e,message:{...e.message,content:a}}}class mo{pidToTrackedSession;taskToStartPromise;sandboxPool;channelManager=null;constructor(e){this.pidToTrackedSession=new Map,this.taskToStartPromise=new Map,this.sandboxPool=e||null}setChannelManager(e){this.channelManager=e}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}getAliveSessionByTaskId(e){for(const[t,n]of this.pidToTrackedSession.entries())if(n.taskId===e){if(this.isProcessAlive(t))return n;this.pidToTrackedSession.delete(t)}}getCurrentSessions(){return Array.from(this.pidToTrackedSession.values())}getSessionByPid(e){return this.pidToTrackedSession.get(e)}registerTaskWorker(e,t){const n=t.pid;if(!n)return void ye.warn(`[SESSION] Missing PID for task ${e}`);ye.info(`[SESSION] Registered task ${e}, PID: ${n}`);const s=this.pidToTrackedSession.get(n);if(!(s&&s.taskId===e||s)){const t={startedBy:"cli",taskId:e,pid:n};this.pidToTrackedSession.set(n,t)}}async decryptTaskMessage(e){if(!e.dataEncryptionKey)return;const t=await fe.getSecretKey();if(!t)return;const n=H(L(e.dataEncryptionKey),t);if(!n)return void ye.warn("[SESSION] Failed to decrypt data encryption key");if(e.dataEncryptionKey=O(n),"task-message"!==e.event)return;const s=e.eventData;if(!s.encryptedMessage)return;const a=X(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:ye.warn("[SESSION] Failed to decrypt task message")}async persistCreateTaskStart(e){const t=fe.resolveDataDir(e.userId,e.taskId),n=fe.resolveAttachmentsDir(e.userId,e.taskId),s=io({dataDir:t,taskId:e.taskId});try{const t=e.eventData;if(s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:t.sequence??0}),t.message){let e=t.message;J(e)&&(e=await uo(e,{attachmentsDir:n,log:(e,t,n)=>ye["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName})}}finally{s.close()}}async persistResumeTaskStart(e){const t=fe.resolveDataDir(e.userId,e.taskId),n=fe.resolveAttachmentsDir(e.userId,e.taskId),s=io({dataDir:t,taskId:e.taskId}),a=e.eventData.sequence;if(null==a)throw new Error(`Missing resume sequence for task ${e.taskId}`);try{const t=e.eventData;if(s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:a}),t.message){let e=t.message;J(e)&&(e=await uo(e,{attachmentsDir:n,log:(e,t,n)=>ye["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName})}}finally{s.close()}}async processTaskMessageAttachments(e){if("task-message"!==e.event)return;const t=e.eventData;if(!t.message||!J(t.message))return;const n=fe.resolveAttachmentsDir(e.userId,e.taskId),s=await uo(t.message,{attachmentsDir:n,log:(e,t,n)=>ye["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)});e.eventData={...t,message:s}}trackWorkerProcess(e,t){const n={startedBy:"daemon",pid:t.pid,childProcess:t,taskId:e.taskId};this.pidToTrackedSession.set(t.pid,n),t.on("exit",(n,s)=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId)}),t.on("error",n=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId)})}shouldLookupChannelReplyTarget(e){const t="task-message"===e.event?e.eventData:null;return"channel"===t?.senderType||"companion"===e.agentType&&"work"===e.taskType&&!e.parentTaskId}resolveChannelReplyTarget(e){return e.channelReplyTarget?e.channelReplyTarget:this.shouldLookupChannelReplyTarget(e)?this.channelManager?.getReplyTargetForTask(e.taskId)??null:null}buildWorkerEnv(e){return{...process.env,...e?{AGENTRIX_CHANNEL_REPLY_TARGET:JSON.stringify(e)}:{}}}async startWorker(e,t){const n={eventId:G(),status:"success",opCode:e.eventId};await this.decryptTaskMessage(e),await this.processTaskMessageAttachments(e),fe.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const s=this.taskToStartPromise.get(e.taskId);if(s)return ye.info(`[SESSION] Task ${e.taskId} is already starting, skip duplicate ${t}`),s;const a=this.startWorkerInternal(e,t,n).finally(()=>{this.taskToStartPromise.get(e.taskId)===a&&this.taskToStartPromise.delete(e.taskId)});return this.taskToStartPromise.set(e.taskId,a),a}async startWorkerInternal(e,t,n){const s=this.getAliveSessionByTaskId(e.taskId);if(s)return ye.info(`[SESSION] Task ${e.taskId} already has worker PID ${s.pid}, skip duplicate ${t}`),n.message=`Worker already running (PID ${s.pid})`,n;const a=fe.resolveProjectCWD(e.userCwd,e.userId,e.taskId),i=["worker","--type",e.agentType||"claude","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","120"],o=this.resolveChannelReplyTarget(e),r=this.buildWorkerEnv(o);let c;if(this.sandboxPool?.isEnabled())try{if(!await this.sandboxPool.createWorkerSandbox(e.taskId,e.userId,a))throw new Error("Failed to create sandbox instance");const{projectPath:t}=await import("./logger-Dq-ORk-l.mjs").then(function(e){return e.d}),{join:n}=await import("path"),s=["--no-warnings","--no-deprecation",n(t(),"dist","index.mjs"),...i],o=`"${process.execPath}" ${s.map(e=>`"${e}"`).join(" ")}`,l=await this.sandboxPool.wrapWorkerCommand(e.taskId,o);ye.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${l}`),c=ze(l,{shell:!0,cwd:a,detached:!0,stdio:["ignore","pipe","pipe"],env:r}),ye.info(`[SESSION] Worker started with sandbox, PID: ${c.pid}`)}catch(t){return ye.error(`[SESSION] Failed to setup sandbox for task ${e.taskId}:`,t),n.status="failed",n.message=`Sandbox setup failed: ${t instanceof Error?t.message:String(t)}`,n}else c=so(i,{cwd:a,detached:!0,stdio:["ignore","pipe","pipe"],env:r}),ye.info(`[SESSION] Worker started without sandbox, PID: ${c.pid}`);return process.env.DEBUG&&(c.stdout?.on("data",e=>{ye.debug(`[Daemon] worker stdout: ${e.toString()}`)}),c.stderr?.on("data",e=>{ye.debug(`[Daemon] worker stderr: ${e.toString()}`)})),c.pid?(ye.info(`[SESSION] Worker started, PID: ${c.pid}`),this.trackWorkerProcess(e,c),n):(n.status="failed",n.message="Failed to start worker - no PID",n)}stopSession(e){for(const[t,n]of this.pidToTrackedSession.entries())if(n.taskId===e){try{(n.childProcess?n.childProcess:{kill:e=>process.kill(t,e)}).kill("SIGTERM"),ye.info(`[SESSION] Task ${e} stopped`);const s=setTimeout(()=>{const n=this.pidToTrackedSession.get(t);if(n&&n.taskId===e&&this.isProcessAlive(t))try{process.kill(t,"SIGKILL"),ye.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){ye.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){ye.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return ye.warn(`[SESSION] Task ${e} not found`),!1}pruneStaleSessions(){for(const[e,t]of this.pidToTrackedSession.entries())try{process.kill(e,0)}catch(t){this.pidToTrackedSession.delete(e)}}shutdown(){ye.info("[SESSION] Shutting down all sessions");for(const[e,t]of this.pidToTrackedSession.entries())try{"daemon"===t.startedBy&&t.childProcess?t.childProcess.kill("SIGTERM"):process.kill(e,"SIGTERM")}catch(t){ye.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};fe.writeTaskInput(e);try{const n=so(["worker","--type","hive-publish","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{ye.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{ye.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;ye.info(`[SESSION] Hive publish worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start hive-publish worker: ${e instanceof Error?e.message:String(e)}`,t}}async startHiveInstallWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};fe.writeTaskInput(e);try{const n=so(["worker","--type","hive-install","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{ye.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{ye.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;ye.info(`[SESSION] Hive install worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start hive-install worker: ${e instanceof Error?e.message:String(e)}`,t}}async startDeploymentWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};fe.writeTaskInput(e);try{const n=so(["worker","--type","deployment","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{ye.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{ye.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;ye.info(`[SESSION] Deployment worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start deployment worker: ${e instanceof Error?e.message:String(e)}`,t}}}class ho{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=Je()}async initialize(e){if(this.settings=e,!e.enabled)return ye.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!kt(this.platform))return ye.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL(fe.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new It,await this.networkManager.initialize(t),ye.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw ye.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=fe.resolveUserWorkSpaceDir(t),a=fe.getStatePaths().logsDir,i=this.settings.filesystem||{},o=this.settings.env||{},r={...i,allowWrite:[...i.allowWrite||[],s,n,a]};if("linux"===this.platform&&i.allowRead){const e=$e.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new St(this.networkManager,c);return this.workerSandboxes.set(e,l),ye.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return ye.error(`[SANDBOX] Failed to create sandbox for task ${e}:`,t),null}}async wrapWorkerCommand(e,t){const n=this.workerSandboxes.get(e);if(!n)throw new Error(`No sandbox found for task ${e}`);const s=await n.wrapWithSandbox(t);return ye.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),ye.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){ye.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),ye.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,ye.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class go{constructor(e,t){this.client=e,this.machineId=t;const n=fe.agentrixAgentsHomeDir,s=S(n,"companion","claude");this.stateFilePath=S(s,"state.json")}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;companionState=null;stateFilePath;cronJobs=new Map;start(){this.loadState(),this.companionState?(ye.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):ye.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),ye.info(`[COMPANION SCHEDULER] Starting with interval ${this.intervalMs}ms`),this.initialDelay=setTimeout(()=>{this.initialDelay=null,this.tick(),this.scheduleNext()},6e4)}stop(){this.initialDelay&&(clearTimeout(this.initialDelay),this.initialDelay=null),this.timer&&(clearTimeout(this.timer),this.timer=null);for(const[e,t]of this.cronJobs)t.stop(),ye.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),ye.info("[COMPANION SCHEDULER] Stopped")}scheduleNext(){this.timer=setTimeout(()=>{this.tick(),this.scheduleNext()},this.intervalMs)}setHeartbeatTaskId(e){this.heartbeatTaskId=e,this.saveStateField("heartbeatTaskId",e)}clearHeartbeatTaskId(){this.heartbeatTaskId=null,this.saveStateField("heartbeatTaskId",void 0),ye.info("[COMPANION SCHEDULER] Cleared heartbeat task ID")}recordInteraction(e){if(!this.companionState?.chatId||e!==this.companionState.chatId)return;const t=(new Date).toISOString();this.saveStateField("lastInteractionTimestamp",t),ye.debug(`[COMPANION SCHEDULER] Recorded interaction at ${t}`)}loadState(){try{if(r(this.stateFilePath)){this.companionState=JSON.parse(c(this.stateFilePath,"utf-8"));const e=this.companionState?.heartbeatIntervalMs??9e5;e!==this.intervalMs&&(ye.info(`[COMPANION SCHEDULER] Interval changed: ${this.intervalMs}ms -> ${e}ms`),this.intervalMs=e),this.enabled=this.companionState?.heartbeatEnabled??!1,this.heartbeatTaskId=this.companionState?.heartbeatTaskId??null,ye.info(`[COMPANION SCHEDULER] Loaded state: agentId=${this.companionState?.agentId}, chatId=${this.companionState?.chatId??"none"}, enabled=${this.enabled}, interval=${this.intervalMs}ms, taskId=${this.heartbeatTaskId??"none"}`)}}catch(e){ye.warn("[COMPANION SCHEDULER] Failed to load state.json",e)}}saveStateField(e,t){try{let n={};r(this.stateFilePath)&&(n=JSON.parse(c(this.stateFilePath,"utf-8"))),void 0===t?delete n[e]:n[e]=t;const s=A(this.stateFilePath);r(s)||p(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),ye.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){ye.warn(`[COMPANION SCHEDULER] Failed to save state field: ${e}`,t)}}getTodayDateString(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}addScheduledTask(e){const t={id:le(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),ye.info(`[COMPANION SCHEDULER] Added scheduled task: id=${t.id}, type=${t.type}, task="${t.task}"`),t}listScheduledTasks(){return this.loadState(),this.companionState?.scheduledTasks??[]}deleteScheduledTask(e){this.loadState();const t=this.companionState?.scheduledTasks??[],n=t.findIndex(t=>t.id===e);if(-1===n)return!1;t.splice(n,1),this.saveStateField("scheduledTasks",t);const s=this.cronJobs.get(e);return s&&(s.stop(),this.cronJobs.delete(e)),ye.info(`[COMPANION SCHEDULER] Deleted scheduled task: id=${e}`),!0}startCronJob(e){try{const t={},n="utc"===e.timeType;let s;if(e.due){if(n){const n=new Date(e.due);s=`${n.getUTCMinutes()} ${n.getUTCHours()} ${n.getUTCDate()} ${n.getUTCMonth()+1} *`,t.timezone="Etc/UTC"}else{const n=e.due.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/);if(!n)return void ye.warn(`[COMPANION SCHEDULER] Cannot parse due date: ${e.due}, skipping: ${e.id}`);s=`${parseInt(n[5])} ${parseInt(n[4])} ${parseInt(n[3])} ${parseInt(n[2])} *`,e.timezone&&(t.timezone=e.timezone)}"once"===e.type&&(t.maxRuns=1)}else{if(!e.cron)return void ye.warn(`[COMPANION SCHEDULER] Invalid task entry, skipping: ${e.id}`);s=e.cron,n?t.timezone="Etc/UTC":e.timezone&&(t.timezone=e.timezone)}const a=new Tt(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),ye.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){ye.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){ye.info(`[COMPANION SCHEDULER] Scheduled task fired: id=${e.id}, task="${e.task}"`),this.loadState();const t=this.companionState;t?.chatId&&(this.client.send("task-message",{eventId:G(),taskId:t.chatId,chatId:t.chatId,from:"machine",message:{type:"companion_reminder",content:`Scheduled task due: ${e.task}`,timestamp:(new Date).toISOString()},senderType:"system",senderId:"system",senderName:"system"}),"once"===e.type&&this.deleteScheduledTask(e.id))}restoreScheduledTasks(){const e=this.companionState?.scheduledTasks??[];if(0===e.length)return;let t=0;for(const n of e)"once"===n.type&&n.due&&new Date(n.due).getTime()<Date.now()?ye.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);ye.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}tick(){if(this.loadState(),!this.companionState)return void ye.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");if(!this.enabled)return void ye.debug("[COMPANION SCHEDULER] Heartbeat disabled, skipping");const e=this.companionState,t=[];e.lastInteractionTimestamp&&(!e.lastHeartbeatTimestamp||new Date(e.lastInteractionTimestamp).getTime()>new Date(e.lastHeartbeatTimestamp).getTime())&&t.push("new_interaction");const n=this.getTodayDateString();if(e.lastHeartbeatDate!==n&&t.push("first_today"),0===t.length)return void ye.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");ye.info(`[COMPANION SCHEDULER] Heartbeat triggered: ${t.join(", ")}`);const s=new Date;this.saveStateField("lastHeartbeatTimestamp",s.toISOString()),this.saveStateField("lastHeartbeatDate",n);const a=s.toLocaleString();this.heartbeatTaskId?(ye.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:G(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:{type:"companion_heartbeat",timestamp:s.toISOString(),triggerTime:a,triggerReasons:t},senderType:"system",senderId:"system",senderName:"system"})):(ye.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:G(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:s.toISOString(),triggerTime:a,triggerReasons:t}))}}class fo{constructor(e,t){this.client=e,this.machineId=t;const n=fe.agentrixAgentsHomeDir,s=S(n,"companion"),a=S(s,"claude");this.bootstrapPath=S(a,"BOOTSTRAP.md"),this.countPath=S(s,"BOOTSTRAP.count"),this.stateFilePath=S(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?ye.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):(ye.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):ye.debug("[COMPANION BOOTSTRAP] BOOTSTRAP.md not found, companion already initialized")}stop(){this.timer&&(clearTimeout(this.timer),this.timer=null)}scheduleNext(){this.timer=setTimeout(()=>this.tick(),this.intervalMs)}tick(){if(!r(this.bootstrapPath))return void ye.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void ye.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return ye.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),ye.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:G(),machineId:t.machineId,agentId:t.agentId,chatId:t.chatId,userId:t.userId}),this.scheduleNext()}readCount(){try{if(r(this.countPath)){const e=parseInt(c(this.countPath,"utf-8").trim(),10);return isNaN(e)?0:e}}catch{}return 0}writeCount(e){try{u(this.countPath,String(e),"utf-8")}catch(e){ye.warn("[COMPANION BOOTSTRAP] Failed to write BOOTSTRAP.count:",e)}}loadState(){try{if(r(this.stateFilePath)){const e=JSON.parse(c(this.stateFilePath,"utf-8"));if(e?.agentId&&e?.machineId&&e?.userId&&e?.chatId)return e}}catch{}return null}}function yo(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function vo(e){if("string"==typeof e)return e;if(!e||"object"!=typeof e)return;const t=e;return"string"==typeof t.text?t.text:void 0}function xo(e){if(!e)return(new Date).toISOString();const t=Number(e);if(Number.isFinite(t))return new Date(t>1e10?t:1e3*t).toISOString();const n=new Date(e);return Number.isNaN(n.getTime())?(new Date).toISOString():n.toISOString()}function wo(e){if(!e||"object"!=typeof e)return;const t=e;for(const e of["name","sender_name","user_name","nickname"]){const n=t[e];if("string"==typeof n&&n.trim())return n}}function bo(e){const t=e?.response?.status,n=e?.response?.data,s=e?.response?.headers?.["x-tt-logid"]||e?.response?.headers?.["x-request-id"];return[t?`status=${t}`:void 0,n?`data=${JSON.stringify(n)}`:void 0,s?`logId=${s}`:void 0,e?.message||e?.msg||String(e)].filter(Boolean).join(", ")}function ko(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class Io{id;platform="lark";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};client;wsClient=null;messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;botOpenId;constructor(e){var t;this.id=e.id,this.credentials={appId:yo((t=e.credentials).appId,"appId"),appSecret:yo(t.appSecret,"appSecret")},this.client=new Et.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:Et.AppType.SelfBuild,domain:Et.Domain.Feishu})}get state(){return this.connectionState}async connect(){if("connected"===this.connectionState||"connecting"===this.connectionState)return;this.setState("connecting"),await this.fetchBotIdentity(),this.wsClient=new Et.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:Et.Domain.Feishu,loggerLevel:Et.LoggerLevel.info,onReady:()=>{ye.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{ye.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{ye.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{ye.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new Et.EventDispatcher({}).register({"im.message.receive_v1":async e=>{const t=this.normalizeMessage(e);t&&await(this.messageHandler?.(t))}});try{await this.wsClient.start({eventDispatcher:e})}catch(e){const t=e instanceof Error?e:new Error(String(e));throw this.setState("error",t),t}}async disconnect(){this.wsClient&&(this.wsClient.close({force:!0}),this.wsClient=null),this.setState("disconnected")}async sendMessage(e,t){const n=await this.client.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:e,msg_type:"text",content:JSON.stringify({text:t})}});if(n.code&&0!==n.code)throw new Error(n.msg||`Lark sendMessage failed with code ${n.code}`)}async sendChannelMessage(e,t){try{const n=t.content?.trim();n&&await this.sendMessage(e,n);for(const n of t.attachments??[])await this.sendAttachment(e,n)}catch(e){throw new Error(`Lark sendChannelMessage failed: ${bo(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:v(t.filePath)}});if(!n?.image_key)throw new Error("Lark image upload did not return image_key");return void await this.sendRawMessage(e,"image",{image_key:n.image_key})}const n=t.fileName||T(t.filePath),s=await this.client.im.file.create({data:{file_type:this.resolveLarkFileType(n,t.mimeType),file_name:n,file:v(t.filePath)}});if(!s?.file_key)throw new Error("Lark file upload did not return file_key");await this.sendRawMessage(e,"file",{file_key:s.file_key})}async getChatName(e){try{const t=await this.client.im.chat.get({path:{chat_id:e}});return t.code&&0!==t.code?(ye.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return ye.warn(`[CHANNEL][LARK] Failed to get chat name for ${e}`,t),e}}async getUserName(e){const t=function(e){return e.startsWith("on_")?"union_id":e.startsWith("ou_")?"open_id":"user_id"}(e);try{const n=await this.client.request({url:"/open-apis/contact/v3/users/basic_batch",method:"POST",params:{user_id_type:t},data:{user_ids:[e]}});if(n.code&&0!==n.code)return ye.warn(`[CHANNEL][LARK] contact.user.basic_batch failed: code=${n.code}, msg=${n.msg}`),e;const s=n.data?.users?.[0];return s?.name||s?.i18n_name?.zh_cn||s?.i18n_name?.en_us||s?.i18n_name?.ja_jp||e}catch(t){return ye.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${bo(t)}`),e}}async getContacts(){const e=[];for await(const t of await this.client.im.chat.listWithIterator({params:{page_size:50,sort_type:"ByActiveTimeDesc"}}))for(const n of t?.items??[])n.chat_id&&e.push({id:n.chat_id,name:n.name||n.chat_id,avatar:n.avatar,description:n.description,chatStatus:n.chat_status,external:n.external});return e}async downloadFile(e,t={}){try{const n=function(e){const[t,n,s]=e.split(":").map(decodeURIComponent);if(!t||!n||!s)throw new Error("Invalid Lark resource key");return{messageId:t,resourceType:n,fileKey:s}}(e),s=sn(t.fileName||n.fileKey),a=await this.client.im.messageResource.get({path:{message_id:n.messageId,file_key:n.fileKey},params:{type:n.resourceType}});return await a.writeFile(s),s}catch(e){return ye.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${bo(e)}`),null}}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async sendRawMessage(e,t,n){const s=await this.client.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:e,msg_type:t,content:JSON.stringify(n)}});if(s.code&&0!==s.code)throw new Error(s.msg||`Lark send ${t} failed with code ${s.code}`)}async fetchBotIdentity(){try{const e=await this.client.request({url:"/open-apis/bot/v3/info",method:"GET"});if(e.code&&0!==e.code)return void ye.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){ye.warn(`[CHANNEL][LARK] bot identity lookup failed: ${bo(e)}`)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}resolveLarkFileType(e,t){const n=E(e).toLowerCase().replace(/^\./,"");return"pdf"===n||"application/pdf"===t?"pdf":["doc","docx"].includes(n)?"doc":["xls","xlsx","csv"].includes(n)?"xls":["ppt","pptx"].includes(n)?"ppt":"mp4"===n||"video/mp4"===t?"mp4":"opus"===n||"audio/opus"===t?"opus":"stream"}normalizeMessage(e){const t=e?.message;if(!t?.message_id||!t?.chat_id)return ye.warn(`[CHANNEL][LARK] Ignoring malformed message event: channel=${this.id}`),null;const n=function(e){try{return JSON.parse(e)}catch{return e}}(t.content??""),s=n&&"object"==typeof n?n:{},a=t.message_type,i="string"==typeof s.file_key?s.file_key:void 0,o="string"==typeof s.image_key?s.image_key:void 0,r=(c=t.mentions,l=this.credentials.appId,p=this.botOpenId,!!Array.isArray(c)&&c.some(e=>{if(!e||"object"!=typeof e)return!1;const t=e;if("bot"===("string"==typeof t.mentioned_type?t.mentioned_type.toLowerCase():void 0))return!0;const n=t.id;if(n&&"object"==typeof n){const e=n;return e.open_id===p||e.app_id===l||e.open_id===l||e.user_id===l}return t.app_id===l||t.open_id===l||t.user_id===l}));var c,l,p;return{id:t.message_id,channelId:this.id,platform:"lark",chatId:t.chat_id,chatType:t.chat_type,senderId:e?.sender?.sender_id?.open_id??e?.sender?.sender_id?.user_id??e?.sender?.sender_id?.union_id,senderType:e?.sender?.sender_type,senderName:wo(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:vo(n),fileKey:i?ko(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?ko(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:xo(t.create_time??e?.create_time??e?.ts),raw:e}}}const So="https://api.telegram.org",To=4e4,Eo=1e3;function _o(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function Co(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Ao(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function $o(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function Mo(e){return e.photo?.[e.photo.length-1]?.file_id}class Po{id;platform="telegram";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;polling=!1;pollController=null;pollPromise=null;retryTimer=null;resolveRetrySleep=null;retryDelayMs=Eo;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=Co(e.token)??Co(e.botToken)??Co(e.bot_token);return{token:t||_o(t,"token")}}(e.credentials)}get state(){return this.connectionState}async connect(){"connected"!==this.connectionState&&"connecting"!==this.connectionState&&(this.setState("connecting"),this.botUser=await this.request("getMe",{},{timeoutMs:To}),this.polling=!0,this.retryDelayMs=Eo,this.pollPromise=this.pollLoop(),this.setState("connected"),ye.info(`[CHANNEL][TELEGRAM] Connected: channel=${this.id}`))}async disconnect(){this.polling=!1,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null,this.resolveRetrySleep?.()),this.resolveRetrySleep=null,this.pollController?.abort(),this.pollController=null,await(this.pollPromise?.catch(()=>{})),this.pollPromise=null,this.setState("disconnected")}async sendMessage(e,t){await this.request("sendMessage",{chat_id:e,text:t},{timeoutMs:To})}async sendChannelMessage(e,t){const n=t.attachments??[],s=t.content?.trim();if(0===n.length)return void(s&&await this.sendMessage(e,s));const a=1===n.length?s:void 0;s&&!a&&await this.sendMessage(e,s);for(let t=0;t<n.length;t+=1)await this.sendAttachment(e,n[t],0===t?a:void 0)}async sendAttachment(e,t,n){const s=this.resolveOutgoingKind(t),a="image"===s?"sendPhoto":"sendDocument",i="image"===s?"photo":"document",o=t.fileName||T(t.filePath),r=await ut(t.filePath),c=new FormData;c.append("chat_id",e),c.append(i,new Blob([r],{type:t.mimeType||"application/octet-stream"}),o),n&&c.append("caption",n),await this.requestForm(a,c,{timeoutMs:To})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:To});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||T(n.file_path);return await on(`${So}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return ye.warn(`[CHANNEL][TELEGRAM] Failed to download file: channel=${this.id}, fileKey=${e}`,t),null}}async getChatName(e){try{const t=await this.request("getChat",{chat_id:e},{timeoutMs:To});return t.title||Ao(t)||t.username||e}catch(t){return ye.warn(`[CHANNEL][TELEGRAM] Failed to get chat name for ${e}`,t),e}}async getUserName(e){try{const t=await this.request("getChat",{chat_id:e},{timeoutMs:To});return Ao(t)||t.username||e}catch(t){return ye.warn(`[CHANNEL][TELEGRAM] Failed to get user name for ${e}`,t),e}}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async pollLoop(){for(;this.polling;)try{const e=await this.request("getUpdates",{offset:this.offset,timeout:30,allowed_updates:["message"]},{timeoutMs:To,isPoll:!0});this.retryDelayMs=Eo,"connected"!==this.connectionState&&this.setState("connected");for(const t of e){this.offset=Math.max(this.offset??0,t.update_id+1);const e=this.normalizeMessage(t);e&&await(this.messageHandler?.(e))}}catch(e){if(!this.polling)break;if(this.isAbortError(e))continue;const t=e instanceof Error?e:new Error(String(e));ye.warn(`[CHANNEL][TELEGRAM] Poll failed: channel=${this.id}, message=${t.message}`),this.setState("error",t),await this.sleepWithCancel(this.retryDelayMs),this.retryDelayMs=Math.min(2*this.retryDelayMs,3e4),this.polling&&this.setState("connecting")}}async request(e,t,n){const s=new AbortController;n.isPoll&&(this.pollController=s);const a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=await fetch(`${So}/bot${this.credentials.token}/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:s.signal}),a=await n.json().catch(()=>({}));if(!n.ok||!a.ok){const e=a.error_code?`code=${a.error_code}`:void 0,t=a.description||`HTTP ${n.status}`;throw new Error([e,t].filter(Boolean).join(", "))}if(void 0===a.result)throw new Error(`Telegram ${e} response is missing result`);return a.result}finally{clearTimeout(a),n.isPoll&&this.pollController===s&&(this.pollController=null)}}async requestForm(e,t,n){const s=new AbortController,a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=await fetch(`${So}/bot${this.credentials.token}/${e}`,{method:"POST",body:t,signal:s.signal}),a=await n.json().catch(()=>({}));if(!n.ok||!a.ok){const e=a.error_code?`code=${a.error_code}`:void 0,t=a.description||`HTTP ${n.status}`;throw new Error([e,t].filter(Boolean).join(", "))}if(void 0===a.result)throw new Error(`Telegram ${e} response is missing result`);return a.result}finally{clearTimeout(a)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}sleepWithCancel(e){return new Promise(t=>{this.resolveRetrySleep=t,this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.resolveRetrySleep=null,t()},e)})}isAbortError(e){return e instanceof Error&&"AbortError"===e.name}isTriggeredMessage(e){const t=this.botUser?.id,n=this.botUser?.username?.toLowerCase(),s=e.text??e.caption??"",a=e.text?e.entities:e.caption_entities,i=Boolean(void 0!==t&&e.reply_to_message?.from?.id===t);let o=!1;if(n){o=s.toLowerCase().includes(`@${n}`);for(const e of a??[]){if("mention"!==e.type&&"bot_command"!==e.type)continue;const t=s.slice(e.offset,e.offset+e.length).toLowerCase();if(t===`@${n}`||t.endsWith(`@${n}`)){o=!0;break}}}return{mentionedBot:o,replyToBot:i,triggered:o||i}}normalizeMessage(e){const t=e.message;if(!t?.chat?.id||!t.message_id)return ye.warn(`[CHANNEL][TELEGRAM] Ignoring malformed message event: channel=${this.id}`),null;const n=String(t.chat.id),s=void 0===t.from?.id?void 0:String(t.from.id),a=this.isTriggeredMessage(t);return{id:String(t.message_id||e.update_id||le()),channelId:this.id,platform:"telegram",chatId:n,chatType:(i=t.chat.type,"private"===i?"p2p":"group"===i||"supergroup"===i?"group":i),senderId:s,senderName:t.from?Ao(t.from):void 0,type:$o(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:Mo(t),mentionedBot:a.mentionedBot,replyToBot:a.replyToBot,triggered:a.triggered,rawContent:t.text??t.caption??t.photo??t.document??t.voice,timestamp:new Date(1e3*t.date).toISOString(),raw:e};var i}}function Ro(e){const t=qo(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${Do({seq:t.seq.toString(),at:t.at,senderType:t.senderType??void 0,senderId:t.senderId??void 0,senderName:t.senderName??void 0})}>${t.text}</msg>\n`},...t.nonTextBlocks]},parent_tool_use_id:null,session_id:""}:null}function No(e){const t=qo(e);return t?`<msg ${Do({seq:t.seq.toString(),at:t.at,senderType:t.senderType??void 0,senderId:t.senderId??void 0,senderName:t.senderName??void 0})}>\n${t.text}\n</msg>`:null}function Do(e){return Object.entries(e).filter(([,e])=>void 0!==e&&""!==e).map(([e,t])=>`${e}="${function(e){return e.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}(t)}"`).join(" ")}function Oo(e){const t=[];for(const n of e){const e=No(n);e&&t.push(e)}return t.join("\n")}function jo(e){return`Ask user: ${e.questions.map((e,t)=>{const n=e.options?.map(e=>e.label).filter(Boolean),s=n&&n.length>0?` options: ${n.join(", ")}`:"";return`Q${t+1}[${e.header}] ${e.question}${s}`}).join(" | ")}`}function Uo(e){const t=e.status?` status=${e.status}`:"",n=e.reason?` reason=${e.reason}`:"",s=e.answers?.length?e.answers.join(", "):"no answers",a=e.details?.filter(Boolean).join(" | ");return`Ask user response:${t}${n} answers: ${s}${a?` details: ${a}`:""}`}function qo(e){const{text:t,nonTextBlocks:n}=(s=e.message,Y(s)?{text:jo(s),nonTextBlocks:[]}:Q(s)?{text:Uo(s),nonTextBlocks:[]}:Z(s)?function(e){switch(e.type){case"user":case"assistant":return function(e){if("string"==typeof e)return{text:e,nonTextBlocks:[]};if(Array.isArray(e)){const t=[],n=[];for(const s of e)"text"!==s.type||"string"!=typeof s.text?n.push(s):t.push(s.text);return{text:t.join("\n"),nonTextBlocks:n}}return{text:"",nonTextBlocks:[]}}(e.message.content);case"result":return"success"===e.subtype?{text:e.result,nonTextBlocks:[]}:{text:Array.isArray(e.errors)?e.errors.filter(e=>"string"==typeof e).join("\n").trim():"",nonTextBlocks:[]}}return{text:"",nonTextBlocks:[]}}(s):{text:"",nonTextBlocks:[]});var s;return t?{seq:e.localSequence,at:e.createdAt,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,text:t,nonTextBlocks:n}:null}class Lo{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=S(fe.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=S(fe.agentrixHomeDir,"channels","group-history"),this.loadState()}stateFilePath;groupHistoryFilePath;adapters=new Map;reconnectTimers=new Map;pendingMessages=new Map;store={version:1,channels:[],bindings:[]};stopping=!1;createTaskLocks=new Map;async start(){this.loadState(),this.store.companionDataEncryptionKey||await this.fetchCompanionEncryptionKeys();const e=this.store.channels.filter(e=>e.enabled);for(const t of e)try{await this.connectChannel(t.id)}catch(e){ye.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}ye.info(`[CHANNEL] Manager started: machineId=${this.machineId}, channels=${this.store.channels.length}, enabled=${e.length}`)}async stop(){this.stopping=!0;for(const e of this.reconnectTimers.values())clearTimeout(e);this.reconnectTimers.clear();for(const e of this.pendingMessages.values())clearTimeout(e.timer);this.pendingMessages.clear();for(const e of this.adapters.values())await e.disconnect().catch(t=>{ye.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),ye.info("[CHANNEL] Manager stopped")}getChannels(){return this.loadState(),this.store.channels.map(e=>({...e,credentials:this.redactCredentials(e.credentials)}))}addChannel(e){this.loadState();const t=(new Date).toISOString(),n={id:le(),platform:e.platform,name:e.name,credentials:e.credentials,enabled:e.enabled??!1,connectionState:"disconnected",createdAt:t,updatedAt:t};return this.store.channels.push(n),this.saveState(),ye.info(`[CHANNEL] Added channel: id=${n.id}, platform=${n.platform}`),{...n,credentials:this.redactCredentials(n.credentials)}}async removeChannel(e){this.loadState();const t=this.store.channels.findIndex(t=>t.id===e);return-1!==t&&(await this.disconnectChannel(e,{disable:!0}).catch(()=>{}),this.store.channels.splice(t,1),this.store.bindings=this.store.bindings.filter(t=>t.channelId!==e),this.saveState(),ye.info(`[CHANNEL] Removed channel: id=${e}`),!0)}async connectChannel(e){this.loadState();const t=this.requireChannel(e);let n;this.clearReconnect(e),this.updateChannel(e,{enabled:!0,connectionState:"connecting",lastError:void 0});try{const s=this.adapters.get(e);s&&"disconnected"!==s.state&&(await s.disconnect().catch(t=>{ye.warn(`[CHANNEL] Failed to reset adapter before reconnect: channel=${e}`,t)}),this.adapters.delete(e),this.clearReconnect(e)),n=this.getOrCreateAdapter(t),await n.connect()}catch(t){const n=t instanceof Error?t.message:String(t);throw this.updateChannel(e,{connectionState:"error",lastError:n}),t}return this.updateChannel(e,{enabled:!0,connectionState:n.state,lastConnectedAt:"connected"===n.state?(new Date).toISOString():t.lastConnectedAt,lastError:"error"===n.state?"Connection failed":void 0}),this.getChannel(e)}async disconnectChannel(e,t={}){this.loadState(),this.requireChannel(e),this.clearReconnect(e),t.disable&&this.updateChannel(e,{enabled:!1});const n=this.adapters.get(e);return n&&(await n.disconnect(),this.adapters.delete(e)),this.updateChannel(e,{enabled:!t.disable&&this.requireChannel(e).enabled,connectionState:"disconnected",lastDisconnectedAt:(new Date).toISOString()}),this.getChannel(e)}async getContacts(e){this.loadState();const t=this.requireChannel(e);return this.getOrCreateAdapter(t).getContacts()}getBindings(e){return this.loadState(),this.requireChannel(e),this.store.bindings.filter(t=>t.channelId===e)}async sendMessageToTaskChannel(e,t){this.loadState();const n=this.getReplyTargetForTask(e);return n?(await this.sendMessageToChannel(n,t),ye.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):(ye.debug(`[CHANNEL] No channel binding for task ${e}`),!1)}getReplyTargetForTask(e){this.loadState();const t=this.store.bindings.find(t=>t.taskId===e);if(!t)return null;const n=this.store.channels.find(e=>e.id===t.channelId);return{channelId:t.channelId,chatId:t.chatId,...n?.platform?{platform:n.platform}:{},...t.chatName?{chatName:t.chatName}:{}}}async sendMessageToChannel(e,t){const n=this.getOrCreateAdapter(this.requireChannel(e.channelId));"connected"!==n.state&&await this.connectChannel(e.channelId);const s="string"==typeof t?{content:t}:t,a=s.content?.trim(),i=s.attachments??[];if(!a&&0===i.length)throw new Error("Channel message requires content or attachments");const o=i.map(e=>({...e,kind:this.resolveAttachmentKind(e)}));for(const e of o)if(!this.isAttachmentKindSupported(n,e.kind))throw new Error(`Channel platform ${n.platform} does not support sending ${e.kind} attachments`);if(o.length>0){if(!n.sendChannelMessage)throw new Error(`Channel platform ${n.platform} does not support outgoing attachment messages`);await n.sendChannelMessage(e.chatId,{content:s.content,attachments:o})}else n.sendChannelMessage?await n.sendChannelMessage(e.chatId,{content:s.content}):await n.sendMessage(e.chatId,s.content??"")}getChannelGroupHistory(e,t={}){if("group"!==e.chatType?.toLowerCase())throw new Error("Channel group history is only available for external group chats");const n=Math.max(1,Math.min(t.limit??30,100)),s=this.buildGroupHistoryRef(e),a=this.openGroupHistoryDb(s);try{const i="number"==typeof t.beforeSeq?a.pageMessagesBefore(t.beforeSeq,n):"number"==typeof t.afterSeq?a.pageMessagesAfter(t.afterSeq,n):a.pageRecentMessages(n);return{historyXml:this.formatExternalGroupHistoryXml(s,i.data,e.chatName||e.chatId,{markTriggered:!1}),hasMoreBefore:"number"!=typeof t.afterSeq&&i.hasMore,hasMoreAfter:"number"==typeof t.afterSeq&&i.hasMore}}finally{a.close()}}removeBinding(e,t){this.loadState(),this.requireChannel(e);const n=this.store.bindings.findIndex(n=>n.channelId===e&&n.id===t);return-1!==n&&(this.store.bindings.splice(n,1),this.saveState(),ye.info(`[CHANNEL] Removed binding: channel=${e}, binding=${t}`),!0)}getChannel(e){const t=this.requireChannel(e);return{...t,credentials:this.redactCredentials(t.credentials)}}getOrCreateAdapter(e){const t=this.adapters.get(e.id);if(t)return t;const n=this.createAdapter(e);return n.onMessage(e=>this.routeMessage(e)),n.onStateChange?.((t,n)=>this.handleAdapterState(e.id,t,n)),this.adapters.set(e.id,n),n}createAdapter(e){if("lark"===e.platform)return new Io({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new mi({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new Po({id:e.id,credentials:e.credentials});throw new Error(`Unsupported channel platform: ${e.platform}`)}resolveAttachmentKind(e){return e.kind&&"auto"!==e.kind?e.kind:e.mimeType?.startsWith("image/")?"image":e.mimeType?.startsWith("audio/")?"audio":e.mimeType?.startsWith("video/")?"video":"file"}isAttachmentKindSupported(e,t){const n=e.capabilities;return!n||("image"===t?!0===n.sendImage||!0===n.sendFile:"audio"===t?!0===n.sendAudio||!0===n.sendFile:"video"===t&&!0===n.sendVideo||!0===n.sendFile)}async routeMessage(e){ye.info(`[CHANNEL] routeMessage raw: ${JSON.stringify(e)}`);const t=await this.downloadMessageAttachments(e),n=this.getPendingMessageKey(t);if(this.isAttachmentOnlyMessage(t))return void this.bufferPendingMessage(n,t);const s=this.takePendingMessages(n),a=s.length>0?this.mergePendingMessages(s,t):t;await this.routeRoutableMessage(a)}async routeRoutableMessage(e){this.loadState();let t=e;if(this.isGroupMessage(e)){if(await this.saveGroupHistoryMessage(e),!this.isGroupMessageTriggered(e))return void ye.info(`[CHANNEL] Stored passive group message only: channel=${e.channelId}, chat=${e.chatId}, message=${e.id}`);const n=await this.resolveChatName(e),s=this.loadRecentGroupHistory(e,30);t=this.injectExternalGroupHistory(e,s,n)}const{binding:n,isNew:s}=await this.getOrCreateBindingForMessage(t);ye.info(`[CHANNEL] routeMessage: isNew=${s}, taskId=${n.taskId}`),s||await this.forwardMessageToTask(t,n)}async flushPendingMessages(e){const t=this.takePendingMessages(e);for(const e of t)await this.routeRoutableMessage(e)}bufferPendingMessage(e,t){const n=this.pendingMessages.get(e);n&&clearTimeout(n.timer);const s=setTimeout(()=>{this.flushPendingMessages(e).catch(t=>{ye.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),ye.info(`[CHANNEL] Buffered attachment-only message: key=${e}, count=${(n?.messages.length??0)+1}`)}takePendingMessages(e){const t=this.pendingMessages.get(e);return t?(clearTimeout(t.timer),this.pendingMessages.delete(e),t.messages):[]}mergePendingMessages(e,t){const n=[...e.flatMap(e=>e.attachmentPaths??[]),...t.attachmentPaths??[]];return{...t,attachmentPaths:n,mentionedBot:t.mentionedBot||e.some(e=>e.mentionedBot),replyToBot:t.replyToBot||e.some(e=>e.replyToBot),triggered:t.triggered||e.some(e=>e.triggered),rawContent:{pendingMessages:e,textMessage:t.rawContent}}}isGroupMessage(e){return"group"===e.chatType?.toLowerCase()}isGroupMessageTriggered(e){return!0===e.mentionedBot||!0===e.replyToBot||!0===e.triggered}async saveGroupHistoryMessage(e){const t=this.openGroupHistoryDb(e);try{const n=await this.resolveGroupMessageSenderName(e);t.saveMessage({eventId:this.getGroupHistoryEventId(e),message:this.buildGroupHistorySdkMessage(e),senderType:"channel",senderId:e.senderId||"channel-user",senderName:n})}finally{t.close()}}loadRecentGroupHistory(e,t){const n=this.openGroupHistoryDb(e);try{const s=this.getGroupHistoryEventId(e),a=n.pageRecentMessages(500).data,i=a.findIndex(e=>e.eventId===s),o=i>=0?a.slice(0,i+1):a,r=this.findPreviousTriggerIndex(o,s),c=r>=0?r+1:0;return o.slice(c).slice(-t)}finally{n.close()}}injectExternalGroupHistory(e,t,n){return{...e,text:this.formatExternalGroupHistoryXml(e,t,n)}}formatExternalGroupHistoryXml(e,t,n,s={markTriggered:!0}){const a=[`<external_group_history ${[`platform="${this.escapeXmlAttribute(e.platform)}"`,`chatName="${this.escapeXmlAttribute(n)}"`,`chatId="${this.escapeXmlAttribute(e.chatId)}"`].join(" ")}>`];return t.forEach((t,n)=>{const i=Do({seq:t.localSequence.toString(),id:t.eventId,at:t.createdAt,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName,mentionedBot:this.getHistoryEntryTriggerFlags(t).mentionedBot?"true":void 0,replyToBot:this.getHistoryEntryTriggerFlags(t).replyToBot?"true":void 0,triggered:!1===s.markTriggered?void 0:t.eventId===this.getGroupHistoryEventId(e)?"true":void 0});a.push(` <msg ${i}>`),a.push(` ${this.escapeXmlText(this.formatHistoryMessageContent(t))}`),a.push(" </msg>")}),a.push("</external_group_history>"),a.join("\n")}formatHistoryMessageContent(e){const t=e.message;if(!t||"object"!=typeof t||"user"!==t.type)return"[non-text message]";const n=t.message.content;return"string"==typeof n?n.trim()||"[non-text message]":Array.isArray(n)&&n.filter(e=>e&&"object"==typeof e&&"text"===e.type&&"string"==typeof e.text).map(e=>e.text).join("\n\n").trim()||"[non-text message]"}buildGroupHistorySdkMessage(e){const t=e.attachmentPaths?.length?`[attachments: ${e.attachmentPaths.join(", ")}]`:void 0;return{type:"user",message:{role:"user",content:[e.text?.trim(),t,e.text?.trim()||t?void 0:`[${e.type}]`].filter(Boolean).join("\n\n")},parent_tool_use_id:null,session_id:"",__channelGroupHistory:{mentionedBot:!0===e.mentionedBot,replyToBot:!0===e.replyToBot,triggered:this.isGroupMessageTriggered(e)}}}async resolveGroupMessageSenderName(e){if(e.senderName?.trim())return e.senderName.trim();const t=e.senderId?.trim(),n=this.adapters.get(e.channelId);if(t&&n?.getUserName)try{const e=await n.getUserName(t);if(e&&e!==t)return e}catch(n){ye.debug(`[CHANNEL] Failed to resolve group sender name: channel=${e.channelId}, sender=${t}`,n)}return t||`${e.platform}:${e.chatId}`}getHistoryEntryTriggerFlags(e){const t=e.message.__channelGroupHistory;if(!t||"object"!=typeof t)return{mentionedBot:!1,replyToBot:!1,triggered:!1};const n=t;return{mentionedBot:!0===n.mentionedBot,replyToBot:!0===n.replyToBot,triggered:!0===n.triggered}}isTriggeredHistoryEntry(e){const t=this.getHistoryEntryTriggerFlags(e);return t.triggered||t.mentionedBot||t.replyToBot}findPreviousTriggerIndex(e,t){for(let n=e.length-1;n>=0;n-=1){const s=e[n];if(s.eventId!==t&&this.isTriggeredHistoryEntry(s))return n}return-1}openGroupHistoryDb(e){const t=this.getGroupHistoryDataDir(e);return r(t)||p(t,{recursive:!0}),io({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return S(this.groupHistoryFilePath,this.encodePathPart(e.channelId),this.encodePathPart(e.chatId))}getGroupHistoryTaskId(e){return`channel-group:${e.channelId}:${e.chatId}`}getGroupHistoryEventId(e){return`channel-group:${e.channelId}:${e.chatId}:${e.id}`}buildGroupHistoryRef(e){const t="telegram"===e.platform||"wechat"===e.platform||"lark"===e.platform?e.platform:"lark";return{id:"__history_page__",channelId:e.channelId,platform:t,chatId:e.chatId,chatType:e.chatType,type:"text",timestamp:(new Date).toISOString()}}encodePathPart(e){return Buffer.from(e).toString("base64url")}escapeXmlText(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}escapeXmlAttribute(e){return this.escapeXmlText(e).replace(/"/g,""").replace(/'/g,"'")}getPendingMessageKey(e){return`${e.channelId}:${e.chatId}`}isAttachmentOnlyMessage(e){const t="string"==typeof e.text&&e.text.trim().length>0,n=Boolean(e.fileKey||e.imageKey||e.attachmentPaths?.length);return!t&&n&&("image"===e.type||"file"===e.type)}async downloadMessageAttachments(e){const t=this.adapters.get(e.channelId);if(!t?.downloadFile)return e;const n=[e.imageKey,e.fileKey].filter(e=>Boolean(e)),s=[...new Set(n)];if(0===s.length)return e;const a=[];for(const n of s){const s=await t.downloadFile(n,{fileName:e.fileName});s&&(ye.info(`[CHANNEL] Downloaded attachment: channel=${e.channelId}, chat=${e.chatId}, path=${s}`),a.push(s))}return a.length>0?{...e,attachmentPaths:[...e.attachmentPaths??[],...a]}:e}async forwardMessageToTask(e,t){if(ye.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void ye.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void ye.warn(`[CHANNEL] Task ${t.taskId} is pending, skipping message forward`);const n=this.readCompanionState(),s=n?.chatId||t.taskId,{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e);this.client.send("task-message",{eventId:G(),taskId:t.taskId,chatId:s,from:"machine",message:a,encryptedMessage:i,messageType:"text",senderType:"channel",senderId:e.senderId||"channel-user",senderName:e.senderName||`${e.platform}:${e.chatId}`,channelReplyTarget:{channelId:e.channelId,chatId:e.chatId,platform:e.platform,chatType:e.chatType,chatName:t.chatName}}),ye.info(`[CHANNEL] Forwarded message to task ${t.taskId}`)}async buildEncryptedMessage(e){const t=e.attachmentPaths??[],n=t.length>0?`[User sent the following attachments: ${t.join(", ")}]`:void 0,s={type:"user",message:{role:"user",content:[n,e.text||(n?void 0:`[${e.type}]`)].filter(Boolean).join("\n\n")}};let a,i=s;if(this.store.companionDataEncryptionKey)try{const e=await fe.getSecretKey();if(e){const t=H(L(this.store.companionDataEncryptionKey),e);t&&(a=ee(s,t),i=void 0)}}catch(e){ye.warn("[CHANNEL] Failed to encrypt message, sending plaintext",e)}return{plainMessage:i,encryptedMessage:a}}async getOrCreateBindingForMessage(e){const t=this.store.bindings.find(t=>t.channelId===e.channelId&&t.chatId===e.chatId);if(t)return{binding:t,isNew:!1};const n=await this.resolveChatName(e),s=await this.createTaskForChat(e,n),a=(new Date).toISOString(),i={id:le(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.store.bindings.push(i),this.saveState(),ye.info(`[CHANNEL] Auto-created binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0}}async createTaskForChat(e,t){const n=this.createTaskLocks.get(e.chatId);if(n)return n;const s=this.doCreateTaskForChat(e,t);this.createTaskLocks.set(e.chatId,s);try{return await s}finally{this.createTaskLocks.delete(e.chatId)}}async doCreateTaskForChat(e,t){const n=this.readCompanionState();if(!n)return ye.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${le()}`;if(this.store.companionDataEncryptionKey||await this.fetchCompanionEncryptionKeys(),!this.client.connected)return ye.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${le()}`;const{plainMessage:s,encryptedMessage:a}=await this.buildEncryptedMessage(e);try{const i=await this.client.sendWithAck("channel-task-create",{eventId:G(),userId:n.userId,chatId:n.chatId,agentId:n.agentId,machineId:n.machineId,customTitle:"wechat"===e.platform?"wechat bot":`${e.platform}/${t}`,taskType:"work",supportedFeatures:["sub-task"],taskAgentIds:[n.agentId],dataEncryptionKey:this.store.companionDataEncryptionKey,ownerEncryptedDataKey:this.store.companionOwnerEncryptedDataKey,message:s,encryptedMessage:a,senderType:"channel",senderId:e.senderId||"channel-user",senderName:e.senderName||`${e.platform}:${e.chatId}`,channelReplyTarget:{channelId:e.channelId,chatId:e.chatId,platform:e.platform,chatType:e.chatType,chatName:t}});return"success"===i?.status&&i.taskId?(ye.info(`[CHANNEL] Created task ${i.taskId} for chat ${e.chatId}`),i.taskId):(ye.error(`[CHANNEL] API task creation failed: ${i?.message||"unknown"}`),`pending-api-error-${le()}`)}catch(e){return ye.error("[CHANNEL] Failed to create task via API",e),`pending-error-${le()}`}}async resolveChatName(e){try{ye.info(`[CHANNEL] resolveChatName: chatType=${e.chatType}, senderId=${e.senderId}, channelId=${e.channelId}`);const t=this.adapters.get(e.channelId),n="p2p"===e.chatType?.toLowerCase();if(n){if(e.senderName)return e.senderName;if(e.senderId&&t?.getUserName){const n=await t.getUserName(e.senderId);if(ye.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if(ye.info(`[CHANNEL] resolveChatName: getChatName returned "${n}"`),n&&n!==e.chatId)return n}return!n&&e.senderName?e.senderName:e.senderId||e.chatId}catch(t){return ye.warn(`[CHANNEL] Failed to resolve chat name for ${e.chatId}: ${t?.message||String(t)}`),e.senderName||e.senderId||e.chatId}}async fetchCompanionEncryptionKeys(){const e=this.readCompanionState();if(e)if(this.client.connected)try{const t=await this.client.sendWithAck("get-task-encryption-keys",{eventId:G(),taskId:e.chatId});"success"===t?.status&&t.dataEncryptionKey?(this.store.companionDataEncryptionKey=t.dataEncryptionKey,this.store.companionOwnerEncryptedDataKey=t.ownerEncryptedDataKey,this.saveState(),ye.info("[CHANNEL] Fetched and stored companion encryption keys")):ye.warn(`[CHANNEL] Failed to fetch encryption keys: ${t?.message||"unknown"}`)}catch(e){ye.warn("[CHANNEL] Error fetching companion encryption keys",e)}else ye.debug("[CHANNEL] Socket not connected, skipping encryption key fetch")}readCompanionState(){const e=S(fe.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return ye.warn("[CHANNEL] Companion state.json not found"),null;try{const t=JSON.parse(c(e,"utf-8"));return t.userId&&t.agentId&&t.chatId&&t.machineId?{userId:t.userId,agentId:t.agentId,chatId:t.chatId,machineId:t.machineId}:(ye.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return ye.warn("[CHANNEL] Failed to read companion state.json",e),null}}handleAdapterState(e,t,n){this.loadState();const s=this.store.channels.find(t=>t.id===e);s&&(this.updateChannel(e,{connectionState:t,lastConnectedAt:"connected"===t?(new Date).toISOString():s.lastConnectedAt,lastDisconnectedAt:"disconnected"===t?(new Date).toISOString():s.lastDisconnectedAt,lastError:n?.message}),this.stopping||"disconnected"!==t&&"error"!==t||!s.enabled||this.scheduleReconnect(e))}scheduleReconnect(e){if(this.reconnectTimers.has(e))return;const t=setTimeout(()=>{this.reconnectTimers.delete(e),this.connectChannel(e).catch(t=>{ye.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),ye.info(`[CHANNEL] Scheduled reconnect: channel=${e}, delayMs=30000`)}clearReconnect(e){const t=this.reconnectTimers.get(e);t&&(clearTimeout(t),this.reconnectTimers.delete(e))}requireChannel(e){const t=this.store.channels.find(t=>t.id===e);if(!t)throw new Error(`Channel ${e} not found`);return t}updateChannel(e,t){const n=this.requireChannel(e);Object.assign(n,t,{updatedAt:(new Date).toISOString()}),this.saveState()}loadState(){try{if(!r(this.stateFilePath))return void(this.store={version:1,channels:[],bindings:[]});const e=JSON.parse(c(this.stateFilePath,"utf-8"));this.store=Ti.parse(e)}catch(e){ye.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=A(this.stateFilePath);r(e)||p(e,{recursive:!0}),u(this.stateFilePath,JSON.stringify(this.store,null,2),"utf-8")}redactCredentials(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,"string"==typeof t&&t.length>0?"********":t]))}}async function Ho(){Object.assign(ye,we({type:"daemon"}));const{requestShutdown:e,shutdownPromise:t}=function(){const{processType:e,onShutdownRequest:t}={processType:"daemon"},n=`[${e.toUpperCase()}]`;let s;const a=new Promise(e=>{s=(s,a)=>{ye.info(`${n} Requesting shutdown (source: ${s}, errorMessage: ${a})`),t&&t(s,a),setTimeout(()=>process.exit(1),1e3),e({source:s,errorMessage:a})}}),i=e=>{process.on(e,()=>{s("os-signal")})};return i("SIGINT"),i("SIGTERM"),process.on("uncaughtException",e=>{ye.info(`${n} FATAL: Uncaught exception`,e),ye.info(`${n} Stack trace: ${e.stack}`),s("exception",e.message)}),process.on("unhandledRejection",e=>{ye.info(`${n} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);ye.info(`${n} Stack trace: ${t.stack}`),s("exception",t.message)}),process.on("exit",e=>{ye.info(`${n} Process exiting with code: ${e}`)}),{requestShutdown:s,shutdownPromise:a}}();console.log("[DAEMON RUN] Starting daemon process..."),ye.debug("[DAEMON RUN] Environment",ss()),await Ft()&&(console.log("Daemon already running..."),process.exit(0));let n=await fe.acquireDaemonLock(5,200);for(;!n;)await zt(),n=await fe.acquireDaemonLock(5,200),n||(ye.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{(function(){if(fe.disableCaffeinate)return ye.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return ye.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(Vn&&!Vn.killed)return ye.debug("[caffeinate] Caffeinate already running"),!0;try{return Vn=ze("caffeinate",["-im"],{stdio:"ignore",detached:!1}),Vn.on("error",e=>{ye.debug("[caffeinate] Error starting caffeinate:",e),Vn=null}),Vn.on("exit",(e,t)=>{ye.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),Vn=null}),ye.info(`[caffeinate] Started with PID ${Vn.pid}`),function(){if(Yn)return;Yn=!0;const e=()=>{Jn()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{ye.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{ye.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return ye.info("[caffeinate] Failed to start caffeinate:",e),!1}})()&&ye.debug("[DAEMON RUN] Sleep prevention enabled");const s=await Jt();ye.debug("[DAEMON RUN] Auth and machine setup complete");const a=new ho;await a.initialize(fe.getSandboxSettings());const i=new mo(a);let o,r,c;const{port:l,host:p,webhookHost:d,stop:u}=await no({getChildren:()=>i.getCurrentSessions(),stopSession:e=>i.stopSession(e),requestShutdown:()=>e("agentrix-cli"),registerSession:(e,t)=>i.registerTaskWorker(e,t),getSocketClient:()=>o?.client,credentials:s,get companionScheduler(){return r},get channelManager(){return c}});try{await os(),ye.debug("[DAEMON RUN] Openers detected")}catch(e){ye.warn("[DAEMON RUN] Failed to detect openers",e)}const m={pid:process.pid,port:l,host:p,webhookHost:d,startTime:(new Date).toLocaleString(),cliVersion:xe.version,logPath:be({type:"daemon"})};fe.writeDaemonState(m),ye.debug("[DAEMON RUN] Daemon state written");const h=new Kn({machineId:s.machineId,serverUrl:fe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:te(s.token,s.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:G(),machineId:s.machineId,timestamp:Date.now().toString(),controlPort:l})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>ye.debug(`[DAEMON SOCKET] ${e}`,...t)},i,{requestShutdown:e}),g=new Lo(h.client,s.machineId);c=g,i.setChannelManager(g),await h.connect(),o=h,ye.info("[DAEMON RUN] Machine client connected to server");const f=new go(h.client,s.machineId);r=f,f.start(),await g.start(),h.setCompanionInteractionCallback(e=>{f.recordInteraction(e)});const y=new fo(h.client,s.machineId);y.start(),h.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&f.setHeartbeatTaskId(e.taskId)});const v=async(e,t)=>{await g.stop(),f.stop(),y.stop(),await h.disconnect(),await u(),await a.shutdown(),await Wt(),await Jn(),await fe.releaseDaemonLock(n),ye.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};ye.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const x=await t;await v(x.source,x.errorMessage)}catch(e){(function(e){return e instanceof Error&&e.message.includes("Machine binding revoked")})(e)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again.")),ye.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",e),process.exit(1)}}const Go="\n\n[Tool result truncated to 1024 bytes]";function Bo(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(Go,"utf8");return n>t?Wo(Go,t):`${Wo(e,t-n)}${Go}`}function Fo(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Wo(e,t){let n="",s=0;for(const a of e){const e=Buffer.byteLength(a,"utf8");if(s+e>t)break;n+=a,s+=e}return n}const zo={senderType:"system",senderId:"system",senderName:"system"};class Ko{client;context;historyDb;getPermissionMode;outbox=new Map;usageOutbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new Zt(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir,logger:t.logger},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.initHandlers()}getPermissionModeSnapshot(){return this.getPermissionMode?.()??null}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Worker connection timeout after 10 seconds"))},1e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.client.disconnect()}sendTaskMessage(e,t,n){const s=G();return this.historyDb.saveMessage({eventId:s,message:t,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}),this.sendTaskEvent(e,t,n),s}sendWorkerInitializing(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd,...void 0!==e?.deployingAgent&&{deployingAgent:e.deployingAgent},...void 0!==e?.upgradingAgent&&{upgradingAgent:e.upgradingAgent}};this.client.send("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.client.send("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.client.send("worker-ready",n)}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.client.send("worker-running",n)}sendPermissionMode(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.client.send("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.client.send("worker-exit",t)}async sendErrorMessageAndExit(e){await this.sendTerminalErrorResultAndWait(e),this.sendWorkerExit("error"),await this.disconnect()}async sendTerminalErrorResultAndWait(e,t){const n=this.sendTerminalErrorResult(e,t);await this.waitForEventAcks(n,2e3)}sendTerminalErrorResult(e,t){const n=this.sendSystemErrorMessage(e,t),s=this.sendTaskEvent(zo,function(e){return{type:"result",subtype:"error_during_execution",duration_ms:0,duration_api_ms:0,is_error:!0,num_turns:0,stop_reason:null,total_cost_usd:0,usage:{input_tokens:0,output_tokens:0,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:0,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"},modelUsage:{},permission_denials:[],errors:[e],uuid:crypto.randomUUID(),session_id:""}}(e),{groupId:t?.groupId});return[n,s]}sendSystemErrorMessage(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:`System Error\n\n${e}`,metadata:{messageType:"system_error"}}]}};return this.sendTaskEvent(zo,n,{groupId:t?.groupId})}sendAssistantMessage(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:e}]}};this.sendTaskEvent(zo,n,{groupId:t?.groupId})}sendAskUser(e,t,n){return this.sendTaskMessage(e,{type:"ask_user",questions:t},{groupId:n?.groupId})}sendAskUserResponse(e,t){return this.sendTaskMessage(zo,t,{opCode:e})}sendTaskEvent(e,t,n){const s=function(e,t=1024){const n=e,s=n?.message?.content;if(!Array.isArray(s))return e;let a=!1;const i=s.map(e=>{if("tool_result"!==e?.type||!("content"in e))return e;const n=function(e,t=1024){if("string"==typeof e)return Bo(e,t);const n=Fo(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?Bo(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:Fo(e);var t}).join("\n"),t):Bo(n,t)}(e.content,t);return n===e.content?e:(a=!0,{...e,content:n})});return a?{...n,message:{...n.message,content:i}}:e}(t),{eventId:a,opCode:i,artifacts:o,navigateToTaskId:r}=n||{},c=a??G(),l={eventId:c,taskId:this.context.taskId,chatId:this.context.chatId,from:"worker",messageType:s.type,message:s,encryptedMessage:void 0,opCode:i,groupId:n?.groupId,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,artifacts:o,navigateToTaskId:r};this.historyDb.saveTaskEvent({eventType:"task-message",eventId:c,eventData:l,taskId:this.context.taskId,chatId:this.context.chatId,sequence:"number"==typeof l.sequence?l.sequence:null});const p=this.buildTaskUsageReport(s,c);if(this.context.dataEncryptionKey){const e=ee(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,l),p&&(this.usageOutbox.set(c,p),this.client.send("task-usage-report",p)),this.client.send("task-message",l),c}waitForEventAcks(e,t){const n=e.filter(e=>this.outbox.has(e));return 0===n.length?Promise.resolve():new Promise(e=>{let s=n.length;const a=t=>{this.ackWaiters.delete(t),s-=1,s<=0&&(clearTimeout(i),e())},i=setTimeout(()=>{for(const e of n)this.ackWaiters.delete(e);e()},t);for(const e of n)this.ackWaiters.set(e,()=>a(e))})}buildTaskUsageReport(e,t){if("result"!==e.type)return null;const n=e.modelUsage;if(!n||"object"!=typeof n)return null;const s={};for(const[e,t]of Object.entries(n)){if(!e||!t||"object"!=typeof t)continue;const n=t,a={inputTokens:this.normalizeUsageCount(n.inputTokens),outputTokens:this.normalizeUsageCount(n.outputTokens),cacheReadInputTokens:this.normalizeUsageCount(n.cacheReadInputTokens),cacheCreationInputTokens:this.normalizeUsageCount(n.cacheCreationInputTokens),webSearchRequests:this.normalizeUsageCount(n.webSearchRequests)};Object.values(a).some(e=>e>0)&&(s[e]=a)}return 0===Object.keys(s).length?null:{eventId:G(),taskId:this.context.taskId,resultEventId:t,modelUsage:s}}normalizeUsageCount(e){return"number"!=typeof e||!Number.isFinite(e)||e<=0?0:Math.trunc(e)}sendUpdateTaskAgentSessionId(e){const t={eventId:G(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.client.send("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:G(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.client.send("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:G(),taskId:this.context.taskId,title:e};this.client.send("change-task-title",t),ye.info(`[AGENT] Title changed to: ${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:G(),taskId:this.context.taskId,agentId:e,...t};this.client.send("update-agent-info",n),ye.info(`[AGENT] Agent info updated: ${JSON.stringify(t)}`)}sendResetTaskSession(){const e={eventId:G(),taskId:this.context.taskId};this.client.send("reset-task-session",e),ye.info(`[AGENT] Session reset requested for task ${this.context.taskId}`)}async sendMergeRequest(e,t){const n={eventId:G(),taskId:this.context.taskId,summary:e,description:t};ye.info(`[MERGE] Sending merge-request event for task ${this.context.taskId}`);const s=await this.client.sendWithAck("merge-request",n);if(!s.success)throw new Error(`Failed to create pull request: ${s.error||"Unknown error"}`);return ye.info(`[MERGE] Pull request created: #${s.data.pullRequestNumber}`),{pullRequestNumber:s.data.pullRequestNumber,pullRequestUrl:s.data.pullRequestUrl}}async sendMergePr(){const e={eventId:G(),taskId:this.context.taskId,mergeMethod:"squash"};return ye.info(`[MERGE-PR] Sending merge-pr event for task ${this.context.taskId}`),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:G(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};ye.info(`[REPO] Sending repository association request: ${e}/${t}/${n}`),this.client.send("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:G(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},{"cancel-task":async e=>{e.taskId===t.taskId&&(ye.info(`[WORKER] Task ${t.taskId} cancelled`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&(ye.info(`[WORKER] Task ${t.taskId} stopped: ${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;let a=e.message??null;if(!a&&e.encryptedMessage&&t.dataEncryptionKey&&(a=X(e.encryptedMessage,t.dataEncryptionKey)??null),!a)return;e.channelReplyTarget&&"object"==typeof a&&(a.__channelReplyTarget=e.channelReplyTarget);const i={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&J(a)&&(a=await uo(a,{attachmentsDir:t.attachmentsDir,log:t.logger})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(a,i))return void ye.debug(`[WORKER] Dropping incoming task-message before persistence: eventId=${e.eventId}`);if(!n.saveMessage({eventId:e.eventId,message:a,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return ye.debug(`[WORKER] Ignoring duplicate incoming task-message: eventId=${e.eventId}`),void s(e.eventId);const o={...e,message:a,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:o,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(a,i)},"task-info-update":async e=>{e.taskId===t.taskId&&t.onTaskInfoUpdate&&await t.onTaskInfoUpdate(e)},"worker-status-request":async e=>{e.taskId===t.taskId&&t.onWorkerStatusRequest&&await t.onWorkerStatusRequest(e)},"sub-task-result-updated":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskResultUpdated&&await t.onSubTaskResultUpdated(e)},"sub-task-ask-user":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskAskUser&&await t.onSubTaskAskUser(e)}});var t,n,s;this.client.onEvent("cancel-task",e["cancel-task"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEvent("task-message",e["task-message"]),this.client.onEvent("task-info-update",e["task-info-update"]),this.client.onEvent("worker-status-request",e["worker-status-request"]),this.client.onEvent("sub-task-result-updated",e["sub-task-result-updated"]),this.client.onEvent("sub-task-ask-user",e["sub-task-ask-user"]),this.client.onEvent("event-ack",e=>{const t=e.data?.sequence;void 0!==e.opCode&&(this.outbox.delete(e.opCode),this.usageOutbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.()),void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(this.outbox.size>0){ye.info(`[WORKER] Reconnected — flushing ${this.outbox.size} outbox message(s)`);for(const[e,t]of this.outbox.entries()){const n=this.usageOutbox.get(e);n&&this.client.send("task-usage-report",n),this.client.send("task-message",t)}}}else this.hasConnectedOnce=!0})}}const Vo=pt(it),Xo="xmz-ai",Jo="agentrix-hive",Yo="https://github.com/xmz-ai/agentrix-hive.git",Qo="github";class Zo{logger;socketClient;taskId;userId;chatId;rootTaskId;parentTaskId;workingDirectory;taskAgents;serverUrl;taskDataKey;agentHomeDir;constructor(e){this.logger=e.logger,this.socketClient=e.socketClient,this.taskId=e.taskId,this.userId=e.userId,this.chatId=e.chatId,this.rootTaskId=e.rootTaskId,this.parentTaskId=e.parentTaskId,this.workingDirectory=e.workingDirectory,this.agentHomeDir=e.agentHomeDir,this.taskAgents=e.taskAgents,this.serverUrl=e.serverUrl,this.taskDataKey=e.taskDataKey}async call(e,t,n){const s=G();try{const a=await this.socketClient.sendWithAck("rpc-call",{eventId:s,taskId:this.taskId,method:e,path:t,query:n?.query,body:n?.body});if(!a.success){const n=a.error||{code:"unknown",message:"Unknown error"};throw new Error(`RPC ${e} ${t} failed: ${n.message} (${n.code})`)}return a.data}catch(n){throw new Error(`RPC ${e} ${t} error: ${n.message}`)}}log(e){this.logger.info(e)}getWorkspace(){return this.workingDirectory}getAgentHomeDir(){return this.agentHomeDir}getUserId(){return this.userId}getTaskId(){return this.taskId}getChatId(){return this.chatId}getRootTaskId(){return this.rootTaskId}getParentTaskId(){return this.parentTaskId}getTaskAgents(){return this.taskAgents}async createDraftAgent(e){return this.call("POST","/v1/draft-agent",{body:{...e,userId:this.userId,taskId:this.taskId}})}async updateDraftAgent(e,t){return this.call("PATCH",`/v1/draft-agent/${e}`,{body:t})}async startSubTask(e){const t={userId:this.userId,chatId:this.chatId,agentId:e.agentId,parentTaskId:this.taskId,customTitle:e.title,cwd:e.cwd,forceUserCwd:e.forceUserCwd};return this.taskDataKey?t.encryptedMessage=ee(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async startIndependentTask(e){const t={userId:this.userId,chatId:this.chatId,agentId:e.agentId,sourceTaskId:this.taskId,customTitle:e.title,cwd:e.cwd,forceUserCwd:e.forceUserCwd,autoNavigate:e.autoNavigate};return this.taskDataKey?t.encryptedMessage=ee(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async startGroupTask(e){const t={userId:this.userId,chatId:e.chatId??this.chatId,parentTaskId:this.taskId,customTitle:e.title,todos:e.todos};return this.taskDataKey?t.encryptedMessage=ee(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async createGroupChat(e){return this.call("POST","/v1/agent-group-chats",{body:{agentIds:e}})}async sendMessage(e){await this.call("POST",`/v1/tasks/${e.taskId}/send-message`,{body:{message:e.message,target:e.target,fromTaskId:this.taskId,senderType:"agent",senderId:this.taskId,senderName:"agent"}})}async showModal(e){await this.call("POST",`/v1/tasks/${e.taskId}/show-modal`,{body:{modalName:e.modalName,modalData:e.modalData}})}async getTaskSession(e){return this.call("GET",`/v1/tasks/${e}/session`)}async findSubTaskByAgent(e){const t=await this.call("GET","/v1/tasks/find-by-agent",{query:{parentTaskId:this.taskId,agentId:e}});return t.taskId?{taskId:t.taskId}:null}async listSubTasks(){return(await this.call("GET","/v1/tasks/sub-tasks",{query:{parentTaskId:this.taskId}})).tasks}async listTasks(e){return(await this.call("GET","/v1/tasks/recent",{query:{chatId:this.chatId,...e?.limit&&{limit:e.limit},...e?.status&&{status:e.status}}})).tasks}async prepareHiveRepository(){const e=await async function(){const e=fe.resolveRepoStoreCheckoutDir(Qo,Xo,Jo),t=fe.resolveRepoStoreLockPath(Qo,Xo,Jo),n=await fe.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await la(e)){if(!wa(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await ga(Yo,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await $a(e,"origin",Aa(Yo));try{return await Vo("git",["pull","--ff-only"],{cwd:e}),{path:e,pullSucceeded:!0}}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}}finally{await fe.releaseFileLock(t,n)}}();return e.pullSucceeded||this.logger.warn(`[Agent-Context] Hive repository update failed; continuing when local copy is usable: ${e.error}`),e}async recordHiveInstall(e,t){return this.call("POST",`/v1/hive/listings/${e}/record-install`,{body:t})}async installHiveListing(e,t){return this.call("POST",`/v1/hive/listings/${e}/install`,{body:t})}async publishToHive(e){return this.call("POST","/v1/hive/publish",{body:e})}async updateHiveListingVersion(e,t){return this.call("POST",`/v1/hive/listings/${e}/update-version`,{body:t})}async createHiveReview(e,t){return this.call("POST",`/v1/hive/listings/${e}/reviews`,{body:t})}async createHiveComment(e,t){return this.call("POST",`/v1/hive/listings/${e}/comments`,{body:t})}async listAgents(){return this.call("GET","/v1/user-agents")}async uploadFile(e){this.logger.info("[Agent-Context] Uploading file...");const t=await Se.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||hn.lookup(e.name)||"application/octet-stream",a=(await this.call("POST","/v1/files/upload-urls",{body:{count:1}})).files[0],i=a.url;this.logger.info(`[Agent-Context] FileUploadUrl: ${i}`);const o=await Se.promises.readFile(e.path),r=await fetch(i,{method:"PUT",headers:{"Content-Type":s},body:o});if(!r.ok)throw new Error(`Failed to upload file to S3: ${r.status} ${r.statusText}`);let c;return await this.call("POST","/v1/files/confirm-upload",{body:{fileId:a.id,name:e.name,size:n,contentType:s,visibility:e.visibility||"private"}}),c="public"===e.visibility?`${this.serverUrl}/v1/files/public/${a.id}`:i.split("?")[0],{fileId:a.id,name:e.name,size:n,contentType:s,url:c}}}function er(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=X(e.encryptedResultMessage,t);s&&"result"===s.type&&(n={type:"result",result:"result"in s?s.result:"",is_error:s.is_error})}const s={...e,resultMessage:n};let a=`<sub-task-result-updated>\n${JSON.stringify(s,null,2)}\n</sub-task-result-updated>`;return a+=n.result.trim().length>0?'\n<system-reminder>The result is already shown to user as a card. Just acknowledge briefly (e.g., "Done!"). Only elaborate if error or needs user action.</system-reminder>':"\n<system-reminder>The sub-task result was empty. You can use reply_to_sub_task to ask it to continue, retry, or resend the result.</system-reminder>",{type:"user",message:{role:"user",content:a}}}function tr(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=X(e.encryptedMessage,t);s&&"ask_user"===s.type&&(n=s)}return{type:"user",message:{role:"user",content:`<sub-task-ask-user>\n${JSON.stringify({taskId:e.taskId,agentId:e.agentId,agentName:e.agentName,taskName:e.taskName,questions:n?.questions??[]},null,2)}\n</sub-task-ask-user>\n<system-reminder>A sub-task agent is asking the user questions. You should answer these questions on behalf of the user based on the task context and instructions. Use the reply_to_sub_task tool to send your answers back.</system-reminder>`}}}function nr(){const e=new Set;return{filter(t){const n=t;if(!n.message||!n.message.content||"string"==typeof n.message.content)return t;const s=n.message.content.filter(t=>!("tool_result"===t.type&&e.has(t.tool_use_id)||"user"===n.type&&"tool_result"!==t.type));return 0===s.length?null:(n.message.content=s,n)},clear(){e.clear()}}}function sr({workClient:e}){return ct("change_title","Change the session title to better describe what you are working on.\n\n## When to Use\n- Call it at the start of a session to set a descriptive title\n- Call it again when the title becomes outdated or too generic\n\nGood titles help users find conversations later.",{title:Qe.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function ar({agentContext:e,log:t}){return ct("emit_to_task","Send a message to a sub-task. Use this to:\n1. Answer a sub-task's ask_user questions: set answers array (one answer per question).\n2. Send follow-up instructions: set instructions only (no answers).",{taskId:Qe.string().describe("Sub-task ID to send the message to"),instructions:Qe.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:Qe.array(Qe.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async n=>{try{let t;return t=n.answers&&n.answers.length>0?{type:"ask_user_response",answers:n.answers}:{type:"user",message:{role:"user",content:n.instructions??""}},await e.sendMessage({taskId:n.taskId,message:t,target:"agent"}),{content:[{type:"text",text:`${n.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${n.taskId}.`}]}}catch(e){return t("error","TASK",`Failed to send message to sub-task ${n.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ir({historyDb:e}){return ct("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:Qe.number().int().min(0).optional().describe("Pagination cursor for older history. Omit this field, or pass 0, to read the latest messages. Only pass a positive sequence value that was returned by the previous result as “Use sequence=N to load earlier messages”; it means return messages before that local sequence, not start at that position."),limit:Qe.number().int().min(1).max(50).default(20).describe("Maximum number of messages to return.")},async t=>{const n=t.limit??20,s=null!=t.sequence&&t.sequence>0,a=s?e.pageMessagesBefore(t.sequence,n):e.pageRecentMessages(n);if(0===a.data.length)return{content:[{type:"text",text:s?"No earlier messages found.":"No task history messages found."}]};let i=Oo(a.data);return a.hasMore&&(i+=`\n\nMore messages available. Use sequence=${Math.min(...a.data.map(e=>e.localSequence))} to load earlier messages.`),{content:[{type:"text",text:i}]}})}function or({agentContext:e}){return ct("get_task_agents","List the agents available for the current task and return taskAgents info.",{},async()=>{const t=e.getTaskAgents();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No task agents available."}]}})}function rr({agentContext:e,log:t}){return ct("list_sub_task","List direct sub tasks for the current task with taskId, title, and cwd.",{},async()=>{try{const t=await e.listSubTasks();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No sub tasks found."}]}}catch(e){return t("error","TASK","Failed to list sub tasks:",e),{content:[{type:"text",text:`Failed to list sub tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function cr({agentContext:e,agentId:t,log:n,setPendingNavigateTaskId:s}){return ct("create_task","Delegate a task to an agent for execution.\n\n**Modes**:\n- Sub-task (default): Creates under current task, linked via parentTaskId.\n- Independent (independent=true): Creates a top-level task with no parent binding. Optionally set autoNavigate=true to auto-switch the user's App UI to the new task.\n\nIf agentId is provided, delegates to that specific agent. Otherwise, creates a task for yourself.\nAlways provide a concise task title in \"title\".\nThe task runs asynchronously - you'll be notified when complete via <sub-task-result-updated> message.\nUse for: multi-step implementations, analysis, code reviews, or any work that takes >30 seconds.\nAfter calling this tool, continue responding to user - don't wait for task completion.",{agentId:Qe.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:Qe.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:Qe.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:Qe.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:Qe.string().optional().describe("Working directory for the task. Pass your current cwd when the sub-task needs to read/write the same project files as you. If omitted, a new isolated workspace is created (scoped by taskId)."),useWorktree:Qe.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:Qe.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:Qe.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async a=>{try{if(a.autoNavigate&&!a.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const i=a.agentId||t;let o;return a.independent?(o=await e.startIndependentTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,autoNavigate:a.autoNavigate}),a.autoNavigate&&s(o.taskId),n("info","TASK",`Created independent task ${o.taskId} for agent ${i} (autoNavigate: ${a.autoNavigate??!1})`)):(o=await e.startSubTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree}),n("info","TASK",`Created sub-task ${o.taskId} for agent ${i}`)),{content:[{type:"text",text:`🚀 Task created: ${o.taskId}\n${a.agentId?`Agent: ${i}\n`:""}${a.independent?"Mode: Independent\n":""}Summary: ${a.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return n("error","TASK","Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function lr({agentContext:e,log:t}){return ct("create_solo_task","Create a single-agent async task in group chat.\n\n## When to Use (sparingly)\n- Long-running background work (>5 minutes)\n- Work that needs separate tracking/progress monitoring\n- Complex multi-step projects with explicit deliverables\n\n## Prefer invoke Instead\nFor most requests, use `invoke` - it's simpler and the agent responds directly in chat.\nOnly use this tool when background tracking is truly needed.\n\nAfter creating: You'll receive <sub-task-result-updated> when task completes.",{title:Qe.string().min(1).max(200).describe("Task title"),instructions:Qe.string().describe("Instructions for the owner agent"),briefSummary:Qe.string().optional().describe("One-line summary shown to user immediately"),agentId:Qe.string().describe("Target agent ID"),cwd:Qe.string().optional().describe("Working directory for the sub-task. Pass your current cwd when the sub-task needs to read/write the same project files as you. If omitted, a new isolated workspace is created (scoped by sub-task taskId)."),useWorktree:Qe.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:n.agentId,message:{type:"user",message:{role:"user",content:n.instructions}},title:n.title,cwd:n.cwd,forceUserCwd:!n.useWorktree})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","TASK","Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function pr({agentContext:e,log:t,agentId:n}){return ct("create_group_task","Create a multi-agent async task plan in group chat.\n\n## When to Use (sparingly)\n- Long-running background work requiring multiple agents (>5 minutes)\n- Complex multi-step projects with explicit deliverables\n- Work that needs separate tracking/progress monitoring\n\n## Prefer invoke Instead\nFor most requests, use `invoke` - it's simpler and agents respond directly in chat.\nOnly use this tool when background tracking with multiple agents is truly needed.\n\nThe planner becomes the task owner; todos are embedded in the task.\nAfter creating: You'll receive <sub-task-result-updated> when task completes.",{title:Qe.string().min(1).max(200).describe("Task title"),requirement:Qe.string().describe("Overall requirement"),briefSummary:Qe.string().optional().describe("One-line summary shown to user immediately"),todos:Qe.array(Qe.object({agentId:Qe.string().describe("Agent ID responsible for the todo"),title:Qe.string().min(1).max(200).describe("Todo title"),instructions:Qe.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:n.title,todos:n.todos,message:{type:"user",message:{role:"user",content:n.requirement}}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","DISPATCH","Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function dr({askUser:e,log:t}){return ct("ask_user",'Ask the user questions when you need clarification or user input. Supports 1-4 questions with 2-4 options each. Use this when you need user decisions or additional information. An "Other" option with free text input is automatically added.',{questions:Qe.array(Qe.object({question:Qe.string().describe("The complete question to ask the user"),header:Qe.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:Qe.boolean().describe("Set to true to allow multiple option selections"),options:Qe.array(Qe.object({label:Qe.string().describe("Option label (1-5 words)"),description:Qe.string().describe("Explanation of what this option means")})).min(2).max(4).describe("Available choices (2-4 options)")})).min(1).max(4).describe("Questions to ask (1-4 questions)")},async n=>{try{const t=n.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(t);return"answered"!==(s.status??"answered")?{content:[{type:"text",text:"The user did not provide an answer within the expected time. \n<system-reminder>Please abort the session, and decide whether to retry when the user provides a new message later.</system-reminder>"}],isError:!0}:{content:[{type:"text",text:`User answers:\n${s.answers.map(e=>e.startsWith("other:")?`Other: "${e.slice(6)}"`:e).join("\n")}`}]}}catch(e){return t("error","ASK_USER","Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function ur({invokeAgent:e}){return ct("invoke",'Let an agent respond to the conversation (talk).\n\n**Use for**: Q&A, explanations, opinions, discussions, debates.\n**Do NOT use for**: Work producing files/code → use assign instead.\n\n**hint parameter**: Optional. Use to reduce agent\'s attention cost or provide meta-context:\n- ✅ Role assignment: hint="You argue FOR REST" (first turn of debate)\n- ✅ Focus guidance: hint="Focus on security aspects"\n- ✅ Long/busy chat: hint="Respond to Alice\'s caching question"\n- ✅ Multi-topic: hint="Re: the API design discussion"\n- ❌ Short, clear context: agent can easily find what to respond to\n\nAgent sees hint (if provided) + conversation history and responds in chat.',{agentId:Qe.string().describe("Target agent ID"),hint:Qe.string().optional().describe("Optional context/instruction for the agent")},async t=>(e(t.agentId,t.hint),{content:[{type:"text",text:`Invoked ${t.agentId}. The agent will respond in the chat later.`}]}))}function mr({workClient:e,agentId:t,uploadFile:n,log:s}){return ct("update_agent_info","Update your display name, avatar, and signature in the platform.\nCall this after onboarding when the user has chosen your name and emoji/image.\nThis syncs your identity to the platform so the App displays your chosen name and avatar.\n\nFor avatar: provide a local image file path. The image will be uploaded to the platform.\nFor signature: a short status line or tagline shown under your name.",{displayName:Qe.string().optional().describe("Your display name"),avatarPath:Qe.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:Qe.string().optional().describe("Short status line or tagline shown under your name")},async a=>{let i;if(a.avatarPath)try{i=(await n({name:"avatar.png",path:a.avatarPath,visibility:"public"})).fileId}catch(e){return s("error","TOOL","Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:a.displayName,avatar:i,signature:a.signature});const o=[];return a.displayName&&o.push(`name → ${a.displayName}`),i&&o.push("avatar → uploaded"),a.signature&&o.push(`signature → ${a.signature}`),{content:[{type:"text",text:`Profile updated: ${o.join(", ")}`}]}})}function hr({assign:e,log:t}){return ct("assign","Assign work to an agent (do the work).\n\n**Use for**: Code, files, reports, artifacts (agent produces output).\n**Do NOT use for**: Q&A, explanations → use invoke instead.\n\nProgress streams to chat in real-time.",{agentId:Qe.string().describe("Target agent ID"),instruction:Qe.string().describe("Task instruction for the agent"),acknowledgment:Qe.string().optional().describe('Agent\'s quick reply shown immediately (e.g., "starting now", "On it")')},async t=>(e(t.agentId,t.instruction,t.acknowledgment),{content:[{type:"text",text:`Assigned work to ${t.agentId}.`}]}))}function gr({agentContext:e,log:t}){return ct("list_tasks","List recent tasks in the current chat.\nUse this to review what tasks have been running, completed, or are still active.\nReturns a lightweight summary of each task (id, title, state, agent, duration, timestamps).",{limit:Qe.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:Qe.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async n=>{try{const t=await e.listTasks({limit:n.limit??10,status:n.status??"all"});return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return t("error","TASK","Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function fr({chatHistoryDb:e}){return ct("read_conversation","Read messages from the main conversation between you and the user. Omit before to read the latest messages; only pass before when paginating to older messages.",{limit:Qe.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:Qe.number().int().min(0).optional().describe("Pagination cursor for older conversation history. Omit this field, or pass 0, to read the latest messages. Only pass a positive before value that was returned by the previous result as “Use before=N to load earlier messages”; it means return messages before that sequence, not start at that position.")},async t=>{if(!e)return{content:[{type:"text",text:"Chat history not available in this mode."}],isError:!0};const n=t.limit??50,s=null!=t.before&&t.before>0?e.pageMessagesBefore(t.before,n):e.pageRecentMessages(n);if(0===s.data.length)return{content:[{type:"text",text:"No conversation messages found."}]};let a=Oo(s.data);return s.hasMore&&(a+=`\n\nMore messages available. Use before=${Math.min(...s.data.map(e=>e.localSequence))} to load earlier messages.`),{content:[{type:"text",text:a}]}})}function yr({agentContext:e,log:t}){return ct("send_reminder","Send an internal reminder to your main self (本体) in the primary chat.\nThis is for companion shadow (heartbeat task) use only.\n\nThe reminder is invisible to the user — it only wakes up the main companion worker.\nThe main companion will see the reminder in its conversation context and decide how to act.\n\nKeep content concise (one sentence). For detailed analysis, write to a file and pass filePath.",{content:Qe.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:Qe.string().optional().describe("Path to detailed analysis file in workspace, if any")},async n=>{try{const t=e.getChatId();return await e.sendMessage({taskId:t,message:{type:"companion_reminder",content:n.content,filePath:n.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return t("error","COMPANION","Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function vr({uploadFile:e,log:n}){return ct("upload_file","Upload a local file to the platform and get a public URL.\nUse this to share images, documents, or other files with the user.\nReturns a public URL that can be embedded in markdown (e.g., ).",{filePath:Qe.string().describe("Absolute path to the local file to upload"),name:Qe.string().optional().describe("Display name for the file (defaults to filename)")},async s=>{try{const n=t("path"),a=s.name||n.basename(s.filePath);return{content:[{type:"text",text:(await e({name:a,path:s.filePath,visibility:"public"})).url}]}}catch(e){return n("error","TOOL","File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const xr=2147483648,wr=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function br({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a,log:i}){return ct("send_channel_message","Send a user-facing message back to the external channel that started this task.\n\nFor channel-bound tasks, normal successful final results are NOT automatically forwarded to the external channel after this tool has been used. You MUST call this tool for anything the external user should see. Before ending the task, ensure the external user has received an appropriate message through this tool. If you end without calling it, the user may see no model-directed response; that is considered a failed channel interaction even if the internal task result is complete.\n\nUse this for user-facing conversational output: acknowledgements, progress updates for long work, questions/choices/permission requests, clear failures or limitations, final answers, and user-facing deliverable notes.\n\nMessages should feel like natural conversation: short, clear, useful. Do not send internal reasoning, verbose logs, stack traces, debug dumps, internal-only summaries, temporary paths, environment variables, tokens, secrets, or private data. Avoid excessive implementation detail unless the user is explicitly collaborating technically and needs it.\n\nAttachments are part of this channel message. Attach only deliverables the user is meant to consume, save, view, or forward: generated images, PDFs, spreadsheets, reports, slide decks, archives, audio/video, or requested exports/packages.\n\nDo NOT send files merely because they were created, edited, read, downloaded, or used. A file created or modified while completing work is not automatically a deliverable; decide based on user intent. Do not decide based on file location or directory: a file inside the workspace can be a deliverable, and a file outside the workspace can still be unsafe or inappropriate. Logs, caches, temporary files, build artifacts, intermediate screenshots, debug outputs, and internal workflow files should not be sent unless the user explicitly asked for them. When modifying files, summarize changes in text unless the user asked to receive, export, package, or forward those files. Never send files containing secrets, credentials, tokens, private data, or local environment details. If the deliverable status is uncertain or sending might expose unintended content, ask for confirmation with this tool first.\n\nThe tool automatically sends to the original channel/chat for this task. Do not provide channel IDs or chat IDs.",{content:Qe.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:Qe.array(Qe.object({filePath:Qe.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:Qe.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:Qe.enum(["auto","image","file","audio","video"]).optional().describe("Attachment kind. Use auto unless you know the exact type.")})).optional().describe("Optional user-facing deliverable files to send with the message.")},async o=>{const r=s?.()??null;if(!r)return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel, so no channel message can be sent."}],isError:!0};a?.();try{const s=o.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await Ir(n));return t}(o.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const i=await Gt(e,{content:s||void 0,attachments:a.length>0?a:void 0},r);return i?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:i.error}}),{content:[{type:"text",text:`Failed to send channel message: ${i.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,mimeType:e.mimeType,kind:e.kind}))}}),{content:[{type:"text",text:a.length>0?`Sent channel message with ${a.length} attachment(s).`:"Sent channel message."}]})}catch(e){return i("warn","CHANNEL","Channel message send rejected or failed:",e),{content:[{type:"text",text:`Failed to send channel message: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function kr({taskId:e,getChannelReplyTarget:t}){return ct("get_channel_group_history","Read older saved history for the external group chat bound to this task.\n\nUse this only when the automatically injected recent group history is not enough to understand context. This tool is read-only and automatically reads the current external channel group; do not provide channel IDs or chat IDs.\n\nThe result is XML-style history with sender metadata. Use it to understand context/history.",{limit:Qe.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:Qe.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:Qe.number().int().nonnegative().optional().describe("Return messages after this local sequence number for newer pages. Do not combine with beforeSeq.")},async n=>{const s=t?.()??null;if(!s||"group"!==s.chatType?.toLowerCase())return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel group chat."}],isError:!0};if(void 0!==n.beforeSeq&&void 0!==n.afterSeq)return{content:[{type:"text",text:"Use beforeSeq or afterSeq, not both."}],isError:!0};const a=await async function(e,t,n={}){return await Lt("/channels/group-history",{taskId:e,target:t,...n})}(e,s,{limit:n.limit,beforeSeq:n.beforeSeq,afterSeq:n.afterSeq});return a?.error?{content:[{type:"text",text:`Failed to read channel group history: ${a.error}`}],isError:!0}:{content:[{type:"text",text:`${[`hasMoreBefore=${Boolean(a.hasMoreBefore)}`,`hasMoreAfter=${Boolean(a.hasMoreAfter)}`].join(" ")}\n\n${a.historyXml??"<external_group_history />"}`}]}})}async function Ir(e){if(!$(e.filePath))throw new Error("filePath must be absolute");const t=await Ct(e.filePath).catch(e=>{throw new Error(`filePath does not exist or cannot be read: ${e instanceof Error?e.message:String(e)}`)});if(!t.isFile())throw new Error("filePath must point to a regular file");if(t.size<=0)throw new Error("file is empty");if(t.size>xr)throw new Error(`file is too large for channel delivery (${t.size} bytes; max 2147483648 bytes)`);const n=e.fileName||T(e.filePath),s=T(e.filePath);if(wr.test(s)||wr.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=hn.lookup(n)||hn.lookup(e.filePath)||"application/octet-stream",i="string"==typeof a?a:"application/octet-stream",o=e.kind||"auto";return{filePath:e.filePath,fileName:e.fileName,kind:o,mimeType:i}}function Sr({agentContext:e,log:t}){return ct("list_agents","List all available agents for the current user, including system agents and user-created agents (both published and draft).",{},async()=>{try{const{agents:t,draftAgents:n}=await e.listAgents(),s=e=>`- **${e.displayName||e.name}** (${e.id})\n Type: ${e.type}\n`+(e.developerName?` Developer: ${e.developerName}\n`:"")+` ${e.description||"No description"}\n`;let a="# Available Agents\n\n";return t.length>0&&(a+="## Published Agents\n\n",a+=t.map(s).join("\n")),n.length>0&&(a+="\n## Draft Agents\n\n",a+=n.map(s).join("\n")),0===t.length&&0===n.length&&(a+="No agents available."),{content:[{type:"text",text:a}]}}catch(e){return t("error","AGENTS","Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*Tr(e){yield e}function Er({visionModel:e,log:t}){return ct("analyze_image","Analyze a local image file and return a description of its contents.\nUse this tool when you need to understand the content of an image file on the local filesystem.\nThe primary model does not support vision, so this tool delegates to a vision-capable model.",{imagePath:Qe.string().describe("Absolute path to the image file to analyze"),prompt:Qe.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async n=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const t=(await _t(n.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[n.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=n.prompt||"Describe this image in detail.",i=rt({prompt:Tr({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:t}},{type:"text",text:a}]},parent_tool_use_id:null,session_id:""}),options:{model:e,permissionMode:"bypassPermissions",maxTurns:1,tools:[]}});let o="";for await(const e of i)if("result"===e.type){o=e.result??"";break}return{content:[{type:"text",text:o||"No description returned."}]}}catch(e){return t("error","VISION","Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function _r({log:e}){return ct("schedule_task",'Create, list, or delete scheduled tasks (reminders and recurring jobs).\nTasks are managed by the daemon scheduler and fire as reminders to the main companion.\n\nUse action "create" to schedule a new task:\n- For one-time tasks: provide "due" (ISO 8601 timestamp)\n- For recurring tasks: provide "cron" (standard 5-field cron expression)\n- Set timeType to "utc" if the time is in UTC, or "local" (default) if in the user\'s timezone\n\nUse action "list" to see all scheduled tasks.\nUse action "delete" with an "id" to remove a task.',{action:Qe.enum(["create","list","delete"]).describe("Operation to perform"),task:Qe.string().optional().describe("Task description (required for create)"),type:Qe.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:Qe.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:Qe.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:Qe.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:Qe.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:Qe.string().optional().describe("Task ID (required for delete)")},async t=>{try{const e=await fe.readDaemonState();if(!e?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${e.port}`;if("list"===t.action){const e=await fetch(`${n}/schedule`),t=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${t.error}`}],isError:!0};const s=t.tasks??[];return 0===s.length?{content:[{type:"text",text:"No scheduled tasks."}]}:{content:[{type:"text",text:s.map(e=>`- [${e.id}] ${"once"===e.type?`once at ${e.due}`:`recurring: ${e.cron}`} — "${e.task}"`).join("\n")}]}}if("create"===t.action){if(!t.task||!t.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const e=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:t.task,type:t.type,due:t.due,cron:t.cron,timezone:t.timezone,timeType:t.timeType})}),s=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0};const a="once"===s.type?`due=${s.due}`:`cron=${s.cron}`;return{content:[{type:"text",text:`Scheduled: id=${s.id}, ${a}`}]}}if("delete"===t.action){if(!t.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const e=await fetch(`${n}/schedule/${t.id}`,{method:"DELETE"}),s=await e.json();return e.ok?{content:[{type:"text",text:`Deleted: ${t.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${t.action}`}],isError:!0}}catch(t){return e("error","SCHEDULE","Schedule task failed:",t),{content:[{type:"text",text:`Failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}})}function Cr({agentContext:e,log:t}){return ct("hive_prepare_repository","Prepare the Agentrix Hive source repository in the local global repo store.\n\nUse this before discovering community agents or skills. This tool only clones/pulls\nthe repository and returns the absolute checkout path. It does not search and does\nnot define the repository layout. After calling it, use Explore with a\ntask-specific goal to find relevant candidates; do not catalog the whole repo\nunless the user explicitly asks for a catalog. If pullSucceeded is false, inspect\nerror and continue with the existing local checkout when it is usable.",{},async()=>{try{const t=await e.prepareHiveRepository();return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Failed to prepare Hive repository:",e),{content:[{type:"text",text:`Failed to prepare Hive repository: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Ar({agentContext:e,log:t}){return ct("hive_publish","Publish a newly created agent or skill to Agentrix Hive after the user explicitly agrees.\n\nUse this for content created by this agent/user. Do not use it to republish\nsomeone else's Hive content that was installed locally. To change an owned\nexisting listing, use hive_update. To suggest changes for someone else's listing,\nmodify locally if needed and leave a hive_comment.",{type:Qe.enum(["agent","skill"]),draftAgentId:Qe.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:Qe.string().optional().describe("Absolute local skill directory for skill publishing"),name:Qe.string().optional().describe("Listing name, lowercase kebab-case"),displayName:Qe.string().optional().describe("Human-readable listing name"),description:Qe.string().optional(),readme:Qe.string().optional(),category:Qe.string().optional(),tags:Qe.array(Qe.string()).optional(),authorType:Qe.enum(["user","agent"]).default("user"),authorId:Qe.string(),machineId:Qe.string().optional(),cloudId:Qe.string().optional()},async n=>{try{const t=await e.publishToHive(n);return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function $r({agentContext:e,log:t}){return ct("hive_update","Publish a new version for an owned Hive listing after the user explicitly agrees.\n\nUse this only when the listing belongs to the user/agent. Do not use it for\nsomeone else's installed Hive content; for those, keep changes local and leave a\nhive_comment with concrete suggestions.",{listingId:Qe.string().describe("Owned HiveListing ID to update"),version:Qe.string().optional().describe("Optional new version; defaults to next patch version"),changelog:Qe.string().optional(),sourceDir:Qe.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:Qe.string().optional(),cloudId:Qe.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.updateHiveListingVersion(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Mr({agentContext:e,log:t}){return ct("hive_record_install","Record a Hive agent or skill after installing it locally.\n\nDo not use this tool to install. First prepare the Hive repository, inspect the\nsource for safety and relevance, ask the user if needed, and perform the local\nagent/skill install yourself. Then read the HiveListing ID from\nagentrix-hive-id.txt in the Hive source directory and pass it as listingId.",{listingId:Qe.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:Qe.string().describe("Absolute local directory where the agent or skill was installed"),name:Qe.string().optional().describe("Optional local name for installed agent"),machineId:Qe.string().optional(),cloudId:Qe.string().optional(),installedVersion:Qe.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.recordHiveInstall(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Pr({agentContext:e,log:t}){return ct("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:Qe.string().describe("HiveListing ID"),rating:Qe.number().int().min(1).max(5),comment:Qe.string().optional().describe("Markdown review text")},async n=>{try{const t=await e.createHiveReview(n.listingId,{rating:n.rating,comment:n.comment??null});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Rr({agentContext:e,log:t}){return ct("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:Qe.string().describe("HiveListing ID"),content:Qe.string().min(1).describe("Markdown comment content"),parentId:Qe.string().optional().describe("Parent comment ID for replies")},async n=>{try{const t=await e.createHiveComment(n.listingId,{content:n.content,parentId:n.parentId});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Nr(e){if(e)return e.replace(/\/+$/g,"")||"/"}function Dr(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,branchName:e.branchName,cwd:Nr(e.cwd)||"",userCwd:Nr(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function Or(e,t){return t??`agentrix/${e}`}async function jr(e){if(!e)return null;const t=await xn();return t?In(e,t):null}async function Ur(e,t){const n=kn(t);if(!n)return void console.warn("[GIT] No PAT user metadata found, skipping git config");const s=n.username,a=n.email||`${n.username}@gitlab.local`;await async function(e,t,n){await ra("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await ra("git",["config","user.email",n],{cwd:e,windowsHide:!0})}(e,s,a),console.log(`[GIT] Set local git config user.name=${s} user.email=${a}`)}async function qr(e,t,n){const s=await jr(n);s?await async function(e,t){const n=Oa();try{await ra("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:ja(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await ra("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,windowsHide:!0})}(t,e)}async function Lr(e,t,n,s,a,i){const o=Or(n,i),c=Aa(t),l=await la(e);if(!wa(e)&&!l)throw new Error(`Directory ${e} exists but is not a git repository`);const d=await jr(a);return wa(e)?(d?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=A(n);r(s)||p(s,{recursive:!0});const a=Oa();try{await ra("git",["-c","credential.helper=","clone",t,n],{env:ja(a,e),windowsHide:!0})}finally{f(a)}}(d,c,e),a&&await Ur(e,a)):await ga(t,e),await Ca(e,"origin",c),await fa(e,o,s),await va(e)):(await $a(e,"origin",c),await qr(e,t,a),a&&await Ur(e,a),await fa(e,o,s),await va(e))}async function Hr(e,t,n,s={}){const a=await jr(s.gitServerId);a?await async function(e,t,n,s=!1){const a=Oa();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await ra("git",i,{cwd:t,env:ja(a,e),windowsHide:!0})}finally{f(a)}}(a,e,t,n):s.gitUrl?await async function(e,t,n,s=!1){const a=["-c","credential.helper=","push",e,n];s&&a.push("--force"),await ra("git",a,{cwd:t,windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=ca(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function Gr(e,t,n){const s=n.trim();if(!s)return;const a=fe.resolveDataDir(e,t),i=S(a,"patch.diff");return await ht(a,{recursive:!0}),await mt(i,`${s}\n`),i}async function Br(e,t,n){await fe.writeLastSentArtifactVersion(e,t,n)}function Fr(e,t){return`Please generate pull request metadata for the changes made in this task.\n\nInitial commit hash: ${e}\n${t?`\n\nAdditional instructions:\n${t}`:""}\n\nProvide a concise title (conventional commits format), a detailed description, and a user-facing summary message.`}function Wr(e,t,n){return{type:"result",subtype:n?"error_during_execution":"success",duration_ms:0,duration_api_ms:0,is_error:n,num_turns:0,result:e,stop_reason:null,total_cost_usd:0,usage:{input_tokens:0,output_tokens:0,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:0,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"},modelUsage:{},permission_denials:[],terminal_reason:n?`exit_code_${t}`:"completed",session_id:"",uuid:At()}}function zr(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:At()}}function Kr(e){const t="```sh\n",n="\n```";return`${t}${Bo(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function Vr(e,t,n,s=6e4){return new Promise(a=>{const i=ze("/bin/bash",["-c",e],{cwd:t,env:process.env,shell:!1});let o=null,r=!1;s>0&&(o=setTimeout(()=>{r=!0,i.kill("SIGTERM"),setTimeout(()=>{i.killed||i.kill("SIGKILL")},1e3)},s));let c="";i.stdout?.on("data",e=>{c+=e.toString()}),i.stderr?.on("data",e=>{c+=e.toString()}),i.on("close",(e,t)=>{let i,l,p;if(o&&clearTimeout(o),r){i=124,p=!0;const e=`\n[Command timed out after ${s/1e3} seconds]`;l=c?`${c}${e}`:e.trim()}else i=null!==e?e:"SIGTERM"===t?143:1,p=0!==i,l=c;const d=Kr(l);n.onOutput(zr(d)),n.onOutput(Wr(d,i,p)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=Kr(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(zr(t)),n.onOutput(Wr(t,1,!0)),n.onComplete(1),a(1)})})}class Xr{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="running";messageIdCounter=0;isStopped=!1;runStartTime=Date.now();commandRunning=!1;isDebouncing=!1;agentRunningMap=new Map;backgroundTaskMap=new Map;anonymousBackgroundTaskCount=0;lastActiveAgentsSignature=null;idleTimeoutHandle=null;idleTimeoutMs;constructor(e){this.config=e,this.idleTimeoutMs=Math.max(0,e.idleTimeoutMs??0)}parseMessage(e){if("user"!==e.type)return{type:"normal",content:"",originalMessage:e};const t=("string"==typeof e.message.content?e.message.content:"").trim();return t.startsWith("!")&&!t.startsWith("![")?{type:"bash-command",content:t.slice(1).trim(),originalMessage:e}:"![merge-request]"===t?{type:"merge-request",content:t,originalMessage:e}:"![merge-pr]"===t?{type:"merge-pr",content:t,originalMessage:e}:"![new]"===t?{type:"new-session",content:t,originalMessage:e}:"![plan]"===t?{type:"plan-mode",content:t,originalMessage:e}:{type:"normal",content:t,originalMessage:e}}async enqueue(e){if(this.isStopped)return void this.log("warn","COORDINATOR","Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void this.log("warn","COORDINATOR","Ignoring malformed user message (missing content)");const t=this.parseMessage(e),n={id:"msg-"+ ++this.messageIdCounter,type:t.type,priority:"normal",content:t.content,originalMessage:e,timestamp:Date.now()};this.messageQueue.push(n),this.log("info","COORDINATOR",`Enqueued message ${n.id} (type: ${n.type}, queue: ${this.messageQueue.length})`),this.tryUpdateWorkerState(),this.tryProcessNext()}async tryProcessNext(){if(!this.isStopped)if(0!==this.messageQueue.length)try{const e=this.messageQueue.shift();this.log("info","COORDINATOR",`Processing message ${e.id} (type: ${e.type})`),await this.processMessage(e),this.log("info","COORDINATOR",`Completed message ${e.id}`)}catch(e){this.log("error","COORDINATOR",`Error processing message: ${e}`)}finally{this.tryUpdateWorkerState(),this.isStopped||this.tryProcessNext()}else this.tryUpdateWorkerState()}async processMessage(e){switch(e.type){case"normal":await this.processNormalMessage(e);break;case"bash-command":await this.processBashCommand(e);break;case"merge-request":await this.processMergeRequest(e);break;case"merge-pr":await this.processMergePr(e);break;case"new-session":await this.processNewSession(e);break;case"plan-mode":await this.processPlanMode(e);break;default:this.log("warn","COORDINATOR",`Unknown message type: ${e.type}`)}}async processNormalMessage(e){this.log("info","COORDINATOR","Processing normal message for SDK");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){this.log("info","COORDINATOR",`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){this.log("info","COORDINATOR","Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){this.log("info","COORDINATOR","Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){this.log("info","COORDINATOR","Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processPlanMode(e){this.log("info","COORDINATOR","Processing plan-mode command"),await this.processCommand(async()=>{if(!this.config.handlers.onPlanMode)return;const t=await this.config.handlers.onPlanMode(e.originalMessage);t&&this.enqueueAgentMessage(t)},e)}async processCommand(e,t){await this.waitWorkerIdle(),this.setCommandRunning(!0),this.markCommandMessageProcessed(t);try{await e()}finally{this.setCommandRunning(!1)}}markCommandMessageProcessed(e){const t=e.originalMessage.__localSequence;void 0!==t&&this.config.onCommandMessageProcessed?.(t)}async waitWorkerIdle(){for(;"idle"!==this.getExecutionState();){if(this.isStopped)throw new Error("Coordinator stopped while waiting for idle");this.log("debug","COORDINATOR","Waiting for worker idle state"),await new Promise(e=>setTimeout(e,100))}}setWorkerState(e){if(this.workerState===e)return;const t=this.workerState;if(this.log("info","COORDINATOR",`Worker state: ${t} → ${e}`),this.workerState=e,"running"===e&&"idle"===t&&(this.runStartTime=Date.now(),this.config.workClient.sendWorkRunning(this.getActiveAgents()),this.lastActiveAgentsSignature=this.getActiveAgentsSignature(),this.clearIdleTimer()),"idle"===e&&"running"===t){let e;this.runStartTime&&(e=Date.now()-this.runStartTime,this.runStartTime=null),this.config.workClient.sendWorkerReady(e),this.lastActiveAgentsSignature=null,this.startIdleTimer(),this.config.onBecameIdle?.()}}updateAgentRunning(e){this.setAgentRunning("default","Agent",e)}setAgentRunning(e,t,n){const s="running"===this.workerState,a=this.lastActiveAgentsSignature;n?this.agentRunningMap.set(e,{agentId:e,agentName:t,startedAt:Date.now()}):this.agentRunningMap.delete(e);const i=this.getActiveAgentsSignature();this.lastActiveAgentsSignature=i,this.tryUpdateWorkerState(),s&&"running"===this.workerState&&i!==a&&this.config.workClient.sendWorkRunning(this.getActiveAgents())}setBackgroundTaskRunning(e,t){e&&(t?this.backgroundTaskMap.set(e,{taskId:e,startedAt:Date.now()}):!this.backgroundTaskMap.delete(e)&&this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,this.log("debug","COORDINATOR",`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Anonymous background task completed (count: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState()}getActiveAgents(){return Array.from(this.agentRunningMap.values()).map(({agentId:e,agentName:t})=>({agentId:e,agentName:t}))}getActiveAgentsSignature(){const e=this.getActiveAgents().slice().sort((e,t)=>e.agentId.localeCompare(t.agentId));return JSON.stringify(e)}enqueueAgentMessage(e){if(this.isStopped)this.log("warn","COORDINATOR","Ignoring agent message - coordinator is stopped");else if(this.agentMessageQueue.push(e),this.agentMessageResolver){const e=this.agentMessageResolver;this.agentMessageResolver=null,e(this.agentMessageQueue.shift())}}hasAgentMessages(){return this.agentMessageQueue.length>0}getAgentQueueLength(){return this.agentMessageQueue.length}async waitForAgentMessage(){return this.isStopped?null:this.agentMessageQueue.length>0?this.agentMessageQueue.shift():new Promise(e=>{this.agentMessageResolver=e})}cancelAgentWait(){if(!this.agentMessageResolver)return;const e=this.agentMessageResolver;this.agentMessageResolver=null,e(null)}setCommandRunning(e){this.commandRunning!==e&&(this.commandRunning=e,this.tryUpdateWorkerState())}hasExecutionWork(){return this.commandRunning||this.agentRunningMap.size>0||this.backgroundTaskMap.size>0||this.anonymousBackgroundTaskCount>0||this.isDebouncing}getExecutionState(){return this.hasExecutionWork()?"running":"idle"}setDebouncing(e){this.isDebouncing!==e&&(this.isDebouncing=e,this.tryUpdateWorkerState())}tryUpdateWorkerState(){if(this.isStopped)return;const e=this.messageQueue.length>0||this.agentMessageQueue.length>0,t=this.hasExecutionWork(),n=!e&&!t;this.setWorkerState(n?"idle":"running")}startIdleTimer(){0!==this.idleTimeoutMs&&(this.idleTimeoutHandle||(this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(this.log("info","COORDINATOR","Idle timeout reached, stopping task"),this.cancelAgentWait(),this.config.onIdleTimeout?.())},this.idleTimeoutMs)))}clearIdleTimer(){this.idleTimeoutHandle&&(clearTimeout(this.idleTimeoutHandle),this.idleTimeoutHandle=null)}getStatus(){return{state:this.workerState}}isActivelyExecuting(){return this.hasExecutionWork()}stop(){this.log("info","COORDINATOR","Stopping coordinator"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait()}log(e,t,n){this.config.logger&&this.config.logger(e,t,n)}}function Jr(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:t}]}};e.sendTaskMessage(zo,n)}async function Yr(e){const{workingDirectory:t,workClient:n,repositoryId:s,gitServerId:a,gitUrl:i,logger:o,allowInteractive:r=!0,askUser:c,commitChanges:l}=e;if(o.info("[MERGE-PR] Executing merge-pr command"),s){try{const e=await _a(t),s=await ya(t),p=await async function(e,t){const n=ca(e);try{return(await n.log([`origin/${t}..HEAD`])).total>0}catch{return!0}}(t,e);if(s||p){if(!r)throw new Error("merge-pr requires user input to resolve git state, which is not supported in oneshot execution mode");const d=await async function(e,t,n,s){let a="";a=e&&t?"You have uncommitted changes and unpushed commits. What would you like to do?":e?"You have uncommitted changes. What would you like to do?":"You have unpushed commits. What would you like to do?";const i=[{question:a,header:"Git Status",multiSelect:!1,options:[{label:"Pause",description:"Stop operation, handle git state manually"},{label:"Push",description:"Push changes and review before merging"},{label:"Push and Merge",description:"Push changes and merge PR immediately"}]}];try{const e=(await n(i)).answers[0];return e.startsWith("other:")?(s.info(`[MERGE-PR] User provided custom input: ${e}, defaulting to Pause`),"Pause"):{Pause:"Pause",Push:"Push","Push and Merge":"PushAndMerge"}[e]||"Pause"}catch(e){return s.error("[MERGE-PR] Ask user failed:",e),"Pause"}}(s,p,c,o);if("Pause"===d)return void Jr(n,"Operation paused. Please handle git state and run merge again.");if(("Push"===d||"PushAndMerge"===d)&&(s&&(o.info("[MERGE-PR] Generating commit message with agent"),await l(),o.info("[MERGE-PR] Committed changes with agent-generated message")),o.info(`[MERGE-PR] Pushing branch ${e} to remote`),await Hr(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===d))return void Jr(n,"✅ All changes pushed to remote. You can now review and run merge again if everything looks good.")}const d=await n.sendMergePr();if(d.success)Jr(n,`✅ PR merged successfully! Branch ${e} has been merged into the target branch.`);else{let e;switch(d.errorType){case"github_conflict":e="Merge conflict detected. Please resolve conflicts manually on GitHub and try again.";break;case"pr_not_open":e="PR is not open. The PR may have already been merged or closed.";break;case"permission_denied":e="Permission denied. You may not have permission to merge this PR.";break;case"merge_failed":e=`Merge failed: ${d.error||"Unknown error"}`;break;default:e=`Failed to merge PR: ${d.error||"Unknown error"}`}n.sendSystemErrorMessage(e)}}catch(e){o.error("[MERGE-PR] Failed:",e);const t=e instanceof Error?e.message:"Unknown error";n.sendSystemErrorMessage(`Failed to push or merge: ${t}`)}o.info("[MERGE-PR] Worker ready after merge-pr execution")}else n.sendSystemErrorMessage("Cannot merge: task has no git repository configured.")}function Qr(e,t){const n=e.updates?.repositoryId;return"string"==typeof n&&0!==n.length&&t.repositoryId!==n&&(t.repositoryId=n,fe.writeTaskInput(t),!0)}function Zr(e,t,n,s={}){const a=n.sendAskUser(e),i=s.timeoutMs??18e5,o=s.onTimeout;return new Promise((e,s)=>{const r=setTimeout(()=>{t.delete(a);const i={type:"ask_user_response",answers:[],status:"timeout",reason:"timeout"};n.sendAskUserResponse(a,i),"abort_task"===o?(n.onTimeoutMessage?.("ask_user timed out. Task cancelled."),n.stopTask?.("ask_user_timeout"),s(new Error("Ask user request timed out"))):e(i)},i);t.set(a,t=>{clearTimeout(r),e(function(e){const t=e.status??"answered";return e.status&&e.reason?e:{...e,status:t,reason:e.reason??("timeout"===t?"timeout":"user")}}(t))})})}function ec(e){return{type:"system",subtype:"init",apiKeySource:"temporary",betas:[],claude_code_version:"codex",cwd:e.cwd,tools:[],mcp_servers:[],model:e.model??"unknown",permissionMode:"default",slash_commands:[],output_style:"codex",skills:[],plugins:[],uuid:le(),session_id:e.sessionId}}function tc(e,t){const n=le();return t.set(e,n),n}function nc(e,t){return t.get(e)||e}function sc(e,t){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"item.started"===e.type?function(e,t){switch(e.type){case"command_execution":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:tc(e.id,t),name:"Bash",input:{command:e.command}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"file_change":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:tc(e.id,t),name:"Edit",input:{changes:e.changes.map(e=>({kind:e.kind,path:e.path}))}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"mcp_tool_call":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:tc(e.id,t),server_name:e.server,name:e.tool,input:e.arguments}]},parent_tool_use_id:null,session_id:""}}(e,t);case"web_search":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:tc(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);default:return null}}(e.item,t):"item.completed"===e.type?function(e,t){switch(e.type){case"agent_message":return function(e){return{type:"assistant",message:{id:e.id,type:"message",container:null,role:"assistant",content:[{citations:null,type:"text",text:e.text}],model:"",usage:{},stop_reason:null,context_management:null,stop_sequence:null},parent_tool_use_id:null,session_id:"",uuid:le().toString()}}(e);case"reasoning":default:return null;case"command_execution":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:nc(e.id,t),content:"failed"===e.status?"Command execution failed":e.aggregated_output||""}]},parent_tool_use_id:null,session_id:""}}(e,t);case"file_change":return function(e,t){const n=t.get(e.id),s=n??tc(e.id,t),a=!n;(e.changes||[]).map(e=>`${e.kind}: ${e.path}`);const i={type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:s,name:"Edit",input:{changes:(e.changes||[]).map(e=>({kind:e.kind,path:e.path}))}}]},parent_tool_use_id:null,session_id:""},o={type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:s,content:"failed"===e.status?"File changes failed":"File changes completed"}]},parent_tool_use_id:null,session_id:""};return a?[i,o]:o}(e,t);case"mcp_tool_call":return function(e,t){const n=nc(e.id,t),s="failed"===e.status&&e.error;return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:n,is_error:s,content:s?e.error.message:e.result?.content||""}]},parent_tool_use_id:null,session_id:""}}(e,t);case"web_search":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:nc(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"todo_list":return function(e){return{type:"assistant",message:{role:"assistant",content:`📋 Todo List:\n${e.items.map(e=>`${e.completed?"✓":"○"} ${e.text}`).join("\n")}`},parent_tool_use_id:null,session_id:""}}(e);case"error":return function(e){return{type:"assistant",message:{role:"assistant",content:`❌ Error: ${e.message}`},parent_tool_use_id:null,session_id:""}}(e)}}(e.item,t):null}let ac,ic,oc;function rc(e){let t=null,n=!1;for(let s=0;s<e.length;s+=1){const a=e[s];if(n)n=!1;else if("\\"!==a||'"'!==t)if('"'!==a&&"'"!==a||null!==t)if(a!==t){if("#"===a&&null===t)return e.slice(0,s)}else t=null;else t=a;else n=!0}return e}function cc(e){const t=e.trim();if(!t)return null;if(t.startsWith('"'))try{return JSON.parse(t)}catch{return null}const n=t.match(/^'([^']*)'$/);return n?n[1]:t.match(/^[A-Za-z0-9._:/@+-]+$/)?t:null}function lc(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||S(n.homedir(),".codex");return S(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(ic===e&&void 0!==ac)return ac;if(ic=e,ac=null,!r(e))return ac;let t;try{t=c(e,"utf8")}catch{return ac}for(const e of t.split(/\r?\n/)){const t=rc(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=cc(n[1])?.trim();return ac=s||null,ac}return ac}()}class pc{createCodex(e){const t={},n=function(){if(void 0!==oc)return oc??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();return e?(oc=e,e):0===nt("codex",["--version"],{stdio:"ignore"}).status?(oc="codex",oc):void(oc=null)}();n&&(t.codexPathOverride=n),e.env&&(t.env=Ls(e.env));const s=function(e){const t=[];var n;e.modeConfig.supportChangeTitle&&e.codexAgentrixEventMcp&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Cs(`\n ## Title Setting Protocol:\n - MUST set a descriptive title as your FIRST action when the user makes a request\n - Use the Agentrix event broker MCP tool for this: server "${(n={serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.titleToolName}).serverName}", tool "${n.toolName}"\n - This is mandatory when the tool is available; do this before any other work\n - Update the title if the conversation direction changes substantially\n `));const s=e.projectAgentrixGuidance?.systemPromptAppend?.trim();return s&&t.push(s),t.length>0?t.join("\n\n"):void 0}(e);return s&&(t.config={...t.config??{},developer_instructions:s}),function(e,t){const n=t.codexAgentrixEventMcp;if(!n)return;const s=e.config??{},a=s.mcp_servers&&"object"==typeof s.mcp_servers&&!Array.isArray(s.mcp_servers)?s.mcp_servers:{};e.config={...s,mcp_servers:{...a,[n.serverName]:{url:n.url,bearer_token_env_var:n.tokenEnvVar}}}}(t,e),new $t(Object.keys(t).length>0?t:void 0)}getAgentConfiguration(){return null}getHooks(){}getMcpServers(){}async executeHook(e,t,n){}async run(e,t){const n=t.abortController,s=this.createCodex(t),a=lc(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),r=await o.run("string"==typeof e?e:Bs(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});return Fs({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:r.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:r.finalResponse??"",structuredOutput:Ws(r.finalResponse??"",Boolean(t.structuredOutputSchema))})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=lc(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),{events:r}=await o.runStreamed("string"==typeof e?e:Bs(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let c=t.agentSessionId||"",l="",p={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const d=new Map,u={get:e=>d.get(e),set:(e,t)=>{d.set(e,t)}};for await(const e of r){if("thread.started"===e.type&&(c=e.thread_id,yield ec({sessionId:c,cwd:t.cwd,model:a??void 0})),"turn.completed"===e.type){e.usage&&(p=e.usage);break}if("turn.failed"===e.type)throw new Error(e.error.message);if("error"===e.type)throw new Error(e.message);if("item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(l=e.item.text),"item.started"===e.type||"item.completed"===e.type){const t=sc(e,u);if(!t)continue;const n=Array.isArray(t)?t:[t];for(const e of n)yield e}}const m=Fs({sessionId:c,model:a??"unknown",numTurns:1,usage:p,result:l,structuredOutput:Ws(l,Boolean(t.structuredOutputSchema))});yield m}loop(e){const t=e.abortController,n=this.createCodex(e),s=lc(e.model),a={workingDirectory:e.cwd,model:s??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let i=e.agentSessionId?n.resumeThread(e.agentSessionId,a):n.startThread(a),o=!1;const r=[];let c=null,l=e.agentSessionId??null,p=0;const d=()=>{if(!o&&(o=!0,c)){const e=c;c=null,e(null)}},u=e=>"string"==typeof e?e:Bs(e),m=async function*(){try{for(;!o&&!t.signal.aborted;){const n=r.length>0?r.shift():await new Promise(e=>{c=e});if(!n)break;let a="";const d=new Map,m={get:e=>d.get(e),set:(e,t)=>{d.set(e,t)}},{events:h}=await i.runStreamed(u(n),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of h){if(o)break;if("thread.started"!==t.type){if("turn.completed"===t.type){l&&(yield Fs({sessionId:l,model:s??"unknown",numTurns:p+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:a,structuredOutput:Ws(a,Boolean(e.structuredOutputSchema))}));break}if("turn.failed"===t.type)throw new Error(t.error.message);if("error"===t.type)throw new Error(t.message);if("item.started"===t.type||"item.completed"===t.type){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(a=t.item.text);const e=sc(t,m);if(!e)continue;const n=Array.isArray(e)?e:[e];for(const e of n)yield e}}else l=t.thread_id,yield ec({sessionId:l,cwd:e.cwd,model:s??void 0})}p+=1}}finally{d()}}();return t.signal.addEventListener("abort",d,{once:!0}),{push:e=>{if(console.log("CodexRunner.loop.push:",JSON.stringify(e,null,2)),!o){if(c){const t=c;return c=null,void t(e)}r.push(e)}},events:m,stop:d}}}const dc=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification","RepositoryInit"];function uc(e){const t={};for(const n of dc){const s=e[n];"function"==typeof s&&(t[n]=s,console.log(`[Hook Loader] ✓ Loaded hook: ${n}`))}const n=Object.keys(t).length;return 0===n?console.warn("[Hook Loader] No valid hooks found in module"):console.log(`[Hook Loader] Successfully loaded ${n} hook(s)`),t}class mc{static pool=new Map;static async create(e,t,n){const s=this.pool.get(t);if(s)return s;let a;if("claude"===e||"companion"===e){const s=await async function(e){const{agentId:t,agentDir:n,logger:s}=e;if(!t||"default"===t)return{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};try{na(s,"info",`Loading agent: ${t}`);const e=await He({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return na(s,"warn",`No claude configuration found for agent ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};const a=e.claude,i=a.plugins.map(e=>({type:"local",path:e})),o=n||Ge().resolveAgentDir(t),r=a.config.sdkMcpTools?.map(e=>S(o,"claude",e)),c={customSystemPrompt:a.systemPrompt,customModel:a.config.model,customFallbackModel:a.config.fallbackModel,customMaxTurns:a.config.maxTurns,customExtraArgs:a.config.extraArgs,customPermissionMode:a.config.settings?.permissionMode,customPlugins:i,systemPromptMode:a.config.systemPrompt?.mode??"append",customPRPromptTemplate:a.prPromptTemplate,prPromptMode:a.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:r};return na(s,"info",`Agent ${t} loaded successfully (${i.length} plugins)`),c}catch{return na(s,"error",`Failed to load agent: ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}}}({agentId:t,agentDir:n?.agentDir,logger:n?.logger});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=ne(),a=t||s.resolveAgentDir(e),i=S(a,"claude");return await async function(e,t){const n=Me(e,"hooks");if(!_e(n))return{};const s=[Me(n,"dist","index.mjs"),Me(n,"dist","index.js"),Me(n,"index.mjs"),Me(n,"index.js")];let a=null;for(const e of s)if(_e(e)){a=e;break}if(!a)return console.warn(`[Hook Loader] Hooks not built: ${n}`),console.warn("[Hook Loader] To build hooks, run:"),console.warn(`[Hook Loader] cd ${n}`),console.warn("[Hook Loader] npm install && npm run build"),console.warn("[Hook Loader] Or place hooks directly in:"),console.warn(`[Hook Loader] ${Me(n,"index.js")} or ${Me(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${bt(a).href}?t=${Date.now()}`,n=await import(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),uc(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return uc(n)}catch(e){throw console.error(`[Hook Loader] Failed to load hooks from ${a}:`,e),new Error(`Hook loading failed: ${e instanceof Error?e.message:String(e)}`)}}(i,n)}catch(e){return void console.warn("[AgentRunners] Failed to load hooks:",e)}}(t,n.agentDir,n.context)),n?.context&&s.customSdkMcpTools&&s.customSdkMcpTools.length>0&&(o=await async function(e,t,n){const s={};for(const a of e)try{n&&n("info","MCP",`Loading SDK MCP tools from: ${a}`);const e=await import(a),i=e.default||e;if(!i){n&&n("warn","MCP",`No default export found in ${a}`);continue}const o="function"==typeof i?i(t):i,r=o.name;s[r]=o,n&&n("info","MCP",`Loaded MCP server: ${r}`)}catch(e){n&&n("error","MCP",`Failed to load SDK MCP tools from ${a}: ${e instanceof Error?e.message:String(e)}`)}return s}(s.customSdkMcpTools,n.context,n.logger)),a=new ta(t,e,s,i,o)}else a=new pc;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class hc{constructor(e){this.workingDirectory=e}async listFiles(e=3){const t=[];return this.listFilesRecursively(this.workingDirectory,t,"",e,0),t}async readFile(e){try{const t=Ae.join(this.workingDirectory,e);return Se.existsSync(t)?Se.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=Ae.join(this.workingDirectory,e);return Se.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=Se.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?ae.includes(o.name)||this.listFilesRecursively(Ae.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class gc{constructor(e){this.params=e}state=null;async setup(){const{options:e,handlers:t}=this.params,{userId:n,taskId:s,cwd:a}=e;if(!a)throw new Error("[WORKSPACE] Missing cwd for workspace setup");const i=fe.getWorkspaceState(n,s),o=e.repositorySourceType,r={...e,repositorySourceType:o},{initialCommitHash:c,isGitRepository:l,setupAction:p,useWorktree:d,initPolicyUpdates:u}=await this.ensureWorkspace(r,t,i);await fe.writeWorkspaceState(n,s,{initialized:!0,initializedAt:(new Date).toISOString(),cwd:a,repositorySourceType:r.repositorySourceType,useWorktree:d,userCwd:e.userCwd,forceUserCwd:e.forceUserCwd,gitUrl:e.gitUrl,baseBranch:e.baseBranch,taskRepositoryId:e.taskRepositoryId,initialCommitHash:c,initPolicies:{...i?.initPolicies,...u}});const m=await async function(e,t,n,s){return async function(e,t,n,s){if(!await la(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await ya(e),i=await va(e),o=s||fe.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await Ea(e,o),c=r?await Gr(t,n,r.patch):void 0,l=await fe.readLastSentArtifactVersion(t,n),p=!!r&&r.artifactVersion!==l;return{currentCommitHash:i,currentArtifactVersion:r?.artifactVersion,hadUncommittedChanges:a,hasNewArtifacts:p,lastSentArtifactVersion:l??void 0,patchPath:c,diffStats:r?.stats}}(e,t,n,s)}(a,n,s,c);return this.state={cwd:a,initialCommitHash:c,isGitRepository:l,setupAction:p,gitStateResult:m},l&&!e.taskRepositoryId&&await async function(e,t){try{const n=await Pa(e);if(!n)return void console.log("[REPO] No origin remote found, skipping repository association");if(!t?.onRepositoryDetected)return;console.log(`[REPO] Detected remote: ${n.host}/${n.owner}/${n.repo}`),t.onRepositoryDetected(n)}catch(e){console.error("[REPO] Failed to send repository association:",e)}}(a,t),this.state}getState(){if(!this.state)throw new Error("[WORKSPACE] Workspace not initialized");return this.state}getCwd(){return this.getState().cwd}getInitialCommitHash(){return this.getState().initialCommitHash}getGitStateResult(){return this.getState().gitStateResult}async prepareResultArtifacts(e={}){const{cwd:t,initialCommitHash:n,isGitRepository:s}=this.getState(),{userId:a,taskId:i}=this.params.options;if(!s||!n)return{};const o=await Ea(t,n);if(!o)return{};try{await Gr(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new hc(e);return se(t)}(t),c=await fe.readLastSentArtifactVersion(a,i);return c&&c===o.artifactVersion?{artifactVersion:o.artifactVersion}:{artifactVersion:o.artifactVersion,artifacts:{artifactVersion:o.artifactVersion,stats:o.stats,preview:r}}}async ensureWorkspace(e,t,n){const s=e.repositorySourceType;return"git-server"===s?this.ensureGitServerWorkspace(e,t,n):"directory"===s?this.ensureDirectoryWorkspace(e,t,n):this.ensureTemporaryWorkspace(e,t,n)}async ensureGitServerWorkspace(e,t,n){const{cwd:s,gitUrl:a,taskId:i,baseBranch:o,branchName:c,gitServerId:l}=e;if(!a)throw new Error("[WORKSPACE] gitUrl is required for git-server mode");const p=e.forceUserCwd||!1===e.useWorktree,d="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await la(s),m=wa(s);if(p)return this.ensureDirectGitServerWorkspace(e,t,n,u,m);if(Boolean(e.taskRepositoryId&&l)&&(!u||d)){const p=await async function(e,t,n,s,a,i){const o=Nr(e)||e,c=Aa(n),l=Ma(c);if(!l)throw new Error(`Unable to resolve repository owner/name from git URL: ${c}`);const p=fe.resolveRepoStoreCheckoutDir(s,l.owner,l.repo),d=fe.resolveRepoStoreLockPath(s,l.owner,l.repo),u=await fe.acquireFileLock(d);if(!u)throw new Error(`Timed out waiting for repo store lock at ${d}`);try{await async function(e,t,n,s){const a=Aa(t);if(!await la(e)){if(!wa(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await ma(e)}await $a(e,"origin",a),await qr(e,t,n);const i=await async function(e,t="origin"){const{stdout:n}=await ra("git",["for-each-ref","--format=%(refname:short)",`refs/remotes/${t}`],{cwd:e,maxBuffer:10485760,windowsHide:!0});return n.split("\n").map(e=>e.trim()).filter(Boolean).map(e=>e.replace(`${t}/`,"")).filter(e=>"HEAD"!==e)}(e),o=function(e,t){if(t&&e.includes(t))return t;if(e.includes("main"))return"main";if(e.includes("master"))return"master";if(e.length>0)return e[0];throw new Error("Cannot create worktree: repository has no remote branches to base the workspace on.")}(i,s);return await async function(e,t,n){await ra("git",["checkout","-B",t,n],{cwd:e,windowsHide:!0})}(e,o,`origin/${o}`),{baseBranch:o}}(p,n,s,a);const e=Or(t,i),c=await pa(p),l=c.find(e=>Nr(e.path)===o);if(l){if(l.branch&&l.branch!==e)throw new Error(`Worktree at ${o} is already attached to branch ${l.branch}. Remove it before retrying: git worktree remove ${o}`);return s&&await Ur(o,s),{initialCommitHash:await va(o)}}const d=c.find(t=>t.branch===e&&Nr(t.path)!==o);if(d)throw new Error(`Branch ${e} is already attached to worktree ${d.path}. Remove it before retrying.`);const u=dt(p),m=(await u.branchLocal()).all.includes(e);if(r(o)&&!wa(o))throw new Error(`Worktree directory already exists at ${o}. This may be from a previous task. To clean up: git worktree remove ${o} OR rm -rf ${o}`);try{m?await u.raw(["worktree","add",o,e]):await da(p,o,e,"HEAD")}catch(e){try{await ua(p,o,!0)}catch{}throw e}return await Ur(o,s),{initialCommitHash:await va(o)}}finally{await fe.releaseFileLock(d,u)}}(s,i,a,l,o,c);return u?{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}:{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,p.initialCommitHash,"none"),isGitRepository:!0,setupAction:"worktree",autoCommitPolicy:"enabled",useWorktree:!0}}if(!u){if(!m)throw new Error(`[WORKSPACE] Directory ${s} exists but is not a git repository.`);const e=await Lr(s,a,i,o,l,c)||await va(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await Ca(s,"origin",Aa(a)),{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:n?.useWorktree??!1}}async ensureDirectGitServerWorkspace(e,t,n,s,a){const{cwd:i,gitUrl:o,taskId:r,baseBranch:c,branchName:l,gitServerId:p}=e;if(!o)throw new Error("[WORKSPACE] gitUrl is required for git-server direct directory mode");if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const e=await Lr(i,o,r,c,p,l)||await va(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await this.assertDirectGitServerRemoteMatches(i,o),{...await this.tryResolveDirtyRepo(e,t,n,{defaultBranchMismatchAction:"Keep"}),setupAction:"reuse",useWorktree:!1}}async assertDirectGitServerRemoteMatches(e,t){const n=Ma(Aa(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${Aa(t)}`);const s=await Pa(e);if(!s)throw new Error(`[WORKSPACE] Direct directory ${e} must have an origin remote matching the selected repository.`);const a=n.host.toLowerCase(),i=s.host.toLowerCase(),o=n.owner.toLowerCase(),r=s.owner.toLowerCase(),c=n.repo.toLowerCase(),l=s.repo.toLowerCase();if(a!==i||o!==r||c!==l)throw new Error(`[WORKSPACE] Direct directory ${e} points to ${s.host}/${s.owner}/${s.repo}, but the selected repository is ${n.host}/${n.owner}/${n.repo}.`)}async ensureDirectoryWorkspace(e,t,n){const{cwd:s,taskId:i,userCwd:o}=e;if(await la(s))return this.tryResolveDirtyRepo(e,t,n);if(!wa(s))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};{if(!o)return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};const t=o.replace(/^~/,a());if(wa(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await la(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await xa(t)||await ha(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=Nr(t)||t;if(!await la(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await xa(i))throw new Error(`Cannot create worktree: repository at ${i} has no commits. Please create an initial commit first: cd ${i} && git add . && git commit -m 'Initial commit'`);const c=Or(n,s),l=(await pa(i)).find(e=>Nr(e.path)===o);if(l){if(l.branch&&l.branch!==c)throw new Error(`Worktree at ${o} is already attached to branch ${l.branch}. Remove it before retrying: git worktree remove ${o}`);return{initialCommitHash:await va(o)}}const p=dt(i),d=(await p.branchLocal()).all.includes(c);if(r(o)&&!wa(o))throw new Error(`Worktree directory already exists at ${o}. This may be from a previous task. To clean up: git worktree remove ${o} OR rm -rf ${o}`);try{d?await p.raw(["worktree","add",o,c]):await da(i,o,c,"HEAD")}catch(e){try{await ua(i,o,!0)}catch{}throw e}return{initialCommitHash:await va(o)}}(t,s,i,e.branchName)}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}}async ensureTemporaryWorkspace(e,t,n){const{cwd:s,taskId:a}=e;if(!await la(s)){await async function(e,t,n){const s=await async function(e,t,n){await ma(e);const s=function(e,t){return{hook_event_name:"RepositoryInit",workspace_path:e,task_id:t}}(e,t);return n?.onRepositoryInit&&await n.onRepositoryInit(s),await ha(e),await va(e)}(e,t,n);return{initialCommitHash:s}}(s,a,t),await fa(s,Or(a,e.branchName),e.baseBranch);const i=await va(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,i,"none"),isGitRepository:!0,setupAction:"init",autoCommitPolicy:"enabled",useWorktree:!1}}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:n?.useWorktree??!1}}async tryResolveDirtyRepo(e,t,n,s={}){let a=null,i="enabled";const o={};if(await async function(e){return!!await la(e)&&await ya(e)}(e.cwd)){const s=this.getPersistedInitPolicy(n,"uncommittedChanges",["Ignore","Commit","Stash"]),r=s?{action:s,remember:!0}:function(e){if(e.channelReplyTarget)return!0;const t=e.eventData;return"object"==typeof t&&null!==t&&"senderType"in t&&"channel"===t.senderType}(e)?{action:"Ignore",remember:!0}:t?.onUncommittedChanges?await t.onUncommittedChanges():{action:"Ignore",remember:!1},c=r.action;if(await async function(e,t){switch(t){case"Ignore":console.log("[GIT] User chose to ignore uncommitted changes");break;case"Stash":console.log("[GIT] Stashing uncommitted changes"),await async function(e){const t=ca(e);await t.stash(["push"])}(e);break;case"Commit":console.log("[GIT] Committing uncommitted changes with agent-generated message");break;case"Abort":throw new Error("Task aborted by user due to uncommitted changes")}}(e.cwd,c),"Abort"===c)throw new Error("Task aborted by user due to uncommitted changes");if("Commit"===c){if(!t?.onCommitUncommittedChanges)throw new Error("Unable to commit uncommitted changes during workspace setup");await t.onCommitUncommittedChanges()}!s&&r.remember&&(o.uncommittedChanges=c),a=c,"Ignore"===c&&(i="disabled_by_ignore")}let r;if(await xa(e.cwd)||await ha(e.cwd),"Ignore"===a){const t=Or(e.taskId,e.branchName);r=await _a(e.cwd)===t?"none":"kept"}else r=await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch");const c=await va(e.cwd);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,c,r),isGitRepository:!0,setupAction:"reuse",autoCommitPolicy:i,useWorktree:n?.useWorktree??!1,initPolicyUpdates:o}}getPersistedInitPolicy(e,t,n){const s=e?.initPolicies?.[t];return s&&n.includes(s)?s:null}resolveInitialCommitHash(e,t,n){return e?"kept"===n?t:e:t}async tryResolveBranchMismatch(e,t,n,s,a){const i=Or(e.taskId,e.branchName),o=await _a(e.cwd);if(o===i)return"none";const r=this.getPersistedInitPolicy(n,"branchMismatch",["Switch","Keep"]),c=r?{action:r,remember:!0}:t?.onBranchMismatch?await t.onBranchMismatch({currentBranch:o,expectedBranch:i,workingDirectory:e.cwd}):{action:a,remember:!1};if("Abort"===c.action)throw new Error("Task aborted by user due to branch mismatch");return!r&&c.remember&&(s.branchMismatch=c.action),"Keep"===c.action?"kept":(await fa(e.cwd,i,e.baseBranch),"switched")}}const fc=Qe.object({title:Qe.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:Qe.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:Qe.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),yc=Ze(fc,{target:"draft-07"}),vc=Ze(fc);function xc(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?fc.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=wc(e),n=JSON.parse(t);return fc.parse(n)}(t.result??"")}function wc(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class bc{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const kc=[{name:"/merge-request",sendAs:"![merge-request]",description:"Create a pull request for current task changes"},{name:"/merge-pr",sendAs:"![merge-pr]",description:"Merge the current pull request"},{name:"/new",sendAs:"![new]",description:"Start a new session for this task"}];function Ic(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function Sc(e=[]){const t=[],n=new Set;for(const e of kc.map(e=>({id:`cli_builtin:${e.name}`,name:e.name,kind:"cli_builtin",sendAs:e.sendAs,description:e.description})))t.push(e),n.add(e.name);const s=Array.from(new Set(e.map(Ic).filter(Boolean)));s.sort((e,t)=>e.localeCompare(t));for(const e of s)n.has(e)||t.push({id:`sdk:${e}`,name:e,kind:"sdk",sendAs:e});return t}const Tc=Qe.object({message:Qe.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),Ec=Ze(Tc,{target:"draft-07"}),_c=Ze(Tc);async function Cc(e){if(!await ya(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await va(e.workingDirectory),n=await async function(e){const t=e.runner.runStreamed("Generate a git commit message for the current uncommitted changes.\n\nRequirements:\n- Follow this repository's commit message conventions.\n- Keep the subject line specific and concise.\n- Add a body only if it materially improves clarity.\n- Return only the commit message.",{cwd:e.workingDirectory,model:e.model,abortController:e.abortController,modeConfig:e.modeConfig,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?Ec:_c}});let n=null;for await(const s of t){if("result"===s.type){n=s;break}await(e.onStreamMessage?.(s))}if(!n)throw new Error("Commit message generation did not return a result message");return function(e){if("success"!==e.subtype)throw new Error("Commit message generation failed before structured output was returned");const t=e,n=(t.structured_output?Tc.parse(t.structured_output):Tc.parse(JSON.parse(wc(t.result??"")))).message.trim();if(!n)throw new Error("Commit message generation returned an empty message");return n}(n)}(e),s=await async function(e,t){const n=t.trim();if(!n)throw new Error("Commit message cannot be empty");const[s,...a]=n.split(/\n\s*\n/).map(e=>e.trim()).filter(Boolean);if(!s)throw new Error("Commit subject cannot be empty");const i=ca(e);await i.add(["--all"]);const o=["commit","-m",s];for(const e of a)o.push("-m",e);return await i.raw(o),await va(e)}(e.workingDirectory,n);if(await ya(e.workingDirectory))throw new Error("Commit completed but working tree is still dirty");if(s===t)throw new Error("Commit completed but HEAD did not change");return{commitHash:s,message:n}}function Ac(e){if(e)return{type:"json_schema",schema:e}}async function $c(e,t){await o.promises.mkdir(t,{recursive:!0});const n=await o.promises.readdir(e,{withFileTypes:!0});for(const s of n){const n=I.join(e,s.name),a=I.join(t,s.name);s.isDirectory()?await $c(n,a):await o.promises.copyFile(n,a)}}function Mc(e){return"oneshot"===function(e){return e.workerExecutionMode??ie}(e)}async function Pc(e){const t=S(e,".agentrix"),n=S(t,"prompt.md"),s=S(t,"plugins"),[a,i]=await Promise.all([Rc(n),Nc(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function Rc(e){try{if(!(await x.stat(e)).isFile())return;const t=(await x.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(Dc(e))return;throw e}}async function Nc(e){let t;try{t=await x.readdir(e,{withFileTypes:!0})}catch(e){if(Dc(e))return[];throw e}const n=[];for(const s of t.sort((e,t)=>e.name.localeCompare(t.name))){if(!s.isDirectory())continue;const t=S(e,s.name),a=S(t,".claude-plugin","plugin.json");try{(await x.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(Dc(e))continue;throw e}}return n}function Dc(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}class Oc{constructor(e,t,n){this.credentials=e,this.options=t,this.workingDirectory=n;const s=this.options.input,{taskId:a,userId:i}=s;this.logger=we({type:"worker",taskId:a}),this.currentAgentSessionId="agentSessionId"in s?s.agentSessionId:void 0;const o=s.taskAgents||[];this.taskAgentsMap=new Map(o.map(e=>[e.id,e]));const r=this.taskAgentsMap.size>1;this.primaryAgentId=r?"planner":s.agentId,this.primaryAgentName=r?"planner":this.taskAgentsMap.get(s.agentId)?.name??"unknown";const c=this.createWorkerClientConfig(i,a,n),l=fe.resolveDataDir(i,a);this.historyDb=io({dataDir:l,taskId:a}),this.workClient=new Ko(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new Zo({logger:this.logger,socketClient:this.workClient.client,taskId:s.taskId,userId:s.userId,chatId:s.chatId,rootTaskId:s.rootTaskId||s.taskId,parentTaskId:s.parentTaskId||null,workingDirectory:this.workingDirectory,agentHomeDir:fe.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:fe.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const p={...Dr(this.options.input),cwd:this.workingDirectory};this.workspace=new gc({options:p,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=nr();logger;workClient;workspace;coordinator;agentContext;runner;agentQueues=new Map;currentAgentSessionId;currentGroupId=null;historyDb;chatHistoryDb=null;agentrixTools;pendingNavigateTaskId=null;pendingPermissions=new Map;grantedPermissions=new Set;loopPermissionModeSetter=null;configuredPermissionMode="bypassPermissions";desiredPermissionMode=null;activePermissionMode=null;lastBroadcastPermissionMode=null;taskAgentsMap;messageSavedListener=null;messageDebounceHandle=null;messageDebounceMs=1e4;lastProcessedSequence=0;primarySessionReady=!1;pendingPrimaryLastSequence=null;primaryAgentId;primaryAgentName;exitReason="completed";pendingChannelReplies=[];channelMessageInvocationCount=0;projectAgentrixGuidance={claudePlugins:[]};newMessageGroupId(){return`group-${crypto.randomUUID()}`}refreshGroupId(){this.currentGroupId=this.newMessageGroupId()}getConfiguredPermissionMode(){if(this.isOneShotExecution())return"bypassPermissions";const e=this.runner?.getAgentConfiguration()?.customPermissionMode;return e??"bypassPermissions"}isOneShotExecution(){return Mc(this.options.input)}initializePermissionModeState(){this.configuredPermissionMode=this.getConfiguredPermissionMode(),this.desiredPermissionMode??=this.configuredPermissionMode}getPermissionModeSnapshot(){return this.desiredPermissionMode??this.configuredPermissionMode??null}broadcastPermissionMode(e){this.lastBroadcastPermissionMode!==e&&(this.lastBroadcastPermissionMode=e,this.workClient.sendPermissionMode(e))}confirmPermissionModeApplied(e){this.desiredPermissionMode=e,this.activePermissionMode=e,this.broadcastPermissionMode(e)}async applyPermissionMode(e){this.loopPermissionModeSetter&&(await this.loopPermissionModeSetter(e),this.confirmPermissionModeApplied(e))}async flushDesiredPermissionMode(){const e=this.getPermissionModeSnapshot();e&&this.loopPermissionModeSetter&&this.activePermissionMode!==e&&await this.applyPermissionMode(e)}async requestPermissionMode(e){this.desiredPermissionMode=e,this.broadcastPermissionMode(e),await this.flushDesiredPermissionMode()}async restoreConfiguredPermissionMode(){await this.requestPermissionMode(this.configuredPermissionMode)}shouldProcessMessage(e){const t=e.message,n=this.getRunnerMode(),s="group_chat"===n||"group_work"===n,a=Q(t);return!!oe(t)||!!re(t)||!(!Z(t)&&!a)&&"agent"!==e.senderType&&(s?e.senderId!==this.primaryAgentId:!!a||"system"===e.senderType&&"user"===t.type||"user"===t.type)}shouldDropHeartbeatWhileBusy(){return this.coordinator.isActivelyExecuting()}async processPendingMessages(){const e=this.historyDb.pageMessagesAfter(this.lastProcessedSequence,100),t=this.getRunnerMode(),n="group_chat"===t||"group_work"===t,s=[];for(const t of e.data)if(this.lastProcessedSequence=t.localSequence,this.shouldProcessMessage(t)){if(n&&this.isUnsupportedGroupPlanCommand(t)){this.log("info","PLAN","Ignoring unsupported ![plan] command in group mode");continue}s.push(t)}if(s.length>0){this.deduplicateHeartbeats(s);const e=this.mergeConsecutiveHumanMessages(s);n?await this.processMessagesAsGroup(e):await this.processMessagesIndividually(e)}e.hasMore&&await this.processPendingMessages()}isUnsupportedGroupPlanCommand(e){const t=e.message;return!(!Z(t)||"user"!==t.type)&&"![plan]"===Bs(t).trim()}deduplicateHeartbeats(e){let t=-1;for(let n=e.length-1;n>=0;n--)oe(e[n].message)&&(-1===t?t=n:(e.splice(n,1),t--))}mergeConsecutiveHumanMessages(e){if(0===e.length)return[];const t=[];let n=0;for(;n<e.length;){const s=e[n];if("human"===s.senderType){const a=[s];for(;n+1<e.length;){const t=e[n+1];if("human"!==t.senderType||t.senderId!==s.senderId)break;a.push(t),n++}1===a.length?t.push(s):t.push(this.createMergedHumanMessage(a))}else t.push(s);n++}return t}createMergedHumanMessage(e){const t=[],n=[];for(const s of e){const e=s.message;if(!Z(e)||"user"!==e.type)continue;const a=e.message.content;if("string"==typeof a)t.push(a);else if(Array.isArray(a))for(const e of a)"text"===e.type?t.push(e.text):n.push(e)}const s=t.join(""),a=n.length>0?[{type:"text",text:s},...n]:s,i=e[0],o=e[e.length-1];return{localSequence:o.localSequence,eventId:o.eventId,senderType:i.senderType,senderId:i.senderId,senderName:i.senderName,createdAt:o.createdAt,message:{type:"user",message:{role:"user",content:a},parent_tool_use_id:null,session_id:i.message?.session_id||""}}}async processMessagesAsGroup(e){const t=[],n=[];for(const s of e){const e=Ro(s);if(e){const s=e.message.content;if("string"==typeof s)t.push(s);else if(Array.isArray(s))for(const e of s)"text"===e.type?t.push(e.text):n.push(e)}}if(0===t.length)return;const s=Math.max(...e.map(e=>e.localSequence)),a=t.join(" "),i={type:"user",message:{role:"user",content:n.length>0?[{type:"text",text:a},...n]:a},parent_tool_use_id:null,session_id:""};this.attachInputMetadata(i,{localSequence:s,isChannelInput:e.some(e=>"channel"===e.senderType),channelReplyTarget:this.extractChannelReplyTarget(e)}),await this.coordinator.enqueue(i)}async processMessagesIndividually(e){for(const t of e){const e=this.formatSingleMessage(t);e&&(this.attachInputMetadata(e,{localSequence:t.localSequence,isChannelInput:"channel"===t.senderType,channelReplyTarget:this.extractChannelReplyTarget([t])}),delete e.__channelReplyTarget,await this.coordinator.enqueue(e))}}attachInputMetadata(e,t){e.__localSequence=t.localSequence,e.__isChannelInput=t.isChannelInput,t.channelReplyTarget&&(e.__channelReplyTarget=t.channelReplyTarget)}extractChannelReplyTarget(e){for(let t=e.length-1;t>=0;t--){const n=e[t].message.__channelReplyTarget;if(this.isChannelReplyTarget(n))return n}return null}formatSingleMessage(e){const t=e.message;if(oe(t)){const e=t;return{type:"user",message:{role:"user",content:this.buildCompanionHeartbeatPrompt(e)},parent_tool_use_id:null,session_id:""}}if(re(t)){const e=t;let n=`[reminder from shadow] ${e.content}`;return e.filePath&&(n+=`\nDetailed analysis: ${e.filePath}`),{type:"user",message:{role:"user",content:n},parent_tool_use_id:null,session_id:""}}return Z(t)&&"user"===t.type?t:null}buildCompanionHeartbeatPrompt(e){const t=this.options.input,n=t.rootTaskId||t.taskId;return["[heartbeat] You are being awakened by a scheduled companion heartbeat.","","Review target:","Always review the recent context of this companion chat and its root chat task before deciding what to do. Do not limit the review to a generic workspace scan.",...[`heartbeat timestamp: ${e.timestamp}`,e.triggerTime?`local trigger time: ${e.triggerTime}`:void 0,e.triggerReasons?.length?`trigger reasons: ${e.triggerReasons.join(", ")}`:void 0,`current worker taskId: ${t.taskId}`,t.chatId?`companion chatId: ${t.chatId}`:void 0,n?`root chat taskId: ${n}`:void 0].filter(e=>Boolean(e)).map(e=>`- ${e}`),"","Decide whether the companion/root chat task has any unfinished user request, failed or incomplete subtask, due reminder, scheduled work, memory worth preserving, or item that should notify the main companion.","Use the available conversation-reading tools for the companion chat/root chat task when needed. If there is nothing actionable after that review, respond briefly and exit."].join("\n")}async prepareMessageForRunner(e){return uo(e,{attachmentsDir:fe.resolveAttachmentsDir(this.options.input.userId,this.taskId),log:(e,t,n,...s)=>{this.log(e,t,n,...s)}})}setupMessageSavedListener(){this.messageSavedListener=()=>{this.triggerMessageProcessing()},this.historyDb.on("message-saved",this.messageSavedListener)}triggerMessageProcessing(){const e=this.getRunnerMode();"group_chat"===e||"group_work"===e?this.scheduleProcessPendingMessages():this.processPendingMessages()}scheduleProcessPendingMessages(){this.coordinator?.setDebouncing(!0),this.messageDebounceHandle&&clearTimeout(this.messageDebounceHandle),this.messageDebounceHandle=setTimeout(async()=>{this.messageDebounceHandle=null,await this.processPendingMessages(),this.coordinator?.setDebouncing(!1)},this.messageDebounceMs)}async start(){let e="completed";try{await this.initialize(),await this.handleEvent(),await this.runClaude()}catch(t){if(!(t instanceof lt)){e="error",this.log("warn","AGENT","Fatal error:",t);const n=t instanceof Error?t.message:String(t);await this.reportFatalError(n)}}finally{await this.exitWorker("error"===e?"error":this.exitReason)}}async autoInstallAgent(e){const t=this.options.input,n=t.agentGitUrl,s=t.agentGitSubDir;if(n)try{this.log("info","AGENT",`Auto-installing agent ${e} from git`),await Es({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){this.log("warn","AGENT",`Auto-install failed for agent ${e}: ${t}`)}else this.log("warn","AGENT",`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=fe.agentrixAgentsHomeDir,a=S(s,`${e}.new`),i=S(s,`${e}-bak`);try{this.log("info","AGENT",`Applying upgrade for ${e}`),_s(n),m(n,a),await $c(t,i),h(t,{recursive:!0,force:!0}),m(a,t),_e(i)&&h(i,{recursive:!0,force:!0}),this.log("info","AGENT",`Upgrade applied for ${e}`)}catch(n){this.log("warn","AGENT",`Upgrade failed for ${e}: ${n}`),!_e(t)&&_e(i)&&m(i,t),_e(a)&&h(a,{recursive:!0,force:!0})}}async initialize(){const e=this.options.input,t=fe.resolveAgentDir(e.agentId),n=S(t,"upgrade"),s=Boolean(e.agentGitUrl),a=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&s&&!_e(t)),i=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!a&&_e(n));await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:a,upgradingAgent:i}),a&&await this.autoInstallAgent(e.agentId),i&&await this.applyAgentUpgrade(e.agentId,t,n);const o=await mc.create(e.agentType,e.agentId,{agentDir:e.agentDir,logger:this.log.bind(this),context:this.agentContext});this.runner=o,this.initializePermissionModeState();const r=await this.workspace.setup();this.projectAgentrixGuidance=await Pc(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${r.setupAction} at ${this.workingDirectory} (${r.initialCommitHash||"none"})`),this.setEnvironmentVariables(),this.lastProcessedSequence=this.historyDb.getAgentLastSequences().get(this.primaryAgentId)??0,this.log("info","HISTORY",`Starting from sequence ${this.lastProcessedSequence} (tracking: ${this.primaryAgentId})`),this.currentAgentSessionId&&(this.historyDb.upsertAgentSession(this.primaryAgentId,this.currentAgentSessionId),this.primarySessionReady=!0),this.setupMessageSavedListener(),this.workClient.sendWorkerInitialized(),this.workClient.sendTaskSlashCommandsUpdate(Sc())}createWorkspaceHandlers(e){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onRepositoryInit:async e=>{await(this.runner?.executeHook("RepositoryInit",e))},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:this.commitCurrentChangesWithAgent.bind(this),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onRepositoryInit:async e=>{await(this.runner?.executeHook("RepositoryInit",e))},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:this.commitCurrentChangesWithAgent.bind(this),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await Ht(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}setEnvironmentVariables(){this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.ANTHROPIC_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.ANTHROPIC_AUTH_TOKEN=this.options.input.api_key)}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new Xr({workerType:"claude",workClient:e,onCommandMessageProcessed:e=>{this.markPrimaryMessageProcessed(e)},handlers:{onNormalMessage:async e=>e,onBashCommand:async(e,t)=>{await this.executeBashCommand(e)},onMergeRequest:async e=>{await this.executeMergeRequest()},onMergePr:async()=>{await this.executeMergePr()},onNewSession:async()=>{await this.executeNewSession()},onPlanMode:async()=>this.isOneShotExecution()?(this.workClient.sendSystemErrorMessage("![plan] is not supported in oneshot execution mode",{groupId:this.currentGroupId??void 0}),null):(await this.requestPermissionMode("plan"),null)},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=er(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}if("sub-task-ask-user"===e){const e=t,n=tr(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}this.isOneShotExecution()?(await this.processPendingMessages(),this.coordinator.hasAgentMessages()||this.isStopping||this.stopTask("oneshot_complete")):this.triggerMessageProcessing(),"task-message"===e&&t?.eventId&&this.workClient.sendEventAck(t.eventId)}async executeMergeRequest(){this.log("info","MERGE","Executing merge-request command");const e=this.getRunnerMode(),t="group_chat"===e||"group_work"===e;try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await ya(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await va(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await ka(this.workingDirectory,a,e)).files.length){const e="No changes to create PR: no files changed since task started";return void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}const i=await _a(this.workingDirectory);this.log("info","MERGE",`Pushing branch ${i} to remote`),await Hr(this.workingDirectory,i,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","Successfully pushed branch to remote");const o=this.runner?.getAgentConfiguration(),r=Fr(a,(o?.customPRPromptTemplate?(n=o.customPRPromptTemplate,s={initialCommitHash:a,currentCommitHash:"",branchName:""},n.replace(/\{\{initialCommitHash\}\}/g,s.initialCommitHash).replace(/\{\{currentCommitHash\}\}/g,s.currentCommitHash).replace(/\{\{branchName\}\}/g,s.branchName)):void 0)??void 0);this.log("debug","MERGE",`PR prompt: ${r.substring(0,200)}...`);const c=this.runner;let l=null;const p=c.runStreamed(r,{cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:yc}});for await(const e of p){if(this.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){l=e;break}const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}if(!l)throw new Error("Merge-request did not return a result message");if("success"!==l.subtype)throw new Error("Merge-request did not return a successful result message");const d=xc(l),u=await this.workClient.sendMergeRequest(d.title,d.description),m=`${d.userMessage}\n\n✅ Pull request created successfully!\nNumber: #${u.pullRequestNumber}\nURL: ${u.pullRequestUrl}`,h={input_tokens:l.usage.input_tokens??0,cached_input_tokens:l.usage.cache_read_input_tokens??0,output_tokens:l.usage.output_tokens??0,reasoning_output_tokens:0};this.workClient.sendTaskMessage(this.getChatSenderMeta(),Fs({sessionId:l.session_id,model:this.options.input.model??"unknown",numTurns:l.num_turns,usage:h,result:m}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.workClient.sendSystemErrorMessage(`❌ Merge-request failed: ${t}\n\nPlease check git status and try again, or create the PR manually.`,{groupId:this.currentGroupId??void 0})}var n,s}async executeBashCommand(e){if(!fe.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await Vr(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await Yr({workingDirectory:this.workingDirectory,workClient:this.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.logger,askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(){this.log("info","MERGE","Generating commit message with agent"),await Cc({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),schemaTarget:"claude",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.taskAgentsMap.size>1?e:this.messageFilter.filter(e);null!==t&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}async runClaude(){if(this.log("info","AGENT",`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void this.log("info","AGENT",`Skipping Claude run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runClaudeOneShot();const e=this.currentAgentSessionId,t=this.runner,n=this.getRunnerModeConfig(),s="group_chat"===n.mode||"group_work"===n.mode,a=this.createPermissionHandler(),i=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.initializePermissionModeState();const o=t.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:e,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:n,agentrixTools:this.agentrixTools,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),visionModel:this.options.input.visionModel,canUseTool:a,hooks:i,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});this.loopPermissionModeSetter=o.setPermissionMode??null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.broadcastPermissionMode(this.getPermissionModeSnapshot()),await this.flushDesiredPermissionMode(),(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(!e){if(this.isStopping)break;continue}this.updateAgentRunning(!0),o.push(await this.prepareMessageForRunner(e));const t=e.__localSequence;if(void 0!==t&&(this.markPrimaryMessageProcessed(t),delete e.__localSequence),Boolean(e.__isChannelInput)){const t=e.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(t)?t:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}delete e.__isChannelInput,delete e.__channelReplyTarget}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of o.events)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,s);this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude agent finished for task ${this.taskId}`)}async runClaudeOneShot(){const e=this.runner,t=this.getRunnerModeConfig(),n="group_chat"===t.mode||"group_work"===t.mode,s=this.createPermissionHandler(),a=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.loopPermissionModeSetter=null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.initializePermissionModeState(),this.broadcastPermissionMode(this.getPermissionModeSnapshot());const i=await this.coordinator.waitForAgentMessage();if(!i)return this.isStopping||this.stopTask("oneshot_complete"),this.resetPrimaryPermissionState(),void this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&(this.markPrimaryMessageProcessed(o),delete i.__localSequence),Boolean(i.__isChannelInput)){const e=i.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(e)?e:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}delete i.__isChannelInput,delete i.__channelReplyTarget,this.updateAgentRunning(!0);try{const o=await this.prepareMessageForRunner(i),r=e.runStreamed(o,{cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:this.currentAgentSessionId,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:t,agentrixTools:this.agentrixTools,allowAskUser:!1,supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),visionModel:this.options.input.visionModel,canUseTool:s,hooks:a,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});for await(const e of r)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,n);this.isStopping||this.stopTask("oneshot_complete")}finally{this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e,t){if("system"===e.type&&"init"===e.subtype)return this.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.workClient.sendTaskSlashCommandsUpdate(Sc(e.slash_commands??[]),e.session_id),this.currentAgentSessionId=e.session_id,this.historyDb.upsertAgentSession(this.primaryAgentId,e.session_id),this.primarySessionReady=!0,null!==this.pendingPrimaryLastSequence&&(this.historyDb.updateAgentLastSequence(this.primaryAgentId,this.pendingPrimaryLastSequence),this.pendingPrimaryLastSequence=null),this.refreshGroupId(),void this.updateAgentRunning(!0);if("result"===e.type)return await this.handleSdkResultMessage(e),this.refreshGroupId(),void this.updateAgentRunning(!1);"system"===e.type&&"task_notification"===e.subtype&&this.handleBackgroundTaskNotification(e);const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}resetPrimaryPermissionState(){this.loopPermissionModeSetter=null,this.activePermissionMode=null}updateAgentRunning(e){this.coordinator?.setAgentRunning(this.primaryAgentId,this.primaryAgentName,e)}markPrimaryMessageProcessed(e){this.historyDb.updateAgentLastSequence(this.primaryAgentId,e),this.primarySessionReady||(this.pendingPrimaryLastSequence=null===this.pendingPrimaryLastSequence?e:Math.max(this.pendingPrimaryLastSequence,e))}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}async handleAskUserQuestionPermission(e){const t=e,n=Array.isArray(t.questions)?t.questions:[];if(0===n.length)return this.log("warn","PERMISSION","AskUserQuestion missing questions"),{behavior:"deny",message:"AskUserQuestion missing questions"};const s=n.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]}));try{const e=await this.askUser(s),a={};for(let t=0;t<n.length;t+=1){const s=n[t]?.question;if(!s)continue;const i=e.answers?.[t];"string"==typeof i&&(a[s]=i)}return{behavior:"allow",updatedInput:{...t,answers:a}}}catch(e){return this.log("warn","PERMISSION",`AskUserQuestion failed: ${e}`),{behavior:"deny",message:"AskUserQuestion failed"}}}createPermissionHandler(){return async(e,t)=>{if("AskUserQuestion"===e)return this.handleAskUserQuestionPermission(t);if("ExitPlanMode"===e)return this.handleExitPlanModePermission(t);if(this.grantedPermissions.has(e))return this.log("info","PERMISSION",`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return this.log("info","PERMISSION",`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;this.log("info","PERMISSION",`Requesting permission for "${e}"`);const a=new Promise(e=>{s=e});this.pendingPermissions.set(e,a);try{const n=await this.requestToolPermission(e);return s(n),"allow"===n?(this.grantedPermissions.add(e),{behavior:"allow",updatedInput:t}):{behavior:"deny",message:"Permission denied by user"}}catch(e){return s("deny"),{behavior:"deny",message:"Permission request failed"}}finally{this.pendingPermissions.delete(e)}}}async handleExitPlanModePermission(e){const t=e.planFilePath??e.filePath;let n,s;if(t){const e=this.workspace.getCwd(),a=e.endsWith("/")?e:e+"/";n=t.startsWith(a)?t.slice(a.length):void 0;try{const e=await Ce.readFile(t,"utf-8");s=e.length>8e3?e.slice(0,8e3)+"\n\n…(truncated)":e}catch{}}!s&&"string"==typeof e.plan&&e.plan&&(s=e.plan);const a=[{question:"Review the plan and choose how to proceed.",header:"Plan Review",multiSelect:!1,options:[{label:"Approve",description:"Approve the plan and start implementation"},{label:"Revise",description:"Need to revise the plan",additionalInput:{enabled:!0,required:!1,placeholder:"Describe what should change."}},{label:"Cancel",description:"Cancel this plan"}],planFilePath:n,planContent:s}];try{const t=await this.askUser(a,{onTimeout:"abort_task"}),n=t.answers[0],s=t.details?.[0]?.trim();return"Approve"===n?{behavior:"allow",updatedInput:e}:"Revise"===n?{behavior:"deny",message:s?`The user wants to revise the plan. Revision notes: ${s}. Please reconsider and update the plan, then call ExitPlanMode again when ready.`:"The user wants to revise the plan. Please reconsider and update the plan, then call ExitPlanMode again when ready."}:(await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"User cancelled plan review",interrupt:!0})}catch{return await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"Plan review failed or was interrupted"}}}async requestToolPermission(e){const t=[{question:`Tool "${e}" is requesting permission to execute. Allow this operation?`,header:"Permission",multiSelect:!1,options:[{label:"Allow",description:"Allow this tool to execute"},{label:"Deny",description:"Deny this tool execution"}]}];try{return"Allow"===(await this.askUser(t,{onTimeout:"abort_task"})).answers[0]?"allow":"deny"}catch(e){return this.log("warn","PERMISSION",`Permission request failed: ${e}`),"deny"}}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.workClient;return Zr(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>n.sendAssistantMessage(e,{groupId:this.currentGroupId??void 0}),stopTask:e=>this.stopTask(e)},t)}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}getRunnerMode(){const e=this.taskAgentsMap.size>1,t=this.options.input.taskType,n=!(!process.env.AGENTRIX_COMPANION_HOME&&!process.env.AGENTRIX_COMPANION_WORKSPACE);return"shadow"===t?"companion_shadow":n&&"chat"===t?"companion_chat":e?"chat"===t?"group_chat":"group_work":"chat"===t?"chat":"work"}getGroupAgents(){if(!(this.taskAgentsMap.size<=1))return Array.from(this.taskAgentsMap.values()).map(e=>({id:e.id,name:e.name,description:e.description}))}getRunnerModeConfig(){return{mode:this.getRunnerMode(),supportChangeTitle:this.supportChangeTitle,groupAgents:this.getGroupAgents()}}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}getStructuredOutputSchema(){return Ac(this.options.input.outputSchema)}createAgentrixTools(){const e=this.taskAgentsMap.size>1;if("companion_shadow"===this.getRunnerMode()){const e=this.options.input.chatId,t=this.options.input.userId,n=fe.resolveDataDir(t,e);this.chatHistoryDb=io({dataDir:n,taskId:e})}return{createTask:cr(t={agentContext:this.agentContext,workClient:this.workClient,uploadFile:e=>this.agentContext.uploadFile(e),taskId:this.taskId,chatId:this.options.input.chatId,agentId:this.primaryAgentId,isGroup:e,historyDb:this.historyDb,chatHistoryDb:this.chatHistoryDb??void 0,askUser:e=>this.askUser(e),log:this.log.bind(this),onChannelMessageInvoked:()=>{this.channelMessageInvocationCount+=1},invokeAgent:(e,t)=>this.invokeAgent(e,t),assign:(e,t,n)=>this.assignWork(e,t,n),setPendingNavigateTaskId:e=>{this.pendingNavigateTaskId=e},getChannelReplyTarget:()=>this.getInjectedChannelReplyTarget(),supportedFeatures:this.options.input.supportedFeatures,visionModel:this.options.input.visionModel}),createSoloTask:lr(t),createGroupTask:pr(t),replyToSubTask:ar(t),changeTaskTitle:sr(t),askUser:dr(t),getTaskHistory:ir(t),getTaskAgents:or(t),listSubTask:rr(t),invoke:ur(t),assign:hr(t),updateAgentInfo:mr(t),sendReminder:yr(t),listTasks:gr(t),readConversation:fr(t),uploadFile:vr(t),sendChannelMessage:br(t),getChannelGroupHistory:kr(t),listAgents:Sr(t),analyzeImage:Er(t),scheduleTask:_r(t),prepareHiveRepository:Cr(t),publishToHive:Ar(t),updateHiveListingVersion:$r(t),recordHiveInstall:Mr(t),createHiveReview:Pr(t),createHiveComment:Rr(t)};var t}resolveTaskAgentName(e){return this.taskAgentsMap.get(e)?.name||""}getChatSenderMeta(){return{senderType:"agent",senderId:this.primaryAgentId,senderName:this.primaryAgentName}}sendAgentErrorMessage(e,t,n,s){const a=t||e,i={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:`System Error\n\n${a}: ${n}`}]}};this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:a},i,{groupId:s?.groupId})}async invokeAgent(e,t){const n=this.buildSubAgentHistoryContext(e,t);if(!n)return!1;const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new bc,this.agentQueues.set(e,i));const o=this.resolveTaskAgentName(e),r=this.getRunnerMode(),c="group_chat"===r||"group_work"===r;return i.run(async()=>{this.coordinator?.setAgentRunning(e,o,!0);const t=this.newMessageGroupId();try{const s=await mc.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),p=this.buildSystemHooks({trackBackgroundTasks:!1}),d=nr(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,agentrixTools:this.agentrixTools,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:l,hooks:p,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});let m=n.message;if("codex"===a&&!n.sessionId){const t=[qs(e,i),"=== CONVERSATION STREAM START FROM HERE ===",Bs(n.message)].join("\n\n").trim();t&&(m=t)}"string"==typeof m?u.push(m):u.push(await this.prepareMessageForRunner(m));const h=n.lastSequence;let g=!1;n.sessionId&&(this.historyDb.updateAgentLastSequence(e,h),g=!0);let f=!1;for await(const n of u.events){if("system"===n.type&&"init"===n.subtype){this.historyDb?.upsertAgentSession(e,n.session_id),g||(this.historyDb.updateAgentLastSequence(e,h),g=!0);continue}if("result"===n.type){this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},n,{groupId:t}),f=!0;break}const s=c?n:d.filter(n);s&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},s,{groupId:t})}}catch(t){this.log("error","INVOKE",`Invoke failed for ${e}:`,t)}finally{this.coordinator?.setAgentRunning(e,o,!1)}}),!0}async assignWork(e,t,n){const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new bc,this.agentQueues.set(e,i));const o=this.resolveTaskAgentName(e),r=this.getRunnerMode(),c="group_chat"===r||"group_work"===r;return i.run(async()=>{this.coordinator?.setAgentRunning(e,o,!0);const s=this.newMessageGroupId();var i;n&&this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},(i=n,{type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:i}]}}),{groupId:this.newMessageGroupId()});try{const n=await mc.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),p=nr(),d=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,agentrixTools:this.agentrixTools,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:r,hooks:l,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});d.push(t);let u=!1;for await(const t of d.events){if("system"===t.type&&"init"===t.subtype)continue;if("result"===t.type){this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},t,{groupId:s}),u=!0;break}const n=c?t:p.filter(t);n&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},n,{groupId:s})}}catch(t){this.log("error","RUN_TASK",`Run task failed for ${e}:`,t);const n=t instanceof Error?t.message:String(t);this.sendAgentErrorMessage(e,o,`I meet some error: ${n}`,{groupId:s})}finally{this.coordinator?.setAgentRunning(e,o,!1)}})}buildSubAgentHistoryContext(e,t){const n=this.historyDb;if(!n)return this.log("warn","HISTORY","Task history DB unavailable; delegate cannot build context."),null;const s=n.getAgentSessions().get(e),a=n.getAgentLastSequences().get(e)??0,i=n.pageRecentMessagesAfter(a,20);if(0===i.data.length&&!t)return null;const o=this.mergeConsecutiveHumanMessages(i.data),r=this.buildHistoryMessages(o,t);return r?{message:r,sessionId:s,lastSequence:i.data.length>0?i.data[i.data.length-1].localSequence:a}:null}buildHistoryMessages(e,t){const n=[];for(const t of e){const e=No(t);e&&n.push(e)}if(0===n.length&&!t)return null;let s=n.join("\n");return t&&(s=`<hint>\n${t}\n</hint>\n\n${s}`),{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}buildSystemHooks(e){const t=e?.trackBackgroundTasks??!0,n=e?.trackPrimaryAgentStop??!1,s={};return t&&(s.PostToolUse=async e=>(this.syncPermissionModeFromPostToolUse(e),this.trackBackgroundTaskFromPostToolUse(e),{})),n&&(s.Stop=async()=>(this.updateAgentRunning(!1),{})),s}trackBackgroundTaskFromPostToolUse(e){if(!e||"object"!=typeof e)return void this.log("debug","TASK","PostToolUse hook input is not an object");const t=e,n=t.tool_input;if(!n||!0!==n.run_in_background)return;const s=this.extractBackgroundTaskId(t.tool_response);if(!s)return this.log("debug","TASK",`PostToolUse(${t.tool_name}) run_in_background=true but no task_id found, using anonymous tracking`),void this.coordinator?.setAnonymousBackgroundTaskRunning(!0);this.coordinator?.setBackgroundTaskRunning(s,!0),this.log("info","TASK",`Background task started: ${s} (tool: ${t.tool_name})`)}syncPermissionModeFromPostToolUse(e){if(!e||"object"!=typeof e)return;const t=(n=e.tool_name,s=this.configuredPermissionMode,"EnterPlanMode"===n?"plan":"ExitPlanMode"===n?s:null);var n,s;t&&this.confirmPermissionModeApplied(t)}handleBackgroundTaskNotification(e){this.updateAgentRunning(!0),this.coordinator?.setBackgroundTaskRunning(e.task_id,!1),this.log("info","TASK",`Background task ${e.task_id} ${e.status}`)}extractBackgroundTaskId(e){const t=new Set,n=new Set,s=e=>{if("string"!=typeof e)return;const n=e.trim();n&&t.add(n)},a=e=>{if(null==e)return;if("string"==typeof e)return void(e=>{const t=/(task[_-]?id|agent[_-]?id|shell[_-]?id)["'\s:=]+([A-Za-z0-9._:-]+)/gi;let n;for(;null!==(n=t.exec(e));)s(n[2])})(e);if("object"!=typeof e)return;if(n.has(e))return;if(n.add(e),Array.isArray(e)){for(const t of e)a(t);return}const t=e;"string"==typeof t.task_id&&s(t.task_id),"string"==typeof t.taskId&&s(t.taskId),"string"==typeof t.agent_id&&s(t.agent_id),"string"==typeof t.agentId&&s(t.agentId),"string"==typeof t.shell_id&&s(t.shell_id),"string"==typeof t.shellId&&s(t.shellId);for(const e of Object.values(t))a(e)};a(e);const i=[...t];return i.length>1&&this.log("warn","TASK",`Multiple background task ids extracted (${i.join(", ")}), using first id ${i[0]}`),i[0]}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.taskAgentsMap.get(s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:fe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(this.credentials.token,this.credentials.machineId,t),dataEncryptionKey:this.options.dataEncryptionKey??null,keepAliveConfig:{intervalMs:2e4,event:"worker-alive",payloadGenerator:()=>{const e=this.coordinator?.getStatus(),n="running"===e?.state?"worker-running":"worker-ready";return{eventId:G(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString(),activeAgents:this.coordinator?.getActiveAgents(),permissionMode:this.getPermissionModeSnapshot()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>this.logger.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:fe.resolveAttachmentsDir(e,t),logger:(e,t,n,...s)=>{this.log(e,t,n,...s)},stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!oe(e)||!this.shouldDropHeartbeatWhileBusy()||(this.log("debug","WORKER","Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(Q(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{Qr(e,this.options.input)},onWorkerStatusRequest:async()=>{const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning():"idle"===e&&this.workClient.sendWorkerReady()},onSubTaskResultUpdated:async e=>{const t=er(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=tr(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`),this.coordinator&&this.coordinator.stop(),this.workClient&&(this.workClient.sendWorkerExit(e),await this.workClient.disconnect()),this.historyDb&&this.historyDb.close(),this.chatHistoryDb&&this.chatHistoryDb.close(),process.exit(0)}async reportFatalError(e){await this.workClient.sendTerminalErrorResultAndWait(e,{groupId:this.currentGroupId??void 0})}log(e,t,n,...s){this.logger&&this.logger[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}const s=this.getRunnerMode(),a="group_chat"===s||"group_work"===s,i=this.pendingNavigateTaskId;if(this.pendingNavigateTaskId=null,a?this.workClient.sendTaskEvent(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}):this.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}),n)try{await Br(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}await this.forwardResultToChannelIfNeeded(e)}async forwardResultToChannelIfNeeded(e){if("result"!==e.type)return;const t=this.pendingChannelReplies.shift(),n=void 0===t?this.getInjectedChannelReplyTarget():t.target??this.getInjectedChannelReplyTarget();if(void 0===t&&!n)return;const s="success"===e.subtype,a=t?this.channelMessageInvocationCount>t.channelMessageInvocationCountAtStart:this.channelMessageInvocationCount>0;if(s&&a)return;const i=this.extractResultTextForChannel(e);if(!i)return;const o=await Gt(this.taskId,i,n),r=s;this.historyDb.saveTaskEvent({taskId:this.taskId,chatId:this.options.input.chatId,eventType:"channel-message-send",sequence:null,eventData:{status:o?.error?"error":"sent",delivery:r?"fallback":"error-forward",reason:r?"send_channel_message_not_invoked":"task_failed",channelId:n?.channelId,hasContent:!0,attachments:[],...o?.error?{error:o.error}:{}}}),o?.error&&this.log("debug","CHANNEL",`Claude reply was not sent to channel: ${o.error}`)}getInjectedChannelReplyTarget(){const e=process.env.AGENTRIX_CHANNEL_REPLY_TARGET;if(!e)return null;try{const t=JSON.parse(e);if("string"==typeof t.channelId&&"string"==typeof t.chatId)return{channelId:t.channelId,chatId:t.chatId,..."string"==typeof t.platform?{platform:t.platform}:{},..."string"==typeof t.chatType?{chatType:t.chatType}:{},..."string"==typeof t.chatName?{chatName:t.chatName}:{}}}catch(e){this.log("debug","CHANNEL","Ignoring invalid channel reply target:",e)}return null}isChannelBoundTask(){return null!==this.getInjectedChannelReplyTarget()}isChannelGroupBoundTask(){return"group"===this.getInjectedChannelReplyTarget()?.chatType?.toLowerCase()}getExternalChannelPromptContext(){const e=this.getInjectedChannelReplyTarget();if(e)return{platform:e.platform,chatType:e.chatType,chatName:e.chatName,chatId:e.chatId}}isChannelReplyTarget(e){return Boolean(e&&"object"==typeof e&&"string"==typeof e.channelId&&"string"==typeof e.chatId)}extractResultTextForChannel(e){if("success"===e.subtype){const t=e.result;if("string"!=typeof t)return null;const n=t.trim();return n.length>0?n:null}const t=e.errors,n=Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0).join("\n").trim():"",s=e.subtype;return`Task failed: ${n||("string"==typeof s?s:"Unknown error")}`}}class jc{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>Nr(e)||e;if(n)return l(n);const p=fe.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.shouldUseWorktree(e)?l(p):e}return l(p)}static async shouldUseWorktree(e){try{return!wa(e)&&await la(e)}catch{return!1}}}var Uc=cn(ke);class qc{constructor(e,t){this.credentials=e,this.options=t}context;threadId=null;isStopping=!1;filteredToolUseIds=new Set;currentModel=null;dataEncryptionKey=null;abortController=new AbortController;coordinator;logger;askUserAwaiter=new Map;workClient;workspace;historyDb=null;currentGroupId=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return Mc(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${le()}`}async start(){try{await this.initialize(),await this.handleEvent(),await this.runCodex(),await this.exitWorker(this.exitReason)}catch(e){if(!this.isStopping){this.isStopping=!0,this.askUserAwaiter.clear(),this.coordinator?.stop(),this.log("warn","AGENT","Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}this.log("info","AGENT",`Task ${this.taskId} stopped gracefully`),await this.exitWorker(this.exitReason)}finally{process.exit(0)}}async initialize(){const e=this.options.input.taskId,t=this.options.input.userId;this.logger=this.createLogger({type:"worker",taskId:e}),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const n=Dr(this.options.input),s=await jc.calculateFinalCwd(n),a={...n,cwd:s};this.log("info","INIT",`Phase 1: Working directory: ${s}`);const i=this.createWorkerClientConfig(t,e,s),o=fe.resolveDataDir(t,e);this.historyDb=io({dataDir:o,taskId:e});const r=new Ko(i.config,{...i.handlers,historyDb:this.historyDb});this.workClient=r,this.log("info","INIT","Phase 2: WorkerClient created");const c=1e3*Math.max(0,this.options.idleTimeoutSecond??0);this.coordinator=this.createMessageCoordinator(r,c),this.log("info","INIT","Phase 3: Coordinator created"),await r.connect(),r.sendWorkerInitializing(),this.log("info","INIT","Phase 4: Connected to server"),this.log("info","INIT","Phase 5: Skipped (no AgentContext for Codex)"),this.log("info","INIT","Phase 6: Skipped (no custom resources for Codex)");const l=new gc({options:a,handlers:this.createWorkspaceHandlers(r,s)}),{initialCommitHash:p,gitStateResult:d,setupAction:u}=await l.setup();this.workspace=l,this.projectAgentrixGuidance=await Pc(s),this.log("info","INIT","Phase 7: Workspace setup complete"),r.sendWorkerInitialized(),r.sendTaskSlashCommandsUpdate(Sc()),this.log("info","INIT","Phase 8: Initialization finalized"),await this.registerWithDaemon(s),this.log("info","INIT","Phase 9: Registered with daemon"),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${u} at ${s} (${p||"none"})`),this.context={credentials:this.credentials,options:this.options,workClient:r,workingDirectory:s,initialCommitHash:p,logger:this.logger},process.env.AGENTRIX_WORKING_DIR=s,process.env.AGENTRIX_WORKING_USER=t,process.env.AGENTRIX_WORKING_TASK=e,this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.OPENAI_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.CODEX_API_KEY=this.options.input.api_key),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,this.log("info","AGENT",`Resuming thread: ${this.threadId}`))}createWorkspaceHandlers(e,t){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await Ht(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new Xr({workerType:"codex",workClient:e,handlers:{onNormalMessage:async e=>this.convertSDKMessageToCodexInput(e),onBashCommand:async(e,t)=>{await this.executeBashCommand(e)},onMergeRequest:async e=>{await this.executeMergeRequest()},onMergePr:async()=>{await this.executeMergePr()},onNewSession:async()=>{await this.executeNewSession()}},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){if("task-message"===this.options.input.event){const{eventId:e,message:t}=this.options.input.eventData;t&&Z(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e&&this.workClient?.sendEventAck(e))}}async executeMergeRequest(){this.refreshGroupId(),this.log("info","MERGE","Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await ya(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await va(this.context.workingDirectory),t=this.context.initialCommitHash,n=await _a(this.context.workingDirectory);if(this.log("info","MERGE",`Pushing branch ${n} to remote`),await Hr(this.context.workingDirectory,n,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","Successfully pushed branch to remote"),!t){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await ka(this.context.workingDirectory,t,e)).files.length){const e="No changes to create PR: no files changed since task started";return void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}const s=Fr(t);this.log("debug","MERGE",`PR prompt: ${s.substring(0,200)}...`);const a=this.options.input.agentId??"default",i=await mc.create("codex",a),o={mode:"work",supportChangeTitle:!1},r=i.runStreamed(s,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,abortController:this.abortController,modeConfig:o,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:vc}});let c=null;for await(const e of r){if(this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){c=e;break}const t=this.filterMessages(e);null!==t&&this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}if(!c)throw new Error("Merge-request did not return a result message");const l=xc(c);await this.createPullRequest(l.title,l.description),this.sendMessage(l.userMessage)}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){this.log("info","WORKER",`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!fe.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.context.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t=await Vr(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await Yr({workingDirectory:this.context.workingDirectory,workClient:this.context.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.context.logger,allowInteractive:!this.isOneShotExecution(),askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(e){const t=this.options.input.agentId??"default",n=await mc.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");this.log("info","MERGE","Generating commit message with agent"),await Cc({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},schemaTarget:"openai",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.filterMessages(e);null!==t&&this.getActiveWorkClient().sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return Ac(this.options.input.outputSchema)}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}async resolveCodexAgentrixEventMcp(){if(!this.supportChangeTitle)return null;const e=await fe.readDaemonState();if(!e?.port)return this.log("debug","MCP","Agentrix event MCP broker unavailable: daemon state not found"),null;const t=function(e,t){const n={taskId:t.taskId,userId:t.userId,machineId:t.machineId??e.machineId,nonce:ce(16).toString("base64url")},s=(a=JSON.stringify(n),Buffer.from(a,"utf8").toString("base64url"));var a;return`${s}.${Bi(s,Gi(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId});return{serverName:Wi,url:qt(e,zi),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:Ki,token:t}}buildCodexRunEnvironment(){if(this.codexAgentrixEventMcp)return{...process.env,[this.codexAgentrixEventMcp.tokenEnvVar]:this.codexAgentrixEventMcp.token}}async runCodex(){this.log("info","AGENT",`Starting Codex agent for task ${this.taskId}`),this.currentModel=lc(this.options.input.model),this.currentModel?this.log("info","AGENT",`Using model: ${this.currentModel}`):this.log("info","AGENT","Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await mc.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void this.log("info","AGENT",`Skipping Codex run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runCodexOneShot(t,n);const s=t.loop({cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(e)this.refreshGroupId(),this.updateAgentRunning(!0),s.push(e);else if(this.isStopping)break}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.log("info","AGENT",`Codex agent finished for task ${this.taskId}`)}async runCodexOneShot(e,t){const n=await this.coordinator.waitForAgentMessage();if(!n)return this.isStopping||this.stopTask("oneshot_complete"),void this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId();const s=e.runStreamed(n,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:t,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.isStopping||this.stopTask("oneshot_complete")}finally{this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e){if("system"===e.type&&"init"===e.subtype)return this.threadId=e.session_id,this.context.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.context.workClient.sendTaskSlashCommandsUpdate(Sc(e.slash_commands??[]),e.session_id),this.log("info","AGENT",`Thread started: ${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);null!==t&&("result"===e.type?await this.handleSdkResultMessage(t):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"!==e.type?this.updateAgentRunning(!0):this.updateAgentRunning(!1)}filterMessages(e){const t=e,n=t?.message?.content;if(!n||"string"==typeof n)return e;const s=n.filter(e=>{return"tool_use"!==e.type||"agentrix"!==(n=e.server_name)&&n!==Wi?!("tool_result"===e.type&&this.filteredToolUseIds.has(e.tool_use_id)||"user"===t.type&&"tool_result"!==e.type):(this.filteredToolUseIds.add(e.id),!1);var n});return 0===s.length?null:(t.message.content=s,t)}sendMessage(e){const t={type:"assistant",message:{id:le().toString(),type:"message",container:null,role:"assistant",content:[{citations:null,type:"text",text:e}],model:this.currentModel||"",usage:{},stop_reason:null,context_management:null,stop_sequence:null},parent_tool_use_id:null,session_id:"",uuid:le().toString()};this.getActiveWorkClient().sendTaskMessage(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.getActiveWorkClient();return Zr(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>this.sendMessage(e),stopTask:e=>this.stopTask(e)},t)}getActiveWorkClient(){const e=this.context?.workClient??this.workClient;if(!e)throw new Error("[WORKER] WorkerClient not available");return e}resolveTaskAgentName(e){const t=this.options.input.taskAgents??[];return t.find(t=>t.id===e)?.name||""}getChatSenderMeta(){const e=this.options.input.agentId;return{senderType:"agent",senderId:e,senderName:this.resolveTaskAgentName(e)??""}}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t){this.log("info","MERGE",`Creating PR: ${e}`);try{const n=await this.context.workClient.sendMergeRequest(e,t);this.sendMessage(`✅ Pull request created successfully!\nNumber: #${n.pullRequestNumber}\nURL: ${n.pullRequestUrl}`)}catch(e){this.log("error","MERGE","Failed to create PR:",e),this.sendMessage(`❌ Failed to create pull request: ${e instanceof Error?e.message:"Unknown error"}`)}}async convertSDKMessageToCodexInput(e){const t=e.message.content;if("string"==typeof t)return t;if(Array.isArray(t)){const e=[],n=fe.resolveAttachmentsDir(this.options.input.userId,this.taskId);for(const s of t)if("text"===s.type&&s.text)e.push(s.text);else if("image"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:s}=await po(t,n,!1);this.log("info","IMAGE",`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){this.log("error","IMAGE",`Failed to download image from ${t}:`,e)}}else if("document"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:a,mimeType:i,filename:o}=await po(t,n,!0);this.log("info","DOCUMENT",`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){this.log("error","DOCUMENT",`Failed to download document from ${t}:`,e)}}const s=e.map(e=>e.trim()).filter(Boolean).join("\n\n").trim();if(s)return s}return""}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}updateAgentRunning(e){this.coordinator?.updateAgentRunning(e)}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.options.input.taskAgents?.find(e=>e.id===s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:fe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(this.credentials.token,this.credentials.machineId,t),dataEncryptionKey:this.dataEncryptionKey,keepAliveConfig:{intervalMs:2e4,event:"worker-alive",payloadGenerator:()=>{const e=this.coordinator?.getStatus(),n="running"===e?.state?"worker-running":"worker-ready";return{eventId:G(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>(this.context?.logger??this.logger)?.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:fe.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(Q(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}Z(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{Qr(e,this.options.input)},onWorkerStatusRequest:async()=>{if(!this.context?.workClient)return;if(!this.coordinator)return;const{state:e}=this.coordinator.getStatus();"running"===e?this.context.workClient.sendWorkRunning():"idle"===e&&this.context.workClient.sendWorkerReady()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`);const n=this.context?.workClient??this.workClient;n&&("error"===e&&t?await n.sendErrorMessageAndExit(t):(n.sendWorkerExit(e),await n.disconnect()),this.historyDb&&this.historyDb.close())}createLogger(e){const{createLogger:t}=Uc;return t(e)}log(e,t,n,...s){const a=this.context?.logger??this.logger;a&&a[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}getCurrentModel(){return this.currentModel||"unknown"}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}if(this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0}),n)try{await Br(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}}}function Lc(){const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(!e)return;if(e.includes("/")||e.includes("\\")||e.startsWith(".")){const t=I.isAbsolute(e)?e:I.resolve(e);return o.existsSync(t)?t:void 0}const t="win32"===process.platform?"where":"which",n=nt(t,[e],{encoding:"utf-8"});return 0===n.status?n.stdout.split(/\r?\n/).map(e=>e.trim()).find(e=>e.length>0):void 0}function Hc(e){const t=e.map(e=>e.toLowerCase().trim().replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")).filter(Boolean);return[...new Set(t)].slice(0,8)}function Gc(e,t=""){const n=o.readdirSync(e,{withFileTypes:!0}),s=[];for(const a of n){const n=t?`${t}/${a.name}`:a.name;"node_modules"!==a.name&&".git"!==a.name&&(a.isDirectory()?s.push(...Gc(I.join(e,a.name),n)):s.push(n))}return s}async function Bc(e,t,n){const s=Gc(e).map(e=>` - ${e}`).join("\n");return new Promise((a,i)=>{let o=!1,r=null;const c=e=>{o||(o=!0,clearTimeout(p),a(e))},l=e=>{o||(o=!0,clearTimeout(p),i(e))},p=setTimeout(()=>{c({approved:!1,reasons:["Review timed out after 10 minutes"],tags:[]})},6e5),d=(u=e=>{r=e,c(e)},ct("hive_publish_review","Submit your security review decision for this Hive publish request. You MUST call this tool exactly once after reviewing all source files.",{approved:Qe.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:Qe.array(Qe.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:Qe.array(Qe.string()).describe("3-8 concise marketplace discovery tags describing the agent or skill capability. Use lowercase kebab-case.")},async e=>(u({approved:e.approved,reasons:e.reasons,tags:Hc(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=ot({name:"hive_review",version:"1.0.0",tools:[d]}),h=[`Review the ${n} "${t}" for security issues before publishing to Hive.`,"",`Source directory: ${e}`,"","Files to review:",s,"","Read each file, then call mcp__hive_review__hive_publish_review with your decision."].join("\n"),g=rt({prompt:h,options:{systemPrompt:'You are a security reviewer for the Agentrix Hive marketplace.\nYour job is to review agent/skill source code before it is published to the public repository.\n\nYou MUST check for real publish-blocking security issues:\n1. **Hardcoded secrets**: API keys, tokens, passwords, private keys, credentials in any file\n2. **PII exposure**: emails, phone numbers, physical addresses, names of real people that appear to be user data or sensitive personal data\n3. **Data exfiltration**: suspicious network requests, unauthorized file uploads, sending user data to external servers\n4. **Malicious code**: eval/exec of untrusted input, shell injection, code that modifies files outside workspace\n5. **Dependency risks**: suspicious or known-malicious packages, typo-squatting package names\n6. **Permission abuse**: code or instructions that abuse permissions to access sensitive files, steal data, persist malware, or operate outside the intended agent/skill workflow\n\nAgentrix-specific review guidance:\n- Do NOT reject solely because an agent config uses permissionMode "bypassPermissions".\n- Do NOT reject solely because allowedTools includes Bash, WebFetch, Read, Write, Edit, or other normal Agentrix/Claude tools. These tools are part of the Agentrix runtime model.\n- Reject permission usage only when the source contains malicious or clearly unsafe behavior, such as reading secrets from home directories, scanning unrelated user files, silently uploading data, destructive shell commands, persistence, credential theft, or instructions to bypass user intent.\n- Generated/local build metadata such as avatar/upload-avatar.json may contain local file paths or localhost URLs from the creator\'s machine. Treat these as cleanup suggestions, not publish-blocking security issues, unless they contain secrets or sensitive personal data beyond ordinary development paths.\n- Ordinary repository paths, localhost URLs, sample usernames in paths, generated artifact paths, and non-secret build cache metadata are not enough to reject a publish request.\n- If you find non-blocking cleanup suggestions, include them in reasons while still approving.\n\nProcess:\n1. Read EVERY source file in the directory using the Read tool\n2. Analyze each file for the issues listed above\n3. Assign marketplace discovery tags for the source. Tags should describe what the agent/skill does, its domain, and useful capability filters.\n4. Call mcp__hive_review__hive_publish_review with your decision and tags.\n\nTag rules:\n- Provide 3-8 tags.\n- Use lowercase kebab-case, for example: web-design, code-review, react, testing, documentation.\n- Prefer functional/domain tags over generic labels.\n\nBe strict about real security issues, but do not reject normal Agentrix runtime configuration or harmless generated local metadata. Approve when there is no credible exploit, secret, malicious behavior, or sensitive user-data exposure.',permissionMode:"bypassPermissions",settingSources:["user","project","local"],maxTurns:30,cwd:e,mcpServers:{hive_review:m},pathToClaudeCodeExecutable:Lc(),stderr:e=>{const t=String(e).trim();t&&console.error(`[HiveReview] Claude stderr: ${t}`)}}});(async()=>{try{for await(const e of g)if("result"===e.type&&e.is_error&&!r){const t=e.result;return void l(new Error(`Claude security review failed: ${t||"unknown Claude Code error"}`))}r||l(new Error("Claude security review finished without submitting a review decision"))}catch(e){l(e)}})()})}const Fc=pt(it);function Wc(e,t,n){const s=fe.serverUrl.replace(/^http/,"ws");return Ne(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function zc(e,...t){const{stdout:n}=await Fc("git",t,{cwd:e});return n.trim()}function Kc(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const Vc=pt(it);function Xc(e,t,n){const s=fe.serverUrl.replace(/^http/,"ws");return Ne(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const Jc=["claude","codex","deployment","companion","hive-publish","hive-install"],Yc={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=fe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const n=Dr(t.input),s=await jc.calculateFinalCwd(n),a=new Oc(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=fe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const n=new qc(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:fe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,sourcePath:a,targetAgentId:i,userId:r,name:c,avatar:l,isSystemAgent:p,supportLocal:d}=n;let u=null;try{if(console.log(`[Deployment] Starting deployment worker for task ${s}`),!o.existsSync(a))throw new Error(`Source path not found: ${a}`);const t=I.join(fe.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await $c(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=fe.serverUrl.replace(/^http/,"ws");return Ne(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}(e,0,s),await new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("WebSocket connection timeout"))},1e4);u.on("connect",()=>{clearTimeout(n),console.log("[Deployment] Connected to server"),u.emit("deploy-agent-complete",{eventId:G(),taskId:s,targetAgentId:i,success:!0,name:c,avatar:l,isSystemAgent:p,supportLocal:d}),console.log("[Deployment] Sent deploy-agent-complete event"),setTimeout(()=>{e()},1e3)}),u.on("connect_error",e=>{clearTimeout(n),t(e)})})}catch(e){throw console.error("[Deployment] Deployment failed:",e),u&&u.connected&&(u.emit("deploy-agent-complete",{eventId:G(),taskId:s,targetAgentId:i,success:!1,error:e instanceof Error?e.message:String(e)}),await new Promise(e=>setTimeout(e,1e3))),e}finally{u&&u.disconnect(),process.exit(0)}}(e,i)}},"hive-publish":{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:fe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,listingId:a,userId:i,sourceDir:r,gitUrl:c,version:l}=n;let p,d,{repoDir:u,name:m}=n,h=n.displayName,g=n.description,f=n.readme,y=null,v=null;try{if(n.environmentVariables)for(const[e,t]of Object.entries(n.environmentVariables))null!=t&&(process.env[e]=String(t));if(console.log(`[HivePublish] Starting for task ${s}, name=${m}`),function(e,t){if(!o.existsSync(e))throw new Error(`Source directory not found: ${e}`);if(!o.statSync(e).isDirectory())throw new Error(`Source path is not a directory: ${e}`);if("skill"===t&&!o.existsSync(I.join(e,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${e}`)}(r,n.type),"skill"===n.type){const e=function(e){const t=I.join(e,"SKILL.md"),n=o.readFileSync(t,"utf-8"),s=n.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);if(!s)throw new Error("SKILL.md must start with YAML frontmatter containing name and description");const a=s[1],i=new Map;for(const e of a.split(/\r?\n/)){const t=e.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);t&&i.set(t[1],t[2].replace(/^["']|["']$/g,"").trim())}const r=i.get("name"),c=i.get("description");if(!r)throw new Error("SKILL.md frontmatter must include name");if(!c)throw new Error("SKILL.md frontmatter must include description");return{name:Kc(r),displayName:r,description:c,readme:n,repoDirName:Kc(r)}}(r);m=e.name,h=e.displayName,g=e.description,f=e.readme,u=I.posix.join(u,e.repoDirName),console.log(`[HivePublish] Parsed skill metadata name=${m}, displayName=${h}`)}v=I.join(fe.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(v,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await zc(v,"clone","--depth","1",c,".");const t=I.join(v,u);if(o.mkdirSync(I.dirname(t),{recursive:!0}),"skill"===n.type&&o.existsSync(t))throw new Error(`Skill already exists in Hive repository: ${u}`);o.existsSync(t)&&o.rmSync(t,{recursive:!0,force:!0}),console.log(`[HivePublish] Copying ${r} → ${u}`),await $c(r,t),o.writeFileSync(I.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await zc(v,"add",".");const i=await async function(e){try{return await Fc("git",["diff","--cached","--quiet"],{cwd:e}),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}(v);if(i){console.log("[HivePublish] Running Claude security review...");const e=await Bc(r,m,n.type);if(p=e.reasons,d=e.tags,!e.approved)throw new Error(`Security review rejected: ${e.reasons.join("; ")}`);console.log("[HivePublish] Security review passed");const t=`publish: ${u} v${l}`;await zc(v,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await zc(v,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const x=await zc(v,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${x}`),y=Wc(e,0,s),await new Promise((e,t)=>{const n=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);y.on("connect",()=>{clearTimeout(n),y.emit("hive-publish-complete",{eventId:G(),taskId:s,listingId:a,success:!0,gitCommitHash:x,hasChanges:i,tags:d,name:m,displayName:h,description:g,readme:f,repoDir:u}),console.log("[HivePublish] Sent hive-publish-complete (success)"),setTimeout(e,1e3)}),y.on("connect_error",e=>{clearTimeout(n),t(e)})})}catch(t){console.error("[HivePublish] Failed:",t);try{y=y??Wc(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{y.emit("hive-publish-complete",{eventId:G(),taskId:s,listingId:a,success:!1,error:t instanceof Error?t.message:String(t),reviewReasons:p}),clearTimeout(n),setTimeout(e,1e3)};y.connected?i():(y.on("connect",i),y.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HivePublish] Failed to send error event")}throw t}finally{if(y&&y.disconnect(),v&&o.existsSync(v))try{o.rmSync(v,{recursive:!0,force:!0})}catch{}process.exit(0)}}(e,i)}},"hive-install":{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:fe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,userId:a,sourceRepoDir:i,gitUrl:r,name:c,sourceType:l}=n,p=n.installDir??n.draftAgentDir;let d=null,u=null;try{console.log(`[HiveInstall] Starting for task ${s}, name=${c}`),u=I.join(fe.agentrixHomeDir,"tmp","hive-install",s),o.mkdirSync(u,{recursive:!0}),console.log("[HiveInstall] Cloning hive repo..."),await async function(e,...t){const{stdout:n}=await Vc("git",t,{cwd:e});return n.trim()}(u,"clone","--depth","1",r,".");const t=I.join(u,i);if(!o.existsSync(t))throw new Error(`Source directory not found in hive repo: ${i}`);if("skill"===l&&!o.existsSync(I.join(t,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${i}`);const n=(m=p).startsWith("~/")?I.join(process.env.HOME||"",m.slice(2)):I.isAbsolute(m)?m:I.join(fe.agentrixHomeDir,m);if(o.existsSync(n))throw new Error(`Target install directory already exists: ${n}`);if(o.mkdirSync(n,{recursive:!0}),console.log(`[HiveInstall] Copying ${i} → ${n}`),await $c(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),_s(n)}catch(e){try{o.rmSync(n,{recursive:!0,force:!0})}catch{}throw e}const a=I.join(n,".git");o.existsSync(a)&&(o.rmSync(a,{recursive:!0,force:!0}),console.log("[HiveInstall] Removed .git from installed directory")),console.log("[HiveInstall] Install completed successfully"),d=Xc(e,0,s),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);d.on("connect",()=>{clearTimeout(a),d.emit("hive-install-complete",{eventId:G(),taskId:s,success:!0,agentDir:n}),console.log("[HiveInstall] Sent hive-install-complete (success)"),setTimeout(e,1e3)}),d.on("connect_error",e=>{clearTimeout(a),t(e)})})}catch(t){console.error("[HiveInstall] Failed:",t);try{d=d??Xc(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{d.emit("hive-install-complete",{eventId:G(),taskId:s,success:!1,error:t instanceof Error?t.message:String(t)}),clearTimeout(n),setTimeout(e,1e3)};d.connected?a():(d.on("connect",a),d.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HiveInstall] Failed to send error event")}throw t}finally{if(d&&d.disconnect(),u&&o.existsSync(u))try{o.rmSync(u,{recursive:!0,force:!0})}catch{}process.exit(0)}var m}(e,i)}},companion:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=fe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const{agentDir:n,homeDir:s}=await Va();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=Dr(t.input),i=await jc.calculateFinalCwd(a),o=new Oc(e,t,i);await o.start()}(e,r)}}};async function Qc(){const e=function(){try{const e=Me(ve(),"package.json"),t=JSON.parse(Ee(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}();try{const t=Ke("npm view @agentrix/cli version",{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:5e3}).trim();return{hasUpgrade:function(e,t){const n=e.split(".").map(Number),s=t.split(".").map(Number);for(let e=0;e<Math.max(n.length,s.length);e++){const t=n[e]||0,a=s[e]||0;if(t>a)return 1;if(t<a)return-1}return 0}(t,e)>0,currentVersion:e,latestVersion:t}}catch(t){return{hasUpgrade:!1,currentVersion:e,latestVersion:null}}}function Zc(){return"true"===process.env.AGENTRIX_DISABLE_AUTO_UPGRADE}async function el(e){try{const{execSync:t}=await import("child_process");return console.log(""),e||(console.log(D.blue("🔄 Checking for upgrades...")),e=await Qc()),e.hasUpgrade?(console.log(D.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`)),t("npm install -g @agentrix/cli@latest",{stdio:"inherit"}),console.log(D.green("✓ Upgrade complete")),console.log(""),!0):(console.log(D.green("✓ Already on latest version")),console.log(""),!0)}catch(e){return console.log(""),console.log(D.yellow("⚠️ Auto-upgrade failed")),console.log(D.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}async function tl(e,t){const n=`${fe.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function nl(e){try{const t=c(S(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function sl(e,t){const n=e=>e.split(".").map(e=>parseInt(e,10)||0),s=n(e),a=n(t);for(let e=0;e<Math.max(s.length,a.length);e++){const t=s[e]??0,n=a[e]??0;if(t>n)return!0;if(t<n)return!1}return!1}async function al(e){const t=fe.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>d(S(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=S(t,s),a=S(n,"upgrade");if(r(a))continue;const i=nl(n);ye.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await tl(s,e);if(!t||!t.gitUrl){ye.info(`[AGENT UPDATE] No git repo for ${s}, skipping`);continue}const n=`${a}.tmp-${Date.now()}`;try{const e=["git","clone","--depth=1","--branch",t.branch,t.gitUrl,n];at(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?S(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=nl(o);if(!c||i&&!sl(c,i)){ye.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}ye.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),ye.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){ye.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}function il(){const e=fe.getStatePaths();return $e.join($e.dirname(e.daemonStateFile),"upgrade-daemon.state.json")}function ol(){try{const e=il();if(!Te.existsSync(e))return null;const t=Te.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function rl(e){try{const t=il();if(Te.existsSync(t)){if("number"==typeof e){const t=ol();if(!t||t.pid!==e)return}Te.unlinkSync(t)}}catch{}}function cl(e){try{return process.kill(e,0),!0}catch{return!1}}function ll(){const e=ol();return!(!e||!cl(e.pid)&&(rl(),1))}function pl(){const e=ol();if(e)try{cl(e.pid)&&process.kill(e.pid,"SIGTERM")}catch{}finally{rl()}}async function dl(){if(Zc())return"no-upgrade";const e=await Qc();if(e.hasUpgrade&&await el(e))return await zt(),await new Promise(e=>setTimeout(e,1e3)),so(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),"upgraded";try{const e=await fe.readCredentials();e&&await al(e)}catch{}return"no-upgrade"}var ul=Object.freeze({__proto__:null,isUpgradeDaemonRunning:ll,startUpgradeDaemon:async function(){await async function(){!function(e){const t=il();Te.writeFileSync(t,JSON.stringify(e,null,2))}({pid:process.pid,startedAt:(new Date).toISOString()}),process.on("SIGTERM",()=>{rl(process.pid),process.exit(0)}),process.on("SIGINT",()=>{rl(process.pid),process.exit(0)});try{"upgraded"===await dl()&&(so(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}for(;;){await new Promise(e=>setTimeout(e,216e5));try{"upgraded"===await dl()&&(so(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}}}()},stopUpgradeDaemon:pl});function ml(e,t){const n=e.trim();if(!n)throw new Error(`${t} is required`);let s;try{s=new URL(n)}catch{throw new Error(`${t} must be a valid URL`)}if("http:"!==s.protocol&&"https:"!==s.protocol)throw new Error(`${t} must use http or https`);return s.toString().replace(/\/+$/,"")}async function hl(e,t){if(!Mt.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=Rt({input:Mt,output:Pt});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}async function gl(){const e=await xn();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}function fl(e){return"string"==typeof e&&e.trim()?e.trim():void 0}async function yl(e){const t=await gl(),n=ml(fl(e["base-url"])??await hl("GitLab base URL"),"baseUrl"),s=ml(fl(e["api-url"])??await hl("GitLab API URL",function(e){return`${ml(e,"baseUrl")}/api/v4`}(n)),"apiUrl"),a=(fl(e["pat-file"])?function(e){if("-"===e)return c(0,"utf8").trim();if(!r(e))throw new Error(`File not found: ${e}`);return c(e,"utf8").trim()}(fl(e["pat-file"])):void 0)??await async function(e){return Mt.isTTY&&Pt.isTTY&&"function"==typeof Mt.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{Mt.setRawMode(!1),Mt.pause(),Mt.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Pt.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Pt.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Pt.write(`${e}: `),Mt.setRawMode(!0),Mt.resume(),Mt.on("data",i)}):hl(e)}("GitLab PAT");if(!a)throw new Error("GitLab PAT is required");let i;const o=await async function(e,t){const{result:n,user:s}=await Ue(e,t);return{valid:n.valid,username:n.username,scopes:n.scopes,meta:n.valid&&s?{username:s.username,email:s.email||"",lastValidatedAt:(new Date).toISOString(),expiresAt:n.expiresAt}:void 0}}(s,a);if(!o.valid)throw new Error(`PAT validation failed for ${s}/user`);i=o.meta;const l=await async function(e){const t=await async function(e){return await Lt("/git-server/register",e)}({name:new URL(e.baseUrl).hostname,baseUrl:e.baseUrl,apiUrl:e.apiUrl});if(t.error||!t.gitServer)throw new Error(`Backend Git server registration failed: ${t.error||"Daemon did not return a registered Git server"}`);return{id:t.gitServer.id,baseUrl:t.gitServer.baseUrl,apiUrl:t.gitServer.apiUrl}}({baseUrl:n,apiUrl:s});var p,d;i&&(p=l.id,d=i,vn.savePatMeta(p,d)),function(e,t){vn.saveGitServerConfig(e,t)}(l.id,{baseUrl:l.baseUrl,apiUrl:l.apiUrl}),function(e,t,n){vn.savePat(e,t,n)}(l.id,a,t);const u=function(e,t){return vn.ensureGitLabWebhookSecret(e,t)}(l.id,t),m=await async function(e){return await Lt("/git-server/complete",{gitServerId:e})}(l.id);if(m.error||!m.success)throw new Error(`Backend Git server completion failed: ${m.error||"Daemon did not confirm completion"}`);console.log(JSON.stringify({id:l.id,type:"gitlab",baseUrl:l.baseUrl,apiUrl:l.apiUrl,webhookEndpointPath:Fe(l.id),webhookUrl:Be(l.id,await fe.readDaemonState()),backendRegistered:!0,patConfigured:!0,patMeta:kn(l.id),webhookSecret:u},null,2))}function vl(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function xl(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||fe.serverUrl}function wl(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return w(S(t,e),b.X_OK),!0}catch{return!1}})}function bl(e,t,n){return new Promise((s,a)=>{const i=st(e,t,{stdio:"inherit",shell:n?.shell||!1,env:process.env});i.on("error",a),i.on("close",t=>{0===t?s():a(new Error(`${e} exited with code ${t}`))})})}async function kl(e){try{return await gt(e),!0}catch{return!1}}function Il(e){return e.filter(e=>e.required&&!e.installed)}async function Sl(e,t){wl(e)?console.log(D.green(`✓ ${e} is installed`)):wl("npm")?(console.log(D.blue(`Installing ${e} with npm...`)),await bl("npm",["install","-g",t])):console.log(D.yellow(`npm is not available. Install ${t} manually.`))}async function Tl(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function El(e,t,n=!0){const s=n?"Y/n":"y/N",a=(await e.question(`${t} (${s}): `)).trim().toLowerCase();return a?"y"===a||"yes"===a:n}async function _l(e,t,n,s){for(console.log(t),n.forEach((e,t)=>{const n=e.value===s?" default":"";console.log(` ${t+1}. ${e.label}${n}`)});;){const t=(await e.question("Select: ")).trim();if(!t)return s;const a=Number.parseInt(t,10);if(!Number.isNaN(a)&&n[a-1])return n[a-1].value;const i=n.find(e=>e.value===t);if(i)return i.value;console.log(D.yellow("Invalid selection"))}}function Cl(e){return JSON.stringify(e)}async function Al(e,t){const n=await async function(e){try{return(await ge.get(`${fe.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||xl()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(D.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),xl()}}(t),s=Rt({input:Mt,output:Pt});try{await async function(e,t,n){const s=S(fe.claudeConfigDir,"settings.json");if(!t&&await kl(s)&&!await El(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(D.gray("Skipped Claude config"));const a=await _l(e,"Configure Claude provider",[{value:"agentrix",label:"Agentrix API"},{value:"official",label:"Anthropic official API"},{value:"proxy",label:"Custom Anthropic-compatible proxy"},{value:"skip",label:"Skip Claude config"}],"agentrix");if("skip"===a)return void console.log(D.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await Tl(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await Tl(e,"Agentrix API key for Claude");else{const t=await Tl(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await Tl(e,"Anthropic auth token")}const o=await Tl(e,"Claude primary model","claude-sonnet-4-6"),r=await Tl(e,"Claude fast model","claude-haiku-4-5"),c=await Tl(e,"Claude subagent model",o||"claude-sonnet-4-6");i.ANTHROPIC_MODEL=o,i.CLAUDE_CODE_SUBAGENT_MODEL=c,i.ANTHROPIC_SMALL_FAST_MODEL=r,i.ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-6",i.ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4-6",i.ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5",await ht(fe.claudeConfigDir,{recursive:!0}),await mt(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(D.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=S(fe.codexHomeDir,"config.toml");if(!t&&await kl(s)&&!await El(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(D.gray("Skipped Codex config"));const a=await _l(e,"Configure Codex provider",[{value:"agentrix",label:"Agentrix API"},{value:"openai",label:"OpenAI official API"},{value:"custom",label:"OpenAI-compatible custom API"},{value:"skip",label:"Skip Codex config"}],"agentrix");if("skip"===a)return void console.log(D.gray("Skipped Codex config"));const i=await Tl(e,"Codex model","gpt-5.5"),o=await _l(e,"Codex API wire format",[{value:"responses",label:"Responses API"},{value:"chat",label:"Chat Completions API"}],"agentrix"===a?"responses":"chat"),r={};let c,l;"agentrix"===a?(c=n,l="AGENTRIX_API_KEY",r[l]=await Tl(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await Tl(e,"OpenAI API key")):(c=await Tl(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await Tl(e,"Custom API key")),await ht(fe.codexHomeDir,{recursive:!0}),await mt(s,function(e){const t=e.provider,n=[`model = ${Cl(e.model)}`,`model_provider = ${Cl(t)}`,'approval_policy = "never"',"","[sandbox_workspace_write]","writable_roots = []","network_access = true","exclude_tmpdir_env_var = false","","[features]","hide_agent_reasoning = false","show_raw_agent_reasoning = false",'file_opener = "vscode"',"",`[model_providers.${t}]`,`name = ${Cl("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${Cl(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${Cl(s)}`)}return e.envKey&&n.push(`env_key = ${Cl(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=fe.readOrInitSettings({sandbox:fe.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};fe.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(D.green(`✓ Wrote Codex config: ${s}`)),console.log(D.green(`✓ Wrote Codex env vars to ${fe.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function $l(e={}){console.log(D.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=ts(),t=[...Il(e.cli.filter(e=>"claude"!==e.name)),...Il(e.sandbox)];"linux"!==process.platform||wl("rg")||t.push({name:"ripgrep",installed:!1,required:!0,description:"Fast code search tool",installCommand:"sudo apt install ripgrep"}),await async function(e){if(0===e.length)return void console.log(D.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(D.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(D.yellow(`- ${t.name}: ${t.installCommand||"install manually"}`));return}const t=[{name:"apt-get",installCommand:e=>["sudo","apt-get","update","&&","sudo","apt-get","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"dnf",installCommand:e=>["sudo","dnf","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"yum",installCommand:e=>["sudo","yum","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"pacman",installCommand:e=>["sudo","pacman","-S","--needed","--noconfirm",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}}].find(e=>wl(e.name))||null;if(!t){console.log(D.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(D.yellow(`- ${t.name}: ${t.installCommand||"install manually"}`));return}const n=e.map(e=>t.packageNames[e.name]).filter(e=>Boolean(e));if(0===n.length)return;console.log(D.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await bl(s.join(" "),[],{shell:!0}):await bl(s[0],s.slice(1))}(t),await Sl("claude","@anthropic-ai/claude-code@latest"),await Sl("codex","@openai/codex@latest");const n=ns();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await Jt();await Al(Boolean(e.force),t),e.skipDaemon||await async function(){if(await Ft())console.log(D.green("✓ Daemon is already running"));else{console.log(D.blue("Starting Agentrix daemon...")),so(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();for(let e=0;e<80;e++)if(await new Promise(e=>setTimeout(e,250)),await Bt())return void console.log(D.green("✓ Daemon started successfully"));console.log(D.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(D.green("\n✓ Agentrix CLI initialization complete"))}const Ml=R(N(process.argv)).scriptName("agentrix").version(xe.version).usage("$0 <command> [options]").option("debug",{alias:"d",type:"boolean",describe:"Use local-debug mode (plaintext, for debugging)",global:!0}).help("help").alias("h","help").alias("v","version").strict().epilog("For more information, visit https://github.com/xmz-ai/agentrix-cli");fe.getStatePaths,Ml.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(D.dim(`Current version: ${xe.version}`));const t=await Bt();await el()||process.exit(1);try{const e=await fe.readCredentials();e&&(console.log(D.dim("Checking agent updates...")),await al(e))}catch{}if(t){console.log(D.blue("Restarting daemon...")),await zt(),await new Promise(e=>setTimeout(e,1e3)),so(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await Bt()){e=!0;break}e?console.log(D.green("✓ Daemon restarted successfully")):console.log(D.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check."))}try{const{version:e}=await import("./logger-Dq-ORk-l.mjs").then(function(e){return e._});console.log(D.green(`\n✓ Now running version: ${e}`))}catch{console.log(D.dim("\nRun 'agentrix --version' to see the new version"))}process.exit(0)}),Ml.command("doctor","System diagnostics & troubleshooting",{},async e=>{await as(),process.exit(0)}),Ml.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await fe.readCredentials())return void console.log(D.yellow("Not currently authenticated"));console.log(D.blue("This will log you out of Agentrix")),console.log(D.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=Ie({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(D.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await zt(),console.log(D.gray("Stopped daemon"))}catch{}await fe.clearCredentials(),console.log(D.gray("Removed credentials")),console.log(D.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(D.blue("Logout cancelled"))}()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),Ml.command("stop","Stop the daemon",{},async e=>{pl(),await zt(),process.exit(0)}),Ml.command("status","Show daemon and authentication status",{},async e=>{await as("daemon"),console.log(""),await async function(){const e=await fe.readCredentials();if(console.log(D.bold("\nAuthentication Status\n")),!e)return void console.log(D.red("✗ Not authenticated"));console.log(D.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(D.gray(` Token: ${t}`)),e.machineId?(console.log(D.green("✓ Machine registered")),console.log(D.gray(` Machine ID: ${e.machineId}`)),console.log(D.gray(` Host: ${n.hostname()}`))):console.log(D.yellow("⚠️ Machine not registered")),console.log(D.gray(`\n Data directory: ${fe.agentrixHomeDir}`));try{await Bt()?console.log(D.green("✓ Daemon running")):console.log(D.gray("✗ Daemon not running"))}catch{console.log(D.gray("✗ Daemon not running"))}}(),process.exit(0)}),Ml.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await Lt("/list")).children||[]}();0===e.length?console.log("No active sessions"):(console.log("Active sessions:"),console.log(JSON.stringify(e,null,2)))}catch(e){console.log("No daemon running")}process.exit(0)}),Ml.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await Zn()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===e.type||"upgrade-daemon"===e.type)).map(e=>({pid:e.pid,command:e.command}))}(),t=[];let n=0;for(const{pid:s,command:a}of e)try{if(console.log(`Killing runaway process PID ${s}: ${a}`),"win32"===process.platform){const e=Xe.sync("taskkill",["/F","/PID",s.toString()],{stdio:"pipe"});if(e.error)throw e.error;if(0!==e.status)throw new Error(`taskkill exited with code ${e.status}`)}else process.kill(s,"SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),(await Ve()).find(e=>e.pid===s)&&(console.log(`Process PID ${s} ignored SIGTERM, using SIGKILL`),process.kill(s,"SIGKILL"));console.log(`Successfully killed runaway process PID ${s}`),n++}catch(e){const n=e.message;t.push({pid:s,error:n}),console.log(`Failed to kill process PID ${s}: ${n}`)}return{killed:n,errors:t}}();console.log(`Cleaned up ${e.killed} runaway processes`),e.errors.length>0&&console.log("Errors:",e.errors),process.exit(0)}),function(e){e.command("git-server","Manage local private GitLab server config",e=>e.command("add","Add a private GitLab server to local daemon config",e=>e.option("base-url",{type:"string",describe:"GitLab base URL, for example https://gitlab.example.com"}).option("api-url",{type:"string",describe:"GitLab API URL, defaults to <base-url>/api/v4"}).option("pat-file",{type:"string",nargs:1,describe:"Read GitLab PAT from a file, or - for stdin"}),async e=>{try{await yl(e),process.exit(0)}catch(e){vl(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await gl(),t=await fe.readDaemonState(),n=await async function(){return await Lt("/git-server/list")}();if(n.error)throw new Error(`Backend Git server list failed: ${n.error}`);const s=(n.gitServers??[]).filter(e=>"gitlab"===e.type&&"local_pat"===e.authModeDefault).map(n=>function(e,t,n){const s=wn(e.id)??{},a=bn(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:Fe(e.id),webhookUrl:Be(e.id,n),patConfigured:(i=e.id,vn.hasPat(i)),patMeta:kn(e.id),webhookSecret:a.webhookSecret,projectTriggerTokens:a.projectTriggerTokens??{}};var i}(n,e,t));console.log(JSON.stringify(s,null,2))}(),process.exit(0)}catch(e){vl(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(Ml),function(e){e.command("init","Initialize CLI dependencies, authentication, and LLM config",e=>e.option("skip-deps",{type:"boolean",default:!1,describe:"Skip dependency installation"}).option("skip-daemon",{type:"boolean",default:!1,describe:"Do not start the daemon after initialization"}).option("force",{type:"boolean",default:!1,describe:"Overwrite existing Claude/Codex config files without prompting"}),async e=>{try{await $l({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(Ml),Ml.command("kill <sessionId>","Stop a specific session",e=>e.positional("sessionId",{type:"string",describe:"Session ID to stop"}),async e=>{try{const t=await async function(e){return(await Lt("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?D.green("✓ Session stopped"):D.red("Failed to stop session"))}catch(e){console.log(D.red("No daemon running"))}process.exit(0)}),Ml.command("daemon",!1,{},async e=>{try{await Jt()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await Ho(),process.exit(0)}),Ml.command("worker",!1,e=>e.option("type",{type:"string",choices:Jc,demandOption:!0,describe:"Worker type to start"}).option("started-by",{type:"string",choices:["daemon","terminal"],describe:"How the session was started"}).option("user-id",{type:"string",demandOption:!0,describe:"User ID for the worker"}).option("task-id",{type:"string",demandOption:!0,describe:"Task ID for the worker"}).option("idle-timeout",{type:"number",default:300,describe:"Idle timeout in seconds"}),async e=>{try{const t=e.type,n=Yc[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=await Jt(),i=e["user-id"],o=e["task-id"],r=e["idle-timeout"];await n.run({credentials:a,startedBy:s,userId:i,taskId:o,idleTimeoutSecond:r})}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),Ml.command("upgrade-daemon",!1,{},async e=>{const{startUpgradeDaemon:t}=await Promise.resolve().then(function(){return ul});await t(),process.exit(0)}),Ml.command("start","Start daemon (if not running) and show status",{},async e=>{try{await Jt()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=ns();if(t.ok||(console.log(D.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(D.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(D.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await Ft()){console.log("Starting Agentrix background service..."),so(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await Bt()){e=!0;break}e?(await new Promise(e=>setTimeout(e,1200)),await Bt()?console.log(D.green("✓ Daemon started successfully")):await async function(){const e=await async function(){const e=S(fe.getStatePaths().logsDir,"daemon.log");try{return(await ut(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(D.red("✗ Daemon exited shortly after startup")),!e)return;const t=e.split("\n").reverse().find(e=>e.includes("Machine binding revoked")||e.includes("Run `agentrix logout` and bind again"));t?console.log(D.yellow(t)):(console.log(D.gray("Recent daemon log:")),console.log(e))}()):console.log(D.yellow("⚠️ Daemon may still be starting..."))}if(Zc()){const e=await Qc();e.hasUpgrade&&(n=e).hasUpgrade&&n.latestVersion&&(console.log(""),console.log(D.yellow("┌────────────────────────────────────────────────────┐")),console.log(D.yellow("│")+" "+D.bold("Upgrade Available")+" "+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+` Current: ${D.dim(n.currentVersion)} → Latest: ${D.green.bold(n.latestVersion)} `+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+" Run "+D.cyan.bold("agentrix upgrade")+" to upgrade "+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+" To enable auto-upgrade, set: "+D.yellow("│")),console.log(D.yellow("│")+" "+D.dim("AGENTRIX_DISABLE_AUTO_UPGRADE=false")+" "+D.yellow("│")),console.log(D.yellow("└────────────────────────────────────────────────────┘")),console.log(""))}else ll()||so(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();var n;await as("daemon"),process.exit(0)}),Ml.demandCommand(1,"Please specify a command. Use --help to see available commands.").parse();
|
|
1
|
+
import{createRequire as e}from"node:module";const t=e(import.meta.url);import n,{tmpdir as s,homedir as a}from"node:os";import*as i from"node:fs";import o,{existsSync as r,readFileSync as c,createWriteStream as l,mkdirSync as p,statSync as d,writeFileSync as u,renameSync as m,rmSync as h,readdirSync as g,unlinkSync as f,cpSync as v,createReadStream as y,promises as x,accessSync as w,constants as b}from"node:fs";import*as k from"node:path";import I,{join as T,basename as S,extname as E,resolve as A,sep as C,dirname as _,relative as $,isAbsolute as P,normalize as M}from"node:path";import R from"yargs";import{hideBin as N}from"yargs/helpers";import D from"chalk";import{encodeBase64 as O,createKeyPairWithUit8Array as U,encryptMachineEncryptionKey as j,generateAESKey as q,decodeBase64 as L,decryptWithEphemeralKey as H,createEventId as G,encryptFileContent as B,splitRtcChunkFrame as F,RtcChunkFlags as W,buildRtcChunkFrame as z,decodeGitPath as K,workerAuth as V,UpdateTaskPreviewUrlRequestSchema as X,AGENTRIX_DEV_INIT_FEATURE as J,decryptSdkMessage as Y,isSDKUserMessage as Q,isAskUserMessage as Z,isAskUserResponseMessage as ee,isSDKMessage as te,encryptSdkMessage as ne,machineAuth as se,getAgentContext as ae,detectPreview as ie,IGNORED_DIRECTORIES as oe,DEFAULT_WORKER_EXECUTION_MODE as re,getTaskExecutionMode as ce,isCompanionHeartbeatMessage as le,isCompanionReminderMessage as pe}from"@agentrix/shared";import{randomBytes as de,randomUUID as ue,createHash as me,createDecipheriv as he,createCipheriv as ge,createHmac as fe,timingSafeEqual as ve}from"node:crypto";import ye from"axios";import{m as xe,l as we,p as be,a as ke,c as Ie,g as Te,b as Se}from"./logger-DnKC_QlD.mjs";import{createInterface as Ee}from"node:readline";import*as Ae from"fs";import Ce,{readFileSync as _e,existsSync as $e,promises as Pe}from"fs";import*as Me from"path";import Re,{join as Ne,dirname as De}from"path";import Oe from"open";import{io as Ue}from"socket.io-client";import{EventEmitter as je}from"node:events";import{pipeline as qe}from"node:stream/promises";import{GitServerLocalStore as Le,validateGitLabPatToken as He,deriveLocalGitServerEncryptionKey as Ge,replacePromptPlaceholders as Be,loadAgentConfig as Fe,getAgentContext as We,buildGitLabWebhookUrl as ze,buildGitLabWebhookEndpointPath as Ke}from"@agentrix/shared/node";import{createRequire as Ve}from"node:module";import{spawn as Xe,execSync as Je}from"child_process";import Ye from"ps-list";import Qe from"cross-spawn";import{getPlatform as Ze}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import et from"fastify";import{z as tt,toJSONSchema as nt}from"zod";import{validatorCompiler as st,serializerCompiler as at}from"fastify-type-provider-zod";import{spawnSync as it,spawn as ot,execSync as rt,execFile as ct,execFileSync as lt}from"node:child_process";import{createSdkMcpServer as pt,query as dt,tool as ut,AbortError as mt}from"@anthropic-ai/claude-agent-sdk";import{promisify as ht}from"node:util";import gt from"simple-git";import{readFile as ft,writeFile as vt,mkdir as yt,access as xt}from"node:fs/promises";import{McpServer as wt}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as bt}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{EventEmitter as kt}from"events";import It from"better-sqlite3";import{fileURLToPath as Tt,pathToFileURL as St}from"url";import{randomUUID as Et}from"crypto";import{isSupportedPlatform as At,NetworkManager as Ct,SandboxManager as _t}from"@xmz-ai/sandbox-runtime";import{Cron as $t}from"croner";import*as Pt from"@larksuiteoapi/node-sdk";import{readFile as Mt,stat as Rt}from"fs/promises";import{Codex as Nt}from"@openai/codex-sdk";import{stdin as Dt,stdout as Ot}from"node:process";import{createInterface as Ut}from"node:readline/promises";import"winston";import"os";const jt=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function qt(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Lt(e,t,n){const s=t.toLowerCase();"http_proxy"===s?(e.HTTP_PROXY=n,e.http_proxy=n):"https_proxy"===s?(e.HTTPS_PROXY=n,e.https_proxy=n):"no_proxy"===s?(e.NO_PROXY=n,e.no_proxy=n):"all_proxy"===s?(e.ALL_PROXY=n,e.all_proxy=n):"global_agent_http_proxy"===s&&(e.GLOBAL_AGENT_HTTP_PROXY=n,e.global_agent_http_proxy=n)}function Ht(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=qt(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=qt(s)))}async function Gt(e){return new Promise(t=>setTimeout(t,e))}function Bt(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function Ft(e,t){const n=await xe.readDaemonState();if(!n?.port){const e="No daemon running, no state file found";return we.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=Bt(n,e),i=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t||{}),signal:AbortSignal.timeout(s)});if(!i.ok){const t=await i.json().catch(()=>null),n=("string"==typeof t?.error?t.error:"string"==typeof t?.message?t.message:void 0)||`Request failed: ${e}, HTTP ${i.status}`;return we.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${Bt(n,e)}, ${t instanceof Error?t.message:"Unknown error"}. Check that the Agentrix daemon is running and that ${n.host??"127.0.0.1"}:${n.port} is reachable.`;return we.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function Wt(e,t){return await Ft("/session-started",{sessionId:e,metadata:t})}async function zt(e,t,n){return await Ft("/devops-init-complete",{taskId:e,userId:t,action:n})}async function Kt(e,t){return await Ft("/devops-init-start",{taskId:e,userId:t})}async function Vt(e,t,n){const s="string"==typeof t?{content:t}:t;return await Ft("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function Xt(){const e=await xe.readDaemonState();if(!e)return!1;try{return process.kill(e.pid,0),!0}catch{return we.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await Yt(),!1}}async function Jt(){if(we.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await Xt())return we.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await xe.readDaemonState();if(!e)return we.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=Ne(be(),"package.json"),n=JSON.parse(_e(t,"utf-8")).version;return we.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return we.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function Yt(){try{await xe.clearDaemonState(),we.debug("[DAEMON RUN] Daemon state file removed")}catch(e){we.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function Qt(){try{const e=await xe.readDaemonState();if(!e)return void we.debug("No daemon state found");we.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await Ft("/stop")}(),void await async function(e){const t=Date.now();for(;Date.now()-t<2e3;)try{process.kill(e,0),await new Promise(e=>setTimeout(e,100))}catch{return}throw new Error("Process did not die within timeout")}(e.pid)}catch(e){we.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){we.debug("Error stopping daemon",e)}}function Zt(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function en(e,t){if(ye.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?Zt(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?Zt(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?Zt(e.message):e instanceof Error?`${t}: ${e.message}`:t}function tn(){return O(new Uint8Array(de(32)))}async function nn(){const e=await xe.readCredentials();if(e){if(await async function(e){try{await ye.get(`${xe.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})}catch(e){throw new Error(en(e,"Stored machine credentials are no longer valid"))}}(e),!e.secret){const t={...e,secret:tn()};return await xe.writeCredentials(t),we.info("[AUTH] Generated missing local auth secret"),t}return we.info("[AUTH] Using existing credentials"),e}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=xe.generateMachineId();n={token:t,secret:tn(),machineId:e},we.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=xe.generateMachineId(),t=new Uint8Array(de(32)),n=await U(t);try{console.log(`[AUTH] Sending auth request to: ${xe.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${O(n.publicKey).substring(0,20)}...`);const t={machineId:e};await ye.post(`${xe.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(en(e,"Failed to create authentication request, please try again later.")),{credentials:null,userPublicKey:null,keypair:n}}const s=await async function(e,t){console.clear(),console.log("\nWeb Authentication\n");const n=function(e,t){const n={key:O(e,"base64"),machineId:t},s=JSON.stringify(n),a=O((new TextEncoder).encode(s),"base64url");return`${xe.webappUrl}/terminal/connect?auth=${a}`}(e.publicKey,t);return console.log("Opening your browser..."),await async function(e){try{return!process.stdout.isTTY||process.env.CI||process.env.HEADLESS?(we.debug("[browser] Headless environment detected, skipping browser open"),!1):(we.debug(`[browser] Attempting to open URL: ${e}`),await Oe(e),we.debug("[browser] Browser opened successfully"),!0)}catch(e){return we.debug("[browser] Failed to open browser:",e),!1}}(n)?(console.log("✓ Browser opened\n"),console.log("Complete authentication in your browser window.")):console.log("Could not open browser automatically."),console.log("\nIf the browser did not open, please copy and paste this URL:"),console.log(n),console.log(""),await async function(e,t){process.stdout.write("Waiting for authentication");let n=0,s=!1;const a=()=>{s=!0,console.log("\n\nAuthentication cancelled."),process.exit(0)};process.on("SIGINT",a);try{for(;!s;){try{const n=await ye.get(`${xe.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=H(L(s),e.secretKey);return a?{token:t,userPublicKey:JSON.parse((new TextDecoder).decode(a)).publicKey}:(console.log("\n\nFailed to decrypt authentication data. Please try again."),{token:null,userPublicKey:null})}}catch(e){return console.log(`\n\n${en(e,"Failed to check authentication status. Please try again.")}`),{token:null,userPublicKey:null}}process.stdout.write("\rWaiting for authentication"+".".repeat(n%3+1)+" "),n++,await Gt(1e3)}}finally{process.off("SIGINT",a)}return{token:null,userPublicKey:null}}(e,t)}(n,e);return s.token?{credentials:{token:s.token,secret:O(t),machineId:e},userPublicKey:s?.userPublicKey,keypair:n}:{credentials:null,userPublicKey:null,keypair:n}}();if(!e.credentials||!e.userPublicKey)throw new Error("Authentication failed or was cancelled");n=e.credentials,s=e.keypair,a=e.userPublicKey}return await xe.writeCredentials(n),await async function(e,t,n,s){try{const a={id:e.machineId,metadata:JSON.stringify(t)};s&&n&&(a.dataEncryptionKey=j(s.publicKey,q(),L(n))),await ye.post(`${xe.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(en(e,"Failed to sync machine data"))}}(n,xe.metadata(),a,s),we.info("[AUTH] Machine setup completed"),n}!function(e=process.env){!function(e=process.env,t){if(!t?.variables)return e;const n=!0===t.enabled;for(const[s,a]of Object.entries(t.variables)){const t=s.trim();if(!t)continue;const i=String(a),o=jt.has(t);(n||o)&&(e[t]=i,Lt(e,t,i),Ht(e,t,i))}}(e,function(e=process.env){const t=T(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?qt(t):T(n.homedir(),".agentrix")}(e),"settings.json");if(!r(t))return null;try{const e=c(t,"utf-8"),n=JSON.parse(e);return n?.daemonEnv||null}catch{return null}}(e))}();class sn{interval=null;socket=null;config;constructor(e){this.config=e}start(e){this.interval&&this.stop(),this.socket=e,this.interval=setInterval(()=>{if(!this.socket)return void this.stop();const e=this.config.payloadGenerator?this.config.payloadGenerator():{};this.socket.emit(this.config.event,e)},this.config.intervalMs)}stop(){this.interval&&(clearInterval(this.interval),this.interval=null),this.socket=null}isRunning(){return null!==this.interval}}function an(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=[];return t.message&&n.push(t.message),t.type&&n.push(`type=${t.type}`),void 0!==t.description&&n.push(`description=${JSON.stringify(t.description)}`),void 0!==t.data&&n.push(`data=${JSON.stringify(t.data)}`),void 0!==t.context&&n.push(`context=${JSON.stringify(t.context)}`),n.filter(Boolean).join(" ")||"unknown socket error"}class on{socket=null;config;eventHandlers=new Map;eventEmitter=new je;KeepAliveManager=null;healthCheckInterval=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new sn(e.keepAliveConfig))}connect(){if(this.socket)return void this.log("Already connected or connecting");const{serverUrl:e,path:t,auth:n={},options:s={}}=this.config,a={path:t,auth:n,transports:["websocket"],reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:5e3,reconnectionAttempts:1/0,...s};this.socket=Ue(e,a),this.setupSocketHandlers(),this.log(`Connecting to ${e}`)}disconnect(){this.socket&&(this.log("Disconnecting"),this.stopHealthCheck(),this.socket.close(),this.socket=null)}get connected(){return this.socket?.connected??!1}replaceSocketHandler(e,t,n){this.socket&&(t&&this.socket.off(e,t),this.socket.on(e,n))}onEvent(e,t){const n=async n=>(this.log(`received event ${e}, data: ${JSON.stringify(n)}`),t(n)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}onEventWithAck(e,t){const n=async(n,s)=>(this.log(`received event with ack ${e}, data: ${JSON.stringify(n)}`),t(n,s)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}unregisterHandler(e){this.eventHandlers.delete(e),this.socket&&this.socket.off(e)}send(e,t){this.socket?(this.log(`send event ${e}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.log("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.log(`send event ${e}, data: ${JSON.stringify(t)}`),this.socket.emitWithAck(e,t)}sendVolatile(e,t){this.socket&&(void 0!==t?this.socket.volatile.emit(e,t):this.socket.volatile.emit(e))}async flush(e=1e4){if(this.connected)return new Promise(t=>{const n=setTimeout(()=>t(),e);this.socket.emit("ping",()=>{clearTimeout(n),t()})})}updateAuth(e){this.socket&&(this.socket.auth=e),this.config.auth=e}onLifecycle(e,t){this.eventEmitter.on(`lifecycle:${e}`,t)}offLifecycle(e){this.eventEmitter.removeAllListeners(`lifecycle:${e}`)}setupSocketHandlers(){this.socket&&(this.socket.on("connect",()=>{this.log("Connected"),this.eventEmitter.emit("lifecycle:connect",this.socket);for(const[e,t]of this.eventHandlers.entries())this.socket.off(e,t),this.socket.on(e,t);this.KeepAliveManager?.start(this.socket),this.startHealthCheck()}),this.socket.on("disconnect",e=>{this.log(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck()}),this.socket.on("connect_error",e=>{this.log(`Connection error: ${an(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.log(`Socket error: ${an(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}startHealthCheck(){const e=this.config.healthCheckConfig;if(!1===e?.enabled)return;const t=e?.intervalMs??3e4,n=e?.timeoutMs??5e3;this.stopHealthCheck(),this.healthCheckInterval=setInterval(()=>{if(!this.socket||!this.connected)return;const e=setTimeout(()=>{this.log("Health check timeout - forcing reconnect"),this.socket&&(this.socket.disconnect(),this.socket.connect())},n);this.socket.once("pong",()=>{clearTimeout(e)}),this.socket.emit("ping")},t)}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null)}log(e,...t){this.config.logger&&this.config.logger(`[SocketClient] ${e}`,...t)}}const rn="attachment",cn={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function ln(){const e=T(xe.agentrixHomeDir,"tmp","channel-files");return r(e)||p(e,{recursive:!0}),e}function pn(e){const t=function(e){if(!e)return;return S(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||rn;return T(ln(),`${ue()}-${t}`)}async function dn(e,t){if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);if(!e.body)throw new Error("Response body is null");const n=function(e,t){if(!e){const e=mn(t);return e?`${rn}${e}`:void 0}if(E(e))return e;const n=mn(t);return n?`${e}${n}`:e}(t||function(e){if(!e)return;const t=e.match(/filename\*=UTF-8''([^;]+)/i);if(t?.[1])return decodeURIComponent(t[1]);const n=e.match(/filename="?([^";]+)"?/i);return n?.[1]}(e.headers.get("content-disposition")),e.headers.get("content-type")),s=pn(n),a=l(s);return await qe(e.body,a),s}async function un(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=S(new URL(e).pathname);return E(t)?t:void 0}catch{return}}(e);return dn(s,t||a)}function mn(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?cn[t]:void 0}function hn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var n=function e(){var n=!1;try{n=this instanceof e}catch{}return n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}),n}var gn,fn,vn,yn={},xn={"application/1d-interleaved-parityfec":{source:"iana"},"application/3gpdash-qoe-report+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/3gpp-ims+xml":{source:"iana",compressible:!0},"application/3gpphal+json":{source:"iana",compressible:!0},"application/3gpphalforms+json":{source:"iana",compressible:!0},"application/a2l":{source:"iana"},"application/ace+cbor":{source:"iana"},"application/activemessage":{source:"iana"},"application/activity+json":{source:"iana",compressible:!0},"application/alto-costmap+json":{source:"iana",compressible:!0},"application/alto-costmapfilter+json":{source:"iana",compressible:!0},"application/alto-directory+json":{source:"iana",compressible:!0},"application/alto-endpointcost+json":{source:"iana",compressible:!0},"application/alto-endpointcostparams+json":{source:"iana",compressible:!0},"application/alto-endpointprop+json":{source:"iana",compressible:!0},"application/alto-endpointpropparams+json":{source:"iana",compressible:!0},"application/alto-error+json":{source:"iana",compressible:!0},"application/alto-networkmap+json":{source:"iana",compressible:!0},"application/alto-networkmapfilter+json":{source:"iana",compressible:!0},"application/alto-updatestreamcontrol+json":{source:"iana",compressible:!0},"application/alto-updatestreamparams+json":{source:"iana",compressible:!0},"application/aml":{source:"iana"},"application/andrew-inset":{source:"iana",extensions:["ez"]},"application/applefile":{source:"iana"},"application/applixware":{source:"apache",extensions:["aw"]},"application/at+jwt":{source:"iana"},"application/atf":{source:"iana"},"application/atfx":{source:"iana"},"application/atom+xml":{source:"iana",compressible:!0,extensions:["atom"]},"application/atomcat+xml":{source:"iana",compressible:!0,extensions:["atomcat"]},"application/atomdeleted+xml":{source:"iana",compressible:!0,extensions:["atomdeleted"]},"application/atomicmail":{source:"iana"},"application/atomsvc+xml":{source:"iana",compressible:!0,extensions:["atomsvc"]},"application/atsc-dwd+xml":{source:"iana",compressible:!0,extensions:["dwd"]},"application/atsc-dynamic-event-message":{source:"iana"},"application/atsc-held+xml":{source:"iana",compressible:!0,extensions:["held"]},"application/atsc-rdt+json":{source:"iana",compressible:!0},"application/atsc-rsat+xml":{source:"iana",compressible:!0,extensions:["rsat"]},"application/atxml":{source:"iana"},"application/auth-policy+xml":{source:"iana",compressible:!0},"application/bacnet-xdd+zip":{source:"iana",compressible:!1},"application/batch-smtp":{source:"iana"},"application/bdoc":{compressible:!1,extensions:["bdoc"]},"application/beep+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/calendar+json":{source:"iana",compressible:!0},"application/calendar+xml":{source:"iana",compressible:!0,extensions:["xcs"]},"application/call-completion":{source:"iana"},"application/cals-1840":{source:"iana"},"application/captive+json":{source:"iana",compressible:!0},"application/cbor":{source:"iana"},"application/cbor-seq":{source:"iana"},"application/cccex":{source:"iana"},"application/ccmp+xml":{source:"iana",compressible:!0},"application/ccxml+xml":{source:"iana",compressible:!0,extensions:["ccxml"]},"application/cdfx+xml":{source:"iana",compressible:!0,extensions:["cdfx"]},"application/cdmi-capability":{source:"iana",extensions:["cdmia"]},"application/cdmi-container":{source:"iana",extensions:["cdmic"]},"application/cdmi-domain":{source:"iana",extensions:["cdmid"]},"application/cdmi-object":{source:"iana",extensions:["cdmio"]},"application/cdmi-queue":{source:"iana",extensions:["cdmiq"]},"application/cdni":{source:"iana"},"application/cea":{source:"iana"},"application/cea-2018+xml":{source:"iana",compressible:!0},"application/cellml+xml":{source:"iana",compressible:!0},"application/cfw":{source:"iana"},"application/city+json":{source:"iana",compressible:!0},"application/clr":{source:"iana"},"application/clue+xml":{source:"iana",compressible:!0},"application/clue_info+xml":{source:"iana",compressible:!0},"application/cms":{source:"iana"},"application/cnrp+xml":{source:"iana",compressible:!0},"application/coap-group+json":{source:"iana",compressible:!0},"application/coap-payload":{source:"iana"},"application/commonground":{source:"iana"},"application/conference-info+xml":{source:"iana",compressible:!0},"application/cose":{source:"iana"},"application/cose-key":{source:"iana"},"application/cose-key-set":{source:"iana"},"application/cpl+xml":{source:"iana",compressible:!0,extensions:["cpl"]},"application/csrattrs":{source:"iana"},"application/csta+xml":{source:"iana",compressible:!0},"application/cstadata+xml":{source:"iana",compressible:!0},"application/csvm+json":{source:"iana",compressible:!0},"application/cu-seeme":{source:"apache",extensions:["cu"]},"application/cwt":{source:"iana"},"application/cybercash":{source:"iana"},"application/dart":{compressible:!0},"application/dash+xml":{source:"iana",compressible:!0,extensions:["mpd"]},"application/dash-patch+xml":{source:"iana",compressible:!0,extensions:["mpp"]},"application/dashdelta":{source:"iana"},"application/davmount+xml":{source:"iana",compressible:!0,extensions:["davmount"]},"application/dca-rft":{source:"iana"},"application/dcd":{source:"iana"},"application/dec-dx":{source:"iana"},"application/dialog-info+xml":{source:"iana",compressible:!0},"application/dicom":{source:"iana"},"application/dicom+json":{source:"iana",compressible:!0},"application/dicom+xml":{source:"iana",compressible:!0},"application/dii":{source:"iana"},"application/dit":{source:"iana"},"application/dns":{source:"iana"},"application/dns+json":{source:"iana",compressible:!0},"application/dns-message":{source:"iana"},"application/docbook+xml":{source:"apache",compressible:!0,extensions:["dbk"]},"application/dots+cbor":{source:"iana"},"application/dskpp+xml":{source:"iana",compressible:!0},"application/dssc+der":{source:"iana",extensions:["dssc"]},"application/dssc+xml":{source:"iana",compressible:!0,extensions:["xdssc"]},"application/dvcs":{source:"iana"},"application/ecmascript":{source:"iana",compressible:!0,extensions:["es","ecma"]},"application/edi-consent":{source:"iana"},"application/edi-x12":{source:"iana",compressible:!1},"application/edifact":{source:"iana",compressible:!1},"application/efi":{source:"iana"},"application/elm+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/elm+xml":{source:"iana",compressible:!0},"application/emergencycalldata.cap+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/emergencycalldata.comment+xml":{source:"iana",compressible:!0},"application/emergencycalldata.control+xml":{source:"iana",compressible:!0},"application/emergencycalldata.deviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.ecall.msd":{source:"iana"},"application/emergencycalldata.providerinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.serviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.subscriberinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.veds+xml":{source:"iana",compressible:!0},"application/emma+xml":{source:"iana",compressible:!0,extensions:["emma"]},"application/emotionml+xml":{source:"iana",compressible:!0,extensions:["emotionml"]},"application/encaprtp":{source:"iana"},"application/epp+xml":{source:"iana",compressible:!0},"application/epub+zip":{source:"iana",compressible:!1,extensions:["epub"]},"application/eshop":{source:"iana"},"application/exi":{source:"iana",extensions:["exi"]},"application/expect-ct-report+json":{source:"iana",compressible:!0},"application/express":{source:"iana",extensions:["exp"]},"application/fastinfoset":{source:"iana"},"application/fastsoap":{source:"iana"},"application/fdt+xml":{source:"iana",compressible:!0,extensions:["fdt"]},"application/fhir+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/fhir+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/fido.trusted-apps+json":{compressible:!0},"application/fits":{source:"iana"},"application/flexfec":{source:"iana"},"application/font-sfnt":{source:"iana"},"application/font-tdpfr":{source:"iana",extensions:["pfr"]},"application/font-woff":{source:"iana",compressible:!1},"application/framework-attributes+xml":{source:"iana",compressible:!0},"application/geo+json":{source:"iana",compressible:!0,extensions:["geojson"]},"application/geo+json-seq":{source:"iana"},"application/geopackage+sqlite3":{source:"iana"},"application/geoxacml+xml":{source:"iana",compressible:!0},"application/gltf-buffer":{source:"iana"},"application/gml+xml":{source:"iana",compressible:!0,extensions:["gml"]},"application/gpx+xml":{source:"apache",compressible:!0,extensions:["gpx"]},"application/gxf":{source:"apache",extensions:["gxf"]},"application/gzip":{source:"iana",compressible:!1,extensions:["gz"]},"application/h224":{source:"iana"},"application/held+xml":{source:"iana",compressible:!0},"application/hjson":{extensions:["hjson"]},"application/http":{source:"iana"},"application/hyperstudio":{source:"iana",extensions:["stk"]},"application/ibe-key-request+xml":{source:"iana",compressible:!0},"application/ibe-pkg-reply+xml":{source:"iana",compressible:!0},"application/ibe-pp-data":{source:"iana"},"application/iges":{source:"iana"},"application/im-iscomposing+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/index":{source:"iana"},"application/index.cmd":{source:"iana"},"application/index.obj":{source:"iana"},"application/index.response":{source:"iana"},"application/index.vnd":{source:"iana"},"application/inkml+xml":{source:"iana",compressible:!0,extensions:["ink","inkml"]},"application/iotp":{source:"iana"},"application/ipfix":{source:"iana",extensions:["ipfix"]},"application/ipp":{source:"iana"},"application/isup":{source:"iana"},"application/its+xml":{source:"iana",compressible:!0,extensions:["its"]},"application/java-archive":{source:"apache",compressible:!1,extensions:["jar","war","ear"]},"application/java-serialized-object":{source:"apache",compressible:!1,extensions:["ser"]},"application/java-vm":{source:"apache",compressible:!1,extensions:["class"]},"application/javascript":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["js","mjs"]},"application/jf2feed+json":{source:"iana",compressible:!0},"application/jose":{source:"iana"},"application/jose+json":{source:"iana",compressible:!0},"application/jrd+json":{source:"iana",compressible:!0},"application/jscalendar+json":{source:"iana",compressible:!0},"application/json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["json","map"]},"application/json-patch+json":{source:"iana",compressible:!0},"application/json-seq":{source:"iana"},"application/json5":{extensions:["json5"]},"application/jsonml+json":{source:"apache",compressible:!0,extensions:["jsonml"]},"application/jwk+json":{source:"iana",compressible:!0},"application/jwk-set+json":{source:"iana",compressible:!0},"application/jwt":{source:"iana"},"application/kpml-request+xml":{source:"iana",compressible:!0},"application/kpml-response+xml":{source:"iana",compressible:!0},"application/ld+json":{source:"iana",compressible:!0,extensions:["jsonld"]},"application/lgr+xml":{source:"iana",compressible:!0,extensions:["lgr"]},"application/link-format":{source:"iana"},"application/load-control+xml":{source:"iana",compressible:!0},"application/lost+xml":{source:"iana",compressible:!0,extensions:["lostxml"]},"application/lostsync+xml":{source:"iana",compressible:!0},"application/lpf+zip":{source:"iana",compressible:!1},"application/lxf":{source:"iana"},"application/mac-binhex40":{source:"iana",extensions:["hqx"]},"application/mac-compactpro":{source:"apache",extensions:["cpt"]},"application/macwriteii":{source:"iana"},"application/mads+xml":{source:"iana",compressible:!0,extensions:["mads"]},"application/manifest+json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["webmanifest"]},"application/marc":{source:"iana",extensions:["mrc"]},"application/marcxml+xml":{source:"iana",compressible:!0,extensions:["mrcx"]},"application/mathematica":{source:"iana",extensions:["ma","nb","mb"]},"application/mathml+xml":{source:"iana",compressible:!0,extensions:["mathml"]},"application/mathml-content+xml":{source:"iana",compressible:!0},"application/mathml-presentation+xml":{source:"iana",compressible:!0},"application/mbms-associated-procedure-description+xml":{source:"iana",compressible:!0},"application/mbms-deregister+xml":{source:"iana",compressible:!0},"application/mbms-envelope+xml":{source:"iana",compressible:!0},"application/mbms-msk+xml":{source:"iana",compressible:!0},"application/mbms-msk-response+xml":{source:"iana",compressible:!0},"application/mbms-protection-description+xml":{source:"iana",compressible:!0},"application/mbms-reception-report+xml":{source:"iana",compressible:!0},"application/mbms-register+xml":{source:"iana",compressible:!0},"application/mbms-register-response+xml":{source:"iana",compressible:!0},"application/mbms-schedule+xml":{source:"iana",compressible:!0},"application/mbms-user-service-description+xml":{source:"iana",compressible:!0},"application/mbox":{source:"iana",extensions:["mbox"]},"application/media-policy-dataset+xml":{source:"iana",compressible:!0,extensions:["mpf"]},"application/media_control+xml":{source:"iana",compressible:!0},"application/mediaservercontrol+xml":{source:"iana",compressible:!0,extensions:["mscml"]},"application/merge-patch+json":{source:"iana",compressible:!0},"application/metalink+xml":{source:"apache",compressible:!0,extensions:["metalink"]},"application/metalink4+xml":{source:"iana",compressible:!0,extensions:["meta4"]},"application/mets+xml":{source:"iana",compressible:!0,extensions:["mets"]},"application/mf4":{source:"iana"},"application/mikey":{source:"iana"},"application/mipc":{source:"iana"},"application/missing-blocks+cbor-seq":{source:"iana"},"application/mmt-aei+xml":{source:"iana",compressible:!0,extensions:["maei"]},"application/mmt-usd+xml":{source:"iana",compressible:!0,extensions:["musd"]},"application/mods+xml":{source:"iana",compressible:!0,extensions:["mods"]},"application/moss-keys":{source:"iana"},"application/moss-signature":{source:"iana"},"application/mosskey-data":{source:"iana"},"application/mosskey-request":{source:"iana"},"application/mp21":{source:"iana",extensions:["m21","mp21"]},"application/mp4":{source:"iana",extensions:["mp4s","m4p"]},"application/mpeg4-generic":{source:"iana"},"application/mpeg4-iod":{source:"iana"},"application/mpeg4-iod-xmt":{source:"iana"},"application/mrb-consumer+xml":{source:"iana",compressible:!0},"application/mrb-publish+xml":{source:"iana",compressible:!0},"application/msc-ivr+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msc-mixer+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msword":{source:"iana",compressible:!1,extensions:["doc","dot"]},"application/mud+json":{source:"iana",compressible:!0},"application/multipart-core":{source:"iana"},"application/mxf":{source:"iana",extensions:["mxf"]},"application/n-quads":{source:"iana",extensions:["nq"]},"application/n-triples":{source:"iana",extensions:["nt"]},"application/nasdata":{source:"iana"},"application/news-checkgroups":{source:"iana",charset:"US-ASCII"},"application/news-groupinfo":{source:"iana",charset:"US-ASCII"},"application/news-transmission":{source:"iana"},"application/nlsml+xml":{source:"iana",compressible:!0},"application/node":{source:"iana",extensions:["cjs"]},"application/nss":{source:"iana"},"application/oauth-authz-req+jwt":{source:"iana"},"application/oblivious-dns-message":{source:"iana"},"application/ocsp-request":{source:"iana"},"application/ocsp-response":{source:"iana"},"application/octet-stream":{source:"iana",compressible:!1,extensions:["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{source:"iana",extensions:["oda"]},"application/odm+xml":{source:"iana",compressible:!0},"application/odx":{source:"iana"},"application/oebps-package+xml":{source:"iana",compressible:!0,extensions:["opf"]},"application/ogg":{source:"iana",compressible:!1,extensions:["ogx"]},"application/omdoc+xml":{source:"apache",compressible:!0,extensions:["omdoc"]},"application/onenote":{source:"apache",extensions:["onetoc","onetoc2","onetmp","onepkg"]},"application/opc-nodeset+xml":{source:"iana",compressible:!0},"application/oscore":{source:"iana"},"application/oxps":{source:"iana",extensions:["oxps"]},"application/p21":{source:"iana"},"application/p21+zip":{source:"iana",compressible:!1},"application/p2p-overlay+xml":{source:"iana",compressible:!0,extensions:["relo"]},"application/parityfec":{source:"iana"},"application/passport":{source:"iana"},"application/patch-ops-error+xml":{source:"iana",compressible:!0,extensions:["xer"]},"application/pdf":{source:"iana",compressible:!1,extensions:["pdf"]},"application/pdx":{source:"iana"},"application/pem-certificate-chain":{source:"iana"},"application/pgp-encrypted":{source:"iana",compressible:!1,extensions:["pgp"]},"application/pgp-keys":{source:"iana",extensions:["asc"]},"application/pgp-signature":{source:"iana",extensions:["asc","sig"]},"application/pics-rules":{source:"apache",extensions:["prf"]},"application/pidf+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pidf-diff+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pkcs10":{source:"iana",extensions:["p10"]},"application/pkcs12":{source:"iana"},"application/pkcs7-mime":{source:"iana",extensions:["p7m","p7c"]},"application/pkcs7-signature":{source:"iana",extensions:["p7s"]},"application/pkcs8":{source:"iana",extensions:["p8"]},"application/pkcs8-encrypted":{source:"iana"},"application/pkix-attr-cert":{source:"iana",extensions:["ac"]},"application/pkix-cert":{source:"iana",extensions:["cer"]},"application/pkix-crl":{source:"iana",extensions:["crl"]},"application/pkix-pkipath":{source:"iana",extensions:["pkipath"]},"application/pkixcmp":{source:"iana",extensions:["pki"]},"application/pls+xml":{source:"iana",compressible:!0,extensions:["pls"]},"application/poc-settings+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/postscript":{source:"iana",compressible:!0,extensions:["ai","eps","ps"]},"application/ppsp-tracker+json":{source:"iana",compressible:!0},"application/problem+json":{source:"iana",compressible:!0},"application/problem+xml":{source:"iana",compressible:!0},"application/provenance+xml":{source:"iana",compressible:!0,extensions:["provx"]},"application/prs.alvestrand.titrax-sheet":{source:"iana"},"application/prs.cww":{source:"iana",extensions:["cww"]},"application/prs.cyn":{source:"iana",charset:"7-BIT"},"application/prs.hpub+zip":{source:"iana",compressible:!1},"application/prs.nprend":{source:"iana"},"application/prs.plucker":{source:"iana"},"application/prs.rdf-xml-crypt":{source:"iana"},"application/prs.xsf+xml":{source:"iana",compressible:!0},"application/pskc+xml":{source:"iana",compressible:!0,extensions:["pskcxml"]},"application/pvd+json":{source:"iana",compressible:!0},"application/qsig":{source:"iana"},"application/raml+yaml":{compressible:!0,extensions:["raml"]},"application/raptorfec":{source:"iana"},"application/rdap+json":{source:"iana",compressible:!0},"application/rdf+xml":{source:"iana",compressible:!0,extensions:["rdf","owl"]},"application/reginfo+xml":{source:"iana",compressible:!0,extensions:["rif"]},"application/relax-ng-compact-syntax":{source:"iana",extensions:["rnc"]},"application/remote-printing":{source:"iana"},"application/reputon+json":{source:"iana",compressible:!0},"application/resource-lists+xml":{source:"iana",compressible:!0,extensions:["rl"]},"application/resource-lists-diff+xml":{source:"iana",compressible:!0,extensions:["rld"]},"application/rfc+xml":{source:"iana",compressible:!0},"application/riscos":{source:"iana"},"application/rlmi+xml":{source:"iana",compressible:!0},"application/rls-services+xml":{source:"iana",compressible:!0,extensions:["rs"]},"application/route-apd+xml":{source:"iana",compressible:!0,extensions:["rapd"]},"application/route-s-tsid+xml":{source:"iana",compressible:!0,extensions:["sls"]},"application/route-usd+xml":{source:"iana",compressible:!0,extensions:["rusd"]},"application/rpki-ghostbusters":{source:"iana",extensions:["gbr"]},"application/rpki-manifest":{source:"iana",extensions:["mft"]},"application/rpki-publication":{source:"iana"},"application/rpki-roa":{source:"iana",extensions:["roa"]},"application/rpki-updown":{source:"iana"},"application/rsd+xml":{source:"apache",compressible:!0,extensions:["rsd"]},"application/rss+xml":{source:"apache",compressible:!0,extensions:["rss"]},"application/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"application/rtploopback":{source:"iana"},"application/rtx":{source:"iana"},"application/samlassertion+xml":{source:"iana",compressible:!0},"application/samlmetadata+xml":{source:"iana",compressible:!0},"application/sarif+json":{source:"iana",compressible:!0},"application/sarif-external-properties+json":{source:"iana",compressible:!0},"application/sbe":{source:"iana"},"application/sbml+xml":{source:"iana",compressible:!0,extensions:["sbml"]},"application/scaip+xml":{source:"iana",compressible:!0},"application/scim+json":{source:"iana",compressible:!0},"application/scvp-cv-request":{source:"iana",extensions:["scq"]},"application/scvp-cv-response":{source:"iana",extensions:["scs"]},"application/scvp-vp-request":{source:"iana",extensions:["spq"]},"application/scvp-vp-response":{source:"iana",extensions:["spp"]},"application/sdp":{source:"iana",extensions:["sdp"]},"application/secevent+jwt":{source:"iana"},"application/senml+cbor":{source:"iana"},"application/senml+json":{source:"iana",compressible:!0},"application/senml+xml":{source:"iana",compressible:!0,extensions:["senmlx"]},"application/senml-etch+cbor":{source:"iana"},"application/senml-etch+json":{source:"iana",compressible:!0},"application/senml-exi":{source:"iana"},"application/sensml+cbor":{source:"iana"},"application/sensml+json":{source:"iana",compressible:!0},"application/sensml+xml":{source:"iana",compressible:!0,extensions:["sensmlx"]},"application/sensml-exi":{source:"iana"},"application/sep+xml":{source:"iana",compressible:!0},"application/sep-exi":{source:"iana"},"application/session-info":{source:"iana"},"application/set-payment":{source:"iana"},"application/set-payment-initiation":{source:"iana",extensions:["setpay"]},"application/set-registration":{source:"iana"},"application/set-registration-initiation":{source:"iana",extensions:["setreg"]},"application/sgml":{source:"iana"},"application/sgml-open-catalog":{source:"iana"},"application/shf+xml":{source:"iana",compressible:!0,extensions:["shf"]},"application/sieve":{source:"iana",extensions:["siv","sieve"]},"application/simple-filter+xml":{source:"iana",compressible:!0},"application/simple-message-summary":{source:"iana"},"application/simplesymbolcontainer":{source:"iana"},"application/sipc":{source:"iana"},"application/slate":{source:"iana"},"application/smil":{source:"iana"},"application/smil+xml":{source:"iana",compressible:!0,extensions:["smi","smil"]},"application/smpte336m":{source:"iana"},"application/soap+fastinfoset":{source:"iana"},"application/soap+xml":{source:"iana",compressible:!0},"application/sparql-query":{source:"iana",extensions:["rq"]},"application/sparql-results+xml":{source:"iana",compressible:!0,extensions:["srx"]},"application/spdx+json":{source:"iana",compressible:!0},"application/spirits-event+xml":{source:"iana",compressible:!0},"application/sql":{source:"iana"},"application/srgs":{source:"iana",extensions:["gram"]},"application/srgs+xml":{source:"iana",compressible:!0,extensions:["grxml"]},"application/sru+xml":{source:"iana",compressible:!0,extensions:["sru"]},"application/ssdl+xml":{source:"apache",compressible:!0,extensions:["ssdl"]},"application/ssml+xml":{source:"iana",compressible:!0,extensions:["ssml"]},"application/stix+json":{source:"iana",compressible:!0},"application/swid+xml":{source:"iana",compressible:!0,extensions:["swidtag"]},"application/tamp-apex-update":{source:"iana"},"application/tamp-apex-update-confirm":{source:"iana"},"application/tamp-community-update":{source:"iana"},"application/tamp-community-update-confirm":{source:"iana"},"application/tamp-error":{source:"iana"},"application/tamp-sequence-adjust":{source:"iana"},"application/tamp-sequence-adjust-confirm":{source:"iana"},"application/tamp-status-query":{source:"iana"},"application/tamp-status-response":{source:"iana"},"application/tamp-update":{source:"iana"},"application/tamp-update-confirm":{source:"iana"},"application/tar":{compressible:!0},"application/taxii+json":{source:"iana",compressible:!0},"application/td+json":{source:"iana",compressible:!0},"application/tei+xml":{source:"iana",compressible:!0,extensions:["tei","teicorpus"]},"application/tetra_isi":{source:"iana"},"application/thraud+xml":{source:"iana",compressible:!0,extensions:["tfi"]},"application/timestamp-query":{source:"iana"},"application/timestamp-reply":{source:"iana"},"application/timestamped-data":{source:"iana",extensions:["tsd"]},"application/tlsrpt+gzip":{source:"iana"},"application/tlsrpt+json":{source:"iana",compressible:!0},"application/tnauthlist":{source:"iana"},"application/token-introspection+jwt":{source:"iana"},"application/toml":{compressible:!0,extensions:["toml"]},"application/trickle-ice-sdpfrag":{source:"iana"},"application/trig":{source:"iana",extensions:["trig"]},"application/ttml+xml":{source:"iana",compressible:!0,extensions:["ttml"]},"application/tve-trigger":{source:"iana"},"application/tzif":{source:"iana"},"application/tzif-leap":{source:"iana"},"application/ubjson":{compressible:!1,extensions:["ubj"]},"application/ulpfec":{source:"iana"},"application/urc-grpsheet+xml":{source:"iana",compressible:!0},"application/urc-ressheet+xml":{source:"iana",compressible:!0,extensions:["rsheet"]},"application/urc-targetdesc+xml":{source:"iana",compressible:!0,extensions:["td"]},"application/urc-uisocketdesc+xml":{source:"iana",compressible:!0},"application/vcard+json":{source:"iana",compressible:!0},"application/vcard+xml":{source:"iana",compressible:!0},"application/vemmi":{source:"iana"},"application/vividence.scriptfile":{source:"apache"},"application/vnd.1000minds.decision-model+xml":{source:"iana",compressible:!0,extensions:["1km"]},"application/vnd.3gpp-prose+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc3ch+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-v2x-local-service-information":{source:"iana"},"application/vnd.3gpp.5gnas":{source:"iana"},"application/vnd.3gpp.access-transfer-events+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.bsf+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gmop+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gtpc":{source:"iana"},"application/vnd.3gpp.interworking-data":{source:"iana"},"application/vnd.3gpp.lpp":{source:"iana"},"application/vnd.3gpp.mc-signalling-ear":{source:"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-payload":{source:"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-signalling":{source:"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-floor-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-signed+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-init-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-transmission-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mid-call+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ngap":{source:"iana"},"application/vnd.3gpp.pfcp":{source:"iana"},"application/vnd.3gpp.pic-bw-large":{source:"iana",extensions:["plb"]},"application/vnd.3gpp.pic-bw-small":{source:"iana",extensions:["psb"]},"application/vnd.3gpp.pic-bw-var":{source:"iana",extensions:["pvb"]},"application/vnd.3gpp.s1ap":{source:"iana"},"application/vnd.3gpp.sms":{source:"iana"},"application/vnd.3gpp.sms+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-ext+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.state-and-event-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ussd+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.bcmcsinfo+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.sms":{source:"iana"},"application/vnd.3gpp2.tcap":{source:"iana",extensions:["tcap"]},"application/vnd.3lightssoftware.imagescal":{source:"iana"},"application/vnd.3m.post-it-notes":{source:"iana",extensions:["pwn"]},"application/vnd.accpac.simply.aso":{source:"iana",extensions:["aso"]},"application/vnd.accpac.simply.imp":{source:"iana",extensions:["imp"]},"application/vnd.acucobol":{source:"iana",extensions:["acu"]},"application/vnd.acucorp":{source:"iana",extensions:["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{source:"apache",compressible:!1,extensions:["air"]},"application/vnd.adobe.flash.movie":{source:"iana"},"application/vnd.adobe.formscentral.fcdt":{source:"iana",extensions:["fcdt"]},"application/vnd.adobe.fxp":{source:"iana",extensions:["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{source:"iana"},"application/vnd.adobe.xdp+xml":{source:"iana",compressible:!0,extensions:["xdp"]},"application/vnd.adobe.xfdf":{source:"iana",extensions:["xfdf"]},"application/vnd.aether.imp":{source:"iana"},"application/vnd.afpc.afplinedata":{source:"iana"},"application/vnd.afpc.afplinedata-pagedef":{source:"iana"},"application/vnd.afpc.cmoca-cmresource":{source:"iana"},"application/vnd.afpc.foca-charset":{source:"iana"},"application/vnd.afpc.foca-codedfont":{source:"iana"},"application/vnd.afpc.foca-codepage":{source:"iana"},"application/vnd.afpc.modca":{source:"iana"},"application/vnd.afpc.modca-cmtable":{source:"iana"},"application/vnd.afpc.modca-formdef":{source:"iana"},"application/vnd.afpc.modca-mediummap":{source:"iana"},"application/vnd.afpc.modca-objectcontainer":{source:"iana"},"application/vnd.afpc.modca-overlay":{source:"iana"},"application/vnd.afpc.modca-pagesegment":{source:"iana"},"application/vnd.age":{source:"iana",extensions:["age"]},"application/vnd.ah-barcode":{source:"iana"},"application/vnd.ahead.space":{source:"iana",extensions:["ahead"]},"application/vnd.airzip.filesecure.azf":{source:"iana",extensions:["azf"]},"application/vnd.airzip.filesecure.azs":{source:"iana",extensions:["azs"]},"application/vnd.amadeus+json":{source:"iana",compressible:!0},"application/vnd.amazon.ebook":{source:"apache",extensions:["azw"]},"application/vnd.amazon.mobi8-ebook":{source:"iana"},"application/vnd.americandynamics.acc":{source:"iana",extensions:["acc"]},"application/vnd.amiga.ami":{source:"iana",extensions:["ami"]},"application/vnd.amundsen.maze+xml":{source:"iana",compressible:!0},"application/vnd.android.ota":{source:"iana"},"application/vnd.android.package-archive":{source:"apache",compressible:!1,extensions:["apk"]},"application/vnd.anki":{source:"iana"},"application/vnd.anser-web-certificate-issue-initiation":{source:"iana",extensions:["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{source:"apache",extensions:["fti"]},"application/vnd.antix.game-component":{source:"iana",extensions:["atx"]},"application/vnd.apache.arrow.file":{source:"iana"},"application/vnd.apache.arrow.stream":{source:"iana"},"application/vnd.apache.thrift.binary":{source:"iana"},"application/vnd.apache.thrift.compact":{source:"iana"},"application/vnd.apache.thrift.json":{source:"iana"},"application/vnd.api+json":{source:"iana",compressible:!0},"application/vnd.aplextor.warrp+json":{source:"iana",compressible:!0},"application/vnd.apothekende.reservation+json":{source:"iana",compressible:!0},"application/vnd.apple.installer+xml":{source:"iana",compressible:!0,extensions:["mpkg"]},"application/vnd.apple.keynote":{source:"iana",extensions:["key"]},"application/vnd.apple.mpegurl":{source:"iana",extensions:["m3u8"]},"application/vnd.apple.numbers":{source:"iana",extensions:["numbers"]},"application/vnd.apple.pages":{source:"iana",extensions:["pages"]},"application/vnd.apple.pkpass":{compressible:!1,extensions:["pkpass"]},"application/vnd.arastra.swi":{source:"iana"},"application/vnd.aristanetworks.swi":{source:"iana",extensions:["swi"]},"application/vnd.artisan+json":{source:"iana",compressible:!0},"application/vnd.artsquare":{source:"iana"},"application/vnd.astraea-software.iota":{source:"iana",extensions:["iota"]},"application/vnd.audiograph":{source:"iana",extensions:["aep"]},"application/vnd.autopackage":{source:"iana"},"application/vnd.avalon+json":{source:"iana",compressible:!0},"application/vnd.avistar+xml":{source:"iana",compressible:!0},"application/vnd.balsamiq.bmml+xml":{source:"iana",compressible:!0,extensions:["bmml"]},"application/vnd.balsamiq.bmpr":{source:"iana"},"application/vnd.banana-accounting":{source:"iana"},"application/vnd.bbf.usp.error":{source:"iana"},"application/vnd.bbf.usp.msg":{source:"iana"},"application/vnd.bbf.usp.msg+json":{source:"iana",compressible:!0},"application/vnd.bekitzur-stech+json":{source:"iana",compressible:!0},"application/vnd.bint.med-content":{source:"iana"},"application/vnd.biopax.rdf+xml":{source:"iana",compressible:!0},"application/vnd.blink-idb-value-wrapper":{source:"iana"},"application/vnd.blueice.multipass":{source:"iana",extensions:["mpm"]},"application/vnd.bluetooth.ep.oob":{source:"iana"},"application/vnd.bluetooth.le.oob":{source:"iana"},"application/vnd.bmi":{source:"iana",extensions:["bmi"]},"application/vnd.bpf":{source:"iana"},"application/vnd.bpf3":{source:"iana"},"application/vnd.businessobjects":{source:"iana",extensions:["rep"]},"application/vnd.byu.uapi+json":{source:"iana",compressible:!0},"application/vnd.cab-jscript":{source:"iana"},"application/vnd.canon-cpdl":{source:"iana"},"application/vnd.canon-lips":{source:"iana"},"application/vnd.capasystems-pg+json":{source:"iana",compressible:!0},"application/vnd.cendio.thinlinc.clientconf":{source:"iana"},"application/vnd.century-systems.tcp_stream":{source:"iana"},"application/vnd.chemdraw+xml":{source:"iana",compressible:!0,extensions:["cdxml"]},"application/vnd.chess-pgn":{source:"iana"},"application/vnd.chipnuts.karaoke-mmd":{source:"iana",extensions:["mmd"]},"application/vnd.ciedi":{source:"iana"},"application/vnd.cinderella":{source:"iana",extensions:["cdy"]},"application/vnd.cirpack.isdn-ext":{source:"iana"},"application/vnd.citationstyles.style+xml":{source:"iana",compressible:!0,extensions:["csl"]},"application/vnd.claymore":{source:"iana",extensions:["cla"]},"application/vnd.cloanto.rp9":{source:"iana",extensions:["rp9"]},"application/vnd.clonk.c4group":{source:"iana",extensions:["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{source:"iana",extensions:["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{source:"iana",extensions:["c11amz"]},"application/vnd.coffeescript":{source:"iana"},"application/vnd.collabio.xodocuments.document":{source:"iana"},"application/vnd.collabio.xodocuments.document-template":{source:"iana"},"application/vnd.collabio.xodocuments.presentation":{source:"iana"},"application/vnd.collabio.xodocuments.presentation-template":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{source:"iana"},"application/vnd.collection+json":{source:"iana",compressible:!0},"application/vnd.collection.doc+json":{source:"iana",compressible:!0},"application/vnd.collection.next+json":{source:"iana",compressible:!0},"application/vnd.comicbook+zip":{source:"iana",compressible:!1},"application/vnd.comicbook-rar":{source:"iana"},"application/vnd.commerce-battelle":{source:"iana"},"application/vnd.commonspace":{source:"iana",extensions:["csp"]},"application/vnd.contact.cmsg":{source:"iana",extensions:["cdbcmsg"]},"application/vnd.coreos.ignition+json":{source:"iana",compressible:!0},"application/vnd.cosmocaller":{source:"iana",extensions:["cmc"]},"application/vnd.crick.clicker":{source:"iana",extensions:["clkx"]},"application/vnd.crick.clicker.keyboard":{source:"iana",extensions:["clkk"]},"application/vnd.crick.clicker.palette":{source:"iana",extensions:["clkp"]},"application/vnd.crick.clicker.template":{source:"iana",extensions:["clkt"]},"application/vnd.crick.clicker.wordbank":{source:"iana",extensions:["clkw"]},"application/vnd.criticaltools.wbs+xml":{source:"iana",compressible:!0,extensions:["wbs"]},"application/vnd.cryptii.pipe+json":{source:"iana",compressible:!0},"application/vnd.crypto-shade-file":{source:"iana"},"application/vnd.cryptomator.encrypted":{source:"iana"},"application/vnd.cryptomator.vault":{source:"iana"},"application/vnd.ctc-posml":{source:"iana",extensions:["pml"]},"application/vnd.ctct.ws+xml":{source:"iana",compressible:!0},"application/vnd.cups-pdf":{source:"iana"},"application/vnd.cups-postscript":{source:"iana"},"application/vnd.cups-ppd":{source:"iana",extensions:["ppd"]},"application/vnd.cups-raster":{source:"iana"},"application/vnd.cups-raw":{source:"iana"},"application/vnd.curl":{source:"iana"},"application/vnd.curl.car":{source:"apache",extensions:["car"]},"application/vnd.curl.pcurl":{source:"apache",extensions:["pcurl"]},"application/vnd.cyan.dean.root+xml":{source:"iana",compressible:!0},"application/vnd.cybank":{source:"iana"},"application/vnd.cyclonedx+json":{source:"iana",compressible:!0},"application/vnd.cyclonedx+xml":{source:"iana",compressible:!0},"application/vnd.d2l.coursepackage1p0+zip":{source:"iana",compressible:!1},"application/vnd.d3m-dataset":{source:"iana"},"application/vnd.d3m-problem":{source:"iana"},"application/vnd.dart":{source:"iana",compressible:!0,extensions:["dart"]},"application/vnd.data-vision.rdz":{source:"iana",extensions:["rdz"]},"application/vnd.datapackage+json":{source:"iana",compressible:!0},"application/vnd.dataresource+json":{source:"iana",compressible:!0},"application/vnd.dbf":{source:"iana",extensions:["dbf"]},"application/vnd.debian.binary-package":{source:"iana"},"application/vnd.dece.data":{source:"iana",extensions:["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{source:"iana",compressible:!0,extensions:["uvt","uvvt"]},"application/vnd.dece.unspecified":{source:"iana",extensions:["uvx","uvvx"]},"application/vnd.dece.zip":{source:"iana",extensions:["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{source:"iana",extensions:["fe_launch"]},"application/vnd.desmume.movie":{source:"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{source:"iana"},"application/vnd.dm.delegation+xml":{source:"iana",compressible:!0},"application/vnd.dna":{source:"iana",extensions:["dna"]},"application/vnd.document+json":{source:"iana",compressible:!0},"application/vnd.dolby.mlp":{source:"apache",extensions:["mlp"]},"application/vnd.dolby.mobile.1":{source:"iana"},"application/vnd.dolby.mobile.2":{source:"iana"},"application/vnd.doremir.scorecloud-binary-document":{source:"iana"},"application/vnd.dpgraph":{source:"iana",extensions:["dpg"]},"application/vnd.dreamfactory":{source:"iana",extensions:["dfac"]},"application/vnd.drive+json":{source:"iana",compressible:!0},"application/vnd.ds-keypoint":{source:"apache",extensions:["kpxx"]},"application/vnd.dtg.local":{source:"iana"},"application/vnd.dtg.local.flash":{source:"iana"},"application/vnd.dtg.local.html":{source:"iana"},"application/vnd.dvb.ait":{source:"iana",extensions:["ait"]},"application/vnd.dvb.dvbisl+xml":{source:"iana",compressible:!0},"application/vnd.dvb.dvbj":{source:"iana"},"application/vnd.dvb.esgcontainer":{source:"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess2":{source:"iana"},"application/vnd.dvb.ipdcesgpdd":{source:"iana"},"application/vnd.dvb.ipdcroaming":{source:"iana"},"application/vnd.dvb.iptv.alfec-base":{source:"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{source:"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-container+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-generic+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-msglist+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-request+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-response+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-init+xml":{source:"iana",compressible:!0},"application/vnd.dvb.pfr":{source:"iana"},"application/vnd.dvb.service":{source:"iana",extensions:["svc"]},"application/vnd.dxr":{source:"iana"},"application/vnd.dynageo":{source:"iana",extensions:["geo"]},"application/vnd.dzr":{source:"iana"},"application/vnd.easykaraoke.cdgdownload":{source:"iana"},"application/vnd.ecdis-update":{source:"iana"},"application/vnd.ecip.rlp":{source:"iana"},"application/vnd.eclipse.ditto+json":{source:"iana",compressible:!0},"application/vnd.ecowin.chart":{source:"iana",extensions:["mag"]},"application/vnd.ecowin.filerequest":{source:"iana"},"application/vnd.ecowin.fileupdate":{source:"iana"},"application/vnd.ecowin.series":{source:"iana"},"application/vnd.ecowin.seriesrequest":{source:"iana"},"application/vnd.ecowin.seriesupdate":{source:"iana"},"application/vnd.efi.img":{source:"iana"},"application/vnd.efi.iso":{source:"iana"},"application/vnd.emclient.accessrequest+xml":{source:"iana",compressible:!0},"application/vnd.enliven":{source:"iana",extensions:["nml"]},"application/vnd.enphase.envoy":{source:"iana"},"application/vnd.eprints.data+xml":{source:"iana",compressible:!0},"application/vnd.epson.esf":{source:"iana",extensions:["esf"]},"application/vnd.epson.msf":{source:"iana",extensions:["msf"]},"application/vnd.epson.quickanime":{source:"iana",extensions:["qam"]},"application/vnd.epson.salt":{source:"iana",extensions:["slt"]},"application/vnd.epson.ssf":{source:"iana",extensions:["ssf"]},"application/vnd.ericsson.quickcall":{source:"iana"},"application/vnd.espass-espass+zip":{source:"iana",compressible:!1},"application/vnd.eszigno3+xml":{source:"iana",compressible:!0,extensions:["es3","et3"]},"application/vnd.etsi.aoc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.asic-e+zip":{source:"iana",compressible:!1},"application/vnd.etsi.asic-s+zip":{source:"iana",compressible:!1},"application/vnd.etsi.cug+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvcommand+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-bc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-cod+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-npvr+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvservice+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsync+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvueprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mcid+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mheg5":{source:"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{source:"iana",compressible:!0},"application/vnd.etsi.pstn+xml":{source:"iana",compressible:!0},"application/vnd.etsi.sci+xml":{source:"iana",compressible:!0},"application/vnd.etsi.simservs+xml":{source:"iana",compressible:!0},"application/vnd.etsi.timestamp-token":{source:"iana"},"application/vnd.etsi.tsl+xml":{source:"iana",compressible:!0},"application/vnd.etsi.tsl.der":{source:"iana"},"application/vnd.eu.kasparian.car+json":{source:"iana",compressible:!0},"application/vnd.eudora.data":{source:"iana"},"application/vnd.evolv.ecig.profile":{source:"iana"},"application/vnd.evolv.ecig.settings":{source:"iana"},"application/vnd.evolv.ecig.theme":{source:"iana"},"application/vnd.exstream-empower+zip":{source:"iana",compressible:!1},"application/vnd.exstream-package":{source:"iana"},"application/vnd.ezpix-album":{source:"iana",extensions:["ez2"]},"application/vnd.ezpix-package":{source:"iana",extensions:["ez3"]},"application/vnd.f-secure.mobile":{source:"iana"},"application/vnd.familysearch.gedcom+zip":{source:"iana",compressible:!1},"application/vnd.fastcopy-disk-image":{source:"iana"},"application/vnd.fdf":{source:"iana",extensions:["fdf"]},"application/vnd.fdsn.mseed":{source:"iana",extensions:["mseed"]},"application/vnd.fdsn.seed":{source:"iana",extensions:["seed","dataless"]},"application/vnd.ffsns":{source:"iana"},"application/vnd.ficlab.flb+zip":{source:"iana",compressible:!1},"application/vnd.filmit.zfc":{source:"iana"},"application/vnd.fints":{source:"iana"},"application/vnd.firemonkeys.cloudcell":{source:"iana"},"application/vnd.flographit":{source:"iana",extensions:["gph"]},"application/vnd.fluxtime.clip":{source:"iana",extensions:["ftc"]},"application/vnd.font-fontforge-sfd":{source:"iana"},"application/vnd.framemaker":{source:"iana",extensions:["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{source:"iana",extensions:["fnc"]},"application/vnd.frogans.ltf":{source:"iana",extensions:["ltf"]},"application/vnd.fsc.weblaunch":{source:"iana",extensions:["fsc"]},"application/vnd.fujifilm.fb.docuworks":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.container":{source:"iana"},"application/vnd.fujifilm.fb.jfi+xml":{source:"iana",compressible:!0},"application/vnd.fujitsu.oasys":{source:"iana",extensions:["oas"]},"application/vnd.fujitsu.oasys2":{source:"iana",extensions:["oa2"]},"application/vnd.fujitsu.oasys3":{source:"iana",extensions:["oa3"]},"application/vnd.fujitsu.oasysgp":{source:"iana",extensions:["fg5"]},"application/vnd.fujitsu.oasysprs":{source:"iana",extensions:["bh2"]},"application/vnd.fujixerox.art-ex":{source:"iana"},"application/vnd.fujixerox.art4":{source:"iana"},"application/vnd.fujixerox.ddd":{source:"iana",extensions:["ddd"]},"application/vnd.fujixerox.docuworks":{source:"iana",extensions:["xdw"]},"application/vnd.fujixerox.docuworks.binder":{source:"iana",extensions:["xbd"]},"application/vnd.fujixerox.docuworks.container":{source:"iana"},"application/vnd.fujixerox.hbpl":{source:"iana"},"application/vnd.fut-misnet":{source:"iana"},"application/vnd.futoin+cbor":{source:"iana"},"application/vnd.futoin+json":{source:"iana",compressible:!0},"application/vnd.fuzzysheet":{source:"iana",extensions:["fzs"]},"application/vnd.genomatix.tuxedo":{source:"iana",extensions:["txd"]},"application/vnd.gentics.grd+json":{source:"iana",compressible:!0},"application/vnd.geo+json":{source:"iana",compressible:!0},"application/vnd.geocube+xml":{source:"iana",compressible:!0},"application/vnd.geogebra.file":{source:"iana",extensions:["ggb"]},"application/vnd.geogebra.slides":{source:"iana"},"application/vnd.geogebra.tool":{source:"iana",extensions:["ggt"]},"application/vnd.geometry-explorer":{source:"iana",extensions:["gex","gre"]},"application/vnd.geonext":{source:"iana",extensions:["gxt"]},"application/vnd.geoplan":{source:"iana",extensions:["g2w"]},"application/vnd.geospace":{source:"iana",extensions:["g3w"]},"application/vnd.gerber":{source:"iana"},"application/vnd.globalplatform.card-content-mgt":{source:"iana"},"application/vnd.globalplatform.card-content-mgt-response":{source:"iana"},"application/vnd.gmx":{source:"iana",extensions:["gmx"]},"application/vnd.google-apps.document":{compressible:!1,extensions:["gdoc"]},"application/vnd.google-apps.presentation":{compressible:!1,extensions:["gslides"]},"application/vnd.google-apps.spreadsheet":{compressible:!1,extensions:["gsheet"]},"application/vnd.google-earth.kml+xml":{source:"iana",compressible:!0,extensions:["kml"]},"application/vnd.google-earth.kmz":{source:"iana",compressible:!1,extensions:["kmz"]},"application/vnd.gov.sk.e-form+xml":{source:"iana",compressible:!0},"application/vnd.gov.sk.e-form+zip":{source:"iana",compressible:!1},"application/vnd.gov.sk.xmldatacontainer+xml":{source:"iana",compressible:!0},"application/vnd.grafeq":{source:"iana",extensions:["gqf","gqs"]},"application/vnd.gridmp":{source:"iana"},"application/vnd.groove-account":{source:"iana",extensions:["gac"]},"application/vnd.groove-help":{source:"iana",extensions:["ghf"]},"application/vnd.groove-identity-message":{source:"iana",extensions:["gim"]},"application/vnd.groove-injector":{source:"iana",extensions:["grv"]},"application/vnd.groove-tool-message":{source:"iana",extensions:["gtm"]},"application/vnd.groove-tool-template":{source:"iana",extensions:["tpl"]},"application/vnd.groove-vcard":{source:"iana",extensions:["vcg"]},"application/vnd.hal+json":{source:"iana",compressible:!0},"application/vnd.hal+xml":{source:"iana",compressible:!0,extensions:["hal"]},"application/vnd.handheld-entertainment+xml":{source:"iana",compressible:!0,extensions:["zmm"]},"application/vnd.hbci":{source:"iana",extensions:["hbci"]},"application/vnd.hc+json":{source:"iana",compressible:!0},"application/vnd.hcl-bireports":{source:"iana"},"application/vnd.hdt":{source:"iana"},"application/vnd.heroku+json":{source:"iana",compressible:!0},"application/vnd.hhe.lesson-player":{source:"iana",extensions:["les"]},"application/vnd.hl7cda+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.hl7v2+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.hp-hpgl":{source:"iana",extensions:["hpgl"]},"application/vnd.hp-hpid":{source:"iana",extensions:["hpid"]},"application/vnd.hp-hps":{source:"iana",extensions:["hps"]},"application/vnd.hp-jlyt":{source:"iana",extensions:["jlt"]},"application/vnd.hp-pcl":{source:"iana",extensions:["pcl"]},"application/vnd.hp-pclxl":{source:"iana",extensions:["pclxl"]},"application/vnd.httphone":{source:"iana"},"application/vnd.hydrostatix.sof-data":{source:"iana",extensions:["sfd-hdstx"]},"application/vnd.hyper+json":{source:"iana",compressible:!0},"application/vnd.hyper-item+json":{source:"iana",compressible:!0},"application/vnd.hyperdrive+json":{source:"iana",compressible:!0},"application/vnd.hzn-3d-crossword":{source:"iana"},"application/vnd.ibm.afplinedata":{source:"iana"},"application/vnd.ibm.electronic-media":{source:"iana"},"application/vnd.ibm.minipay":{source:"iana",extensions:["mpy"]},"application/vnd.ibm.modcap":{source:"iana",extensions:["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{source:"iana",extensions:["irm"]},"application/vnd.ibm.secure-container":{source:"iana",extensions:["sc"]},"application/vnd.iccprofile":{source:"iana",extensions:["icc","icm"]},"application/vnd.ieee.1905":{source:"iana"},"application/vnd.igloader":{source:"iana",extensions:["igl"]},"application/vnd.imagemeter.folder+zip":{source:"iana",compressible:!1},"application/vnd.imagemeter.image+zip":{source:"iana",compressible:!1},"application/vnd.immervision-ivp":{source:"iana",extensions:["ivp"]},"application/vnd.immervision-ivu":{source:"iana",extensions:["ivu"]},"application/vnd.ims.imsccv1p1":{source:"iana"},"application/vnd.ims.imsccv1p2":{source:"iana"},"application/vnd.ims.imsccv1p3":{source:"iana"},"application/vnd.ims.lis.v2.result+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy.id+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings.simple+json":{source:"iana",compressible:!0},"application/vnd.informedcontrol.rms+xml":{source:"iana",compressible:!0},"application/vnd.informix-visionary":{source:"iana"},"application/vnd.infotech.project":{source:"iana"},"application/vnd.infotech.project+xml":{source:"iana",compressible:!0},"application/vnd.innopath.wamp.notification":{source:"iana"},"application/vnd.insors.igm":{source:"iana",extensions:["igm"]},"application/vnd.intercon.formnet":{source:"iana",extensions:["xpw","xpx"]},"application/vnd.intergeo":{source:"iana",extensions:["i2g"]},"application/vnd.intertrust.digibox":{source:"iana"},"application/vnd.intertrust.nncp":{source:"iana"},"application/vnd.intu.qbo":{source:"iana",extensions:["qbo"]},"application/vnd.intu.qfx":{source:"iana",extensions:["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.conceptitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.knowledgeitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsmessage+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.packageitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.planningitem+xml":{source:"iana",compressible:!0},"application/vnd.ipunplugged.rcprofile":{source:"iana",extensions:["rcprofile"]},"application/vnd.irepository.package+xml":{source:"iana",compressible:!0,extensions:["irp"]},"application/vnd.is-xpr":{source:"iana",extensions:["xpr"]},"application/vnd.isac.fcs":{source:"iana",extensions:["fcs"]},"application/vnd.iso11783-10+zip":{source:"iana",compressible:!1},"application/vnd.jam":{source:"iana",extensions:["jam"]},"application/vnd.japannet-directory-service":{source:"iana"},"application/vnd.japannet-jpnstore-wakeup":{source:"iana"},"application/vnd.japannet-payment-wakeup":{source:"iana"},"application/vnd.japannet-registration":{source:"iana"},"application/vnd.japannet-registration-wakeup":{source:"iana"},"application/vnd.japannet-setstore-wakeup":{source:"iana"},"application/vnd.japannet-verification":{source:"iana"},"application/vnd.japannet-verification-wakeup":{source:"iana"},"application/vnd.jcp.javame.midlet-rms":{source:"iana",extensions:["rms"]},"application/vnd.jisp":{source:"iana",extensions:["jisp"]},"application/vnd.joost.joda-archive":{source:"iana",extensions:["joda"]},"application/vnd.jsk.isdn-ngn":{source:"iana"},"application/vnd.kahootz":{source:"iana",extensions:["ktz","ktr"]},"application/vnd.kde.karbon":{source:"iana",extensions:["karbon"]},"application/vnd.kde.kchart":{source:"iana",extensions:["chrt"]},"application/vnd.kde.kformula":{source:"iana",extensions:["kfo"]},"application/vnd.kde.kivio":{source:"iana",extensions:["flw"]},"application/vnd.kde.kontour":{source:"iana",extensions:["kon"]},"application/vnd.kde.kpresenter":{source:"iana",extensions:["kpr","kpt"]},"application/vnd.kde.kspread":{source:"iana",extensions:["ksp"]},"application/vnd.kde.kword":{source:"iana",extensions:["kwd","kwt"]},"application/vnd.kenameaapp":{source:"iana",extensions:["htke"]},"application/vnd.kidspiration":{source:"iana",extensions:["kia"]},"application/vnd.kinar":{source:"iana",extensions:["kne","knp"]},"application/vnd.koan":{source:"iana",extensions:["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{source:"iana",extensions:["sse"]},"application/vnd.las":{source:"iana"},"application/vnd.las.las+json":{source:"iana",compressible:!0},"application/vnd.las.las+xml":{source:"iana",compressible:!0,extensions:["lasxml"]},"application/vnd.laszip":{source:"iana"},"application/vnd.leap+json":{source:"iana",compressible:!0},"application/vnd.liberty-request+xml":{source:"iana",compressible:!0},"application/vnd.llamagraphics.life-balance.desktop":{source:"iana",extensions:["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{source:"iana",compressible:!0,extensions:["lbe"]},"application/vnd.logipipe.circuit+zip":{source:"iana",compressible:!1},"application/vnd.loom":{source:"iana"},"application/vnd.lotus-1-2-3":{source:"iana",extensions:["123"]},"application/vnd.lotus-approach":{source:"iana",extensions:["apr"]},"application/vnd.lotus-freelance":{source:"iana",extensions:["pre"]},"application/vnd.lotus-notes":{source:"iana",extensions:["nsf"]},"application/vnd.lotus-organizer":{source:"iana",extensions:["org"]},"application/vnd.lotus-screencam":{source:"iana",extensions:["scm"]},"application/vnd.lotus-wordpro":{source:"iana",extensions:["lwp"]},"application/vnd.macports.portpkg":{source:"iana",extensions:["portpkg"]},"application/vnd.mapbox-vector-tile":{source:"iana",extensions:["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.conftoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.license+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.mdcf":{source:"iana"},"application/vnd.mason+json":{source:"iana",compressible:!0},"application/vnd.maxar.archive.3tz+zip":{source:"iana",compressible:!1},"application/vnd.maxmind.maxmind-db":{source:"iana"},"application/vnd.mcd":{source:"iana",extensions:["mcd"]},"application/vnd.medcalcdata":{source:"iana",extensions:["mc1"]},"application/vnd.mediastation.cdkey":{source:"iana",extensions:["cdkey"]},"application/vnd.meridian-slingshot":{source:"iana"},"application/vnd.mfer":{source:"iana",extensions:["mwf"]},"application/vnd.mfmp":{source:"iana",extensions:["mfm"]},"application/vnd.micro+json":{source:"iana",compressible:!0},"application/vnd.micrografx.flo":{source:"iana",extensions:["flo"]},"application/vnd.micrografx.igx":{source:"iana",extensions:["igx"]},"application/vnd.microsoft.portable-executable":{source:"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{source:"iana"},"application/vnd.miele+json":{source:"iana",compressible:!0},"application/vnd.mif":{source:"iana",extensions:["mif"]},"application/vnd.minisoft-hp3000-save":{source:"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{source:"iana"},"application/vnd.mobius.daf":{source:"iana",extensions:["daf"]},"application/vnd.mobius.dis":{source:"iana",extensions:["dis"]},"application/vnd.mobius.mbk":{source:"iana",extensions:["mbk"]},"application/vnd.mobius.mqy":{source:"iana",extensions:["mqy"]},"application/vnd.mobius.msl":{source:"iana",extensions:["msl"]},"application/vnd.mobius.plc":{source:"iana",extensions:["plc"]},"application/vnd.mobius.txf":{source:"iana",extensions:["txf"]},"application/vnd.mophun.application":{source:"iana",extensions:["mpn"]},"application/vnd.mophun.certificate":{source:"iana",extensions:["mpc"]},"application/vnd.motorola.flexsuite":{source:"iana"},"application/vnd.motorola.flexsuite.adsi":{source:"iana"},"application/vnd.motorola.flexsuite.fis":{source:"iana"},"application/vnd.motorola.flexsuite.gotap":{source:"iana"},"application/vnd.motorola.flexsuite.kmr":{source:"iana"},"application/vnd.motorola.flexsuite.ttc":{source:"iana"},"application/vnd.motorola.flexsuite.wem":{source:"iana"},"application/vnd.motorola.iprm":{source:"iana"},"application/vnd.mozilla.xul+xml":{source:"iana",compressible:!0,extensions:["xul"]},"application/vnd.ms-3mfdocument":{source:"iana"},"application/vnd.ms-artgalry":{source:"iana",extensions:["cil"]},"application/vnd.ms-asf":{source:"iana"},"application/vnd.ms-cab-compressed":{source:"iana",extensions:["cab"]},"application/vnd.ms-color.iccprofile":{source:"apache"},"application/vnd.ms-excel":{source:"iana",compressible:!1,extensions:["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{source:"iana",extensions:["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{source:"iana",extensions:["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{source:"iana",extensions:["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{source:"iana",extensions:["xltm"]},"application/vnd.ms-fontobject":{source:"iana",compressible:!0,extensions:["eot"]},"application/vnd.ms-htmlhelp":{source:"iana",extensions:["chm"]},"application/vnd.ms-ims":{source:"iana",extensions:["ims"]},"application/vnd.ms-lrm":{source:"iana",extensions:["lrm"]},"application/vnd.ms-office.activex+xml":{source:"iana",compressible:!0},"application/vnd.ms-officetheme":{source:"iana",extensions:["thmx"]},"application/vnd.ms-opentype":{source:"apache",compressible:!0},"application/vnd.ms-outlook":{compressible:!1,extensions:["msg"]},"application/vnd.ms-package.obfuscated-opentype":{source:"apache"},"application/vnd.ms-pki.seccat":{source:"apache",extensions:["cat"]},"application/vnd.ms-pki.stl":{source:"apache",extensions:["stl"]},"application/vnd.ms-playready.initiator+xml":{source:"iana",compressible:!0},"application/vnd.ms-powerpoint":{source:"iana",compressible:!1,extensions:["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{source:"iana",extensions:["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{source:"iana",extensions:["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{source:"iana",extensions:["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{source:"iana",extensions:["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{source:"iana",extensions:["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{source:"iana",compressible:!0},"application/vnd.ms-printing.printticket+xml":{source:"apache",compressible:!0},"application/vnd.ms-printschematicket+xml":{source:"iana",compressible:!0},"application/vnd.ms-project":{source:"iana",extensions:["mpp","mpt"]},"application/vnd.ms-tnef":{source:"iana"},"application/vnd.ms-windows.devicepairing":{source:"iana"},"application/vnd.ms-windows.nwprinting.oob":{source:"iana"},"application/vnd.ms-windows.printerpairing":{source:"iana"},"application/vnd.ms-windows.wsd.oob":{source:"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.lic-resp":{source:"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.meter-resp":{source:"iana"},"application/vnd.ms-word.document.macroenabled.12":{source:"iana",extensions:["docm"]},"application/vnd.ms-word.template.macroenabled.12":{source:"iana",extensions:["dotm"]},"application/vnd.ms-works":{source:"iana",extensions:["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{source:"iana",extensions:["wpl"]},"application/vnd.ms-xpsdocument":{source:"iana",compressible:!1,extensions:["xps"]},"application/vnd.msa-disk-image":{source:"iana"},"application/vnd.mseq":{source:"iana",extensions:["mseq"]},"application/vnd.msign":{source:"iana"},"application/vnd.multiad.creator":{source:"iana"},"application/vnd.multiad.creator.cif":{source:"iana"},"application/vnd.music-niff":{source:"iana"},"application/vnd.musician":{source:"iana",extensions:["mus"]},"application/vnd.muvee.style":{source:"iana",extensions:["msty"]},"application/vnd.mynfc":{source:"iana",extensions:["taglet"]},"application/vnd.nacamar.ybrid+json":{source:"iana",compressible:!0},"application/vnd.ncd.control":{source:"iana"},"application/vnd.ncd.reference":{source:"iana"},"application/vnd.nearst.inv+json":{source:"iana",compressible:!0},"application/vnd.nebumind.line":{source:"iana"},"application/vnd.nervana":{source:"iana"},"application/vnd.netfpx":{source:"iana"},"application/vnd.neurolanguage.nlu":{source:"iana",extensions:["nlu"]},"application/vnd.nimn":{source:"iana"},"application/vnd.nintendo.nitro.rom":{source:"iana"},"application/vnd.nintendo.snes.rom":{source:"iana"},"application/vnd.nitf":{source:"iana",extensions:["ntf","nitf"]},"application/vnd.noblenet-directory":{source:"iana",extensions:["nnd"]},"application/vnd.noblenet-sealer":{source:"iana",extensions:["nns"]},"application/vnd.noblenet-web":{source:"iana",extensions:["nnw"]},"application/vnd.nokia.catalogs":{source:"iana"},"application/vnd.nokia.conml+wbxml":{source:"iana"},"application/vnd.nokia.conml+xml":{source:"iana",compressible:!0},"application/vnd.nokia.iptv.config+xml":{source:"iana",compressible:!0},"application/vnd.nokia.isds-radio-presets":{source:"iana"},"application/vnd.nokia.landmark+wbxml":{source:"iana"},"application/vnd.nokia.landmark+xml":{source:"iana",compressible:!0},"application/vnd.nokia.landmarkcollection+xml":{source:"iana",compressible:!0},"application/vnd.nokia.n-gage.ac+xml":{source:"iana",compressible:!0,extensions:["ac"]},"application/vnd.nokia.n-gage.data":{source:"iana",extensions:["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{source:"iana",extensions:["n-gage"]},"application/vnd.nokia.ncd":{source:"iana"},"application/vnd.nokia.pcd+wbxml":{source:"iana"},"application/vnd.nokia.pcd+xml":{source:"iana",compressible:!0},"application/vnd.nokia.radio-preset":{source:"iana",extensions:["rpst"]},"application/vnd.nokia.radio-presets":{source:"iana",extensions:["rpss"]},"application/vnd.novadigm.edm":{source:"iana",extensions:["edm"]},"application/vnd.novadigm.edx":{source:"iana",extensions:["edx"]},"application/vnd.novadigm.ext":{source:"iana",extensions:["ext"]},"application/vnd.ntt-local.content-share":{source:"iana"},"application/vnd.ntt-local.file-transfer":{source:"iana"},"application/vnd.ntt-local.ogw_remote-access":{source:"iana"},"application/vnd.ntt-local.sip-ta_remote":{source:"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{source:"iana"},"application/vnd.oasis.opendocument.chart":{source:"iana",extensions:["odc"]},"application/vnd.oasis.opendocument.chart-template":{source:"iana",extensions:["otc"]},"application/vnd.oasis.opendocument.database":{source:"iana",extensions:["odb"]},"application/vnd.oasis.opendocument.formula":{source:"iana",extensions:["odf"]},"application/vnd.oasis.opendocument.formula-template":{source:"iana",extensions:["odft"]},"application/vnd.oasis.opendocument.graphics":{source:"iana",compressible:!1,extensions:["odg"]},"application/vnd.oasis.opendocument.graphics-template":{source:"iana",extensions:["otg"]},"application/vnd.oasis.opendocument.image":{source:"iana",extensions:["odi"]},"application/vnd.oasis.opendocument.image-template":{source:"iana",extensions:["oti"]},"application/vnd.oasis.opendocument.presentation":{source:"iana",compressible:!1,extensions:["odp"]},"application/vnd.oasis.opendocument.presentation-template":{source:"iana",extensions:["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{source:"iana",compressible:!1,extensions:["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{source:"iana",extensions:["ots"]},"application/vnd.oasis.opendocument.text":{source:"iana",compressible:!1,extensions:["odt"]},"application/vnd.oasis.opendocument.text-master":{source:"iana",extensions:["odm"]},"application/vnd.oasis.opendocument.text-template":{source:"iana",extensions:["ott"]},"application/vnd.oasis.opendocument.text-web":{source:"iana",extensions:["oth"]},"application/vnd.obn":{source:"iana"},"application/vnd.ocf+cbor":{source:"iana"},"application/vnd.oci.image.manifest.v1+json":{source:"iana",compressible:!0},"application/vnd.oftn.l10n+json":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessdownload+xml":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessstreaming+xml":{source:"iana",compressible:!0},"application/vnd.oipf.cspg-hexbinary":{source:"iana"},"application/vnd.oipf.dae.svg+xml":{source:"iana",compressible:!0},"application/vnd.oipf.dae.xhtml+xml":{source:"iana",compressible:!0},"application/vnd.oipf.mippvcontrolmessage+xml":{source:"iana",compressible:!0},"application/vnd.oipf.pae.gem":{source:"iana"},"application/vnd.oipf.spdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.oipf.spdlist+xml":{source:"iana",compressible:!0},"application/vnd.oipf.ueprofile+xml":{source:"iana",compressible:!0},"application/vnd.oipf.userprofile+xml":{source:"iana",compressible:!0},"application/vnd.olpc-sugar":{source:"iana",extensions:["xo"]},"application/vnd.oma-scws-config":{source:"iana"},"application/vnd.oma-scws-http-request":{source:"iana"},"application/vnd.oma-scws-http-response":{source:"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.drm-trigger+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.imd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.ltkm":{source:"iana"},"application/vnd.oma.bcast.notification+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.provisioningtrigger":{source:"iana"},"application/vnd.oma.bcast.sgboot":{source:"iana"},"application/vnd.oma.bcast.sgdd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.sgdu":{source:"iana"},"application/vnd.oma.bcast.simple-symbol-container":{source:"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.sprov+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.stkm":{source:"iana"},"application/vnd.oma.cab-address-book+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-feature-handler+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-pcc+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-subs-invite+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-user-prefs+xml":{source:"iana",compressible:!0},"application/vnd.oma.dcd":{source:"iana"},"application/vnd.oma.dcdc":{source:"iana"},"application/vnd.oma.dd2+xml":{source:"iana",compressible:!0,extensions:["dd2"]},"application/vnd.oma.drm.risd+xml":{source:"iana",compressible:!0},"application/vnd.oma.group-usage-list+xml":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+cbor":{source:"iana"},"application/vnd.oma.lwm2m+json":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+tlv":{source:"iana"},"application/vnd.oma.pal+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.detailed-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.final-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.groups+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.invocation-descriptor+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.optimized-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.push":{source:"iana"},"application/vnd.oma.scidm.messages+xml":{source:"iana",compressible:!0},"application/vnd.oma.xcap-directory+xml":{source:"iana",compressible:!0},"application/vnd.omads-email+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-file+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-folder+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omaloc-supl-init":{source:"iana"},"application/vnd.onepager":{source:"iana"},"application/vnd.onepagertamp":{source:"iana"},"application/vnd.onepagertamx":{source:"iana"},"application/vnd.onepagertat":{source:"iana"},"application/vnd.onepagertatp":{source:"iana"},"application/vnd.onepagertatx":{source:"iana"},"application/vnd.openblox.game+xml":{source:"iana",compressible:!0,extensions:["obgx"]},"application/vnd.openblox.game-binary":{source:"iana"},"application/vnd.openeye.oeb":{source:"iana"},"application/vnd.openofficeorg.extension":{source:"apache",extensions:["oxt"]},"application/vnd.openstreetmap.data+xml":{source:"iana",compressible:!0,extensions:["osm"]},"application/vnd.opentimestamps.ots":{source:"iana"},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawing+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{source:"iana",compressible:!1,extensions:["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slide":{source:"iana",extensions:["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{source:"iana",extensions:["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.template":{source:"iana",extensions:["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{source:"iana",compressible:!1,extensions:["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{source:"iana",extensions:["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.theme+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.vmldrawing":{source:"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{source:"iana",compressible:!1,extensions:["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{source:"iana",extensions:["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.core-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.relationships+xml":{source:"iana",compressible:!0},"application/vnd.oracle.resource+json":{source:"iana",compressible:!0},"application/vnd.orange.indata":{source:"iana"},"application/vnd.osa.netdeploy":{source:"iana"},"application/vnd.osgeo.mapguide.package":{source:"iana",extensions:["mgp"]},"application/vnd.osgi.bundle":{source:"iana"},"application/vnd.osgi.dp":{source:"iana",extensions:["dp"]},"application/vnd.osgi.subsystem":{source:"iana",extensions:["esa"]},"application/vnd.otps.ct-kip+xml":{source:"iana",compressible:!0},"application/vnd.oxli.countgraph":{source:"iana"},"application/vnd.pagerduty+json":{source:"iana",compressible:!0},"application/vnd.palm":{source:"iana",extensions:["pdb","pqa","oprc"]},"application/vnd.panoply":{source:"iana"},"application/vnd.paos.xml":{source:"iana"},"application/vnd.patentdive":{source:"iana"},"application/vnd.patientecommsdoc":{source:"iana"},"application/vnd.pawaafile":{source:"iana",extensions:["paw"]},"application/vnd.pcos":{source:"iana"},"application/vnd.pg.format":{source:"iana",extensions:["str"]},"application/vnd.pg.osasli":{source:"iana",extensions:["ei6"]},"application/vnd.piaccess.application-licence":{source:"iana"},"application/vnd.picsel":{source:"iana",extensions:["efif"]},"application/vnd.pmi.widget":{source:"iana",extensions:["wg"]},"application/vnd.poc.group-advertisement+xml":{source:"iana",compressible:!0},"application/vnd.pocketlearn":{source:"iana",extensions:["plf"]},"application/vnd.powerbuilder6":{source:"iana",extensions:["pbd"]},"application/vnd.powerbuilder6-s":{source:"iana"},"application/vnd.powerbuilder7":{source:"iana"},"application/vnd.powerbuilder7-s":{source:"iana"},"application/vnd.powerbuilder75":{source:"iana"},"application/vnd.powerbuilder75-s":{source:"iana"},"application/vnd.preminet":{source:"iana"},"application/vnd.previewsystems.box":{source:"iana",extensions:["box"]},"application/vnd.proteus.magazine":{source:"iana",extensions:["mgz"]},"application/vnd.psfs":{source:"iana"},"application/vnd.publishare-delta-tree":{source:"iana",extensions:["qps"]},"application/vnd.pvi.ptid1":{source:"iana",extensions:["ptid"]},"application/vnd.pwg-multiplexed":{source:"iana"},"application/vnd.pwg-xhtml-print+xml":{source:"iana",compressible:!0},"application/vnd.qualcomm.brew-app-res":{source:"iana"},"application/vnd.quarantainenet":{source:"iana"},"application/vnd.quark.quarkxpress":{source:"iana",extensions:["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{source:"iana"},"application/vnd.radisys.moml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conn+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-stream+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-base+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-detect+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-group+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-speech+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-transform+xml":{source:"iana",compressible:!0},"application/vnd.rainstor.data":{source:"iana"},"application/vnd.rapid":{source:"iana"},"application/vnd.rar":{source:"iana",extensions:["rar"]},"application/vnd.realvnc.bed":{source:"iana",extensions:["bed"]},"application/vnd.recordare.musicxml":{source:"iana",extensions:["mxl"]},"application/vnd.recordare.musicxml+xml":{source:"iana",compressible:!0,extensions:["musicxml"]},"application/vnd.renlearn.rlprint":{source:"iana"},"application/vnd.resilient.logic":{source:"iana"},"application/vnd.restful+json":{source:"iana",compressible:!0},"application/vnd.rig.cryptonote":{source:"iana",extensions:["cryptonote"]},"application/vnd.rim.cod":{source:"apache",extensions:["cod"]},"application/vnd.rn-realmedia":{source:"apache",extensions:["rm"]},"application/vnd.rn-realmedia-vbr":{source:"apache",extensions:["rmvb"]},"application/vnd.route66.link66+xml":{source:"iana",compressible:!0,extensions:["link66"]},"application/vnd.rs-274x":{source:"iana"},"application/vnd.ruckus.download":{source:"iana"},"application/vnd.s3sms":{source:"iana"},"application/vnd.sailingtracker.track":{source:"iana",extensions:["st"]},"application/vnd.sar":{source:"iana"},"application/vnd.sbm.cid":{source:"iana"},"application/vnd.sbm.mid2":{source:"iana"},"application/vnd.scribus":{source:"iana"},"application/vnd.sealed.3df":{source:"iana"},"application/vnd.sealed.csf":{source:"iana"},"application/vnd.sealed.doc":{source:"iana"},"application/vnd.sealed.eml":{source:"iana"},"application/vnd.sealed.mht":{source:"iana"},"application/vnd.sealed.net":{source:"iana"},"application/vnd.sealed.ppt":{source:"iana"},"application/vnd.sealed.tiff":{source:"iana"},"application/vnd.sealed.xls":{source:"iana"},"application/vnd.sealedmedia.softseal.html":{source:"iana"},"application/vnd.sealedmedia.softseal.pdf":{source:"iana"},"application/vnd.seemail":{source:"iana",extensions:["see"]},"application/vnd.seis+json":{source:"iana",compressible:!0},"application/vnd.sema":{source:"iana",extensions:["sema"]},"application/vnd.semd":{source:"iana",extensions:["semd"]},"application/vnd.semf":{source:"iana",extensions:["semf"]},"application/vnd.shade-save-file":{source:"iana"},"application/vnd.shana.informed.formdata":{source:"iana",extensions:["ifm"]},"application/vnd.shana.informed.formtemplate":{source:"iana",extensions:["itp"]},"application/vnd.shana.informed.interchange":{source:"iana",extensions:["iif"]},"application/vnd.shana.informed.package":{source:"iana",extensions:["ipk"]},"application/vnd.shootproof+json":{source:"iana",compressible:!0},"application/vnd.shopkick+json":{source:"iana",compressible:!0},"application/vnd.shp":{source:"iana"},"application/vnd.shx":{source:"iana"},"application/vnd.sigrok.session":{source:"iana"},"application/vnd.simtech-mindmapper":{source:"iana",extensions:["twd","twds"]},"application/vnd.siren+json":{source:"iana",compressible:!0},"application/vnd.smaf":{source:"iana",extensions:["mmf"]},"application/vnd.smart.notebook":{source:"iana"},"application/vnd.smart.teacher":{source:"iana",extensions:["teacher"]},"application/vnd.snesdev-page-table":{source:"iana"},"application/vnd.software602.filler.form+xml":{source:"iana",compressible:!0,extensions:["fo"]},"application/vnd.software602.filler.form-xml-zip":{source:"iana"},"application/vnd.solent.sdkm+xml":{source:"iana",compressible:!0,extensions:["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{source:"iana",extensions:["dxp"]},"application/vnd.spotfire.sfs":{source:"iana",extensions:["sfs"]},"application/vnd.sqlite3":{source:"iana"},"application/vnd.sss-cod":{source:"iana"},"application/vnd.sss-dtf":{source:"iana"},"application/vnd.sss-ntf":{source:"iana"},"application/vnd.stardivision.calc":{source:"apache",extensions:["sdc"]},"application/vnd.stardivision.draw":{source:"apache",extensions:["sda"]},"application/vnd.stardivision.impress":{source:"apache",extensions:["sdd"]},"application/vnd.stardivision.math":{source:"apache",extensions:["smf"]},"application/vnd.stardivision.writer":{source:"apache",extensions:["sdw","vor"]},"application/vnd.stardivision.writer-global":{source:"apache",extensions:["sgl"]},"application/vnd.stepmania.package":{source:"iana",extensions:["smzip"]},"application/vnd.stepmania.stepchart":{source:"iana",extensions:["sm"]},"application/vnd.street-stream":{source:"iana"},"application/vnd.sun.wadl+xml":{source:"iana",compressible:!0,extensions:["wadl"]},"application/vnd.sun.xml.calc":{source:"apache",extensions:["sxc"]},"application/vnd.sun.xml.calc.template":{source:"apache",extensions:["stc"]},"application/vnd.sun.xml.draw":{source:"apache",extensions:["sxd"]},"application/vnd.sun.xml.draw.template":{source:"apache",extensions:["std"]},"application/vnd.sun.xml.impress":{source:"apache",extensions:["sxi"]},"application/vnd.sun.xml.impress.template":{source:"apache",extensions:["sti"]},"application/vnd.sun.xml.math":{source:"apache",extensions:["sxm"]},"application/vnd.sun.xml.writer":{source:"apache",extensions:["sxw"]},"application/vnd.sun.xml.writer.global":{source:"apache",extensions:["sxg"]},"application/vnd.sun.xml.writer.template":{source:"apache",extensions:["stw"]},"application/vnd.sus-calendar":{source:"iana",extensions:["sus","susp"]},"application/vnd.svd":{source:"iana",extensions:["svd"]},"application/vnd.swiftview-ics":{source:"iana"},"application/vnd.sycle+xml":{source:"iana",compressible:!0},"application/vnd.syft+json":{source:"iana",compressible:!0},"application/vnd.symbian.install":{source:"apache",extensions:["sis","sisx"]},"application/vnd.syncml+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xsm"]},"application/vnd.syncml.dm+wbxml":{source:"iana",charset:"UTF-8",extensions:["bdm"]},"application/vnd.syncml.dm+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xdm"]},"application/vnd.syncml.dm.notification":{source:"iana"},"application/vnd.syncml.dmddf+wbxml":{source:"iana"},"application/vnd.syncml.dmddf+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{source:"iana"},"application/vnd.syncml.dmtnds+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.syncml.ds.notification":{source:"iana"},"application/vnd.tableschema+json":{source:"iana",compressible:!0},"application/vnd.tao.intent-module-archive":{source:"iana",extensions:["tao"]},"application/vnd.tcpdump.pcap":{source:"iana",extensions:["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{source:"iana",compressible:!0},"application/vnd.tmd.mediaflex.api+xml":{source:"iana",compressible:!0},"application/vnd.tml":{source:"iana"},"application/vnd.tmobile-livetv":{source:"iana",extensions:["tmo"]},"application/vnd.tri.onesource":{source:"iana"},"application/vnd.trid.tpt":{source:"iana",extensions:["tpt"]},"application/vnd.triscape.mxs":{source:"iana",extensions:["mxs"]},"application/vnd.trueapp":{source:"iana",extensions:["tra"]},"application/vnd.truedoc":{source:"iana"},"application/vnd.ubisoft.webplayer":{source:"iana"},"application/vnd.ufdl":{source:"iana",extensions:["ufd","ufdl"]},"application/vnd.uiq.theme":{source:"iana",extensions:["utz"]},"application/vnd.umajin":{source:"iana",extensions:["umj"]},"application/vnd.unity":{source:"iana",extensions:["unityweb"]},"application/vnd.uoml+xml":{source:"iana",compressible:!0,extensions:["uoml"]},"application/vnd.uplanet.alert":{source:"iana"},"application/vnd.uplanet.alert-wbxml":{source:"iana"},"application/vnd.uplanet.bearer-choice":{source:"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{source:"iana"},"application/vnd.uplanet.cacheop":{source:"iana"},"application/vnd.uplanet.cacheop-wbxml":{source:"iana"},"application/vnd.uplanet.channel":{source:"iana"},"application/vnd.uplanet.channel-wbxml":{source:"iana"},"application/vnd.uplanet.list":{source:"iana"},"application/vnd.uplanet.list-wbxml":{source:"iana"},"application/vnd.uplanet.listcmd":{source:"iana"},"application/vnd.uplanet.listcmd-wbxml":{source:"iana"},"application/vnd.uplanet.signal":{source:"iana"},"application/vnd.uri-map":{source:"iana"},"application/vnd.valve.source.material":{source:"iana"},"application/vnd.vcx":{source:"iana",extensions:["vcx"]},"application/vnd.vd-study":{source:"iana"},"application/vnd.vectorworks":{source:"iana"},"application/vnd.vel+json":{source:"iana",compressible:!0},"application/vnd.verimatrix.vcas":{source:"iana"},"application/vnd.veritone.aion+json":{source:"iana",compressible:!0},"application/vnd.veryant.thin":{source:"iana"},"application/vnd.ves.encrypted":{source:"iana"},"application/vnd.vidsoft.vidconference":{source:"iana"},"application/vnd.visio":{source:"iana",extensions:["vsd","vst","vss","vsw"]},"application/vnd.visionary":{source:"iana",extensions:["vis"]},"application/vnd.vividence.scriptfile":{source:"iana"},"application/vnd.vsf":{source:"iana",extensions:["vsf"]},"application/vnd.wap.sic":{source:"iana"},"application/vnd.wap.slc":{source:"iana"},"application/vnd.wap.wbxml":{source:"iana",charset:"UTF-8",extensions:["wbxml"]},"application/vnd.wap.wmlc":{source:"iana",extensions:["wmlc"]},"application/vnd.wap.wmlscriptc":{source:"iana",extensions:["wmlsc"]},"application/vnd.webturbo":{source:"iana",extensions:["wtb"]},"application/vnd.wfa.dpp":{source:"iana"},"application/vnd.wfa.p2p":{source:"iana"},"application/vnd.wfa.wsc":{source:"iana"},"application/vnd.windows.devicepairing":{source:"iana"},"application/vnd.wmc":{source:"iana"},"application/vnd.wmf.bootstrap":{source:"iana"},"application/vnd.wolfram.mathematica":{source:"iana"},"application/vnd.wolfram.mathematica.package":{source:"iana"},"application/vnd.wolfram.player":{source:"iana",extensions:["nbp"]},"application/vnd.wordperfect":{source:"iana",extensions:["wpd"]},"application/vnd.wqd":{source:"iana",extensions:["wqd"]},"application/vnd.wrq-hp3000-labelled":{source:"iana"},"application/vnd.wt.stf":{source:"iana",extensions:["stf"]},"application/vnd.wv.csp+wbxml":{source:"iana"},"application/vnd.wv.csp+xml":{source:"iana",compressible:!0},"application/vnd.wv.ssp+xml":{source:"iana",compressible:!0},"application/vnd.xacml+json":{source:"iana",compressible:!0},"application/vnd.xara":{source:"iana",extensions:["xar"]},"application/vnd.xfdl":{source:"iana",extensions:["xfdl"]},"application/vnd.xfdl.webform":{source:"iana"},"application/vnd.xmi+xml":{source:"iana",compressible:!0},"application/vnd.xmpie.cpkg":{source:"iana"},"application/vnd.xmpie.dpkg":{source:"iana"},"application/vnd.xmpie.plan":{source:"iana"},"application/vnd.xmpie.ppkg":{source:"iana"},"application/vnd.xmpie.xlim":{source:"iana"},"application/vnd.yamaha.hv-dic":{source:"iana",extensions:["hvd"]},"application/vnd.yamaha.hv-script":{source:"iana",extensions:["hvs"]},"application/vnd.yamaha.hv-voice":{source:"iana",extensions:["hvp"]},"application/vnd.yamaha.openscoreformat":{source:"iana",extensions:["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{source:"iana",compressible:!0,extensions:["osfpvg"]},"application/vnd.yamaha.remote-setup":{source:"iana"},"application/vnd.yamaha.smaf-audio":{source:"iana",extensions:["saf"]},"application/vnd.yamaha.smaf-phrase":{source:"iana",extensions:["spf"]},"application/vnd.yamaha.through-ngn":{source:"iana"},"application/vnd.yamaha.tunnel-udpencap":{source:"iana"},"application/vnd.yaoweme":{source:"iana"},"application/vnd.yellowriver-custom-menu":{source:"iana",extensions:["cmp"]},"application/vnd.youtube.yt":{source:"iana"},"application/vnd.zul":{source:"iana",extensions:["zir","zirz"]},"application/vnd.zzazz.deck+xml":{source:"iana",compressible:!0,extensions:["zaz"]},"application/voicexml+xml":{source:"iana",compressible:!0,extensions:["vxml"]},"application/voucher-cms+json":{source:"iana",compressible:!0},"application/vq-rtcpxr":{source:"iana"},"application/wasm":{source:"iana",compressible:!0,extensions:["wasm"]},"application/watcherinfo+xml":{source:"iana",compressible:!0,extensions:["wif"]},"application/webpush-options+json":{source:"iana",compressible:!0},"application/whoispp-query":{source:"iana"},"application/whoispp-response":{source:"iana"},"application/widget":{source:"iana",extensions:["wgt"]},"application/winhlp":{source:"apache",extensions:["hlp"]},"application/wita":{source:"iana"},"application/wordperfect5.1":{source:"iana"},"application/wsdl+xml":{source:"iana",compressible:!0,extensions:["wsdl"]},"application/wspolicy+xml":{source:"iana",compressible:!0,extensions:["wspolicy"]},"application/x-7z-compressed":{source:"apache",compressible:!1,extensions:["7z"]},"application/x-abiword":{source:"apache",extensions:["abw"]},"application/x-ace-compressed":{source:"apache",extensions:["ace"]},"application/x-amf":{source:"apache"},"application/x-apple-diskimage":{source:"apache",extensions:["dmg"]},"application/x-arj":{compressible:!1,extensions:["arj"]},"application/x-authorware-bin":{source:"apache",extensions:["aab","x32","u32","vox"]},"application/x-authorware-map":{source:"apache",extensions:["aam"]},"application/x-authorware-seg":{source:"apache",extensions:["aas"]},"application/x-bcpio":{source:"apache",extensions:["bcpio"]},"application/x-bdoc":{compressible:!1,extensions:["bdoc"]},"application/x-bittorrent":{source:"apache",extensions:["torrent"]},"application/x-blorb":{source:"apache",extensions:["blb","blorb"]},"application/x-bzip":{source:"apache",compressible:!1,extensions:["bz"]},"application/x-bzip2":{source:"apache",compressible:!1,extensions:["bz2","boz"]},"application/x-cbr":{source:"apache",extensions:["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{source:"apache",extensions:["vcd"]},"application/x-cfs-compressed":{source:"apache",extensions:["cfs"]},"application/x-chat":{source:"apache",extensions:["chat"]},"application/x-chess-pgn":{source:"apache",extensions:["pgn"]},"application/x-chrome-extension":{extensions:["crx"]},"application/x-cocoa":{source:"nginx",extensions:["cco"]},"application/x-compress":{source:"apache"},"application/x-conference":{source:"apache",extensions:["nsc"]},"application/x-cpio":{source:"apache",extensions:["cpio"]},"application/x-csh":{source:"apache",extensions:["csh"]},"application/x-deb":{compressible:!1},"application/x-debian-package":{source:"apache",extensions:["deb","udeb"]},"application/x-dgc-compressed":{source:"apache",extensions:["dgc"]},"application/x-director":{source:"apache",extensions:["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{source:"apache",extensions:["wad"]},"application/x-dtbncx+xml":{source:"apache",compressible:!0,extensions:["ncx"]},"application/x-dtbook+xml":{source:"apache",compressible:!0,extensions:["dtb"]},"application/x-dtbresource+xml":{source:"apache",compressible:!0,extensions:["res"]},"application/x-dvi":{source:"apache",compressible:!1,extensions:["dvi"]},"application/x-envoy":{source:"apache",extensions:["evy"]},"application/x-eva":{source:"apache",extensions:["eva"]},"application/x-font-bdf":{source:"apache",extensions:["bdf"]},"application/x-font-dos":{source:"apache"},"application/x-font-framemaker":{source:"apache"},"application/x-font-ghostscript":{source:"apache",extensions:["gsf"]},"application/x-font-libgrx":{source:"apache"},"application/x-font-linux-psf":{source:"apache",extensions:["psf"]},"application/x-font-pcf":{source:"apache",extensions:["pcf"]},"application/x-font-snf":{source:"apache",extensions:["snf"]},"application/x-font-speedo":{source:"apache"},"application/x-font-sunos-news":{source:"apache"},"application/x-font-type1":{source:"apache",extensions:["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{source:"apache"},"application/x-freearc":{source:"apache",extensions:["arc"]},"application/x-futuresplash":{source:"apache",extensions:["spl"]},"application/x-gca-compressed":{source:"apache",extensions:["gca"]},"application/x-glulx":{source:"apache",extensions:["ulx"]},"application/x-gnumeric":{source:"apache",extensions:["gnumeric"]},"application/x-gramps-xml":{source:"apache",extensions:["gramps"]},"application/x-gtar":{source:"apache",extensions:["gtar"]},"application/x-gzip":{source:"apache"},"application/x-hdf":{source:"apache",extensions:["hdf"]},"application/x-httpd-php":{compressible:!0,extensions:["php"]},"application/x-install-instructions":{source:"apache",extensions:["install"]},"application/x-iso9660-image":{source:"apache",extensions:["iso"]},"application/x-iwork-keynote-sffkey":{extensions:["key"]},"application/x-iwork-numbers-sffnumbers":{extensions:["numbers"]},"application/x-iwork-pages-sffpages":{extensions:["pages"]},"application/x-java-archive-diff":{source:"nginx",extensions:["jardiff"]},"application/x-java-jnlp-file":{source:"apache",compressible:!1,extensions:["jnlp"]},"application/x-javascript":{compressible:!0},"application/x-keepass2":{extensions:["kdbx"]},"application/x-latex":{source:"apache",compressible:!1,extensions:["latex"]},"application/x-lua-bytecode":{extensions:["luac"]},"application/x-lzh-compressed":{source:"apache",extensions:["lzh","lha"]},"application/x-makeself":{source:"nginx",extensions:["run"]},"application/x-mie":{source:"apache",extensions:["mie"]},"application/x-mobipocket-ebook":{source:"apache",extensions:["prc","mobi"]},"application/x-mpegurl":{compressible:!1},"application/x-ms-application":{source:"apache",extensions:["application"]},"application/x-ms-shortcut":{source:"apache",extensions:["lnk"]},"application/x-ms-wmd":{source:"apache",extensions:["wmd"]},"application/x-ms-wmz":{source:"apache",extensions:["wmz"]},"application/x-ms-xbap":{source:"apache",extensions:["xbap"]},"application/x-msaccess":{source:"apache",extensions:["mdb"]},"application/x-msbinder":{source:"apache",extensions:["obd"]},"application/x-mscardfile":{source:"apache",extensions:["crd"]},"application/x-msclip":{source:"apache",extensions:["clp"]},"application/x-msdos-program":{extensions:["exe"]},"application/x-msdownload":{source:"apache",extensions:["exe","dll","com","bat","msi"]},"application/x-msmediaview":{source:"apache",extensions:["mvb","m13","m14"]},"application/x-msmetafile":{source:"apache",extensions:["wmf","wmz","emf","emz"]},"application/x-msmoney":{source:"apache",extensions:["mny"]},"application/x-mspublisher":{source:"apache",extensions:["pub"]},"application/x-msschedule":{source:"apache",extensions:["scd"]},"application/x-msterminal":{source:"apache",extensions:["trm"]},"application/x-mswrite":{source:"apache",extensions:["wri"]},"application/x-netcdf":{source:"apache",extensions:["nc","cdf"]},"application/x-ns-proxy-autoconfig":{compressible:!0,extensions:["pac"]},"application/x-nzb":{source:"apache",extensions:["nzb"]},"application/x-perl":{source:"nginx",extensions:["pl","pm"]},"application/x-pilot":{source:"nginx",extensions:["prc","pdb"]},"application/x-pkcs12":{source:"apache",compressible:!1,extensions:["p12","pfx"]},"application/x-pkcs7-certificates":{source:"apache",extensions:["p7b","spc"]},"application/x-pkcs7-certreqresp":{source:"apache",extensions:["p7r"]},"application/x-pki-message":{source:"iana"},"application/x-rar-compressed":{source:"apache",compressible:!1,extensions:["rar"]},"application/x-redhat-package-manager":{source:"nginx",extensions:["rpm"]},"application/x-research-info-systems":{source:"apache",extensions:["ris"]},"application/x-sea":{source:"nginx",extensions:["sea"]},"application/x-sh":{source:"apache",compressible:!0,extensions:["sh"]},"application/x-shar":{source:"apache",extensions:["shar"]},"application/x-shockwave-flash":{source:"apache",compressible:!1,extensions:["swf"]},"application/x-silverlight-app":{source:"apache",extensions:["xap"]},"application/x-sql":{source:"apache",extensions:["sql"]},"application/x-stuffit":{source:"apache",compressible:!1,extensions:["sit"]},"application/x-stuffitx":{source:"apache",extensions:["sitx"]},"application/x-subrip":{source:"apache",extensions:["srt"]},"application/x-sv4cpio":{source:"apache",extensions:["sv4cpio"]},"application/x-sv4crc":{source:"apache",extensions:["sv4crc"]},"application/x-t3vm-image":{source:"apache",extensions:["t3"]},"application/x-tads":{source:"apache",extensions:["gam"]},"application/x-tar":{source:"apache",compressible:!0,extensions:["tar"]},"application/x-tcl":{source:"apache",extensions:["tcl","tk"]},"application/x-tex":{source:"apache",extensions:["tex"]},"application/x-tex-tfm":{source:"apache",extensions:["tfm"]},"application/x-texinfo":{source:"apache",extensions:["texinfo","texi"]},"application/x-tgif":{source:"apache",extensions:["obj"]},"application/x-ustar":{source:"apache",extensions:["ustar"]},"application/x-virtualbox-hdd":{compressible:!0,extensions:["hdd"]},"application/x-virtualbox-ova":{compressible:!0,extensions:["ova"]},"application/x-virtualbox-ovf":{compressible:!0,extensions:["ovf"]},"application/x-virtualbox-vbox":{compressible:!0,extensions:["vbox"]},"application/x-virtualbox-vbox-extpack":{compressible:!1,extensions:["vbox-extpack"]},"application/x-virtualbox-vdi":{compressible:!0,extensions:["vdi"]},"application/x-virtualbox-vhd":{compressible:!0,extensions:["vhd"]},"application/x-virtualbox-vmdk":{compressible:!0,extensions:["vmdk"]},"application/x-wais-source":{source:"apache",extensions:["src"]},"application/x-web-app-manifest+json":{compressible:!0,extensions:["webapp"]},"application/x-www-form-urlencoded":{source:"iana",compressible:!0},"application/x-x509-ca-cert":{source:"iana",extensions:["der","crt","pem"]},"application/x-x509-ca-ra-cert":{source:"iana"},"application/x-x509-next-ca-cert":{source:"iana"},"application/x-xfig":{source:"apache",extensions:["fig"]},"application/x-xliff+xml":{source:"apache",compressible:!0,extensions:["xlf"]},"application/x-xpinstall":{source:"apache",compressible:!1,extensions:["xpi"]},"application/x-xz":{source:"apache",extensions:["xz"]},"application/x-zmachine":{source:"apache",extensions:["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{source:"iana"},"application/xacml+xml":{source:"iana",compressible:!0},"application/xaml+xml":{source:"apache",compressible:!0,extensions:["xaml"]},"application/xcap-att+xml":{source:"iana",compressible:!0,extensions:["xav"]},"application/xcap-caps+xml":{source:"iana",compressible:!0,extensions:["xca"]},"application/xcap-diff+xml":{source:"iana",compressible:!0,extensions:["xdf"]},"application/xcap-el+xml":{source:"iana",compressible:!0,extensions:["xel"]},"application/xcap-error+xml":{source:"iana",compressible:!0},"application/xcap-ns+xml":{source:"iana",compressible:!0,extensions:["xns"]},"application/xcon-conference-info+xml":{source:"iana",compressible:!0},"application/xcon-conference-info-diff+xml":{source:"iana",compressible:!0},"application/xenc+xml":{source:"iana",compressible:!0,extensions:["xenc"]},"application/xhtml+xml":{source:"iana",compressible:!0,extensions:["xhtml","xht"]},"application/xhtml-voice+xml":{source:"apache",compressible:!0},"application/xliff+xml":{source:"iana",compressible:!0,extensions:["xlf"]},"application/xml":{source:"iana",compressible:!0,extensions:["xml","xsl","xsd","rng"]},"application/xml-dtd":{source:"iana",compressible:!0,extensions:["dtd"]},"application/xml-external-parsed-entity":{source:"iana"},"application/xml-patch+xml":{source:"iana",compressible:!0},"application/xmpp+xml":{source:"iana",compressible:!0},"application/xop+xml":{source:"iana",compressible:!0,extensions:["xop"]},"application/xproc+xml":{source:"apache",compressible:!0,extensions:["xpl"]},"application/xslt+xml":{source:"iana",compressible:!0,extensions:["xsl","xslt"]},"application/xspf+xml":{source:"apache",compressible:!0,extensions:["xspf"]},"application/xv+xml":{source:"iana",compressible:!0,extensions:["mxml","xhvml","xvml","xvm"]},"application/yang":{source:"iana",extensions:["yang"]},"application/yang-data+json":{source:"iana",compressible:!0},"application/yang-data+xml":{source:"iana",compressible:!0},"application/yang-patch+json":{source:"iana",compressible:!0},"application/yang-patch+xml":{source:"iana",compressible:!0},"application/yin+xml":{source:"iana",compressible:!0,extensions:["yin"]},"application/zip":{source:"iana",compressible:!1,extensions:["zip"]},"application/zlib":{source:"iana"},"application/zstd":{source:"iana"},"audio/1d-interleaved-parityfec":{source:"iana"},"audio/32kadpcm":{source:"iana"},"audio/3gpp":{source:"iana",compressible:!1,extensions:["3gpp"]},"audio/3gpp2":{source:"iana"},"audio/aac":{source:"iana"},"audio/ac3":{source:"iana"},"audio/adpcm":{source:"apache",extensions:["adp"]},"audio/amr":{source:"iana",extensions:["amr"]},"audio/amr-wb":{source:"iana"},"audio/amr-wb+":{source:"iana"},"audio/aptx":{source:"iana"},"audio/asc":{source:"iana"},"audio/atrac-advanced-lossless":{source:"iana"},"audio/atrac-x":{source:"iana"},"audio/atrac3":{source:"iana"},"audio/basic":{source:"iana",compressible:!1,extensions:["au","snd"]},"audio/bv16":{source:"iana"},"audio/bv32":{source:"iana"},"audio/clearmode":{source:"iana"},"audio/cn":{source:"iana"},"audio/dat12":{source:"iana"},"audio/dls":{source:"iana"},"audio/dsr-es201108":{source:"iana"},"audio/dsr-es202050":{source:"iana"},"audio/dsr-es202211":{source:"iana"},"audio/dsr-es202212":{source:"iana"},"audio/dv":{source:"iana"},"audio/dvi4":{source:"iana"},"audio/eac3":{source:"iana"},"audio/encaprtp":{source:"iana"},"audio/evrc":{source:"iana"},"audio/evrc-qcp":{source:"iana"},"audio/evrc0":{source:"iana"},"audio/evrc1":{source:"iana"},"audio/evrcb":{source:"iana"},"audio/evrcb0":{source:"iana"},"audio/evrcb1":{source:"iana"},"audio/evrcnw":{source:"iana"},"audio/evrcnw0":{source:"iana"},"audio/evrcnw1":{source:"iana"},"audio/evrcwb":{source:"iana"},"audio/evrcwb0":{source:"iana"},"audio/evrcwb1":{source:"iana"},"audio/evs":{source:"iana"},"audio/flexfec":{source:"iana"},"audio/fwdred":{source:"iana"},"audio/g711-0":{source:"iana"},"audio/g719":{source:"iana"},"audio/g722":{source:"iana"},"audio/g7221":{source:"iana"},"audio/g723":{source:"iana"},"audio/g726-16":{source:"iana"},"audio/g726-24":{source:"iana"},"audio/g726-32":{source:"iana"},"audio/g726-40":{source:"iana"},"audio/g728":{source:"iana"},"audio/g729":{source:"iana"},"audio/g7291":{source:"iana"},"audio/g729d":{source:"iana"},"audio/g729e":{source:"iana"},"audio/gsm":{source:"iana"},"audio/gsm-efr":{source:"iana"},"audio/gsm-hr-08":{source:"iana"},"audio/ilbc":{source:"iana"},"audio/ip-mr_v2.5":{source:"iana"},"audio/isac":{source:"apache"},"audio/l16":{source:"iana"},"audio/l20":{source:"iana"},"audio/l24":{source:"iana",compressible:!1},"audio/l8":{source:"iana"},"audio/lpc":{source:"iana"},"audio/melp":{source:"iana"},"audio/melp1200":{source:"iana"},"audio/melp2400":{source:"iana"},"audio/melp600":{source:"iana"},"audio/mhas":{source:"iana"},"audio/midi":{source:"apache",extensions:["mid","midi","kar","rmi"]},"audio/mobile-xmf":{source:"iana",extensions:["mxmf"]},"audio/mp3":{compressible:!1,extensions:["mp3"]},"audio/mp4":{source:"iana",compressible:!1,extensions:["m4a","mp4a"]},"audio/mp4a-latm":{source:"iana"},"audio/mpa":{source:"iana"},"audio/mpa-robust":{source:"iana"},"audio/mpeg":{source:"iana",compressible:!1,extensions:["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{source:"iana"},"audio/musepack":{source:"apache"},"audio/ogg":{source:"iana",compressible:!1,extensions:["oga","ogg","spx","opus"]},"audio/opus":{source:"iana"},"audio/parityfec":{source:"iana"},"audio/pcma":{source:"iana"},"audio/pcma-wb":{source:"iana"},"audio/pcmu":{source:"iana"},"audio/pcmu-wb":{source:"iana"},"audio/prs.sid":{source:"iana"},"audio/qcelp":{source:"iana"},"audio/raptorfec":{source:"iana"},"audio/red":{source:"iana"},"audio/rtp-enc-aescm128":{source:"iana"},"audio/rtp-midi":{source:"iana"},"audio/rtploopback":{source:"iana"},"audio/rtx":{source:"iana"},"audio/s3m":{source:"apache",extensions:["s3m"]},"audio/scip":{source:"iana"},"audio/silk":{source:"apache",extensions:["sil"]},"audio/smv":{source:"iana"},"audio/smv-qcp":{source:"iana"},"audio/smv0":{source:"iana"},"audio/sofa":{source:"iana"},"audio/sp-midi":{source:"iana"},"audio/speex":{source:"iana"},"audio/t140c":{source:"iana"},"audio/t38":{source:"iana"},"audio/telephone-event":{source:"iana"},"audio/tetra_acelp":{source:"iana"},"audio/tetra_acelp_bb":{source:"iana"},"audio/tone":{source:"iana"},"audio/tsvcis":{source:"iana"},"audio/uemclip":{source:"iana"},"audio/ulpfec":{source:"iana"},"audio/usac":{source:"iana"},"audio/vdvi":{source:"iana"},"audio/vmr-wb":{source:"iana"},"audio/vnd.3gpp.iufp":{source:"iana"},"audio/vnd.4sb":{source:"iana"},"audio/vnd.audiokoz":{source:"iana"},"audio/vnd.celp":{source:"iana"},"audio/vnd.cisco.nse":{source:"iana"},"audio/vnd.cmles.radio-events":{source:"iana"},"audio/vnd.cns.anp1":{source:"iana"},"audio/vnd.cns.inf1":{source:"iana"},"audio/vnd.dece.audio":{source:"iana",extensions:["uva","uvva"]},"audio/vnd.digital-winds":{source:"iana",extensions:["eol"]},"audio/vnd.dlna.adts":{source:"iana"},"audio/vnd.dolby.heaac.1":{source:"iana"},"audio/vnd.dolby.heaac.2":{source:"iana"},"audio/vnd.dolby.mlp":{source:"iana"},"audio/vnd.dolby.mps":{source:"iana"},"audio/vnd.dolby.pl2":{source:"iana"},"audio/vnd.dolby.pl2x":{source:"iana"},"audio/vnd.dolby.pl2z":{source:"iana"},"audio/vnd.dolby.pulse.1":{source:"iana"},"audio/vnd.dra":{source:"iana",extensions:["dra"]},"audio/vnd.dts":{source:"iana",extensions:["dts"]},"audio/vnd.dts.hd":{source:"iana",extensions:["dtshd"]},"audio/vnd.dts.uhd":{source:"iana"},"audio/vnd.dvb.file":{source:"iana"},"audio/vnd.everad.plj":{source:"iana"},"audio/vnd.hns.audio":{source:"iana"},"audio/vnd.lucent.voice":{source:"iana",extensions:["lvp"]},"audio/vnd.ms-playready.media.pya":{source:"iana",extensions:["pya"]},"audio/vnd.nokia.mobile-xmf":{source:"iana"},"audio/vnd.nortel.vbk":{source:"iana"},"audio/vnd.nuera.ecelp4800":{source:"iana",extensions:["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{source:"iana",extensions:["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{source:"iana",extensions:["ecelp9600"]},"audio/vnd.octel.sbc":{source:"iana"},"audio/vnd.presonus.multitrack":{source:"iana"},"audio/vnd.qcelp":{source:"iana"},"audio/vnd.rhetorex.32kadpcm":{source:"iana"},"audio/vnd.rip":{source:"iana",extensions:["rip"]},"audio/vnd.rn-realaudio":{compressible:!1},"audio/vnd.sealedmedia.softseal.mpeg":{source:"iana"},"audio/vnd.vmx.cvsd":{source:"iana"},"audio/vnd.wave":{compressible:!1},"audio/vorbis":{source:"iana",compressible:!1},"audio/vorbis-config":{source:"iana"},"audio/wav":{compressible:!1,extensions:["wav"]},"audio/wave":{compressible:!1,extensions:["wav"]},"audio/webm":{source:"apache",compressible:!1,extensions:["weba"]},"audio/x-aac":{source:"apache",compressible:!1,extensions:["aac"]},"audio/x-aiff":{source:"apache",extensions:["aif","aiff","aifc"]},"audio/x-caf":{source:"apache",compressible:!1,extensions:["caf"]},"audio/x-flac":{source:"apache",extensions:["flac"]},"audio/x-m4a":{source:"nginx",extensions:["m4a"]},"audio/x-matroska":{source:"apache",extensions:["mka"]},"audio/x-mpegurl":{source:"apache",extensions:["m3u"]},"audio/x-ms-wax":{source:"apache",extensions:["wax"]},"audio/x-ms-wma":{source:"apache",extensions:["wma"]},"audio/x-pn-realaudio":{source:"apache",extensions:["ram","ra"]},"audio/x-pn-realaudio-plugin":{source:"apache",extensions:["rmp"]},"audio/x-realaudio":{source:"nginx",extensions:["ra"]},"audio/x-tta":{source:"apache"},"audio/x-wav":{source:"apache",extensions:["wav"]},"audio/xm":{source:"apache",extensions:["xm"]},"chemical/x-cdx":{source:"apache",extensions:["cdx"]},"chemical/x-cif":{source:"apache",extensions:["cif"]},"chemical/x-cmdf":{source:"apache",extensions:["cmdf"]},"chemical/x-cml":{source:"apache",extensions:["cml"]},"chemical/x-csml":{source:"apache",extensions:["csml"]},"chemical/x-pdb":{source:"apache"},"chemical/x-xyz":{source:"apache",extensions:["xyz"]},"font/collection":{source:"iana",extensions:["ttc"]},"font/otf":{source:"iana",compressible:!0,extensions:["otf"]},"font/sfnt":{source:"iana"},"font/ttf":{source:"iana",compressible:!0,extensions:["ttf"]},"font/woff":{source:"iana",extensions:["woff"]},"font/woff2":{source:"iana",extensions:["woff2"]},"image/aces":{source:"iana",extensions:["exr"]},"image/apng":{compressible:!1,extensions:["apng"]},"image/avci":{source:"iana",extensions:["avci"]},"image/avcs":{source:"iana",extensions:["avcs"]},"image/avif":{source:"iana",compressible:!1,extensions:["avif"]},"image/bmp":{source:"iana",compressible:!0,extensions:["bmp"]},"image/cgm":{source:"iana",extensions:["cgm"]},"image/dicom-rle":{source:"iana",extensions:["drle"]},"image/emf":{source:"iana",extensions:["emf"]},"image/fits":{source:"iana",extensions:["fits"]},"image/g3fax":{source:"iana",extensions:["g3"]},"image/gif":{source:"iana",compressible:!1,extensions:["gif"]},"image/heic":{source:"iana",extensions:["heic"]},"image/heic-sequence":{source:"iana",extensions:["heics"]},"image/heif":{source:"iana",extensions:["heif"]},"image/heif-sequence":{source:"iana",extensions:["heifs"]},"image/hej2k":{source:"iana",extensions:["hej2"]},"image/hsj2":{source:"iana",extensions:["hsj2"]},"image/ief":{source:"iana",extensions:["ief"]},"image/jls":{source:"iana",extensions:["jls"]},"image/jp2":{source:"iana",compressible:!1,extensions:["jp2","jpg2"]},"image/jpeg":{source:"iana",compressible:!1,extensions:["jpeg","jpg","jpe"]},"image/jph":{source:"iana",extensions:["jph"]},"image/jphc":{source:"iana",extensions:["jhc"]},"image/jpm":{source:"iana",compressible:!1,extensions:["jpm"]},"image/jpx":{source:"iana",compressible:!1,extensions:["jpx","jpf"]},"image/jxr":{source:"iana",extensions:["jxr"]},"image/jxra":{source:"iana",extensions:["jxra"]},"image/jxrs":{source:"iana",extensions:["jxrs"]},"image/jxs":{source:"iana",extensions:["jxs"]},"image/jxsc":{source:"iana",extensions:["jxsc"]},"image/jxsi":{source:"iana",extensions:["jxsi"]},"image/jxss":{source:"iana",extensions:["jxss"]},"image/ktx":{source:"iana",extensions:["ktx"]},"image/ktx2":{source:"iana",extensions:["ktx2"]},"image/naplps":{source:"iana"},"image/pjpeg":{compressible:!1},"image/png":{source:"iana",compressible:!1,extensions:["png"]},"image/prs.btif":{source:"iana",extensions:["btif"]},"image/prs.pti":{source:"iana",extensions:["pti"]},"image/pwg-raster":{source:"iana"},"image/sgi":{source:"apache",extensions:["sgi"]},"image/svg+xml":{source:"iana",compressible:!0,extensions:["svg","svgz"]},"image/t38":{source:"iana",extensions:["t38"]},"image/tiff":{source:"iana",compressible:!1,extensions:["tif","tiff"]},"image/tiff-fx":{source:"iana",extensions:["tfx"]},"image/vnd.adobe.photoshop":{source:"iana",compressible:!0,extensions:["psd"]},"image/vnd.airzip.accelerator.azv":{source:"iana",extensions:["azv"]},"image/vnd.cns.inf2":{source:"iana"},"image/vnd.dece.graphic":{source:"iana",extensions:["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{source:"iana",extensions:["djvu","djv"]},"image/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"image/vnd.dwg":{source:"iana",extensions:["dwg"]},"image/vnd.dxf":{source:"iana",extensions:["dxf"]},"image/vnd.fastbidsheet":{source:"iana",extensions:["fbs"]},"image/vnd.fpx":{source:"iana",extensions:["fpx"]},"image/vnd.fst":{source:"iana",extensions:["fst"]},"image/vnd.fujixerox.edmics-mmr":{source:"iana",extensions:["mmr"]},"image/vnd.fujixerox.edmics-rlc":{source:"iana",extensions:["rlc"]},"image/vnd.globalgraphics.pgb":{source:"iana"},"image/vnd.microsoft.icon":{source:"iana",compressible:!0,extensions:["ico"]},"image/vnd.mix":{source:"iana"},"image/vnd.mozilla.apng":{source:"iana"},"image/vnd.ms-dds":{compressible:!0,extensions:["dds"]},"image/vnd.ms-modi":{source:"iana",extensions:["mdi"]},"image/vnd.ms-photo":{source:"apache",extensions:["wdp"]},"image/vnd.net-fpx":{source:"iana",extensions:["npx"]},"image/vnd.pco.b16":{source:"iana",extensions:["b16"]},"image/vnd.radiance":{source:"iana"},"image/vnd.sealed.png":{source:"iana"},"image/vnd.sealedmedia.softseal.gif":{source:"iana"},"image/vnd.sealedmedia.softseal.jpg":{source:"iana"},"image/vnd.svf":{source:"iana"},"image/vnd.tencent.tap":{source:"iana",extensions:["tap"]},"image/vnd.valve.source.texture":{source:"iana",extensions:["vtf"]},"image/vnd.wap.wbmp":{source:"iana",extensions:["wbmp"]},"image/vnd.xiff":{source:"iana",extensions:["xif"]},"image/vnd.zbrush.pcx":{source:"iana",extensions:["pcx"]},"image/webp":{source:"apache",extensions:["webp"]},"image/wmf":{source:"iana",extensions:["wmf"]},"image/x-3ds":{source:"apache",extensions:["3ds"]},"image/x-cmu-raster":{source:"apache",extensions:["ras"]},"image/x-cmx":{source:"apache",extensions:["cmx"]},"image/x-freehand":{source:"apache",extensions:["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{source:"apache",compressible:!0,extensions:["ico"]},"image/x-jng":{source:"nginx",extensions:["jng"]},"image/x-mrsid-image":{source:"apache",extensions:["sid"]},"image/x-ms-bmp":{source:"nginx",compressible:!0,extensions:["bmp"]},"image/x-pcx":{source:"apache",extensions:["pcx"]},"image/x-pict":{source:"apache",extensions:["pic","pct"]},"image/x-portable-anymap":{source:"apache",extensions:["pnm"]},"image/x-portable-bitmap":{source:"apache",extensions:["pbm"]},"image/x-portable-graymap":{source:"apache",extensions:["pgm"]},"image/x-portable-pixmap":{source:"apache",extensions:["ppm"]},"image/x-rgb":{source:"apache",extensions:["rgb"]},"image/x-tga":{source:"apache",extensions:["tga"]},"image/x-xbitmap":{source:"apache",extensions:["xbm"]},"image/x-xcf":{compressible:!1},"image/x-xpixmap":{source:"apache",extensions:["xpm"]},"image/x-xwindowdump":{source:"apache",extensions:["xwd"]},"message/cpim":{source:"iana"},"message/delivery-status":{source:"iana"},"message/disposition-notification":{source:"iana",extensions:["disposition-notification"]},"message/external-body":{source:"iana"},"message/feedback-report":{source:"iana"},"message/global":{source:"iana",extensions:["u8msg"]},"message/global-delivery-status":{source:"iana",extensions:["u8dsn"]},"message/global-disposition-notification":{source:"iana",extensions:["u8mdn"]},"message/global-headers":{source:"iana",extensions:["u8hdr"]},"message/http":{source:"iana",compressible:!1},"message/imdn+xml":{source:"iana",compressible:!0},"message/news":{source:"iana"},"message/partial":{source:"iana",compressible:!1},"message/rfc822":{source:"iana",compressible:!0,extensions:["eml","mime"]},"message/s-http":{source:"iana"},"message/sip":{source:"iana"},"message/sipfrag":{source:"iana"},"message/tracking-status":{source:"iana"},"message/vnd.si.simp":{source:"iana"},"message/vnd.wfa.wsc":{source:"iana",extensions:["wsc"]},"model/3mf":{source:"iana",extensions:["3mf"]},"model/e57":{source:"iana"},"model/gltf+json":{source:"iana",compressible:!0,extensions:["gltf"]},"model/gltf-binary":{source:"iana",compressible:!0,extensions:["glb"]},"model/iges":{source:"iana",compressible:!1,extensions:["igs","iges"]},"model/mesh":{source:"iana",compressible:!1,extensions:["msh","mesh","silo"]},"model/mtl":{source:"iana",extensions:["mtl"]},"model/obj":{source:"iana",extensions:["obj"]},"model/step":{source:"iana"},"model/step+xml":{source:"iana",compressible:!0,extensions:["stpx"]},"model/step+zip":{source:"iana",compressible:!1,extensions:["stpz"]},"model/step-xml+zip":{source:"iana",compressible:!1,extensions:["stpxz"]},"model/stl":{source:"iana",extensions:["stl"]},"model/vnd.collada+xml":{source:"iana",compressible:!0,extensions:["dae"]},"model/vnd.dwf":{source:"iana",extensions:["dwf"]},"model/vnd.flatland.3dml":{source:"iana"},"model/vnd.gdl":{source:"iana",extensions:["gdl"]},"model/vnd.gs-gdl":{source:"apache"},"model/vnd.gs.gdl":{source:"iana"},"model/vnd.gtw":{source:"iana",extensions:["gtw"]},"model/vnd.moml+xml":{source:"iana",compressible:!0},"model/vnd.mts":{source:"iana",extensions:["mts"]},"model/vnd.opengex":{source:"iana",extensions:["ogex"]},"model/vnd.parasolid.transmit.binary":{source:"iana",extensions:["x_b"]},"model/vnd.parasolid.transmit.text":{source:"iana",extensions:["x_t"]},"model/vnd.pytha.pyox":{source:"iana"},"model/vnd.rosette.annotated-data-model":{source:"iana"},"model/vnd.sap.vds":{source:"iana",extensions:["vds"]},"model/vnd.usdz+zip":{source:"iana",compressible:!1,extensions:["usdz"]},"model/vnd.valve.source.compiled-map":{source:"iana",extensions:["bsp"]},"model/vnd.vtu":{source:"iana",extensions:["vtu"]},"model/vrml":{source:"iana",compressible:!1,extensions:["wrl","vrml"]},"model/x3d+binary":{source:"apache",compressible:!1,extensions:["x3db","x3dbz"]},"model/x3d+fastinfoset":{source:"iana",extensions:["x3db"]},"model/x3d+vrml":{source:"apache",compressible:!1,extensions:["x3dv","x3dvz"]},"model/x3d+xml":{source:"iana",compressible:!0,extensions:["x3d","x3dz"]},"model/x3d-vrml":{source:"iana",extensions:["x3dv"]},"multipart/alternative":{source:"iana",compressible:!1},"multipart/appledouble":{source:"iana"},"multipart/byteranges":{source:"iana"},"multipart/digest":{source:"iana"},"multipart/encrypted":{source:"iana",compressible:!1},"multipart/form-data":{source:"iana",compressible:!1},"multipart/header-set":{source:"iana"},"multipart/mixed":{source:"iana"},"multipart/multilingual":{source:"iana"},"multipart/parallel":{source:"iana"},"multipart/related":{source:"iana",compressible:!1},"multipart/report":{source:"iana"},"multipart/signed":{source:"iana",compressible:!1},"multipart/vnd.bint.med-plus":{source:"iana"},"multipart/voice-message":{source:"iana"},"multipart/x-mixed-replace":{source:"iana"},"text/1d-interleaved-parityfec":{source:"iana"},"text/cache-manifest":{source:"iana",compressible:!0,extensions:["appcache","manifest"]},"text/calendar":{source:"iana",extensions:["ics","ifb"]},"text/calender":{compressible:!0},"text/cmd":{compressible:!0},"text/coffeescript":{extensions:["coffee","litcoffee"]},"text/cql":{source:"iana"},"text/cql-expression":{source:"iana"},"text/cql-identifier":{source:"iana"},"text/css":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["css"]},"text/csv":{source:"iana",compressible:!0,extensions:["csv"]},"text/csv-schema":{source:"iana"},"text/directory":{source:"iana"},"text/dns":{source:"iana"},"text/ecmascript":{source:"iana"},"text/encaprtp":{source:"iana"},"text/enriched":{source:"iana"},"text/fhirpath":{source:"iana"},"text/flexfec":{source:"iana"},"text/fwdred":{source:"iana"},"text/gff3":{source:"iana"},"text/grammar-ref-list":{source:"iana"},"text/html":{source:"iana",compressible:!0,extensions:["html","htm","shtml"]},"text/jade":{extensions:["jade"]},"text/javascript":{source:"iana",compressible:!0},"text/jcr-cnd":{source:"iana"},"text/jsx":{compressible:!0,extensions:["jsx"]},"text/less":{compressible:!0,extensions:["less"]},"text/markdown":{source:"iana",compressible:!0,extensions:["markdown","md"]},"text/mathml":{source:"nginx",extensions:["mml"]},"text/mdx":{compressible:!0,extensions:["mdx"]},"text/mizar":{source:"iana"},"text/n3":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["n3"]},"text/parameters":{source:"iana",charset:"UTF-8"},"text/parityfec":{source:"iana"},"text/plain":{source:"iana",compressible:!0,extensions:["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{source:"iana",charset:"UTF-8"},"text/prs.fallenstein.rst":{source:"iana"},"text/prs.lines.tag":{source:"iana",extensions:["dsc"]},"text/prs.prop.logic":{source:"iana"},"text/raptorfec":{source:"iana"},"text/red":{source:"iana"},"text/rfc822-headers":{source:"iana"},"text/richtext":{source:"iana",compressible:!0,extensions:["rtx"]},"text/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"text/rtp-enc-aescm128":{source:"iana"},"text/rtploopback":{source:"iana"},"text/rtx":{source:"iana"},"text/sgml":{source:"iana",extensions:["sgml","sgm"]},"text/shaclc":{source:"iana"},"text/shex":{source:"iana",extensions:["shex"]},"text/slim":{extensions:["slim","slm"]},"text/spdx":{source:"iana",extensions:["spdx"]},"text/strings":{source:"iana"},"text/stylus":{extensions:["stylus","styl"]},"text/t140":{source:"iana"},"text/tab-separated-values":{source:"iana",compressible:!0,extensions:["tsv"]},"text/troff":{source:"iana",extensions:["t","tr","roff","man","me","ms"]},"text/turtle":{source:"iana",charset:"UTF-8",extensions:["ttl"]},"text/ulpfec":{source:"iana"},"text/uri-list":{source:"iana",compressible:!0,extensions:["uri","uris","urls"]},"text/vcard":{source:"iana",compressible:!0,extensions:["vcard"]},"text/vnd.a":{source:"iana"},"text/vnd.abc":{source:"iana"},"text/vnd.ascii-art":{source:"iana"},"text/vnd.curl":{source:"iana",extensions:["curl"]},"text/vnd.curl.dcurl":{source:"apache",extensions:["dcurl"]},"text/vnd.curl.mcurl":{source:"apache",extensions:["mcurl"]},"text/vnd.curl.scurl":{source:"apache",extensions:["scurl"]},"text/vnd.debian.copyright":{source:"iana",charset:"UTF-8"},"text/vnd.dmclientscript":{source:"iana"},"text/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"text/vnd.esmertec.theme-descriptor":{source:"iana",charset:"UTF-8"},"text/vnd.familysearch.gedcom":{source:"iana",extensions:["ged"]},"text/vnd.ficlab.flt":{source:"iana"},"text/vnd.fly":{source:"iana",extensions:["fly"]},"text/vnd.fmi.flexstor":{source:"iana",extensions:["flx"]},"text/vnd.gml":{source:"iana"},"text/vnd.graphviz":{source:"iana",extensions:["gv"]},"text/vnd.hans":{source:"iana"},"text/vnd.hgl":{source:"iana"},"text/vnd.in3d.3dml":{source:"iana",extensions:["3dml"]},"text/vnd.in3d.spot":{source:"iana",extensions:["spot"]},"text/vnd.iptc.newsml":{source:"iana"},"text/vnd.iptc.nitf":{source:"iana"},"text/vnd.latex-z":{source:"iana"},"text/vnd.motorola.reflex":{source:"iana"},"text/vnd.ms-mediapackage":{source:"iana"},"text/vnd.net2phone.commcenter.command":{source:"iana"},"text/vnd.radisys.msml-basic-layout":{source:"iana"},"text/vnd.senx.warpscript":{source:"iana"},"text/vnd.si.uricatalogue":{source:"iana"},"text/vnd.sosi":{source:"iana"},"text/vnd.sun.j2me.app-descriptor":{source:"iana",charset:"UTF-8",extensions:["jad"]},"text/vnd.trolltech.linguist":{source:"iana",charset:"UTF-8"},"text/vnd.wap.si":{source:"iana"},"text/vnd.wap.sl":{source:"iana"},"text/vnd.wap.wml":{source:"iana",extensions:["wml"]},"text/vnd.wap.wmlscript":{source:"iana",extensions:["wmls"]},"text/vtt":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["vtt"]},"text/x-asm":{source:"apache",extensions:["s","asm"]},"text/x-c":{source:"apache",extensions:["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{source:"nginx",extensions:["htc"]},"text/x-fortran":{source:"apache",extensions:["f","for","f77","f90"]},"text/x-gwt-rpc":{compressible:!0},"text/x-handlebars-template":{extensions:["hbs"]},"text/x-java-source":{source:"apache",extensions:["java"]},"text/x-jquery-tmpl":{compressible:!0},"text/x-lua":{extensions:["lua"]},"text/x-markdown":{compressible:!0,extensions:["mkd"]},"text/x-nfo":{source:"apache",extensions:["nfo"]},"text/x-opml":{source:"apache",extensions:["opml"]},"text/x-org":{compressible:!0,extensions:["org"]},"text/x-pascal":{source:"apache",extensions:["p","pas"]},"text/x-processing":{compressible:!0,extensions:["pde"]},"text/x-sass":{extensions:["sass"]},"text/x-scss":{extensions:["scss"]},"text/x-setext":{source:"apache",extensions:["etx"]},"text/x-sfv":{source:"apache",extensions:["sfv"]},"text/x-suse-ymp":{compressible:!0,extensions:["ymp"]},"text/x-uuencode":{source:"apache",extensions:["uu"]},"text/x-vcalendar":{source:"apache",extensions:["vcs"]},"text/x-vcard":{source:"apache",extensions:["vcf"]},"text/xml":{source:"iana",compressible:!0,extensions:["xml"]},"text/xml-external-parsed-entity":{source:"iana"},"text/yaml":{compressible:!0,extensions:["yaml","yml"]},"video/1d-interleaved-parityfec":{source:"iana"},"video/3gpp":{source:"iana",extensions:["3gp","3gpp"]},"video/3gpp-tt":{source:"iana"},"video/3gpp2":{source:"iana",extensions:["3g2"]},"video/av1":{source:"iana"},"video/bmpeg":{source:"iana"},"video/bt656":{source:"iana"},"video/celb":{source:"iana"},"video/dv":{source:"iana"},"video/encaprtp":{source:"iana"},"video/ffv1":{source:"iana"},"video/flexfec":{source:"iana"},"video/h261":{source:"iana",extensions:["h261"]},"video/h263":{source:"iana",extensions:["h263"]},"video/h263-1998":{source:"iana"},"video/h263-2000":{source:"iana"},"video/h264":{source:"iana",extensions:["h264"]},"video/h264-rcdo":{source:"iana"},"video/h264-svc":{source:"iana"},"video/h265":{source:"iana"},"video/iso.segment":{source:"iana",extensions:["m4s"]},"video/jpeg":{source:"iana",extensions:["jpgv"]},"video/jpeg2000":{source:"iana"},"video/jpm":{source:"apache",extensions:["jpm","jpgm"]},"video/jxsv":{source:"iana"},"video/mj2":{source:"iana",extensions:["mj2","mjp2"]},"video/mp1s":{source:"iana"},"video/mp2p":{source:"iana"},"video/mp2t":{source:"iana",extensions:["ts"]},"video/mp4":{source:"iana",compressible:!1,extensions:["mp4","mp4v","mpg4"]},"video/mp4v-es":{source:"iana"},"video/mpeg":{source:"iana",compressible:!1,extensions:["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{source:"iana"},"video/mpv":{source:"iana"},"video/nv":{source:"iana"},"video/ogg":{source:"iana",compressible:!1,extensions:["ogv"]},"video/parityfec":{source:"iana"},"video/pointer":{source:"iana"},"video/quicktime":{source:"iana",compressible:!1,extensions:["qt","mov"]},"video/raptorfec":{source:"iana"},"video/raw":{source:"iana"},"video/rtp-enc-aescm128":{source:"iana"},"video/rtploopback":{source:"iana"},"video/rtx":{source:"iana"},"video/scip":{source:"iana"},"video/smpte291":{source:"iana"},"video/smpte292m":{source:"iana"},"video/ulpfec":{source:"iana"},"video/vc1":{source:"iana"},"video/vc2":{source:"iana"},"video/vnd.cctv":{source:"iana"},"video/vnd.dece.hd":{source:"iana",extensions:["uvh","uvvh"]},"video/vnd.dece.mobile":{source:"iana",extensions:["uvm","uvvm"]},"video/vnd.dece.mp4":{source:"iana"},"video/vnd.dece.pd":{source:"iana",extensions:["uvp","uvvp"]},"video/vnd.dece.sd":{source:"iana",extensions:["uvs","uvvs"]},"video/vnd.dece.video":{source:"iana",extensions:["uvv","uvvv"]},"video/vnd.directv.mpeg":{source:"iana"},"video/vnd.directv.mpeg-tts":{source:"iana"},"video/vnd.dlna.mpeg-tts":{source:"iana"},"video/vnd.dvb.file":{source:"iana",extensions:["dvb"]},"video/vnd.fvt":{source:"iana",extensions:["fvt"]},"video/vnd.hns.video":{source:"iana"},"video/vnd.iptvforum.1dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.1dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.2dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.2dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.ttsavc":{source:"iana"},"video/vnd.iptvforum.ttsmpeg2":{source:"iana"},"video/vnd.motorola.video":{source:"iana"},"video/vnd.motorola.videop":{source:"iana"},"video/vnd.mpegurl":{source:"iana",extensions:["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{source:"iana",extensions:["pyv"]},"video/vnd.nokia.interleaved-multimedia":{source:"iana"},"video/vnd.nokia.mp4vr":{source:"iana"},"video/vnd.nokia.videovoip":{source:"iana"},"video/vnd.objectvideo":{source:"iana"},"video/vnd.radgamettools.bink":{source:"iana"},"video/vnd.radgamettools.smacker":{source:"iana"},"video/vnd.sealed.mpeg1":{source:"iana"},"video/vnd.sealed.mpeg4":{source:"iana"},"video/vnd.sealed.swf":{source:"iana"},"video/vnd.sealedmedia.softseal.mov":{source:"iana"},"video/vnd.uvvu.mp4":{source:"iana",extensions:["uvu","uvvu"]},"video/vnd.vivo":{source:"iana",extensions:["viv"]},"video/vnd.youtube.yt":{source:"iana"},"video/vp8":{source:"iana"},"video/vp9":{source:"iana"},"video/webm":{source:"apache",compressible:!1,extensions:["webm"]},"video/x-f4v":{source:"apache",extensions:["f4v"]},"video/x-fli":{source:"apache",extensions:["fli"]},"video/x-flv":{source:"apache",compressible:!1,extensions:["flv"]},"video/x-m4v":{source:"apache",extensions:["m4v"]},"video/x-matroska":{source:"apache",compressible:!1,extensions:["mkv","mk3d","mks"]},"video/x-mng":{source:"apache",extensions:["mng"]},"video/x-ms-asf":{source:"apache",extensions:["asf","asx"]},"video/x-ms-vob":{source:"apache",extensions:["vob"]},"video/x-ms-wm":{source:"apache",extensions:["wm"]},"video/x-ms-wmv":{source:"apache",compressible:!1,extensions:["wmv"]},"video/x-ms-wmx":{source:"apache",extensions:["wmx"]},"video/x-ms-wvx":{source:"apache",extensions:["wvx"]},"video/x-msvideo":{source:"apache",extensions:["avi"]},"video/x-sgi-movie":{source:"apache",extensions:["movie"]},"video/x-smv":{source:"apache",extensions:["smv"]},"x-conference/x-cooltalk":{source:"apache",extensions:["ice"]},"x-shader/x-fragment":{compressible:!0},"x-shader/x-vertex":{compressible:!0}},wn=(vn||(vn=1,function(e){var t,n,s,a=fn?gn:(fn=1,gn=xn),i=Re.extname,o=/^\s*([^;\s]*)(?:;|\s|$)/,r=/^text\//i;function c(e){if(!e||"string"!=typeof e)return!1;var t=o.exec(e),n=t&&a[t[1].toLowerCase()];return n&&n.charset?n.charset:!(!t||!r.test(t[1]))&&"UTF-8"}e.charset=c,e.charsets={lookup:c},e.contentType=function(t){if(!t||"string"!=typeof t)return!1;var n=-1===t.indexOf("/")?e.lookup(t):t;if(!n)return!1;if(-1===n.indexOf("charset")){var s=e.charset(n);s&&(n+="; charset="+s.toLowerCase())}return n},e.extension=function(t){if(!t||"string"!=typeof t)return!1;var n=o.exec(t),s=n&&e.extensions[n[1].toLowerCase()];return!(!s||!s.length)&&s[0]},e.extensions=Object.create(null),e.lookup=function(t){if(!t||"string"!=typeof t)return!1;var n=i("x."+t).toLowerCase().substr(1);return n&&e.types[n]||!1},e.types=Object.create(null),t=e.extensions,n=e.types,s=["nginx","apache",void 0,"iana"],Object.keys(a).forEach(function(e){var i=a[e],o=i.extensions;if(o&&o.length){t[e]=o;for(var r=0;r<o.length;r++){var c=o[r];if(n[c]){var l=s.indexOf(a[n[c]].source),p=s.indexOf(i.source);if("application/octet-stream"!==n[c]&&(l>p||l===p&&"application/"===n[c].substr(0,12)))continue}n[c]=e}}})}(yn)),yn);function bn(e,t){e?e.send("workspace-file-response",t):we.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function kn(e,t,n,s){return{eventId:G(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function In(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;we.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,p=function(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return function(e){const t=A(ln()),n=A(e);if(n!==t&&!n.startsWith(`${t}${C}`))throw new Error("Access denied: channel attachment path is outside channel files directory");return n}(decodeURIComponent(e))}return xe.resolveWorkspaceFilePath(e,t,n)}(s,n,a);if(!i.existsSync(p))return we.warn(`[WORKSPACE] File not found: ${p}`),void bn(e.client,kn(o,n,"file_not_found","File or directory not found"));const d=await i.promises.stat(p),u=d.mtime.toISOString();if(c&&u===c)return void function(e,t,n,s){we.debug(`[WORKSPACE] File not modified: ${s}`),bn(e,{eventId:G(),requestId:t,taskId:n,success:!0,notModified:!0})}(e.client,o,n,p);if(d.isDirectory())return void await async function(e,t,n,s,a,o){const r=await i.promises.readdir(s,{withFileTypes:!0}),c=await Promise.all(r.map(async e=>{const t=k.join(s,e.name),n=await i.promises.stat(t);return{name:e.name,type:e.isDirectory()?"directory":"file",size:n.size,modifiedAt:n.mtime.toISOString(),accessDenied:n.size>o}}));bn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:{type:"directory",entries:c,metadata:{size:0,modifiedAt:a.mtime.toISOString()}}})}(e.client,o,n,p,d,t);{const s=wn.lookup(p)||"application/octet-stream";return d.size>t?void function(e,t,n,s,a,i,o){we.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),bn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:{type:"file",metadata:{size:a.size,mimeType:i,modifiedAt:a.mtime.toISOString(),accessDenied:!0}}})}(e.client,o,n,p,d,s,t):void await async function(e,t,n,s,a,o){const r=wn.lookup(s)||"application/octet-stream",c=(await i.promises.readFile(s)).toString("base64");let l=null;o&&(l=await async function(e){try{const t=await xe.getSecretKey();if(!t)return we.warn("[WORKSPACE] Machine secret key not available"),null;const n=L(e);return H(n,t)||(we.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return we.warn("[WORKSPACE] Error decrypting dataEncryptionKey:",e),null}}(o));const p={type:"file",metadata:{size:a.size,mimeType:r,modifiedAt:a.mtime.toISOString()}};l?p.encryptedContent=B(c,l):p.content=c,bn(e,{eventId:G(),requestId:t,taskId:n,success:!0,data:p})}(e.client,o,n,p,d,l)}}catch(t){we.error(`[WORKSPACE] Failed to handle workspace-file-request: ${t.message}`,t);const s="ENOENT"===t.code?"file_not_found":"EACCES"===t.code?"permission_denied":"unknown_error";bn(e.client,kn(o,n,s,t.message))}}}const Tn=new Le({credentialsDir:T(xe.agentrixHomeDir,"credentials")});async function Sn(){const e=await xe.readCredentials();return e?.secret?Ge(e.secret):null}function En(e){return Tn.loadGitServerConfig(e)}function An(e,t){return Tn.loadGitLabWebhookBridgeSecrets(e,t)}function Cn(e){return Tn.loadPatMeta(e)}function _n(e,t){return Tn.loadPat(e,t)}const $n=100,Pn=[{method:"GET",pattern:/^\/user$/},{method:"GET",pattern:/^\/projects$/},{method:"GET",pattern:/^\/projects\/[^/]+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/repository\/branches$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/issues\/\d+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/issues\/\d+\/discussions\/[^/]+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/changes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/notes$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions$/},{method:"GET",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/approvals$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+\/notes$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/approve$/},{method:"POST",pattern:/^\/projects\/[^/]+\/merge_requests$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/discussions\/[^/]+\/notes\/\d+$/},{method:"PUT",pattern:/^\/projects\/[^/]+\/merge_requests\/\d+\/merge$/}];class Mn{apiUrl;pat;requestId;gitServerId;constructor(e,t,n){this.apiUrl=e,this.pat=t,this.requestId=n?.requestId,this.gitServerId=n?.gitServerId}logPrefix(){return`[GITLAB EXECUTOR] reqId=${this.requestId??"-"}, gitServer=${this.gitServerId??"-"}`}summarizeResult(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"id"in n&&"status"in n?`id=${String(n.id??"-")}, status=${String(n.status??"-")}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}truncateText(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}async requestWithResponse(e,t="GET",n){const s=`${this.apiUrl}${e}`,a={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/json"},i=Date.now();we.debug(`${this.logPrefix()} request start: ${t} ${e}`);try{const o=await fetch(s,{method:t,headers:a,body:n?JSON.stringify(n):void 0}),r=Date.now()-i;if(!o.ok){const n=await o.text().catch(()=>"Unknown error"),s=this.truncateText(n);throw we.warn(`${this.logPrefix()} request failed: ${t} ${e}, status=${o.status}, elapsedMs=${r}, detail=${s}`),{status:o.status,message:`GitLab API error: ${o.status} ${o.statusText}`,detail:s}}return we.debug(`${this.logPrefix()} request success: ${t} ${e}, elapsedMs=${r}`),{data:await o.json(),headers:o.headers}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw we.error(`${this.logPrefix()} request exception: ${t} ${e}, message=${s}`),{status:0,message:`GitLab request failed: ${s}`}}}async requestForm(e,t){const n=`${this.apiUrl}${e}`,s={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/x-www-form-urlencoded"},a=Date.now();we.debug(`${this.logPrefix()} form request start: POST ${e}`);try{const i=await fetch(n,{method:"POST",headers:s,body:t}),o=Date.now()-a;if(!i.ok){const t=await i.text().catch(()=>"Unknown error"),n=this.truncateText(t);throw we.warn(`${this.logPrefix()} form request failed: POST ${e}, status=${i.status}, elapsedMs=${o}, detail=${n}`),{status:i.status,message:`GitLab API error: ${i.status} ${i.statusText}`,detail:n}}return we.debug(`${this.logPrefix()} form request success: POST ${e}, elapsedMs=${o}`),await i.json()}catch(t){if("object"==typeof t&&null!==t&&"status"in t)throw t;const n=t instanceof Error?t.message:"Unknown network error";throw we.error(`${this.logPrefix()} form request exception: POST ${e}, message=${n}`),{status:0,message:`GitLab request failed: ${n}`}}}async request(e,t="GET",n){const{data:s}=await this.requestWithResponse(e,t,n);return s}withQueryParams(e,t){const[n,s=""]=e.split("?"),a=new URLSearchParams(s);for(const[e,n]of Object.entries(t))a.set(e,String(n));const i=a.toString();return i?`${n}?${i}`:n}parseTotalPages(e){const t=e.get("x-total-pages");if(!t)return null;const n=Number.parseInt(t,10);return!Number.isFinite(n)||n<=0?null:n}async fetchRemainingPagesInBatches(e,t){const n=[];for(let s=2;s<=e;s+=4){const a=Math.min(s+4-1,e),i=Array.from({length:a-s+1},(e,t)=>s+t),o=await Promise.all(i.map(e=>t(e)));for(const e of o)n.push(...e)}return n}async requestPaginated(e){const t=this.withQueryParams(e,{per_page:$n,page:1}),n=await this.requestWithResponse(t),s=[...n.data],a=this.parseTotalPages(n.headers);if(a&&a>1){const t=await this.fetchRemainingPagesInBatches(a,async t=>{const n=this.withQueryParams(e,{per_page:$n,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===$n){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:$n,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<$n)break;t+=1}}return s}async executeOperation(e,t){we.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let n;switch(e){case"listRepos":n=await this.listRepos();break;case"listBranches":n=await this.listBranches(t.owner,t.name);break;case"createMergeRequest":n=await this.createMergeRequest(t);break;case"getMergeRequest":n=await this.getMergeRequest(t.owner,t.name,t.iid);break;case"listMergeRequests":n=await this.listMergeRequests(t.owner,t.name);break;case"triggerPipeline":n=await this.triggerPipeline(t);break;case"ensurePipelineTriggerToken":n=await this.ensurePipelineTriggerToken(t);break;case"requestGitlabApi":n=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":n={authMode:"local_pat",hasPat:!0};break;default:throw{status:400,message:`Unknown operation: ${e}`}}return we.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,n)}`),n}catch(t){const n=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw we.error(`${this.logPrefix()} operation failed: op=${e}, message=${n}`),t}}async listRepos(){return(await this.requestPaginated("/projects?membership=true&order_by=updated_at&sort=desc")).map(e=>({id:e.id,owner:e.path_with_namespace.split("/").slice(0,-1).join("/")||e.namespace.path,name:e.path,fullName:e.path_with_namespace,defaultBranch:e.default_branch,isPrivate:"private"===e.visibility,description:e.description,url:e.web_url,createdAt:e.created_at,updatedAt:e.updated_at}))}async listBranches(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.requestPaginated(`/projects/${n}/repository/branches`)).map(e=>({name:e.name,commit:{sha:e.commit.id,url:""},protected:e.protected}))}async createMergeRequest(e){const t=encodeURIComponent(`${e.owner}/${e.repo}`),n=await this.request(`/projects/${t}/merge_requests`,"POST",{source_branch:e.head,target_branch:e.base,title:e.title,description:e.body||""});return{number:n.iid,title:n.title,body:n.description,state:"opened"===n.state?"open":n.state,url:n.web_url,head:n.source_branch,base:n.target_branch,createdAt:n.created_at,updatedAt:n.updated_at}}async getMergeRequest(e,t,n){const s=encodeURIComponent(`${e}/${t}`),a=await this.request(`/projects/${s}/merge_requests/${n}`);return{number:a.iid,title:a.title,body:a.description,state:"opened"===a.state?"open":a.state,url:a.web_url,head:a.source_branch,base:a.target_branch,createdAt:a.created_at,updatedAt:a.updated_at}}async listMergeRequests(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.request(`/projects/${n}/merge_requests?state=opened&per_page=20`)).map(e=>({number:e.iid,title:e.title,body:e.description,state:"opened"===e.state?"open":e.state,url:e.web_url,head:e.source_branch,base:e.target_branch,createdAt:e.created_at,updatedAt:e.updated_at}))}parseNonEmptyString(e,t){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} is required`};return e.trim()}parseOptionalString(e,t){if(null!=e){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} must be a non-empty string`};return e.trim()}}resolveProjectPath(e){if("number"==typeof e.projectId||"string"==typeof e.projectId){const t=String(e.projectId).trim();if(t.length>0)return encodeURIComponent(t)}const t=this.parseOptionalString(e.projectPath,"projectPath");if(t)return encodeURIComponent(t);const n=this.parseOptionalString(e.owner,"owner"),s=this.parseOptionalString(e.repo??e.name,"repo");if(!n||!s)throw{status:400,message:"projectId, projectPath, or owner + repo is required"};return encodeURIComponent(`${n}/${s}`)}parsePipelineVariables(e){if(null==e)return{};if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Pipeline variables must be an object"};const t={};for(const[n,s]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw{status:400,message:`Pipeline variable name is invalid: ${n}`};if(null!=s){if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Pipeline variable value for "${n}" is invalid`};t[n]=String(s)}}return t}isUsableTriggerToken(e){return"string"==typeof e&&e.length>=20&&!e.includes("*")}async resolvePipelineTriggerToken(e,t){const n=this.parseOptionalString(t.triggerToken,"triggerToken");if(n)return n;if(!0!==t.createTriggerIfMissing)throw{status:400,message:"triggerToken is required unless createTriggerIfMissing is true"};const s=this.parseOptionalString(t.triggerDescription,"triggerDescription")??"Agentrix webhook bridge",a=(await this.requestPaginated(`/projects/${e}/triggers`)).find(e=>e.description===s&&this.isUsableTriggerToken(e.token));if(a?.token)return a.token;const i=new URLSearchParams;i.set("description",s);const o=await this.requestForm(`/projects/${e}/triggers`,i);if(!this.isUsableTriggerToken(o.token))throw{status:502,message:"GitLab did not return a usable pipeline trigger token"};return o.token}async ensurePipelineTriggerToken(e){const t=this.resolveProjectPath(e);return{token:await this.resolvePipelineTriggerToken(t,{...e,createTriggerIfMissing:!0})}}async triggerPipeline(e){const t=this.resolveProjectPath(e),n=this.parseNonEmptyString(e.ref,"ref"),s=this.parsePipelineVariables(e.variables),a=await this.resolvePipelineTriggerToken(t,e),i=new URLSearchParams;i.set("token",a),i.set("ref",n);for(const[e,t]of Object.entries(s))i.set(`variables[${e}]`,t);const o=await this.requestForm(`/projects/${t}/trigger/pipeline`,i);return{id:o.id,iid:o.iid,projectId:o.project_id,ref:o.ref,sha:o.sha,status:o.status,source:o.source,url:o.web_url,createdAt:o.created_at,updatedAt:o.updated_at}}parseProxyMethod(e){const t="string"==typeof e?e.toUpperCase():"GET";if("GET"===t||"POST"===t||"PUT"===t||"PATCH"===t||"DELETE"===t)return t;throw{status:400,message:`Unsupported proxy method: ${String(e)}`}}parseProxyPath(e){if("string"!=typeof e||0===e.length)throw{status:400,message:"Proxy path is required"};if(!e.startsWith("/"))throw{status:400,message:'Proxy path must start with "/"'};if(e.includes("://")||e.includes(".."))throw{status:400,message:"Proxy path contains invalid segments"};if(e.includes("?"))throw{status:400,message:"Proxy path must not contain query string; use payload.query"};return e}buildProxyQueryString(e){if(null==e)return"";if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Proxy query must be an object"};const t=new URLSearchParams;for(const[n,s]of Object.entries(e))if(null!=s)if(Array.isArray(s))for(const e of s){if("string"!=typeof e&&"number"!=typeof e&&"boolean"!=typeof e)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(e))}else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(s))}return t.toString()}isProxyAllowed(e,t){return Pn.some(n=>n.method===e&&n.pattern.test(t))}async requestGitlabApi(e){const t=this.parseProxyMethod(e.method),n=this.parseProxyPath(e.path),s=this.buildProxyQueryString(e.query),a=s.length>0?`${n}?${s}`:n;if(!this.isProxyAllowed(t,n))throw{status:403,message:`Proxy path not allowed: ${t} ${n}`};return"GET"===t?await this.request(a,t):await this.request(a,t,e.body)}}function Rn(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function Nn(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function Dn(e){return ye.isAxiosError(e)?{message:e.message,status:e.response?.status,code:e.code}:{message:e instanceof Error?e.message:String(e)}}async function On(e,t){if(!e.apiKey)throw new Error("missing api key");const n="anthropic"===t?{"x-api-key":e.apiKey,"anthropic-version":"2023-06-01"}:{Authorization:`Bearer ${e.apiKey}`},s=await ye.get(Rn(e.baseUrl),{headers:n,timeout:1e4});return(s.data?.data||[]).map(e=>e&&"object"==typeof e&&"id"in e?String(e.id):null).filter(e=>Boolean(e))}async function Un(e){const t=function(e){try{const t=new URL(e).hostname.toLowerCase();if("api.anthropic.com"===t||t.endsWith(".anthropic.com"))return"anthropic";if("api.openai.com"===t||t.endsWith(".openai.com"))return"openai"}catch{return null}return null}(e.baseUrl),n=t?[t]:["anthropic","openai"];let s;for(const a of n){we.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${Nn(Rn(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await On(e,a);return we.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=Dn(t);we.warn(`[MODELS] Models request failed: source=${e.source}, protocol=${a}, status=${n.status??"-"}, code=${n.code??"-"}, message=${n.message}`)}}throw s instanceof Error?s:new Error("failed to fetch models")}function jn(e,t){const n=t.ANTHROPIC_MODEL||e?.model||process.env.ANTHROPIC_MODEL;if(!n)return;const s=n.toLowerCase();return"opus"===s?t.ANTHROPIC_DEFAULT_OPUS_MODEL||process.env.ANTHROPIC_DEFAULT_OPUS_MODEL||"claude-opus-4-6":"sonnet"===s?t.ANTHROPIC_DEFAULT_SONNET_MODEL||process.env.ANTHROPIC_DEFAULT_SONNET_MODEL||"claude-sonnet-4-6":"haiku"===s?t.ANTHROPIC_DEFAULT_HAIKU_MODEL||process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL||"claude-haiku-4-5":n}async function qn(e){const t=[];if(!e||"claude"===e){const e=function(){const e=function(e){if(!r(e))return null;try{return JSON.parse(c(e,"utf-8"))}catch{return null}}(T(xe.claudeConfigDir,"settings.json")),t=e?.env||{},n=t.ANTHROPIC_BASE_URL||process.env.ANTHROPIC_BASE_URL||"https://api.anthropic.com",s=t.ANTHROPIC_AUTH_TOKEN||t.ANTHROPIC_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN||process.env.ANTHROPIC_API_KEY;return s?{baseUrl:n,apiKey:s,source:"claude",defaultModel:jn(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=T(xe.codexHomeDir,"config.toml");if(!r(e))return process.env.OPENAI_API_KEY?{baseUrl:process.env.OPENAI_BASE_URL||"https://api.openai.com",apiKey:process.env.OPENAI_API_KEY,source:"codex",defaultModel:process.env.OPENAI_MODEL}:null;const t=c(e,"utf-8"),n=t.match(/^model_provider\s*=\s*"([^"]+)"/m)?.[1]||"openai",s=t.match(/^model\s*=\s*"([^"]+)"/m)?.[1],a=t.match(new RegExp(`\\[model_providers\\.${n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\]([\\s\\S]*?)(?=\\n\\[|$)`)),i=a?.[1]||"",o=i.match(/^\s*base_url\s*=\s*"([^"]+)"/m)?.[1]||process.env.OPENAI_BASE_URL||"https://api.openai.com",l=i.match(/^\s*env_key\s*=\s*"([^"]+)"/m)?.[1]||("agentrix"===n?"AGENTRIX_API_KEY":"OPENAI_API_KEY");return{baseUrl:o,apiKey:process.env[l],source:"codex",defaultModel:s}}();e&&t.push(e)}we.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${Nn(e.baseUrl)}:hasKey=${Boolean(e.apiKey)}:defaultModel=${e.defaultModel??"-"}`).join(",")||"-"}`);const n=new Set,s=[],a=t.find(e=>e.defaultModel)?.defaultModel;for(const e of t)try{for(const t of await Un(e))n.add(t)}catch(t){const n=Dn(t);s.push({source:e.source,baseUrl:Nn(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?we.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):we.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function Ln(e,t){return{eventId:G(),status:"failed",opCode:e,message:t}}function Hn(e){return async(t,n)=>{if(we.info(`[EVENT HANDLER] create-task: ${t.taskId}, agentType=${t.agentType}, agentId=${t.agentId}`),"shadow"!==t.taskType&&e.onCompanionInteraction?.(t.chatId),"task-message"!==t.event)return we.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(Ln(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&we.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){we.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function Gn(e){return async(t,n)=>{we.debug(`[EVENT HANDLER] resume-task: ${t.taskId}, agentSessionId=${t.agentSessionId}`),"shadow"!==t.taskType&&e.onCompanionInteraction?.(t.chatId);try{const s=await e.workerManager.startWorker(t,"resume-task");"success"!==s.status&&we.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){we.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function Bn(e){return async(t,n)=>{if(we.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return we.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(Ln(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await qn(t.agentType);if(0===e.length&&!s)return we.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(Ln(t.eventId,"No models available from configured endpoints"));we.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:G(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){we.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function Fn(e){return async t=>{we.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function Wn(e){return async(t,n)=>{we.info(`[EVENT HANDLER] deploy-agent received: taskId=${t.taskId}, draftAgentId=${t.draftAgentId}, targetAgentId=${t.targetAgentId}, sourcePath=${t.sourcePath}`);try{const s=await e.workerManager.startDeploymentWorker(t);"success"!==s.status&&we.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){we.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function zn(e){return async(t,n)=>{we.info(`[EVENT HANDLER] hive-publish received: taskId=${t.taskId}, name=${t.name}, repoDir=${t.repoDir}`);try{const s=await e.workerManager.startHivePublishWorker(t);"success"!==s.status&&we.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){we.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function Kn(e){return async(t,n)=>{we.info(`[EVENT HANDLER] hive-install received: taskId=${t.taskId}, name=${t.name}, hiveListingId=${t.hiveListingId}`);try{const s=await e.workerManager.startHiveInstallWorker(t);"success"!==s.status&&we.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){we.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(Ln(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function Vn(e){return async t=>{we.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||we.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function Xn(e){return async t=>{we.info(`[GITLAB PROXY] request received: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, ttlMs=${t.ttlMs}, payloadKeys=${function(e){const t=Object.keys(e||{});return t.length>0?t.join(","):"-"}(t.payload)}`);const n=Date.now(),s=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?(e.client.send("daemon-gitlab-response",s),we.info(`[GITLAB PROXY] response sent: reqId=${t.requestId}, op=${t.operation}, success=${n.success}, executionMs=${n.executionTimeMs}`)):we.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=await Sn();if(!e)return we.warn(`[GITLAB PROXY] git server encryption key unavailable: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"Git server encryption key not available",executionTimeMs:Date.now()-n});const a=_n(t.gitServerId,e);if(!a)return we.warn(`[GITLAB PROXY] PAT missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:`No PAT configured for git server ${t.gitServerId}`,executionTimeMs:Date.now()-n});const i=t.payload.apiUrl;if(!i)return we.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:Date.now()-n});we.info(`[GITLAB PROXY] executing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, apiHost=${function(e){try{return new URL(e).host}catch{return"invalid-url"}}(i)}`);const o=new Mn(i,a,{requestId:t.requestId,gitServerId:t.gitServerId}),r=await o.executeOperation(t.operation,t.payload);we.info(`[GITLAB PROXY] execution succeeded: reqId=${t.requestId}, op=${t.operation}, summary=${function(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}(t.operation,r)}`),s({success:!0,data:r,executionTimeMs:Date.now()-n})}catch(e){const a=e;let i="GITLAB_CONNECTIVITY_FAILED";401===a.status?i="PAT_INVALID":403===a.status?i="PAT_SCOPE_INSUFFICIENT":404===a.status&&(i="RESOURCE_NOT_FOUND");const o="string"==typeof a.message?a.message:"Unknown error",r="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,c="number"==typeof a.status?String(a.status):"unknown";we.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${i}, status=${c}, message=${o}${r?`, detail=${r}`:""}`),s({success:!1,errorCode:i,errorMessage:o,executionTimeMs:Date.now()-n})}}}const Jn=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function Yn(e,t){if(!e)return;if("string"==typeof t)return void(e.sendMessage?e.sendMessage(t):e.send&&e.send(t));const n=Buffer.from(t);e.sendMessageBinary?e.sendMessageBinary(n):e.send&&e.send(n)}class Qn{client;machineId;iceServers=[];sessions=new Map;rtcModule={};peerConstructor;constructor(e,t){this.client=e,this.machineId=t;const n=Ve(import.meta.url);try{this.rtcModule=n("node-datachannel"),this.peerConstructor=(s=this.rtcModule).RTCPeerConnection||s.PeerConnection||s.RTCConnection||s.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}catch(e){const t=e instanceof Error?e.message:String(e);we.warn(`[RTC] node-datachannel unavailable; RTC support disabled: ${t}`)}var s}registerHandlers(){this.peerConstructor?(this.client.onLifecycle("connect",()=>{this.requestIceServers()}),this.client.onEvent("rtc-ice-servers-response",e=>this.handleIceServersResponse(e)),this.client.onEvent("machine-rtc-request",e=>this.handleRtcRequest(e)),this.client.onEvent("rtc-signal",e=>this.handleRtcSignal(e))):we.warn("[RTC] node-datachannel RTCPeerConnection not available")}shutdown(){this.sessions.forEach(e=>{e.peerConnection.close?.()}),this.sessions.clear()}requestIceServers(){this.client.send("rtc-ice-servers-request",{eventId:G()})}handleIceServersResponse(e){this.iceServers=function(e){const t=[];return e.forEach(e=>{Array.isArray(e.urls)?t.push(...e.urls):t.push(e.urls)}),t}(e.iceServers),we.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void we.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId))return void this.sendMachineRtcResponse(e.sessionId,t,!0);const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),this.sendMachineRtcResponse(e.sessionId,t,!0)}sendMachineRtcResponse(e,t,n,s){this.client.send("machine-rtc-response",{eventId:G(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void we.warn("[RTC] rtc-signal missing userId");const n=e.workspaceUserId||t,s=e.taskId;let a=this.sessions.get(e.sessionId);if(!a){const i=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers});a={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:i,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]},this.sessions.set(e.sessionId,a),this.registerPeerHandlers(a)}try{this.applyRemoteSignal(a,e.signal)}catch(e){we.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{we.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{we.info(`[RTC] ICE gathering (${e.sessionId}): ${t}`)}),t.onLocalDescription?.((t,n)=>{const s=function(e,t){return e&&"object"==typeof e&&"string"==typeof e.sdp?{sdp:e.sdp,type:e.type||t}:{sdp:String(e||""),type:t}}(t,n);this.client.send("rtc-signal",{eventId:G(),machineId:this.machineId,sessionId:e.sessionId,from:"machine",signal:s,userId:e.userId})}),t.onLocalCandidate?.((t,n,s)=>{const a=function(e,t,n){return"string"==typeof e?{candidate:e,sdpMid:t||"0",sdpMLineIndex:n??0}:e&&"string"==typeof e.candidate?{candidate:e.candidate,sdpMid:e.sdpMid||e.mid||t||"0",sdpMLineIndex:"number"==typeof e.sdpMLineIndex?e.sdpMLineIndex:n??0}:null}(t,n,s);a&&this.client.send("rtc-signal",{eventId:G(),machineId:this.machineId,sessionId:e.sessionId,from:"machine",signal:{candidate:a},userId:e.userId})}),t.onDataChannel?.(t=>{e.dataChannel=t,this.registerDataChannel(e,t)})}registerDataChannel(e,t){t.onOpen?.(()=>{we.info(`[RTC] Data channel open (${e.sessionId})`),e.lastActivity=Date.now(),Yn(t,JSON.stringify({v:1,type:"control.ready",channel:"control",requestId:`req-${e.sessionId}`,streamId:0,timestamp:(new Date).toISOString(),payload:{ok:!0}}))}),t.onClosed?.(()=>{we.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{we.error(`[RTC] Data channel error (${e.sessionId})`,t)}),t.onMessage?.(t=>{e.lastActivity=Date.now(),this.handleDataChannelMessage(e,t)})}handleDataChannelMessage(e,t){if(Buffer.isBuffer(t)||t instanceof Uint8Array){try{F(new Uint8Array(t))}catch(e){we.warn("[RTC] Received binary payload without handler")}return}let n=null;if("string"==typeof t?n=t:t&&"string"==typeof t.text&&(n=t.text),!n)return;let s=null;try{s=JSON.parse(n)}catch(e){return void we.warn("[RTC] Non-JSON message",n)}s&&"string"==typeof s.type&&"file.request"===s.type&&this.handleFileRequest(e,s).catch(e=>{we.error("[RTC] Failed to handle file request",e)})}async handleFileRequest(e,t){const n=t.payload;if(!n)return;if(n.userId!==e.workspaceUserId)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"unauthorized",message:"Unauthorized workspace access"}});if(e.allowedTaskId&&n.taskId!==e.allowedTaskId)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"unauthorized",message:"Unauthorized task access"}});const s=(a=n.userId,o=n.taskId,r=n.relativePath,xe.resolveWorkspaceFilePath(a,o,r));var a,o,r;if(!i.existsSync(s))return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"file_not_found",message:"File or directory not found"}});const c=await i.promises.stat(s);if(!function(e,t){return!t||e.mtime.toISOString()!==t}(c,n.ifModifiedSince))return void this.sendControl(e,{v:1,type:"file.not_modified",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString()});if(c.isDirectory()||"directory"===n.entryType){const n=await i.promises.readdir(s,{withFileTypes:!0}),a={entries:await Promise.all(n.map(async e=>{const t=k.join(s,e.name),n=await i.promises.stat(t);return{name:e.name,type:e.isDirectory()?"directory":"file",size:n.size,modifiedAt:n.mtime.toISOString()}})),modifiedAt:c.mtime.toISOString()};return void this.sendControl(e,{v:1,type:"file.dir",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:a})}const l=1024*(n.maxFileSizeMB??Jn)*1024;if(c.size>l)return void this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:"file_too_large",message:"File exceeds size limit"}});const p=wn.lookup(s)||"application/octet-stream",d={size:c.size,mimeType:"string"==typeof p?p:"application/octet-stream",modifiedAt:c.mtime.toISOString()};this.sendControl(e,{v:1,type:"file.meta",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:d}),await this.sendFileChunks(e,t.streamId,s),this.sendControl(e,{v:1,type:"file.end",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{size:c.size}})}async sendFileChunks(e,t,n){const s=e.dataChannel;if(!s)return;const a=i.createReadStream(n,{highWaterMark:65536});let o=0;await new Promise((e,n)=>{a.on("data",e=>{const n=W.Binary|(0===o?W.Start:0),a=Buffer.isBuffer(e)?e:Buffer.from(e),i=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),r=z({streamId:t,seq:o,flags:n,payloadLength:i.length},i);Yn(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=z({streamId:t,seq:o,flags:W.End|W.Binary,payloadLength:0},new Uint8Array);Yn(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&Yn(n,JSON.stringify(t))}applyRemoteSignal(e,t){const{peerConnection:n}=e;if(t&&t.sdp&&t.type)return n.setRemoteDescription?.(t.sdp,t.type),e.remoteDescriptionSet=!0,e.pendingCandidates?.forEach(e=>{try{n.addRemoteCandidate?.(e.candidate,e.mid)}catch(e){we.warn("[RTC] Failed to add queued candidate",e)}}),void(e.pendingCandidates=[]);if(t&&t.candidate){const s=t.candidate,a="string"==typeof s?s:s&&"string"==typeof s.candidate?s.candidate:null,i=t.sdpMid||s?.sdpMid||s?.mid||"0";if(a){if(!e.remoteDescriptionSet)return void e.pendingCandidates?.push({candidate:a,mid:i});n.addRemoteCandidate?.(a,i)}}}}class Zn{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new on(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client},this.rtcManager=new Qn(this.client,s),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 30 seconds"))},3e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":Hn(t=this.context),"resume-task":Gn(t),"list-models":Bn(t),"stop-task":Vn(t),"deploy-agent":Wn(t),"hive-publish":zn(t),"hive-install":Kn(t),"shutdown-machine":Fn(t),"workspace-file-request":In({client:t.client}),"daemon-gitlab-request":Xn(t)};var t;this.client.onEventWithAck("create-task",e["create-task"]),this.client.onEventWithAck("resume-task",e["resume-task"]),this.client.onEventWithAck("list-models",e["list-models"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEventWithAck("deploy-agent",e["deploy-agent"]),this.client.onEventWithAck("hive-publish",e["hive-publish"]),this.client.onEventWithAck("hive-install",e["hive-install"]),this.client.onEvent("shutdown-machine",e["shutdown-machine"]),this.client.onEvent("workspace-file-request",e["workspace-file-request"]),this.client.onEvent("daemon-gitlab-request",e["daemon-gitlab-request"])}}let es=null;let ts=!1;async function ns(){if(ts)we.info("[caffeinate] Already stopping, skipping");else if(es&&!es.killed){ts=!0,we.info(`[caffeinate] Stopping caffeinate process PID ${es.pid}`);try{es.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),es&&!es.killed&&es.kill("SIGKILL"),es=null,ts=!1}catch(e){we.info("[caffeinate] Error stopping caffeinate:",e),ts=!1}}}let ss=!1;function as(e){const{pid:t,name:n,cmd:s}=e;if(t===process.pid||t===process.ppid)return null;if(!(n.includes("agentrix")||"node"===n&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("dist\\index.mjs"))||("MainThread"===n||n.includes("MainThread"))&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("agentrix.mjs"))||s.includes("agentrix.mjs")||s.includes("agentrix-cli")||s.includes("tsx")&&s.includes("src/index.ts")&&s.includes("agentrix-cli")))return null;let a="unknown";const i=s.toLowerCase();return i.includes(" worker")?a="worker":i.includes(" upgrade-daemon")?a="upgrade-daemon":i.includes(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function is(){try{let e;e="win32"===process.platform?await async function(){try{const e=Je("wmic process where \"name='node.exe'\" get ProcessId,CommandLine /format:csv",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}),t=[],n=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=1;e<n.length;e++){const s=n[e];if(!s)continue;const a=s.indexOf(",");if(-1===a)continue;const i=s.substring(a+1),o=i.lastIndexOf(",");if(-1===o)continue;const r=i.substring(0,o).trim(),c=i.substring(o+1).trim(),l=parseInt(c,10);isNaN(l)||t.push({pid:l,name:"node",cmd:r})}return t}catch(e){return[]}}():(await Ye()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=as(n);e&&t.push(e)}return t}catch(e){return[]}}function os(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:Je(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function rs(){const e=Ze(),t=function(){const e=os("git"),t=os("claude"),n=os("codex");return[{name:"git",installed:e.available,required:!0,description:"Version control system (required for all tasks)",installCommand:"https://git-scm.com/downloads",path:e.path},{name:"claude",installed:t.available,required:!0,description:"Claude Code CLI (required for most features)",installCommand:"npm install -g @anthropic-ai/claude-code",path:t.path},{name:"codex",installed:n.available,required:!1,description:"Codex CLI (optional, for Codex tasks)",installCommand:"npm install -g @codex-ai/codex-cli",path:n.path}]}(),n=function(e){if("macos"===e){const e=os("rg");return[{name:"ripgrep",installed:e.available,required:!0,description:"Fast code search tool (required by sandbox)",installCommand:"brew install ripgrep",path:e.path}]}if("linux"===e){const e=os("bwrap"),t=os("socat");return[{name:"bubblewrap",installed:e.available,required:!0,description:"Sandboxing tool for Linux",installCommand:"sudo apt install bubblewrap # Debian/Ubuntu\nsudo yum install bubblewrap # RHEL/CentOS\nsudo pacman -S bubblewrap # Arch",path:e.path},{name:"socat",installed:t.available,required:!0,description:"Socket communication tool (required by sandbox)",installCommand:"sudo apt install socat # Debian/Ubuntu\nsudo yum install socat # RHEL/CentOS\nsudo pacman -S socat # Arch",path:t.path}]}return[]}(e),s=t.filter(e=>e.required&&!e.installed),a=n.filter(e=>e.required&&!e.installed);return{cli:t,sandbox:n,allSatisfied:0===s.length&&0===a.length,missingSandbox:a,missingCli:s}}function cs(){const e=rs(),t=[],n=e.cli.find(e=>"git"===e.name);n&&!n.installed&&t.push("git");for(const n of e.missingSandbox)t.push(n.name);return{ok:0===t.length,missing:t}}function ls(){return{PWD:process.env.PWD,AGENTRIX_HOME_DIR:process.env.AGENTRIX_HOME_DIR,AGENTRIX_SERVER_URL:process.env.AGENTRIX_SERVER_URL,AGENTRIX_PROJECT_ROOT:process.env.AGENTRIX_PROJECT_ROOT,DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING:process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING,NODE_ENV:process.env.NODE_ENV,DEBUG:process.env.DEBUG,workingDirectory:process.cwd(),processArgv:process.argv,agentrixDir:xe.agentrixHomeDir,serverUrl:xe.serverUrl,logsDir:xe.getStatePaths().logsDir,processPid:process.pid,nodeVersion:process.version,platform:process.platform,arch:process.arch,user:process.env.USER,home:process.env.HOME,shell:process.env.SHELL,terminal:process.env.TERM}}async function ps(e){if(e||(e="all"),console.log(D.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(D.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${D.green(ke.version)}`),console.log(`Platform: ${D.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${D.green(process.version)}`),console.log(""),console.log(D.bold("🔧 Daemon Spawn Diagnostics"));const e=be(),t=T(e,"bin","agentrix.mjs"),n=T(e,"dist","index.mjs");console.log(`Project Root: ${D.blue(e)}`),console.log(`Wrapper Script: ${D.blue(t)}`),console.log(`CLI Entrypoint: ${D.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?D.green("✓ Yes"):D.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?D.green("✓ Yes"):D.red("❌ No")}`),console.log(""),console.log(D.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${D.blue(xe.agentrixHomeDir)}`),console.log(`Server URL: ${D.blue(xe.serverUrl)}`),console.log(`Logs Dir: ${D.blue(xe.getStatePaths().logsDir)}`),console.log(D.bold("\n🌍 Environment Variables"));const s=ls();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?D.green(s.AGENTRIX_HOME_DIR):D.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?D.green(s.AGENTRIX_SERVER_URL):D.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?D.yellow("ENABLED"):D.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?D.green(s.DEBUG):D.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?D.green(s.NODE_ENV):D.gray("not set")}`),console.log(D.bold("\n🔐 Authentication"));try{await xe.readCredentials()?console.log(D.green("✓ Authenticated (credentials found)")):console.log(D.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(D.red("❌ Error reading credentials"))}!function(e=!1){const t=rs(),n=Ze();console.log(D.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(D.green(`✓ ${n.name}`),D.gray(`- ${n.description}`)),e&&n.path&&console.log(D.gray(` Location: ${n.path}`));else{const e=n.required?D.red("❌"):D.yellow("⚠️");console.log(`${e} ${n.name}`,D.gray(`- ${n.description}`)),n.installCommand&&console.log(D.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(D.bold("\n🔒 Sandbox Dependencies")),console.log(D.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(D.green(`✓ ${n.name}`),D.gray(`- ${n.description}`)),e&&n.path&&console.log(D.gray(` Location: ${n.path}`))):(console.log(D.red(`❌ ${n.name}`),D.gray(`- ${n.description}`)),n.installCommand&&console.log(D.blue(` Install: ${n.installCommand}`)))}else console.log(D.bold("\n🔒 Sandbox Dependencies")),console.log(D.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(D.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(D.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(D.red(` • ${t.name}`));console.log(D.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(D.bold("\n🤖 Daemon Status"));try{const t=await Xt(),n=await xe.readDaemonState();if(t&&n?(console.log(D.green("✓ Daemon is running")),console.log(` PID: ${n.pid}`),console.log(` Started: ${new Date(n.startTime).toLocaleString()}`),console.log(` CLI Version: ${n.cliVersion}`),n.port&&console.log(` HTTP Port: ${n.port}`)):n&&!t?console.log(D.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(D.red("❌ Daemon is not running")),n){console.log(D.bold("\n📄 Daemon State:"));const e=xe.getStatePaths();console.log(D.blue(`Location: ${e.daemonStateFile}`)),console.log(D.gray(JSON.stringify(n,null,2)))}const s=await is();if(s.length>0){console.log(D.bold("\n🔍 All Agentrix CLI Processes"));const e=s.reduce((e,t)=>(e[t.type]||(e[t.type]=[]),e[t.type].push(t),e),{});Object.entries(e).forEach(([e,t])=>{console.log(D.blue(`\n${{daemon:"🤖 Daemon","upgrade-daemon":"🔄 Upgrade Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?D.cyan:e.includes("daemon")?D.blue:D.gray;console.log(` ${s(`PID ${t}`)}: ${D.gray(n)}`)})})}else console.log(D.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(D.bold("\n💡 Process Management")),console.log(D.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(D.red("❌ Error checking daemon status"))}}let ds=null;async function us(){const e=ys(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(ds&&ds.expiresAt>Date.now()&&ds.overridesSignature===t)return ds.openers;const n=hs(e),s=[];for(const e of n){const t=e.isSupported();t&&s.push({id:e.id,label:e.label,kind:e.kind,method:e.method,urlTemplate:e.urlTemplate,supported:t})}return ds={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function ms(e){const t=process.platform;if("darwin"===t)return function(e){const t=gs(e),n=[];if(t){const e=Ss(t);n.push("-e",`set defaultLocation to POSIX file "${e}"`,"-e","set chosenFolder to choose folder default location defaultLocation")}else n.push("-e","set chosenFolder to choose folder");return n.push("-e","POSIX path of chosenFolder"),fs(ks("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=bs("powershell")?"powershell":bs("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=gs(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${Ts(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return fs(ks(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=gs(e);if(bs("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return fs(ks("zenity",e,{captureOutput:!0}))}if(bs("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),fs(ks("kdialog",e,{captureOutput:!0}))}throw new Error("No supported directory picker is available")}(e);throw new Error("Directory picker is not supported on this platform")}function hs(e){const t=process.platform,n=["Visual Studio Code","Visual Studio Code - Insiders"],s=["Cursor"],a=["IntelliJ IDEA","IntelliJ IDEA CE","IntelliJ IDEA Ultimate"],i=["WebStorm"],o=["PyCharm","PyCharm CE","PyCharm Professional"],c=[{id:"vscode",label:"VS Code",kind:"editor",method:"scheme",urlTemplate:"vscode://file/{path}?windowId=_blank",scheme:"vscode",macAppNames:n,isSupported:()=>xs("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>xs("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>xs("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>xs("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>xs("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?bs("osascript")&&ws("Terminal"):"win32"===e?bs("wt")||bs("powershell")||bs("pwsh")||bs("cmd"):"linux"===e&&Boolean(vs())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(bs("wt"))return void Is("wt",["-d",e]);const t=bs("powershell")?"powershell":bs("pwsh")?"pwsh":null;return t?void Is(t,["-NoExit","-Command",`Set-Location -LiteralPath '${Ts(e)}'`]):void Is("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=vs();if(!t)throw new Error("No supported terminal is available");return void Is(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!ks("osascript",["-e",'tell application "Terminal"',"-e",`do script "${Ss(`cd ${Es(e)}`)}"`,"-e","activate","-e","end tell"]))throw new Error("Failed to open Terminal")}(e,t)},{id:"file-manager",label:"darwin"===t?"Finder":"win32"===t?"Explorer":"Files",kind:"file-manager",method:"cli",isSupported:()=>function(e){return"darwin"===e?bs("open"):"win32"===e||"linux"===e&&(bs("xdg-open")||bs("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return bs("xdg-open")?void ks("xdg-open",[e]):void ks("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}ks("explorer",[e])}else ks("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?bs("osascript"):"win32"===e?bs("powershell")||bs("pwsh"):"linux"===e&&bs("gio")}(t),open:e=>function(e,t){if("darwin"!==t)if("win32"!==t){if("linux"!==t)throw new Error("Open With is not supported on this platform");ks("gio",["open","--ask",e])}else ks(bs("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${Ts(e)}'`]);else if(null===ks("osascript",["-e",`set targetPath to POSIX file "${Ss(e)}"`,"-e","set appChoice to choose application","-e","tell appChoice to open targetPath"],{captureOutput:!0}))throw new Error("No application selected")}(e,t)}];return function(e,t,n){const s=n??ys();return e.map(e=>{const n=s[e.id];if(!n)return e;if(!1===n.enabled)return{...e,isSupported:()=>!1};const a={...e,label:n.label??e.label,method:n.method??e.method,urlTemplate:n.urlTemplate??e.urlTemplate};if(n.command){const s=function(e){return e?Array.isArray(e)?e:[e]:[]}(n.appName??e.macAppNames);a.method="cli",a.isSupported=()=>function(e,t,n){return"darwin"===n&&t.length>0?t.some(e=>ws(e)):I.isAbsolute(e)||e.includes(I.sep)?r(e):bs(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!ks(e,(t&&t.length>0?t:["{path}"]).map(e=>e.split("{path}").join(n))))throw new Error(`Command failed: ${e}`)}(n.command,n.args,e)}return a})}(c,t,e)}function gs(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!d(t).isDirectory())return}catch{return}return t}}function fs(e){if(!e)return null;return e.trim()||null}function vs(){const e=Es(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&bs(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${Es(t)} && exec ${e}`]}:[{command:"gnome-terminal",args:e=>["--working-directory",e]},{command:"kgx",args:e=>["--working-directory",e]},{command:"konsole",args:e=>["--workdir",e]},{command:"xfce4-terminal",args:e=>["--working-directory",e]},{command:"mate-terminal",args:e=>["--working-directory",e]},{command:"lxterminal",args:e=>["--working-directory",e]},{command:"alacritty",args:e=>["--working-directory",e]},{command:"kitty",args:e=>["--directory",e]},{command:"xterm",args:t=>["-e","sh","-lc",`cd ${Es(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${Es(t)} && exec ${e}`]}].find(e=>bs(e.command))??null}function ys(){try{const e=xe.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return we.warn("[OPENERS] Failed to read opener overrides",e),{}}}function xs(e,t,s){return"darwin"===t?function(e,t){if(bs("mdfind")){const t=ks("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(bs("plutil")){const t=[I.join(n.homedir(),"Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"),"/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"];for(const n of t){if(!r(n))continue;const t=ks("plutil",["-extract","LSHandlers","json","-o","-",n],{captureOutput:!0});if(t)try{const n=JSON.parse(t);if(Array.isArray(n)&&n.some(t=>t.LSHandlerURLScheme?.toLowerCase()===e.toLowerCase()))return!0}catch(e){we.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>ws(e))}(e,s):"win32"===t?function(e){return bs("reg")&&(Boolean(ks("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean(ks("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(bs("xdg-settings")){const t=ks("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(bs("gio")){const t=ks("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function ws(e){return"darwin"===process.platform&&Boolean(ks("open",["-Ra",e]))}function bs(e){return"win32"===process.platform?Boolean(ks("where",[e])):Boolean(ks("sh",["-c",`command -v ${e}`]))}function ks(e,t,n){const s=it(e,t,{encoding:n?.captureOutput?"utf8":void 0,stdio:n?.captureOutput?"pipe":"ignore",windowsHide:!0});if(0!==s.status){if(n?.captureOutput){const n="string"==typeof s.stderr?s.stderr.trim():"";n&&we.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function Is(e,t){ot(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function Ts(e){return e.replace(/'/g,"''")}function Ss(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Es(e){return`'${e.replace(/'/g,"'\\''")}'`}function As(e,t){if(t){const n=$(t,e),s=!n||n.startsWith("..")||P(n)?S(e):n;return T(t,"versions",s)}let n=_(e),s=0;for(;s<10;){if(r(T(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return T(n,"versions",t)}const t=_(n);if(t===n)break;n=t,s++}const a=_(e),i=S(e);return T(a,`.${i}.version`)}function Cs(e,t){const n=As(e,t);if(!r(n))return"0.0.0";try{return c(n,"utf-8").trim()}catch(e){return"0.0.0"}}function _s(e,t,n){try{const s=As(e,n),a=_(s);r(a)||p(a,{recursive:!0}),u(s,t,"utf-8")}catch(e){}}function $s(e,t){const n=e.split(".").map(Number),s=t.split(".").map(Number);for(let e=0;e<3;e++){const t=n[e]||0,a=s[e]||0;if(t>a)return 1;if(t<a)return-1}return 0}function Ps(e,t,n){const s=Cs(e,n),a=$s(t.metadata.version,s);if(!r(e)){const s=_(e);return r(s)||p(s,{recursive:!0}),u(e,t.content,"utf-8"),_s(e,t.metadata.version,n),{updated:!0,reason:"created"}}if(a<=0)return{updated:!1,reason:"up-to-date"};switch(t.metadata.updateStrategy){case"overwrite":return u(e,t.content,"utf-8"),_s(e,t.metadata.version,n),{updated:!0,reason:"overwritten"};case"create-only":return{updated:!1,reason:"create-only"};case"notify-user":return{updated:!1,reason:"requires-user-approval"};default:return{updated:!1,reason:"unknown-strategy"}}}function Ms(e){return`# Upgrade: ${e.template.metadata.description||e.template.relativePath}\n\n**Relative Path**: \`${e.template.relativePath}\`\n**Template Language**: \`${e.template.language??"common"}\`\n**Current Version**: v${e.currentVersion}\n**New Version**: v${e.newVersion}\n**Target Path**: \`${e.targetPath}\`\n**Upgrade File Path**: \`${e.upgradePath}\`\n**Version Marker Path**: \`${e.versionPath}\`\n\n---\n\n## New Content\n\n${e.template.content}\n\n---\n\n## Integration Instructions\n\n1. Read the new content above\n2. Compare with the exact target file: \`${e.targetPath}\`\n3. Integrate the new features in the Companion's current voice and language\n4. Keep existing customizations\n5. Use Write tool to update the exact version marker path \`${e.versionPath}\` with content: "${e.newVersion}"\n6. Delete this file when done: \`${e.upgradePath}\`\n`}async function Rs(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=T(xe.agentrixAgentsHomeDir,t);if(r(i))return{agentDir:i};const o=`${i}.tmp-${Date.now()}`;try{const e=["git","clone","--depth=1"];if(s&&e.push("--branch",s),e.push(n,o),rt(e.join(" "),{stdio:"pipe"}),a){const e=T(o,a);if(!r(e))throw new Error(`Sub-directory "${a}" not found in cloned repository`);m(e,i),h(o,{recursive:!0,force:!0})}else m(o,i);return Ns(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function Ns(e){const t=[],n=T(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=T(n,e);d(s).isDirectory()&&r(T(s,"package.json"))&&t.push(s)}const s=T(e,"claude","hooks");r(s)&&r(T(s,"package.json"))&&t.push(s);for(const e of t)rt("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),rt("yarn build",{cwd:e,stdio:"pipe"})}function Ds(e){const t=e.split("\n");for(;t.length>0&&""===t[0].trim();)t.shift();for(;t.length>0&&""===t[t.length-1].trim();)t.pop();const n=t.reduce((e,t)=>{if(""===t.trim())return e;const n=t.match(/^\s*/)[0].length;return Math.min(e,n)},1/0);return t.map(e=>e.slice(n)).join("\n")}const Os=Ds("\n ## Title Setting Protocol:\n - MUST set a descriptive title using mcp__agentrix__change_title as your FIRST action when the user makes a request\n - This is mandatory, not optional - do this before any other work\n - Update the title if the conversation direction changes substantially\n");const Us=Ds("\n Important: If the content to be written to a file is too long, split it into chunks and write them to the file incrementally. Writing too much content at once can easily cause errors.\n");function js(e){const t="group"===e?.chatType?.toLowerCase();return Ds(`\n ## External Channel Context\n\n ${function(e){const t=function(e){const t=e?.trim();return t?{telegram:"Telegram",wechat:"WeChat",lark:"Lark"}[t.toLowerCase()]??t:null}(e?.platform),n=[e?.chatType?`chat type: ${e.chatType}`:void 0,e?.chatName?`chat name: ${e.chatName}`:void 0,e?.chatId?`chat id: ${e.chatId}`:void 0].filter(Boolean).join(", ");return Ds(t?`\n This task was started from an external messaging channel on ${t}.\n The user is interacting with you through ${t}.\n ${n?`Channel context: ${n}.`:""}\n `:"\n This task was started from an external messaging channel such as Telegram, WeChat, or Lark.\n The user is interacting with you through that external platform.\n ")}(e)}\n\n ${t?Ds("\n This external channel is a group chat. Recent group history may already be injected into the current input as `<external_group_history>` with `<msg>` entries and sender metadata.\n\n If you need more context from earlier group messages, use `mcp__agentrix__get_channel_group_history` to page older saved group history. That tool is read-only and is only for understanding context/history.\n "):""}\n\n Your normal final result is NOT automatically sent to the external channel. It is stored in Agentrix/task history.\n\n The external user is waiting on the external platform. If you do not call \`mcp__agentrix__send_channel_message\` during this turn, the user will see absolutely nothing from your model-directed channel response. Any runtime fallback is only an emergency safety net; do not rely on it.\n\n You MUST use \`mcp__agentrix__send_channel_message\` to send anything the external user should see: acknowledgements, progress updates, questions, results, and failures.\n\n Before ending the task, you MUST ensure the external user has received an appropriate user-facing message via \`mcp__agentrix__send_channel_message\`.\n\n Do not put user-facing content only in the final internal result; the system will NOT forward the normal success result when you have used the channel message tool.\n\n For multi-step tasks, at minimum call \`mcp__agentrix__send_channel_message\` once before ending with the final conclusion.\n\n If the user receives no message at all, the answer is considered a failure regardless of how complete the internal result is.\n\n ## What to send with send_channel_message\n\n Use \`mcp__agentrix__send_channel_message\` to send user-facing conversational messages to the external channel.\n The purpose is to help the user understand that you are working, what state the work is in, and what the final result is.\n\n You should send:\n - Acknowledgement/progress when the task is long-running, multi-step, or requires waiting, so the user knows work started or is ongoing.\n - Questions/choices/permission requests when user input is needed or you are blocked.\n - User-understandable results when done: conclusion, summary, next steps, and key deliverable notes.\n - Clear failure/limitation messages when the task cannot be completed, a platform does not support something, permission is missing, or an external service fails.\n\n Do not send:\n - Internal reasoning, verbose execution logs, stack traces, debug dumps.\n - Internal summaries that only matter to Agentrix/task history.\n - Excessive implementation detail unless the user is explicitly collaborating technically and needs it.\n - Temporary paths, environment variables, tokens, secrets, or private data.\n\n Style:\n - External channel messages should feel like natural conversation: short, clear, useful.\n - For simple tasks, usually send only the final answer.\n - For long tasks, send a brief start/progress message and a final result message.\n - If attachments are sent, briefly explain what they are and what the user can do next.\n\n ## What attachments to send\n\n Attachments are part of \`send_channel_message\` and are only for deliverables the user should consume, save, view, or forward.\n\n Send attachments for:\n - Files the user explicitly asked to generate, export, package, send, or share.\n - Final deliverables such as images, posters, charts, PDFs, spreadsheets, reports, slides, archives, audio, or video.\n - Artifacts without which the channel answer would be incomplete.\n\n Do not send attachments for:\n - Files that were merely created, edited, read, downloaded, or used while doing the work.\n - Logs, caches, temporary files, build artifacts, intermediate screenshots, debug outputs unless the user explicitly asked for them.\n - Files containing secrets, credentials, private data, or local environment details.\n - Any file that is only part of the work process rather than a user deliverable.\n\n Decision rules:\n - A file generated for the user to use/view/save is usually an attachment deliverable.\n - A file created or modified while completing work is not automatically a deliverable; decide based on user intent.\n - Do not decide based on file location or directory.\n - A file inside the workspace can be a deliverable.\n - A file outside the workspace can still be unsafe or inappropriate.\n - Decide based on semantics and user intent, not path location.\n - When modifying files, do not send them automatically; summarize changes in text unless the user asked to receive, export, package, or forward those files.\n - If uncertain or risky, ask for confirmation via \`send_channel_message\` first.\n\n Do NOT send files just because they were created, edited, read, downloaded, or used during the task.\n After sending the external response, your final result can briefly summarize what you sent for Agentrix history.\n If the platform does not support sending that attachment type, explain that and provide the best available alternative.\n`)}js();const qs=Ds('\n ## Input Data Format (Conversation Stream)\n\n Messages come in this XML format. Pay attention to `seq` to understand the order.\n\n <msg seq="N" at="ISO_TIME" senderType="human|agent" senderId="id" senderName="name">\n content\n </msg>\n'),Ls=Ds('\n ## Orchestration Decision Framework\n\n **Core Principle**: Analyze dependencies FIRST to choose orchestration mode.\n\n **Decision Rule**:\n - **No dependencies** (agents work independently) → Direct execution\n - **Has dependencies** (sequential, turn-taking, coordination) → Plan-Execute-Replan loop\n\n ### Mode 1: Direct Execution (No Dependencies)\n\n When agents can work independently with no coordination:\n - Single agent request\n - Parallel opinions (no need to build on each other)\n - Independent work tasks\n\n **Examples**:\n - "Claude, explain X" → invoke(claude)\n - "What do you both think?" → invoke(claude), invoke(codex)\n - "Claude, write parser. Codex, write formatter." → assign both\n\n ### Mode 2: Plan-Execute-Replan Loop (Has Dependencies)\n\n When work has sequential dependencies or coordination:\n\n **The Loop**:\n 1. **PLAN**: TodoWrite defines structure/order\n 2. **EXECUTE**: invoke/assign first agent\n 3. **WAIT**: Agent responds in next message batch\n 4. **REPLAN**: Update TODO (mark done), identify next\n 5. **REPEAT**: Continue until complete\n\n **Dependency types**:\n - **Sequential**: Agent B needs Agent A\'s output\n - **Turn-taking**: Debate/conversation structure (A→B→A)\n - **Coordination**: Multiple agents with defined roles\n\n **Example - Debate** (turn-taking dependency):\n ```\n User: "4-round debate on REST vs GraphQL"\n\n PLAN (TodoWrite):\n - [ ] Claude: Opening argument FOR REST\n - [ ] Codex: Counter argument FOR GraphQL\n - [ ] Claude: Rebuttal\n - [ ] Codex: Final response\n\n EXECUTE: invoke(claude, hint="You argue FOR REST. Present your opening argument.")\n WAIT: Claude responds with REST argument\n REPLAN: Mark done, next is codex\n EXECUTE: invoke(codex, hint="You argue FOR GraphQL. Counter the REST arguments.")\n WAIT: Codex responds with GraphQL argument\n REPLAN: Mark done, next is claude rebuttal\n EXECUTE: invoke(claude) // No hint needed - role already established from history\n REPEAT...\n ```\n\n **hint usage**: Use hint to reduce agent\'s attention cost or provide meta-context:\n - ✅ Role assignment: first turn of debate (hint="You argue FOR REST")\n - ✅ Focus guidance: (hint="Focus only on performance aspects")\n - ✅ Long/busy chat: help agent locate relevant context (hint="Respond to Alice\'s question about caching")\n - ✅ Multi-topic: clarify which thread to address (hint="Re: the API design discussion")\n - ❌ Short, clear context: agent can easily find what to respond to\n - ❌ Role already established: agent knows their role from recent history\n\n **Why TodoWrite**: Planner is event-driven, can\'t "wait" for responses. TodoWrite provides persistent state across turns.\n\n ### Best Practices\n\n - Match agent to user intent by reviewing capabilities (get_task_agents)\n - Review history (get_task_history) when context is unclear\n\n ### Common Mistakes\n\n - ❌ Invoke just because an agent spoke; only act on unmet user requests\n - ❌ Repeated or cascading invokes on the same request\n - ❌ Invoke multiple agents with dependencies simultaneously\n - ❌ Use TodoWrite for independent requests (over-engineering)\n - ❌ Forget to update TODO after agent responds\n'),Hs=Ds('\n You are Planner, orchestrating a chat group where Users and Agents interact.\n Your goal is to observe the conversation stream, analyze context, and direct appropriate agents via tools.\n\n ## Visibility Rules\n\n - Your text output is NOT shown to users, but IS visible to developers for debugging\n - Keep brief reasoning/analysis in your output to help developers understand your decisions\n - NEVER attempt to answer user questions directly - let agents handle all user interaction\n\n ## Output Format\n\n 1. Brief reasoning (for developer debugging)\n 2. Tool calls if needed\n 3. Final output: ONLY "✅" on a new line (no other text after it)\n'),Gs=Ds("\n # Task Delegation\n\n ## When to Delegate (use create_task)\n\n - Implementation work: writing code, editing files, running tests\n - Investigation: multi-file analysis, tracing bugs, code archaeology\n - Code reviews, audits, or quality scans\n - Producing artifacts: reports, plans, configs\n - Any work where the user is waiting for you to finish before the conversation can continue\n\n ## When to Respond Directly\n\n - Answering questions, explaining concepts\n - Quick file lookups to answer a specific question (1-2 reads is fine)\n - Short code snippets or examples in conversation\n - Discussion, planning, decision-making with the user\n\n ## Your Role in Conversation\n\n The conversation is for **discussion, decisions, and summaries** — not for executing work.\n\n - Discuss approaches, trade-offs, and options with the user\n - Make decisions together (or present recommendations)\n - Summarize task results when they come back\n - Coordinate and plan — then delegate execution to tasks\n\n ## Anti-Patterns (Do NOT do these in conversation)\n\n - ❌ **Code editing**: Don't write/edit code directly in conversation — create a task\n - ❌ **Research rabbit holes**: Don't grep → read → grep → read in conversation — delegate the investigation\n - ❌ **Building artifacts**: Any output that produces files (code, reports, configs) belongs in a task\n - ❌ **Running tests/builds**: Don't run test suites or build commands in conversation — create a task\n\n **Rule of thumb**: If you're about to *change* something or *produce* something, it's a task. If you're about to *answer* something, respond directly.\n\n ## After Delegating\n\n - User sees task creation confirmation immediately\n - Continue responding to user's other questions\n - You'll receive <sub-task-result-updated> when task completes\n - Briefly summarize the result to user — no deep analysis needed\n - Do NOT create duplicate sub-tasks unless explicitly asked\n\n ## Using emit_to_task Effectively\n\n emit_to_task sends follow-up instructions to a running or completed sub-task. Use it for:\n\n - **User adds requirements**: User says \"also add tests\" → emit to the existing task, don't create a new one\n - **Passing decisions**: You discussed options with user, user chose option B → emit the decision to the task\n - **Course correction**: Task went in wrong direction → emit new guidance\n - **Providing context**: Task asks a question → get answer from user → emit answer to task\n - **Retry after failure**: Task failed → emit instructions to retry with fixes\n\n Do NOT use emit_to_task to:\n - Start a completely different task (create a new task instead)\n - Send very long instructions (if the scope changed drastically, create a new task)\n\n ## Task Granularity\n\n - **One task = one coherent unit of work** (e.g., \"implement login page\", \"investigate memory leak\")\n - Don't create a task for a single trivial operation (e.g., \"read one file\")\n - Don't cram unrelated work into one task — split them so they can run in parallel\n - Multiple independent tasks CAN run in parallel\n"),Bs=Ds(`\n ${Hs}\n\n ${qs}\n\n ${Ls}\n`),Fs=Ds('\n ## Message Format\n\n Messages in this group chat are formatted as XML:\n\n <msg seq="N" at="ISO_TIME" senderType="human|agent" senderId="id" senderName="name">\n content\n </msg>\n\n You may also receive a `<hint>` block at the start:\n\n <hint>\n context or instruction from the orchestrator\n </hint>\n\n The hint provides context for your response (e.g., debate role, focus area).\n Follow the hint\'s guidance while responding to the conversation.\n\n When responding, just reply naturally - the system will handle formatting.\n');function Ws(e){const t=["# Available Agents",""];for(const n of e)n.description?t.push(`- **${n.name}** (${n.id}): ${n.description}`):t.push(`- **${n.name}** (${n.id})`);return t.join("\n")}function zs(e,t){const n=t.find(t=>t.id===e);if(!n)return Ws(t);const s=t.filter(t=>t.id!==e),a=["# Group Context","",`You are \`${n.name}\`. `,"You are a member of this group chat."];if(n.description&&a.push(`Your role: ${n.description}`),s.length>0){a.push(""),a.push("## Other Agents in This Group"),a.push("");for(const e of s)e.description?a.push(`- **${e.name}**: ${e.description}`):a.push(`- **${e.name}**`)}return a.push(""),a.push(Fs),a.join("\n")}function Ks(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function Vs(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function Xs(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function Js(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(Vs).map(e=>e.text).join("\n").trim():""}function Ys(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n={input_tokens:e.usage.input_tokens,output_tokens:e.usage.output_tokens,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:e.usage.cached_input_tokens,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"};return{type:"result",subtype:"success",duration_ms:0,duration_api_ms:0,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:n,modelUsage:{[e.model]:{inputTokens:t>0?t:0,outputTokens:e.usage.output_tokens,cacheReadInputTokens:e.usage.cached_input_tokens,cacheCreationInputTokens:0,webSearchRequests:0,costUSD:0,contextWindow:0,maxOutputTokens:0}},permission_denials:[],uuid:crypto.randomUUID(),session_id:e.sessionId,structured_output:e.structuredOutput}}function Qs(e,t){if(!t)return;const n=e?.trim();if(!n)throw new Error("Structured output was requested but the agent returned an empty response");try{return JSON.parse(n)}catch(e){const t=n.length>200?`${n.slice(0,200)}...`:n;throw new Error(`Structured output was requested but the agent returned invalid JSON: ${e instanceof Error?e.message:"unknown error"}; response=${JSON.stringify(t)}`)}}const Zs="agentrix",ea="1.0.0";async function*ta(e){yield e}let na;const sa=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],aa=["EnterPlanMode","ExitPlanMode"],ia=new Set(aa),oa=["Glob","Grep","Read","Skill"],ra=["Read","Glob","Grep"],ca=["Read","Glob","Grep","TodoWrite"];function la(e){const{agentId:t,modeConfig:n,cwd:s,agentConfig:a,channelBound:i,channelContext:o,projectGuidance:r,promptPlaceholders:c,enableTaskPreviewUrl:l}=e,{mode:p,groupAgents:d}=n,u=a.customSystemPrompt,m=a.systemPromptMode??"append",h=function(e,t=!0){const{mode:n,supportChangeTitle:s}=e,a=[Us];switch(n){case"work":case"group_work":s&&a.unshift(Os),t&&a.push(Ds(`\n ## Task Preview URL Protocol:\n - If the user provided a service startup port, relevant startup documentation, or you started/reused a frontend service yourself, publish the preview URL for the current Agentrix task whenever you know the running service port.\n - Use \`${"mcp__agentrix__publish_task_preview_url"}\` to publish the preview URL.\n - Publish only absolute http or https URLs. Local preview URLs such as http://localhost:5173 are valid.\n - Do not publish URLs for backend-only services or endpoints that are not user-facing frontend previews.\n `));break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":a.unshift(Gs)}return a.join("\n\n")}(n,l);if("group_chat"===p||"group_work"===p){const e=[Bs];return d&&d.length>0&&e.push(Ws(d)),h&&e.push(h),i&&e.push(js(o)),r?.systemPromptAppend&&e.push(r.systemPromptAppend),e.join("\n\n")}const g="reply"===p&&d&&d.length>0?zs(t,d):void 0,f={},v=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE;v&&(f.COMPANION_HOME=v,f.COMPANION_MODE="companion_shadow"===p?"shadow":"chat"),Object.assign(f,c);const y=Object.keys(f).length>0?f:void 0,x=u?Be(u,s,y):void 0;if("replace"===m&&x){const e=[x];return g&&e.push(g),h&&e.push(h),i&&e.push(js(o)),r?.systemPromptAppend&&e.push(r.systemPromptAppend),e.join("\n\n")}const w=[];return g&&w.push(g),h&&w.push(h),i&&w.push(js(o)),x&&w.push(x),r?.systemPromptAppend&&w.push(r.systemPromptAppend),{type:"preset",preset:"claude_code",append:w.length>0?w.join("\n\n"):void 0}}function pa(e,t,n,s,a,i,o,c){const l=la({agentId:e,modeConfig:n.modeConfig,cwd:n.cwd,agentConfig:s,channelBound:n.channelBound,channelContext:n.channelContext,projectGuidance:n.projectAgentrixGuidance,promptPlaceholders:n.promptPlaceholders,enableTaskPreviewUrl:n.enableTaskPreviewUrl}),p=(d=function(e){switch(e){case"work":case"companion_shadow":return;case"chat":case"companion_chat":return[...sa];case"reply":return[...oa];case"group_chat":return[...ra];case"group_work":return[...ca]}}(n.modeConfig.mode),Boolean(n.disableClaudePlanModeTools)&&d?d.filter(e=>!ia.has(e)):d);var d;const u=function(e,t){const n={},s=e=>async(t,n,s)=>await e(t,n,s)??{},a=new Set([...Object.keys(e),...t?Object.keys(t):[]]);for(const i of a){const a=[],o=e[i];o&&a.push(s(o));const r=t?.[i];r&&a.push(s(r)),n[i]=[{hooks:a}]}return n}(n.hooks??{},a),m=function(){if(void 0!==na)return na??void 0;const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(e){const t=function(e){const t=e.trim();if(t){if(t.includes("/")||t.includes("\\")||t.startsWith(".")){const e=P(t)?t:A(t);return r(e)?e:void 0}return function(e){const t="win32"===process.platform?"where":"which",n=it(t,[e],{encoding:"utf-8"});if(0===n.status)return n.stdout.split(/\r?\n/).map(e=>e.trim()).find(e=>e.length>0)}(t)}}(e);if(t)return na=t,t}na=null}(),h=o?function(e){const{modeConfig:t,tools:n,agentType:s,allowAskUser:a=!0,supportedFeatures:i,channelBound:o,channelGroupBound:r,visionModel:c,enableTaskPreviewUrl:l=!0,extraTools:p=[],serverName:d=Zs,serverVersion:u=ea}=e,{mode:m,supportChangeTitle:h}=t,g=[];switch(m){case"work":i?.includes("sub-task")&&(g.push(n.createTask),g.push(n.replyToSubTask),g.push(n.listSubTask)),h&&g.push(n.changeTaskTitle),a&&g.push(n.askUser),l&&g.push(n.publishTaskPreviewUrl),g.push(n.getTaskHistory);break;case"chat":g.push(n.createTask),g.push(n.replyToSubTask),a&&g.push(n.askUser),g.push(n.getTaskHistory),g.push(n.listSubTask);break;case"group_chat":g.push(n.invoke),g.push(n.createSoloTask),g.push(n.createGroupTask),g.push(n.replyToSubTask),g.push(n.getTaskAgents),g.push(n.getTaskHistory);break;case"group_work":g.push(n.invoke),g.push(n.assign),h&&g.push(n.changeTaskTitle),l&&g.push(n.publishTaskPreviewUrl),g.push(n.getTaskAgents),g.push(n.getTaskHistory);break;case"reply":g.push(n.getTaskHistory),a&&g.push(n.askUser);break;case"companion_chat":g.push(n.createTask),g.push(n.replyToSubTask),a&&g.push(n.askUser),g.push(n.getTaskHistory),g.push(n.uploadFile),g.push(n.listAgents),g.push(n.scheduleTask);break;case"companion_shadow":g.push(n.getTaskHistory),g.push(n.readConversation),g.push(n.listAgents),g.push(n.scheduleTask)}("companion_chat"===m||"companion_shadow"===m)&&(g.push(n.listTasks),g.push(n.sendReminder),g.push(n.prepareHiveRepository),g.push(n.publishToHive),g.push(n.updateHiveListingVersion),g.push(n.recordHiveInstall),g.push(n.createHiveReview),g.push(n.createHiveComment)),"companion"===s&&g.push(n.updateAgentInfo),o&&"companion_shadow"!==m&&g.push(n.sendChannelMessage),r&&"companion_shadow"!==m&&g.push(n.getChannelGroupHistory),c&&"companion_shadow"!==m&&"reply"!==m&&g.push(n.analyzeImage),g.push(...p);const f=pt({name:d,version:u,tools:g}),v=g.map(e=>((e,t)=>`mcp__${e}__${t}`)(d,e.name));return{server:f,toolNames:v}}({modeConfig:n.modeConfig,tools:o,agentType:t,allowAskUser:n.allowAskUser,supportedFeatures:n.supportedFeatures,channelBound:n.channelBound,channelGroupBound:n.channelGroupBound,visionModel:n.visionModel,enableTaskPreviewUrl:n.enableTaskPreviewUrl,extraTools:n.agentrixExtraTools}):void 0,g={...h?.server?{agentrix:h.server}:{},...n.mcpServers??{},...i??{}};return{stderr:n.stderr,model:n.model||s.customModel,fallbackModel:s.customFallbackModel,cwd:n.cwd,resume:n.agentSessionId,permissionMode:n.initialPermissionMode??s.customPermissionMode??"bypassPermissions",settingSources:["user","project","local"],systemPrompt:l,tools:p,...n.disableClaudePlanModeTools?{disallowedTools:[...aa]}:{},mcpServers:g,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?Ks(n.env):void 0,pathToClaudeCodeExecutable:m,maxTurns:s.customMaxTurns??n.maxTurns??c,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:u,outputFormat:n.structuredOutputSchema}}class da{constructor(e,t,n,s,a){this.agentId=e,this.agentType=t,this.agentConfig=n,this.agentHooks=s,this.agentMcpServers=a}getAgentConfiguration(){return this.agentConfig}getHooks(){return this.agentHooks}getMcpServers(){return this.agentMcpServers}async executeHook(e,t,n){await async function(e,t,n,s){if(!e)return;const a=e[t];if(!a)return;const i=s||(e=>console.log(e));try{i(`[${t}] Executing hook...`);const e=new AbortController,s=setTimeout(()=>{e.abort()},6e4);try{await a(n,"",{signal:e.signal}),i(`[${t}] Hook executed successfully`)}finally{clearTimeout(s)}}catch(e){console.warn(`[${t}] Hook failed (non-fatal):`,e)}}(this.agentHooks,e,t,n)}async run(e,t){const n=this.agentConfig,s="string"==typeof e?Xs(e):e;let a=null;const i=dt({prompt:ta(s),options:pa(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const e of i)if(console.log("ClaudeRunner.run: received message",JSON.stringify(e)),"result"===e.type){a=e;break}if(!a)throw new Error("ClaudeRunner.run: missing result message");return a}async*runStreamed(e,t){const n=this.agentConfig,s="string"==typeof e?Xs(e):e,a=dt({prompt:ta(s),options:pa(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const e of a)if(yield e,"result"===e.type)break}loop(e){const t=e.abortController,n=this.agentConfig,s=pa(this.agentId,this.agentType,e,n,this.agentHooks,this.agentMcpServers,e.agentrixTools);let a=!1;const i=[];let o=null,r=null;const c=()=>{if(!a&&(a=!0,o)){const e=o;o=null,e(null)}},l=async function*(){for(;!a&&!t.signal.aborted;){if(i.length>0){yield i.shift();continue}const e=await new Promise(e=>{o=e});if(!e)break;yield e}},p=async function*(){try{const e=dt({prompt:l(),options:s});r=e;for await(const t of e)yield t}finally{r=null,c()}}();return t.signal.addEventListener("abort",c,{once:!0}),{push:e=>{if(console.log("ClaudeRunner.loop.push:",JSON.stringify(e,null,2)),a)return;const t="string"==typeof e?Xs(e):e;if(o){const e=o;return o=null,void e(t)}i.push(t)},events:p,stop:c,setPermissionMode:async e=>{r&&await r.setPermissionMode(e)}}}}function ua(e,t,n){e&&e(t,"AGENT",n)}function ma(){return`Companion probe timed out after ${Math.round(45)}s`}function ha(e){return e instanceof Error&&e.message?e.message:String(e)}function ga(e){return"string"==typeof e.result&&e.result.trim()?e.result:Array.isArray(e.permission_denials)&&e.permission_denials.length>0?String(e.permission_denials[0]):"error_max_turns"===e.subtype?"Companion probe exceeded max turns":"Companion probe failed"}async function fa(){const e=T(xe.agentrixHomeDir,"tmp","companion-probe");p(e,{recursive:!0});const t=new da("default","claude",{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}),n=new AbortController;let s=!1;const a=setTimeout(()=>{s=!0,n.abort()},45e3);try{const a=await t.run("hi",{cwd:e,abortController:n,modeConfig:{mode:"chat",supportChangeTitle:!1}});return a.is_error?{success:!1,error:s?ma():ga(a)}:{success:!0}}catch(e){return{success:!1,error:s?ma():ha(e)}}finally{clearTimeout(a)}}const va=ht(ct);function ya(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),gt(t)}async function xa(e){try{const t=ya(e);return await t.checkIsRepo()}catch{return!1}}async function wa(e){const t=ya(e),n=(await t.raw(["worktree","list","--porcelain"])).trim().split("\n").filter(Boolean),s=[];let a=null;for(const e of n)if(e.startsWith("worktree "))a&&s.push(a),a={path:e.replace("worktree ","").trim(),branch:null,commit:"",isMain:0===s.length};else if(a)if(e.startsWith("HEAD "))a.commit=e.replace("HEAD ","").trim();else{if(e.startsWith("branch ")){const t=e.replace("branch ","").trim();a.branch=t.replace("refs/heads/","");continue}e.startsWith("detached")&&(a.branch=null)}return a&&s.push(a),s}async function ba(e,t,n,s="HEAD"){const a=_(t);if(r(a)||p(a,{recursive:!0}),r(t)&&!$a(t))throw new Error(`Worktree directory already exists at ${t}`);const i=ya(e);await i.raw(["worktree","add","-b",n,t,s])}async function ka(e,t,n=!1){const s=ya(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function Ia(e){const t=ya(e);await t.init()}async function Ta(e){const t=ya(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function Sa(e,t){const n=_(t);r(n)||p(n,{recursive:!0});const s=ya();await s.clone(e,t)}async function Ea(e,t,n){const s=ya(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(n&&await s.checkout(n),await s.checkoutLocalBranch(t))}async function Aa(e){const t=ya(e);return!(await t.status()).isClean()}async function Ca(e){const t=ya(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function _a(e){try{const t=ya(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function $a(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function Pa(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function Ma(e,t,n){const s=ya(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:Pa(K(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function Ra(e,t){try{const{stdout:n}=await va("git",t,{cwd:e,maxBuffer:10485760,windowsHide:!0});return n}catch(e){const t=e;if(1===t.code&&"string"==typeof t.stdout)return t.stdout;throw e}}function Na(e){return e.split("\n").map(e=>e.trim()).filter(Boolean).map(e=>function(e){const[t,n,s]=e.split("\t");if(!t||!n||!s)return null;const a="-"===t?0:Number.parseInt(t,10),i="-"===n?0:Number.parseInt(n,10);if(Number.isNaN(a)||Number.isNaN(i))return null;const o=s.startsWith("/dev/null => ")?s.slice(13):s;return{path:Pa(K(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function Da(e,t){return me("sha256").update(`${e}\n${t}`).digest("hex")}async function Oa(e,t){const n=await Ra(e,["diff","--binary","--find-renames",t,"--"]),s=Na(await Ra(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await va("git",["ls-files","--others","--exclude-standard","-z"],{cwd:e,maxBuffer:10485760,windowsHide:!0});return t.split("\0").filter(Boolean)}(e),i=await Promise.all(a.map(t=>Ra(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=Na((await Promise.all(a.map(t=>Ra(e,["diff","--no-index","--numstat","--","/dev/null",t])))).join("\n")),r=function(e){const t=e.trim();return t?`${t}\n`:""}([n,...i].filter(Boolean).join("\n"));return r?{patch:r,stats:{totalInsertions:(c=[...s,...o]).reduce((e,t)=>e+t.insertions,0),totalDeletions:c.reduce((e,t)=>e+t.deletions,0),files:c},artifactVersion:Da(t,r)}:null;var c}async function Ua(e){const t=ya(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function ja(e,t,n){const s=ya(e);await s.remote(["set-url",t,n])}function qa(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function La(e,t,n){const s=ya(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await ja(e,t,n):await s.addRemote(t,n)}function Ha(e){const t=e.match(/^git@([^:]+):(.+)\/(.+?)(?:\.git)?$/);if(t){const[,n,s,a]=t;return{url:e,host:n.split("-")[0],owner:s,repo:a}}const n=e.match(/^https?:\/\/([^/]+)\/(.+)\/(.+?)(?:\.git)?$/);if(n){const[,t,s,a]=n;return{url:e,host:t,owner:s,repo:a}}return null}async function Ga(e){try{const t=ya(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?Ha(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const Ba="oauth2",Fa="AGENTRIX_GIT_USERNAME",Wa="AGENTRIX_GIT_PASSWORD";function za(){const e=T(s(),`git-askpass-${ue()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${Fa}:-${Ba}}" ;;\n *) printf '%s\\n' "\${${Wa}:-}" ;;\nesac\n`,{mode:448}),e}function Ka(e,t,n=Ba){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[Fa]:n,[Wa]:t}}function Va(){const e={...process.env};return delete e.GIT_ASKPASS,delete e.SSH_ASKPASS,delete e.VSCODE_GIT_ASKPASS_NODE,delete e.VSCODE_GIT_ASKPASS_MAIN,delete e.VSCODE_GIT_ASKPASS_EXTRA_ARGS,e.GIT_TERMINAL_PROMPT="0",e}const Xa=ht(ct),Ja="github",Ya="xmz-ai",Qa="agentrix-agent",Za="https://github.com/xmz-ai/agentrix-agent.git",ei="main";async function ti(e,t,n){await Xa("git",["clone","--depth=1","--branch",t,e,n]),await La(n,"origin",qa(e))}async function ni(e){const t=xe.resolveRepoStoreCheckoutDir(Ja,Ya,Qa),n=T(t,"companion"),s=xe.resolveRepoStoreLockPath(Ja,Ya,Qa),a=await xe.acquireFileLock(s);if(!a)throw new Error(`Timed out waiting for Companion template repository lock at ${s}`);try{const{gitUrl:s,branch:a}=await async function(e){if(e?.token){const t=await async function(e){const t=`${xe.serverUrl}/v1/agents/${encodeURIComponent("companion")}/git-url`;try{const n=await fetch(t,{headers:{Authorization:`Bearer ${e}`}});return n.ok?n.json():null}catch{return null}}(e.token);if(t?.gitUrl)return{gitUrl:t.gitUrl,branch:t.branch||ei}}return{gitUrl:Za,branch:ei}}(e);if(!await xa(t)){if(!$a(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await ti(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(e){return{path:t,companionDir:n,pullSucceeded:!1,error:e instanceof Error?e.message:String(e)}}}try{return await async function(e,t,n){await Xa("git",["fetch","--depth=1",e,t],{cwd:n}),await Xa("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await La(n,"origin",qa(e))}(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(e){if(function(e){const t=e instanceof Error?e.message:String(e);return t.includes("refusing to merge unrelated histories")||t.includes("Not possible to fast-forward")||t.includes("non-fast-forward")}(e))try{return await async function(e,t,n){const s=T(_(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await ti(e,t,s),h(n,{recursive:!0,force:!0}),m(s,n)}catch(e){throw h(s,{recursive:!0,force:!0}),e}}(s,a,t),{path:t,companionDir:n,pullSucceeded:!0}}catch(s){return{path:t,companionDir:n,pullSucceeded:!1,error:`${e instanceof Error?e.message:String(e)}; failed to replace checkout: ${s instanceof Error?s.message:String(s)}`}}return{path:t,companionDir:n,pullSucceeded:!1,error:e instanceof Error?e.message:String(e)}}}finally{await xe.releaseFileLock(s,a)}}function si(e){r(e)||p(e,{recursive:!0})}function ai(e){return e.split("\\").join("/")}function ii(e,t){const n=T(t,"template","versions",`${e}.json`);if(!r(n))return{};try{const e=c(n,"utf-8");return JSON.parse(e)}catch(e){return console.warn(`[Companion] Failed to parse ${n}:`,e),{}}}function oi(e){const t=[e,process.env.AGENTRIX_COMPANION_TEMPLATE_LANGUAGE,process.env.LC_ALL,process.env.LC_MESSAGES,process.env.LANG];for(const e of t){if(!e)continue;const t=e.trim().toLowerCase();if(t){if(t.startsWith("zh"))return"zh-Hans";if(t.startsWith("en"))return"en"}}return"en"}function ri(e){return T(e,"versions/.companion-template-language.json")}async function ci(e){const t=xe.agentrixAgentsHomeDir,n=T(t,"companion"),s=T(n,"claude"),a=!r(T(n,"agent.json")),i=await ni(e?.credentials);let o=r(T(i.companionDir,"agent.json"))?i.companionDir:n;if(i.pullSucceeded||console.warn("[Companion] Template repository update failed:",i.error||"unknown error"),a){const e=await fa();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(T(o,"agent.json")))v(o,n,{recursive:!0}),Ns(n),console.log("[Companion] Installed from template repository");else try{await Rs({agentId:"companion",gitUrl:Za,branch:"main",subDir:"companion"}),console.log("[Companion] Installed from git fallback")}catch(e){console.warn("[Companion] Git install failed, will retry next boot:",e instanceof Error?e.message:e)}r(T(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await Rs({agentId:"companion",gitUrl:Za,branch:"main",subDir:"companion"})),o=r(T(i.companionDir,"agent.json"))?i.companionDir:n}si(T(s,"memory"));const l=oi(e?.preferredLanguage),p=function(e,t,n){if(n)return{language:t,source:"initial-install",verified:!0};const s=function(e){const t=ri(e);if(!r(t))return null;try{const e=JSON.parse(c(t,"utf-8"));return"en"===(n=e.language)||"zh-Hans"===n?e.language:null}catch{return null}var n}(e);if(s)return{language:s,source:"marker",verified:!0};const a=function(e){const t=T(e,"claude","HEARTBEAT.md");if(!r(t))return null;const n=c(t,"utf-8");return/[\u3400-\u9fff]/.test(n)||n.includes("# 心跳")?"zh-Hans":n.includes("# Heartbeat")||n.includes("## Routine")?"en":null}(e);return a?{language:a,source:"inferred",verified:!0}:{language:t,source:"unverified",verified:!1}}(n,l,a);"marker"===p.source&&p.language!==l&&console.log(`[Companion] Using installed template language ${p.language}; requested language ${l} ignored for safe upgrades`),p.verified||console.warn(`[Companion] Could not safely determine installed template language; language-specific pending upgrades will be diagnostic-only. Requested language: ${l}`);const{language:m,templates:h}=function(e,t,n){const s=oi(e),a=ii("common",t),i=ii(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=T(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n,language:"common",sourcePath:s})}const p=T(t,"template","languages",s),u=function(e){const t={};if(!r(e))return t;const n=s=>{const a=g(s).sort();for(const i of a){const a=T(s,i);if(d(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=ai($(e,a));t[o]=c(a,"utf-8")}};return n(e),t}(p);for(const[e,t]of Object.entries(u)){const a=i[e]||(n?l:void 0);a&&o.push({relativePath:e,content:t,metadata:a,language:s,sourcePath:T(p,e)})}if(0===o.length)throw new Error(`Companion template files are missing in ${t}`);return{language:s,templates:o}}(p.language,o,a);!function(e,t,n){if("unverified"===n)return;const s=ri(e);si(_(s)),u(s,JSON.stringify({language:t,source:n,updatedAt:(new Date).toISOString()},null,2),"utf-8")}(n,m,p.source);const f=[];for(const e of h){const t=Ps(T(n,e.relativePath),e,n);if(f.push({path:e.relativePath,updated:t.updated,reason:t.reason}),t.updated){const n="created"===t.reason?"Created":"Updated";console.log(`[Companion] ${n}: ${e.relativePath}`)}}f.some(e=>e.updated&&(e.path.startsWith("claude/plugins/")||e.path.startsWith("claude/hooks/")))&&(Ns(n),console.log("[Companion] Rebuilt plugins after template updates"));const{pendingUpgrades:y,blockedUpgrades:x}=function(e,t,n={}){const s=[],a=[];for(const i of e){if("notify-user"!==i.metadata.updateStrategy)continue;const e=T(t,i.relativePath);if(!r(e))continue;const o=Cs(e,t);if($s(i.metadata.version,o)>0){const r={template:i,targetPath:e,upgradePath:`${e}.upgrade`,versionPath:As(e,t),currentVersion:o,newVersion:i.metadata.version},c=i.language??"common";if("common"!==c){if(!1===n.languageVerified){a.push({...r,reason:`Cannot safely determine installed Companion template language; refusing to generate ${c} upgrade content for ${i.relativePath}.`});continue}if(n.currentLanguage&&c!==n.currentLanguage){a.push({...r,reason:`Template language ${c} does not match installed Companion language ${n.currentLanguage}.`});continue}}s.push(r)}}return{pendingUpgrades:s,blockedUpgrades:a}}(h,n,{currentLanguage:m,languageVerified:p.verified});if(y.length>0||x.length>0)try{const e=T(s,"UPGRADES.md"),t=function(e){const t=e.pendingUpgrades,n=e.blockedUpgrades??[],s=t.length>0?t.map(e=>`### ${e.template.metadata.description||e.template.relativePath}\n\n- Relative path: \`${e.template.relativePath}\`\n- Template language: \`${e.template.language??"common"}\`\n- Current version: \`v${e.currentVersion}\`\n- New version: \`v${e.newVersion}\`\n- Target path: \`${e.targetPath}\`\n- Upgrade file path: \`${e.upgradePath}\`\n- Version marker path: \`${e.versionPath}\``).join("\n\n"):"None.",a=n.length>0?n.map(e=>`### ${e.template.metadata.description||e.template.relativePath}\n\n- Relative path: \`${e.template.relativePath}\`\n- Template language: \`${e.template.language??"common"}\`\n- Current version: \`v${e.currentVersion}\`\n- New version: \`v${e.newVersion}\`\n- Target path: \`${e.targetPath}\`\n- Upgrade file path: \`${e.upgradePath}\`\n- Version marker path: \`${e.versionPath}\`\n- Reason: ${e.reason}`).join("\n\n"):"None.";return`# Upgrades Available\n\nGenerated by Agentrix Companion upgrade detection.\n\n- Agent root: \`${e.agentDir}\`\n- Current Companion template language: \`${e.language}\`\n- Language source: \`${e.languageSource}\`\n\n## Ready Upgrades\n\n${s}\n\n## Blocked Upgrades\n\n${a}\n\n---\n\n**Shadow's Instructions:**\n\nWhen you detect this file:\n1. Read this file to identify available upgrades\n2. For each ready upgrade, read the exact \`Upgrade file path\`\n3. Integrate the new content into the target file while preserving local customizations when possible\n4. Update the exact \`Version marker path\` with the new version number\n5. Delete processed \`.upgrade\` files\n6. Delete this file when all ready upgrades are applied and there are no blocked upgrades\n7. If an upgrade cannot be applied safely, leave the files in place and write the reason under Blocked Upgrades in this file; do not notify the main companion\n`}({pendingUpgrades:y,blockedUpgrades:x,agentDir:n,language:m,languageSource:p.source});u(e,t,"utf-8");for(const e of y)u(e.upgradePath,Ms(e),"utf-8");console.log(`[Companion] Created UPGRADES.md with ${y.length} pending upgrade(s) and ${x.length} blocked upgrade(s)`),console.log("[Companion] Shadow will process upgrades on next heartbeat")}catch(e){console.warn("[Companion] Failed to create upgrade files (permission denied?):",e instanceof Error?e.message:e),console.warn("[Companion] Upgrade detection will be skipped. Please check sandbox permissions for agents directory.")}return console.log(`[Companion] Language: ${m}`),{agentDir:n,homeDir:s}}const li="https://ilinkai.weixin.qq.com",pi="https://novac2c.cdn.weixin.qq.com/c2c",di=1e3,ui=Ve(import.meta.url)("qrcode-terminal");function mi(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function hi(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function gi(e,t){if("number"==typeof e&&Number.isFinite(e)&&e>0)return e;if("string"==typeof e){const t=Number(e);if(Number.isFinite(t)&&t>0)return t}return t}function fi(e){if("number"==typeof e||"string"==typeof e){const t=Number(e);if(Number.isFinite(t))return new Date(t>1e10?t:1e3*t).toISOString();const n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return(new Date).toISOString()}function vi(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function yi(e){if("string"==typeof e.text)return e.text;if("string"==typeof e.content)return e.content;if(e.text_item?.text)return e.text_item.text;for(const t of e.item_list??[]){if("string"==typeof t.text)return t.text;if("string"==typeof t.text_item?.text)return t.text_item.text}}function xi(e){const t=String(e.message_type??e.msg_type??"").toLowerCase();if(t.includes("image"))return"image";if(t.includes("file"))return"file";if(t.includes("voice")||t.includes("audio"))return"voice";if(e.image_item)return"image";if(e.file_item)return"file";for(const t of function(e){return e.item_list??[]}(e)){const e=String(t.type??"").toLowerCase();if(t.image_item||e.includes("image"))return"image";if(t.file_item||e.includes("file"))return"file";if(e.includes("voice")||e.includes("audio"))return"voice"}return"text"}function wi(e){if(e.image_item?.media?.full_url)return bi(e.image_item.media,e.image_item.aeskey,"image.jpg");if(e.image_item?.url)return e.image_item.url;if(e.image_item?.file_id)return e.image_item.file_id;if(e.image_item?.image_key)return e.image_item.image_key;for(const t of e.item_list??[]){if(t.image_item?.media?.full_url)return bi(t.image_item.media,t.image_item.aeskey,"image.jpg");if(t.image_item?.url)return t.image_item.url;if(t.image_item?.file_id)return t.image_item.file_id;if(t.image_item?.image_key)return t.image_item.image_key}}function bi(e,t,n){const s={url:e.full_url||"",aesKey:e.aes_key||t,fileName:n};return`wechat-media:${Buffer.from(JSON.stringify(s)).toString("base64url")}`}function ki(e){return e?Array.isArray(e.updates)?e.updates:Array.isArray(e.msgs)?e.msgs:Array.isArray(e.message_list)?e.message_list:Array.isArray(e.items)?e.items:[]:[]}function Ii(e){return e.retcode??e.ret??e.errcode}function Ti(e,t){const n=Ii(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function Si(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function Ei(e){let t="";return ui.generate(e,{small:!0},e=>{t=e}),t}class Ai{id;platform="wechat";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;polling=!1;pollController=null;pollPromise=null;retryTimer=null;resolveRetrySleep=null;retryDelayMs=di;contextTokens=new Map;clientId=de(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=hi(e.token)??hi(e.botToken)??hi(e.bot_token)??hi(e.apiKey)??hi(e.api_key);return{baseUrl:hi(e.baseUrl)??hi(e.base_url)??li,token:t||mi(t,"token"),routeTag:hi(e.routeTag)??hi(e.route_tag),getUpdatesBuf:hi(e.getUpdatesBuf)??hi(e.get_updates_buf)??"",channelVersion:hi(e.channelVersion)??hi(e.channel_version)??"1.0.0",pollTimeoutMs:gi(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:gi(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:hi(e.fileDownloadEndpoint)??hi(e.file_download_endpoint)??hi(e.downloadEndpoint)??hi(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||li,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${Si(t,"get_bot_qrcode")}?bot_type=3`,{method:"GET",headers:n}),a=await s.json().catch(()=>({}));if(!s.ok)throw new Error(`HTTP ${s.status}: ${JSON.stringify(a)}`);const i=Ii(a);if(i&&0!==i)throw new Error(Ti(a,"WeChat QR login failed"));if(!a.qrcode||!a.qrcode_img_content)throw new Error("WeChat QR login response is missing qrcode data");return{qrcode:a.qrcode,qrcodeContent:a.qrcode_img_content,qrcodeTerminal:Ei(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||li,s=await fetch(`${Si(n,"get_qrcode_status")}?qrcode=${encodeURIComponent(e)}`,{method:"GET",headers:{"iLink-App-ClientVersion":"1"}}),a=await s.json().catch(()=>({}));if(!s.ok)throw new Error(`HTTP ${s.status}: ${JSON.stringify(a)}`);const i=Ii(a);if(i&&0!==i)throw new Error(Ti(a,"WeChat QR status failed"));return{status:a.status||"wait",token:a.bot_token,baseUrl:a.baseurl,ilinkBotId:a.ilink_bot_id,ilinkUserId:a.ilink_user_id}}get state(){return this.connectionState}async connect(){"connected"!==this.connectionState&&"connecting"!==this.connectionState&&(this.polling=!0,this.retryDelayMs=di,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),we.info(`[CHANNEL][WECHAT] Connected: channel=${this.id}`))}async disconnect(){this.polling=!1,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null,this.resolveRetrySleep?.()),this.resolveRetrySleep=null,this.pollController?.abort(),this.pollController=null,await(this.pollPromise?.catch(()=>{})),this.pollPromise=null,this.setState("disconnected")}async sendMessage(e,t){const n=this.contextTokens.get(e);if(!n)throw new Error(`WeChat sendMessage requires an iLink context_token for chat ${e}; wait for this contact to send a message first`);const s=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${de(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[{type:1,text_item:{text:t}}]}},{timeoutMs:this.credentials.requestTimeoutMs}),a=Ii(s);if(a&&0!==a)throw new Error(Ti(s,"WeChat sendMessage failed"))}async sendChannelMessage(e,t){const n=t.content?.trim();n&&await this.sendMessage(e,n);for(const n of t.attachments??[])await this.sendAttachment(e,n)}async sendAttachment(e,t){const n=this.contextTokens.get(e);if(!n)throw new Error(`WeChat send attachment requires an iLink context_token for chat ${e}; wait for this contact to send a message first`);const s=t.fileName?.trim()||S(t.filePath),a=await ft(t.filePath),i=this.resolveOutgoingKind(t),o="image"===i?1:3,r="image"===i?2:4,c=await this.uploadWechatMedia(e,a,s,o),l={full_url:c.fullUrl,aes_key:c.aesKey,encrypt_query_param:c.encryptQueryParam,encrypt_type:1},p="image"===i?{type:r,image_item:{media:l,aeskey:c.aesKeyHex,mid_size:c.encryptedSize}}:{type:r,file_item:{file_name:s,name:s,md5:c.md5,media:l,len:String(a.length)}},d=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${de(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[p]}},{timeoutMs:this.credentials.requestTimeoutMs}),u=Ii(d);if(u&&0!==u)throw new Error(Ti(d,"WeChat send attachment failed"))}resolveOutgoingKind(e){return"image"===e.kind?"image":e.kind&&"auto"!==e.kind&&"file"!==e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}async uploadWechatMedia(e,t,n,s){const a=de(16).toString("hex"),i=de(16).toString("hex"),o=this.encryptWechatMedia(t,i),r=me("md5").update(t).digest("hex"),c=await this.request("getuploadurl",{media_type:s,to_user_id:e,filekey:a,rawsize:t.length,rawfilemd5:r,filesize:o.length,no_need_thumb:!0,aeskey:i},{timeoutMs:this.credentials.requestTimeoutMs}),l=Ii(c);if(l&&0!==l)throw new Error(Ti(c,"WeChat getuploadurl failed"));const p=this.extractUploadParam(c),d=await fetch(`${pi}/upload?encrypted_query_param=${encodeURIComponent(p)}&filekey=${encodeURIComponent(a)}`,{method:"POST",headers:{"Content-Type":"application/octet-stream","Content-Length":String(o.length)},body:o});if(!d.ok){const e=await d.text().catch(()=>"");throw new Error(`WeChat CDN upload failed: HTTP ${d.status}: ${e||d.statusText}`)}const u=d.headers.get("x-encrypted-param");if(!u)throw new Error("WeChat CDN upload response missing x-encrypted-param");return{fullUrl:`${pi}/download?encrypted_query_param=${encodeURIComponent(u)}`,aesKey:Buffer.from(i,"utf-8").toString("base64"),aesKeyHex:i,encryptQueryParam:u,md5:r,encryptedSize:o.length}}extractUploadParam(e){const t=e.upload_param;if("string"==typeof t&&t.trim())return t.trim();const n=e.data;if(n&&"object"==typeof n){const e=n.upload_param;if("string"==typeof e&&e.trim())return e.trim()}throw new Error("WeChat getuploadurl response missing upload_param")}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=function(e){if(!e.startsWith("wechat-media:"))return null;try{const t=JSON.parse(Buffer.from(e.slice(13),"base64url").toString("utf-8"));return"string"==typeof t?.url&&t.url?{url:t.url,aesKey:"string"==typeof t.aesKey?t.aesKey:void 0,fileName:"string"==typeof t.fileName?t.fileName:void 0}:null}catch{return null}}(e);if(n)return await this.downloadEncryptedMedia(n,t.fileName);if(/^https?:\/\//i.test(e))return await un(e,t.fileName);const s=await this.requestDownloadFile(e);return await dn(s,t.fileName||e)}catch(t){return we.warn(`[CHANNEL][WECHAT] Failed to download file: channel=${this.id}, fileKey=${e}`,t),null}}async getChatName(e){return e}async getUserName(e){return e}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async pollLoop(){for(;this.polling;)try{const e=await this.request("getupdates",{get_updates_buf:this.credentials.getUpdatesBuf},{timeoutMs:Math.max(this.credentials.requestTimeoutMs,this.credentials.pollTimeoutMs+5e3)}),t=Ii(e);if(t&&0!==t)throw new Error(Ti(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=di,"connected"!==this.connectionState&&this.setState("connected");for(const e of ki(n)){const t=this.normalizeMessage(e);t&&await(this.messageHandler?.(t))}}catch(e){if(!this.polling)break;if(this.isAbortError(e))continue;const t=e instanceof Error?e:new Error(String(e));we.warn(`[CHANNEL][WECHAT] Poll failed: channel=${this.id}, message=${t.message}`),this.setState("error",t),await this.sleepWithCancel(this.retryDelayMs),this.retryDelayMs=Math.min(2*this.retryDelayMs,3e4),this.polling&&this.setState("connecting")}}async request(e,t,n){const s=new AbortController;"getupdates"===e&&(this.pollController=s);const a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=this.buildHeaders(),a=await fetch(this.apiUrl(e),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,...t}),signal:s.signal}),i=await a.json().catch(()=>({}));if(!a.ok)throw new Error(`HTTP ${a.status}: ${JSON.stringify(i)}`);return i}finally{clearTimeout(a),"getupdates"===e&&this.pollController===s&&(this.pollController=null)}}async requestDownloadFile(e){const t=new AbortController,n=setTimeout(()=>t.abort(),this.credentials.requestTimeoutMs);try{const n=this.buildHeaders(),s=await fetch(this.apiUrl(this.credentials.fileDownloadEndpoint),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,file_id:e,file_key:e,image_key:e}),signal:t.signal});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`HTTP ${s.status}: ${e||s.statusText}`)}return s}finally{clearTimeout(n)}}async downloadEncryptedMedia(e,t){const n=await fetch(e.url);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=Buffer.from(await n.arrayBuffer()),a=e.aesKey?this.decryptWechatMedia(s,e.aesKey):s,i=pn(t||e.fileName||"attachment");return await vt(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=he("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=he("aes-128-ecb",n,null);return t.setAutoPadding(!1),Buffer.concat([t.update(e),t.final()])}}encryptWechatMedia(e,t){const n=Buffer.from(t,"hex");if(16!==n.length)throw new Error(`Invalid WeChat upload AES key length: ${n.length}`);const s=ge("aes-128-ecb",n,null);return Buffer.concat([s.update(e),s.final()])}decodeWechatAesKey(e){const t=Buffer.from(e,"base64").toString("utf-8"),n=/^[0-9a-f]{32}$/i.test(t)?t:e,s=/^[0-9a-f]{32}$/i.test(n)?Buffer.from(n,"hex"):Buffer.from(n,"utf-8");if(16!==s.length)throw new Error(`Invalid WeChat media AES key length: ${s.length}`);return s}buildHeaders(){const e={"Content-Type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${this.credentials.token}`,"X-WECHAT-UIN":this.generateWechatUin()};return this.credentials.routeTag&&(e.SKRouteTag=this.credentials.routeTag),e}apiUrl(e){return Si(this.credentials.baseUrl,e)}generateWechatUin(){const e=de(4).readUInt32BE(0).toString();return Buffer.from(e).toString("base64")}sleepWithCancel(e){return new Promise(t=>{this.resolveRetrySleep=t,this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.resolveRetrySleep=null,t()},e)})}isAbortError(e){return e instanceof Error&&"AbortError"===e.name}normalizeMessage(e){const t=e.chat_id??e.room_id??e.talker??e.from_user_id;if(!t)return we.warn(`[CHANNEL][WECHAT] Ignoring malformed message event: channel=${this.id}`),null;e.context_token&&this.contextTokens.set(t,e.context_token);const n=e,s=function(e){if(e.file_item){const t=e.file_item.file_name??e.file_item.name;return{fileKey:e.file_item.media?.full_url?bi(e.file_item.media,void 0,t):e.file_item.file_id??e.file_item.file_key,fileName:t}}for(const t of e.item_list??[])if(t.file_item){const e=t.file_item.file_name??t.file_item.name;return{fileKey:t.file_item.media?.full_url?bi(t.file_item.media,void 0,e):t.file_item.file_id??t.file_item.file_key,fileName:e}}return{}}(e),a=e.from_user_id??e.sender??t,i=!0===n.is_at||!0===n.mentioned_bot||!0===n.at_bot,o=!0===n.reply_to_bot||!0===n.is_reply_to_bot;return{id:e.message_id??e.msg_id??String(e.id??e.seq??ue()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:vi(n,["sender_name","nickname","user_name"]),type:xi(e),text:yi(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:wi(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:fi(e.timestamp??e.create_time),raw:e}}}const Ci=["telegram","wechat","lark"],_i=tt.enum(Ci),$i=tt.enum(["connecting","connected","disconnected","error"]),Pi=tt.enum(["text","image","file","voice"]),Mi=tt.record(tt.string(),tt.unknown()),Ri=tt.object({id:tt.string(),platform:_i,name:tt.string().optional(),credentials:Mi,enabled:tt.boolean(),connectionState:$i,lastConnectedAt:tt.string().optional(),lastDisconnectedAt:tt.string().optional(),lastError:tt.string().optional(),createdAt:tt.string(),updatedAt:tt.string()}),Ni=tt.object({platform:_i,name:tt.string().optional(),credentials:Mi,enabled:tt.boolean().optional()}),Di=tt.object({id:tt.string(),channelId:tt.string(),chatId:tt.string(),taskId:tt.string(),chatName:tt.string().optional(),createdAt:tt.string(),updatedAt:tt.string()});tt.object({id:tt.string(),channelId:tt.string(),platform:_i,chatId:tt.string(),chatType:tt.string().optional(),senderId:tt.string().optional(),senderType:tt.string().optional(),senderName:tt.string().optional(),type:Pi,text:tt.string().optional(),fileKey:tt.string().optional(),fileName:tt.string().optional(),imageKey:tt.string().optional(),attachmentPaths:tt.array(tt.string()).optional(),mentionedBot:tt.boolean().optional(),replyToBot:tt.boolean().optional(),triggered:tt.boolean().optional(),rawContent:tt.unknown().optional(),timestamp:tt.string(),raw:tt.unknown().optional()});const Oi=tt.object({id:tt.string(),name:tt.string(),avatar:tt.string().optional(),description:tt.string().optional(),chatStatus:tt.string().optional(),external:tt.boolean().optional()}),Ui=tt.enum(["auto","image","file","audio","video"]),ji=tt.object({filePath:tt.string(),fileName:tt.string().optional(),mimeType:tt.string().optional(),kind:Ui.optional()});tt.object({content:tt.string().optional(),attachments:tt.array(ji).optional()});const qi=tt.object({version:tt.literal(1),channels:tt.array(Ri),bindings:tt.array(Di),companionDataEncryptionKey:tt.string().optional(),companionOwnerEncryptedDataKey:tt.string().optional()});function Li(e){return!e||"object"!=typeof e||Array.isArray(e)?null:e}function Hi(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Gi(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function Bi(e){const t=e?.trim().toLowerCase();return"issue"===t?"issue":"mergerequest"===t||"merge_request"===t?"merge_request":void 0}function Fi(e){const t=e.split("/").filter(Boolean);if(t.length<2)return{owner:"",name:e};const n=t[t.length-1];return{owner:t.slice(0,-1).join("/"),name:n}}function Wi(e){const t=Li(e.project);return t?{id:Gi(t.id),path:Hi(t.path),path_with_namespace:Hi(t.path_with_namespace),default_branch:Hi(t.default_branch),web_url:Hi(t.web_url)}:null}function zi(e){const t=Li(e.object_attributes);return t?{iid:Gi(t.iid),title:Hi(t.title),url:Hi(t.url),action:Hi(t.action),state:Hi(t.state)}:null}function Ki(e){const t=Li(e.object_attributes);return t?{iid:Gi(t.iid),title:Hi(t.title),url:Hi(t.url),action:Hi(t.action),state:Hi(t.state),source_branch:Hi(t.source_branch),target_branch:Hi(t.target_branch)}:null}function Vi(e){const t=Li(e.object_attributes);return t?{id:Gi(t.id),note:Hi(t.note),noteable_type:Hi(t.noteable_type),url:Hi(t.url),action:Hi(t.action),system:(n=t.system,"boolean"==typeof n?n:void 0)}:null;var n}function Xi(e){const t=Li(e.object_attributes);return t?{id:Gi(t.id),iid:Gi(t.iid),status:Hi(t.status),source:Hi(t.source),ref:Hi(t.ref),sha:Hi(t.sha),url:Hi(t.url)}:null}function Ji(e){return Hi(e.event_type)||Hi(e.object_kind)||"unknown"}function Yi(e){return!!e&&/(?:^|[^A-Za-z0-9._-])(?:@agentrix|\/agentrix)(?=$|[^A-Za-z0-9._-])/i.test(e)}function Qi(e,t,n,s){const{owner:a,name:i}=Fi(s.path_with_namespace??"");return{AGENTRIX_EVENT_NAME:t,AGENTRIX_EVENT_ACTION:n,AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:a,AGENTRIX_REPOSITORY_NAME:i,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"}}function Zi(e,t,n,s){const a={ref:t,variables:n};return e.id?a.projectId=e.id:e.path_with_namespace&&(a.projectPath=e.path_with_namespace),s.triggerToken&&(a.triggerToken=s.triggerToken),void 0!==s.createTriggerIfMissing&&(a.createTriggerIfMissing=s.createTriggerIfMissing),a}function eo(e,t,n){switch(Ji(t)){case"issue":return function(e,t,n){if("issue"!==Ji(t))return null;const s=Wi(t),a=zi(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes project.default_branch"};const{owner:o,name:r}=Fi(s.path_with_namespace),c=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"close":case"closed":return"closed";case"update":case"updated":case"edit":case"edited":return"edited";default:return"opened"===t?"opened":"closed"===t?"closed":e||"unknown"}}(a.action,a.state),l={AGENTRIX_EVENT_NAME:"issue",AGENTRIX_EVENT_ACTION:c,AGENTRIX_ISSUE_NUMBER:String(a.iid),AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:o,AGENTRIX_REPOSITORY_NAME:r,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"};a.title&&(l.AGENTRIX_ISSUE_TITLE=a.title);const p=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/issues/${t.iid}`:void 0}(s,a);return p&&(l.AGENTRIX_ISSUE_URL=p),{operationPayload:Zi(s,i,l,n),action:c}}(e,t,n);case"note":return function(e,t,n){const s=Wi(t),a=Vi(t);if(!s?.path_with_namespace||!a?.note||!0===a.system||!Yi(a.note))return null;const i=Bi(a.noteable_type);if(!i)return null;const o=Li("issue"===i?t.issue:t.merge_request),r=Gi(o?.iid);if(!r)return null;const c="merge_request"===i?Hi(o?.source_branch):void 0,l="merge_request"===i?Hi(o?.target_branch):void 0,p=n.ref||l||s.default_branch||c;if(!p)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes a usable ref"};const d=function(e){switch(e){case void 0:case"create":case"created":return"created";case"update":case"updated":return"updated";case"delete":case"deleted":return"deleted";default:return e||"unknown"}}(a.action),u=Qi(e,"note",d,s);return u.AGENTRIX_NOTEABLE_TYPE=i,u.AGENTRIX_NOTE_BODY=a.note,a.id&&(u.AGENTRIX_NOTE_ID=String(a.id)),a.url&&(u.AGENTRIX_NOTE_URL=a.url),"issue"===i?u.AGENTRIX_ISSUE_NUMBER=String(r):(u.AGENTRIX_PR_NUMBER=String(r),c&&(u.AGENTRIX_HEAD_REF=c),l&&(u.AGENTRIX_BASE_REF=l)),{operationPayload:Zi(s,p,u,n),action:d}}(e,t,n);case"merge_request":return function(e,t,n){const s=Wi(t),a=Ki(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||a.target_branch||s.default_branch||a.source_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes target_branch or project.default_branch"};const o=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"update":case"updated":return"updated";case"merge":case"merged":return"merged";case"close":case"closed":return"closed";default:return"merged"===t?"merged":"closed"===t?"closed":"opened"===t?"opened":e||"unknown"}}(a.action,a.state),r=Qi(e,"merge_request",o,s);r.AGENTRIX_PR_NUMBER=String(a.iid),a.source_branch&&(r.AGENTRIX_HEAD_REF=a.source_branch),a.target_branch&&(r.AGENTRIX_BASE_REF=a.target_branch),a.title&&(r.AGENTRIX_MR_TITLE=a.title);const c=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/merge_requests/${t.iid}`:void 0}(s,a);return c&&(r.AGENTRIX_MR_URL=c),{operationPayload:Zi(s,i,r,n),action:o}}(e,t,n);case"pipeline":return function(e,t,n){const s=Wi(t),a=Xi(t);if(!s?.path_with_namespace||!a?.status||"failed"!==a.status||"trigger"===a.source)return null;const i=n.ref||a.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes object_attributes.ref or project.default_branch"};const o=Qi(e,"pipeline",a.status,s);o.AGENTRIX_PIPELINE_STATUS=a.status,o.AGENTRIX_REF=i,a.source&&(o.AGENTRIX_PIPELINE_SOURCE=a.source),a.id&&(o.AGENTRIX_PIPELINE_ID=String(a.id)),a.iid&&(o.AGENTRIX_PIPELINE_IID=String(a.iid)),a.sha&&(o.AGENTRIX_SHA=a.sha);const r=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.id?`${e.web_url}/-/pipelines/${t.id}`:void 0}(s,a);r&&(o.AGENTRIX_PIPELINE_URL=r);const c=function(e){const t=Li(e.merge_request);return Gi(t?.iid)}(t);return c&&(o.AGENTRIX_PR_NUMBER=String(c)),{operationPayload:Zi(s,i,o,n),action:a.status}}(e,t,n);default:return null}}function to(e){const t=Ji(e);if("note"===t){const t=Vi(e);return!0===t?.system?"system_note":Yi(t?.note)?"unsupported_note":"note_command_missing"}if("pipeline"===t){const t=Xi(e);return t?.status&&"failed"!==t.status?"pipeline_status_unsupported":"trigger"===t?.source?"pipeline_source_unsupported":"unsupported_pipeline"}return"issue"===t||"merge_request"===t?"missing_required_payload":"unsupported_event"}function no(e){return e.secret||e.token}function so(e,t){return fe("sha256",t).update(e).digest("base64url")}function ao(e,t){const[n,s,a]=t.split(".");if(!n||!s||void 0!==a)throw new Error("Invalid Agentrix event MCP token format");if(!function(e,t){const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&ve(n,s)}(s,so(n,no(e))))throw new Error("Invalid Agentrix event MCP token signature");let i;try{i=JSON.parse((o=n,Buffer.from(o,"base64url").toString("utf8")))}catch{throw new Error("Invalid Agentrix event MCP token payload")}var o;if(!(i.taskId&&i.userId&&i.machineId&&i.nonce))throw new Error("Incomplete Agentrix event MCP token payload");if(i.machineId!==e.machineId)throw new Error("Agentrix event MCP token machine mismatch");return i}const io="agentrix_event_broker",oo="/mcp/agentrix-event-broker",ro="change_title",co="publish_task_preview_url";function lo(e){return{changeTitle:(t,n)=>async function(e,t,n){const s=new on({serverUrl:xe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(e.token,e.machineId,t.taskId),options:{reconnection:!1,timeout:1e4},logger:(e,...t)=>{we.debug(`[EVENT MCP] ${e}`,...t)}});try{await async function(e){await new Promise((t,n)=>{const s=setTimeout(()=>{e.offLifecycle("connect"),e.offLifecycle("connect_error"),n(new Error("Agentrix event broker worker socket connection timeout"))},1e4);e.onLifecycle("connect",()=>{clearTimeout(s),e.offLifecycle("connect_error"),t()}),e.onLifecycle("connect_error",t=>{clearTimeout(s),e.offLifecycle("connect"),n(t instanceof Error?t:new Error(String(t)))}),e.connect()})}(s),s.send("change-task-title",{eventId:G(),taskId:t.taskId,title:n}),await s.flush(5e3)}finally{s.disconnect()}}(e,t,n),publishTaskPreviewUrl:(t,n)=>async function(e,t,n){const s=await fetch(`${xe.serverUrl}/v1/tasks/${encodeURIComponent(t.taskId)}/preview-url`,{method:"PUT",headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json","X-Agentrix-Task":t.taskId},body:JSON.stringify({previewUrl:n})});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`Failed to publish task preview URL (${s.status}): ${e||s.statusText}`)}}(e,t,n)}}async function po(e,t,n){const s=function(e){const t=e.headers.authorization;if(!t)throw new Error("Missing Agentrix event MCP bearer token");const n=/^Bearer\s+(.+)$/i.exec(t);if(!n?.[1])throw new Error("Invalid Agentrix event MCP authorization header");return n[1]}(e),a=function(e){const t=new wt({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(ro,{title:"Change session title",description:["Emit an Agentrix event that changes the current session title.","Use this early in a task when the conversation has no user-provided title."].join(" "),inputSchema:{title:tt.string().min(1).max(200).describe("New title for the current Agentrix task")}},async({title:t})=>{const n=await async function(e,t,n){const s=n.trim();if(!s)throw new Error("Title must not be empty");return await e.changeTitle(t,s),`Agentrix title change event emitted for task ${t.taskId}: ${s}`}(e.dispatcher,e.context,t);return{content:[{type:"text",text:n}]}}),!1!==e.context.taskPreviewEnabled&&t.registerTool(co,{title:"Publish task preview URL",description:["Record the frontend preview URL for the current Agentrix task.","Use this on a local machine when a browser-viewable frontend URL exists after starting or reusing the local environment.","The URL must be absolute http(s); localhost URLs are allowed."].join(" "),inputSchema:{previewUrl:tt.string().min(1).max(2048).describe("Absolute http(s) URL for the current task preview")}},async({previewUrl:t})=>{const n=await async function(e,t,n){const s=X.parse({previewUrl:n});return await e.publishTaskPreviewUrl(t,s.previewUrl),`Agentrix preview URL updated for task ${t.taskId}: ${s.previewUrl}`}(e.dispatcher,e.context,t);return{content:[{type:"text",text:n}]}}),t}({context:ao(n.credentials,s),dispatcher:n.dispatcher}),i=new bt({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){we.warn("[EVENT MCP] Failed to handle MCP request:",e),t.raw.headersSent||(t.raw.writeHead(500,{"Content-Type":"application/json"}),t.raw.end(JSON.stringify({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})))}finally{await i.close().catch(()=>{}),await a.close().catch(()=>{})}}function uo(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=T(e,a.name),i=d(s),o=$(t,s);n.push({name:a.name,path:o,size:i.size,modifiedAt:i.mtimeMs,isDirectory:a.isDirectory()}),a.isDirectory()&&n.push(...uo(s,t))}return n}function mo(){return T(xe.agentrixAgentsHomeDir,"companion","claude")}const ho=tt.object({id:tt.string(),type:tt.string(),name:tt.string(),baseUrl:tt.string(),apiUrl:tt.string(),oauthServerId:tt.string().nullable().optional(),ownerId:tt.string().nullable().optional(),authModeDefault:tt.string().optional(),executionMode:tt.string().optional(),syncMode:tt.string().optional(),networkMode:tt.string().optional(),githubAppName:tt.string().nullable().optional(),enabled:tt.boolean().optional(),createdAt:tt.string().optional(),updatedAt:tt.string().optional()}).passthrough();async function go(e,t,n){let s;try{return await Promise.race([e,new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)})])}finally{s&&clearTimeout(s)}}function fo(e){return Array.isArray(e)?e[0]:e}function vo(e){return e instanceof Error?e.message:"Unknown error"}async function yo(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:G(),method:t,path:n,body:s},o=await go(e.sendWithAck("machine-rpc-call",i),a,`Timed out waiting for machine RPC ${t} ${n}`);if(!o.success){const e=o.error?.message||`Machine RPC failed: ${t} ${n}`;throw new Error(e)}return o.data}function xo(e){const{getChildren:t,stopSession:n,startDevOpsInit:s,completeDevOpsInit:a,requestShutdown:i,registerSession:o,credentials:l,getSocketClient:m}=e;return new Promise(h=>{const g=xe.getDaemonControlHost(),f=xe.getDaemonWebhookHost(),v=et({logger:!1});v.removeContentTypeParser("application/json"),v.addContentTypeParser("application/json",{parseAs:"string"},(e,t,n)=>{const s="string"==typeof t?t:t.toString("utf8");if(0!==s.trim().length)try{n(null,JSON.parse(s))}catch(e){const t=e instanceof Error?e:new Error("Invalid JSON body");t.statusCode=400,n(t,void 0)}else n(null,{})}),v.setValidatorCompiler(st),v.setSerializerCompiler(at);const y=v.withTypeProvider();!function(e,t){const n={credentials:t.credentials,dispatcher:t.dispatcher??lo(t.credentials)};e.post(oo,async(e,t)=>{try{await po(e,t,n)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return we.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(oo,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(oo,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(v,{credentials:l});const x=e=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),e.header("Access-Control-Allow-Private-Network","true")};y.post("/session-started",{schema:{body:tt.object({sessionId:tt.string(),metadata:tt.any()}),response:{200:tt.object({status:tt.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return we.debug(`[CONTROL SERVER] Session started: ${t}`),o(t,n),{status:"ok"}}),y.post("/devops-init-complete",{schema:{body:tt.object({taskId:tt.string(),userId:tt.string(),action:tt.enum(["continue","stop"])}),response:{200:tt.object({status:tt.literal("ok")})}}},async e=>{const{taskId:t,userId:n,action:s}=e.body;return we.info(`[CONTROL SERVER] Agentrix DevOps init complete for task ${t}, action=${s}`),a?.({taskId:t,userId:n,action:s}),{status:"ok"}}),y.post("/devops-init-start",{schema:{body:tt.object({taskId:tt.string(),userId:tt.string()}),response:{200:tt.object({status:tt.literal("ok")})}}},async e=>{const{taskId:t,userId:n}=e.body;return we.info(`[CONTROL SERVER] Starting Agentrix DevOps init for existing task ${t}`),s?.({taskId:t,userId:n}),{status:"ok"}}),y.options("/ping",async(e,t)=>(x(t),t.send())),y.get("/ping",{schema:{response:{200:tt.object({status:tt.literal("ok"),machineId:tt.string(),timestamp:tt.string(),controlHost:tt.string(),webhookHost:tt.string()})}}},async(e,t)=>(x(t),{status:"ok",machineId:l.machineId,timestamp:(new Date).toISOString(),controlHost:g,webhookHost:f})),y.options("/openers",async(e,t)=>(x(t),t.send())),y.get("/openers",{schema:{response:{200:tt.object({openers:tt.array(tt.object({id:tt.string(),label:tt.string(),kind:tt.enum(["system","file-manager","terminal","editor","ide"]),method:tt.enum(["scheme","cli"]),urlTemplate:tt.string().optional(),supported:tt.boolean()}))})}}},async(e,t)=>(x(t),{openers:await us()})),y.options("/open",async(e,t)=>(x(t),t.send())),y.options("/pick-directory",async(e,t)=>(x(t),t.send())),y.post("/open",{schema:{body:tt.object({path:tt.string(),openerId:tt.string(),userId:tt.string().optional(),taskId:tt.string().optional()}),response:{200:tt.object({success:tt.boolean(),error:tt.string().optional()})}}},async(e,t)=>{x(t);const{path:n,openerId:s,userId:a,taskId:i}=e.body;return await async function({openerId:e,targetPath:t,userId:n,taskId:s}){const a=hs(ys()).find(t=>t.id===e);if(!a)return{success:!1,error:"Unknown openerId"};if("cli"!==a.method||!a.open)return{success:!1,error:"Opener is not executable by CLI"};if(!a.isSupported())return{success:!1,error:"Opener is not supported on this system"};let i;try{i=function(e,t,n){const s=I.resolve(e);if(!I.isAbsolute(s))throw new Error("Path must be absolute");if(!d(s).isDirectory())throw new Error("Path must be a directory");if(t&&n){const e=xe.getTaskCwd(t,n);if(e&&!function(e,t){const n=I.relative(t,e);return""===n||!n.startsWith("..")&&!I.isAbsolute(n)}(s,I.resolve(e)))throw new Error("Path is outside the task workspace")}return s}(t,n,s)}catch(e){return{success:!1,error:e instanceof Error?e.message:"Invalid path"}}try{return a.open(i),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Failed to open path";return we.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),y.post("/pick-directory",{schema:{body:tt.object({defaultPath:tt.string().optional()}),response:{200:tt.object({path:tt.string().nullable(),error:tt.string().optional()})}}},async(e,t)=>{x(t);try{return{path:ms(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),y.post("/companion/ensure",{schema:{body:tt.object({preferredLanguage:tt.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:tt.object({agentDir:tt.string()})}}},async e=>await ci({preferredLanguage:e.body?.preferredLanguage,credentials:l})),y.post("/companion/probe",{schema:{response:{200:tt.object({success:tt.boolean(),error:tt.string().optional()})}}},async()=>await fa()),y.get("/companion/workspace/status",{schema:{response:{200:tt.object({exists:tt.boolean()})}}},async()=>{const e=mo();return{exists:r(e)}}),y.get("/companion/workspace",{schema:{response:{200:tt.object({files:tt.array(tt.object({name:tt.string(),path:tt.string(),size:tt.number(),modifiedAt:tt.number(),isDirectory:tt.boolean()}))})}}},async()=>{const e=mo();return r(e)?{files:uo(e,e)}:{files:[]}}),y.get("/companion/file",{schema:{querystring:tt.object({path:tt.string()}),response:{200:tt.object({content:tt.string()}),404:tt.object({error:tt.string()})}}},async(e,t)=>{const n=mo(),s=M(T(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),y.put("/companion/file",{schema:{body:tt.object({path:tt.string(),content:tt.string()}),response:{200:tt.object({success:tt.boolean()}),400:tt.object({error:tt.string()})}}},async(e,t)=>{const n=mo(),s=M(T(n,e.body.path));return s.startsWith(n)?(p(_(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),y.get("/companion/config",{schema:{response:{200:tt.object({heartbeatIntervalMs:tt.number(),heartbeatEnabled:tt.boolean(),lastHeartbeatTimestamp:tt.string().nullable(),lastHeartbeatDate:tt.string().nullable(),lastMaintenanceHeartbeatTimestamp:tt.string().nullable(),heartbeatTriggerCount:tt.number(),lastInteractionTimestamp:tt.string().nullable()})}}},async()=>{const e=mo(),t=T(e,"state.json");let n=9e5,s=!1,a=null,i=null,o=null,l=0,p=null;if(r(t))try{const e=JSON.parse(c(t,"utf-8"));"number"==typeof e.heartbeatIntervalMs&&(n=e.heartbeatIntervalMs),"boolean"==typeof e.heartbeatEnabled&&(s=e.heartbeatEnabled),"string"==typeof e.lastHeartbeatTimestamp&&(a=e.lastHeartbeatTimestamp),"string"==typeof e.lastHeartbeatDate&&(i=e.lastHeartbeatDate),"string"==typeof e.lastMaintenanceHeartbeatTimestamp&&(o=e.lastMaintenanceHeartbeatTimestamp),"number"==typeof e.heartbeatTriggerCount&&(l=e.heartbeatTriggerCount),"string"==typeof e.lastInteractionTimestamp&&(p=e.lastInteractionTimestamp)}catch{}return{heartbeatIntervalMs:n,heartbeatEnabled:s,lastHeartbeatTimestamp:a,lastHeartbeatDate:i,lastMaintenanceHeartbeatTimestamp:o,heartbeatTriggerCount:l,lastInteractionTimestamp:p}}),y.put("/companion/config",{schema:{body:tt.object({heartbeatIntervalMs:tt.number().optional(),heartbeatEnabled:tt.boolean().optional()}),response:{200:tt.object({success:tt.boolean()})}}},async t=>{const n=mo(),s=T(n,"state.json");let a={};if(r(s))try{a=JSON.parse(c(s,"utf-8"))}catch{}const{heartbeatIntervalMs:i,heartbeatEnabled:o}=t.body;return void 0!==i&&(a.heartbeatIntervalMs=i),void 0!==o&&(a.heartbeatEnabled=o),p(_(s),{recursive:!0}),u(s,JSON.stringify(a,null,2),"utf-8"),e.companionScheduler?.reloadStateAndReschedule(),{success:!0}}),y.post("/agent/install",{schema:{body:tt.object({agentId:tt.string(),gitUrl:tt.string(),branch:tt.string().optional(),subDir:tt.string().optional()}),response:{200:tt.object({agentDir:tt.string()}),500:tt.object({error:tt.string()})}}},async(e,t)=>{try{return await Rs(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),y.post("/git-server/register",{schema:{body:tt.object({name:tt.string().min(1),baseUrl:tt.string().url(),apiUrl:tt.string().url()}),response:{200:tt.object({gitServer:tt.object({id:tt.string(),type:tt.string(),name:tt.string(),baseUrl:tt.string(),apiUrl:tt.string()}),machineId:tt.string()}),502:tt.object({error:tt.string()})}}},async(e,t)=>{try{const n=await yo(m?.(),"POST","/v1/git-servers/machine-register",{...e.body,machineId:l.machineId});return t.send(n)}catch(n){const s=vo(n);return we.warn(`[GIT SERVER] register failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),y.post("/git-server/complete",{schema:{body:tt.object({gitServerId:tt.string().min(1)}),response:{200:tt.object({success:tt.boolean(),machineId:tt.string()}),502:tt.object({error:tt.string()})}}},async(e,t)=>{try{const n=await yo(m?.(),"POST",`/v1/git-servers/${encodeURIComponent(e.body.gitServerId)}/machine-complete`,{machineId:l.machineId});return t.send(n)}catch(n){const s=vo(n);return we.warn(`[GIT SERVER] complete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),y.post("/git-server/list",{schema:{response:{200:tt.object({gitServers:tt.array(ho)}),502:tt.object({error:tt.string()})}}},async(e,t)=>{try{const e=await yo(m?.(),"POST","/v1/git-servers/machine-list",{machineId:l.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=vo(e);return we.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),y.post("/git-server/delete",{schema:{body:tt.object({gitServerId:tt.string().min(1)}),response:{200:tt.object({success:tt.boolean(),machineId:tt.string()}),502:tt.object({error:tt.string()})}}},async(e,t)=>{try{const n=await yo(m?.(),"POST",`/v1/git-servers/${encodeURIComponent(e.body.gitServerId)}/machine-unlink`,{machineId:l.machineId});return t.send({success:!0,machineId:l.machineId,...n&&"object"==typeof n?n:{}})}catch(n){const s=vo(n);return we.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),y.post("/webhooks/gitlab/:gitServerId",{schema:{params:tt.object({gitServerId:tt.string()}),body:tt.record(tt.string(),tt.unknown()),response:{200:tt.object({status:tt.enum(["triggered","ignored","failed"]),eventType:tt.string(),action:tt.string().optional(),pipeline:tt.unknown().optional(),reason:tt.string().optional(),errorMessage:tt.string().optional(),errorDetail:tt.string().optional(),upstreamStatus:tt.number().optional()}),400:tt.object({error:tt.string()}),401:tt.object({error:tt.string()}),403:tt.object({error:tt.string()}),404:tt.object({error:tt.string()}),502:tt.object({error:tt.string()}),500:tt.object({error:tt.string()})}}},async(e,t)=>{const n=ue(),s=Date.now(),a=function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body),i=function(e){const t=Ji(e);if("issue"===t){const t=zi(e);if(!t?.iid)return null}else if("merge_request"===t){const t=Ki(e);if(!t?.iid)return null}else if("note"===t){const t=Vi(e);if(!0===t?.system||!Yi(t?.note))return null;const n=Bi(t?.noteable_type),s="issue"===n?Li(e.issue):"merge_request"===n?Li(e.merge_request):null;if(!Gi(s?.iid))return null}else if("pipeline"===t){const t=Xi(e);if("failed"!==t?.status||"trigger"===t.source)return null}else if("issue"!==t&&"merge_request"!==t)return null;return function(e){const t=Wi(e);return t?.id?String(t.id):t?.path_with_namespace??null}(e)}(e.body),o=e.ip||"-",r="string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-",c=(a,i)=>{const o=Date.now()-s,r=function(e){if(!e||"object"!=typeof e)return"type="+typeof e;const t=e;if("string"==typeof t.error)return`error=${t.error}`;const n=String(t.status??"-"),s=String(t.eventType??"-"),a=String(t.action??"-"),i=String(t.reason??"-"),o=String(t.upstreamStatus??"-"),r=String(t.errorMessage??"-"),c=function(e){if(!e||"object"!=typeof e)return"-";const t=e,n=t.id??t.iid??"-",s=t.status??"-",a=t.ref??"-",i=t.web_url??t.webUrl??"-";return`id=${String(n)}, status=${String(s)}, ref=${String(a)}, webUrl=${String(i)}`}(t.pipeline);return`status=${n}, eventType=${s}, action=${a}, reason=${i}, upstreamStatus=${o}, errorMessage=${r}, pipeline=${c}`}(i);return we[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};we.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}, remote=${o}, userAgent=${r}`);const l=await Sn();if(!l)return c(500,{error:"Git server encryption key not available"});const p=An(e.params.gitServerId,l),d=p?.webhookSecret;if(!d)return c(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});if(!function(e,t){if("string"!=typeof e)return!1;const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&ve(n,s)}(e.headers["x-gitlab-token"],d))return c(401,{error:"Invalid GitLab webhook token"});const u=fo(e.headers["x-gitlab-event-uuid"])??fo(e.headers["x-gitlab-delivery"]),h=a;(async function(e,t,n,s,a){if(!a?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:G(),provider:"gitlab",gitServerId:e,deliveryId:n,eventType:s,payload:t},o=await go(a.sendWithAck("repository-inbox-webhook",i),5e3,"Timed out waiting for repository inbox webhook ack");if("success"!==o.status)throw new Error(o.message||"API failed to process repository inbox webhook")})(e.params.gitServerId,e.body,u,h,m?.()).catch(t=>{const s=t instanceof Error?t.message:String(t);we.warn(`[GITLAB WEBHOOK] inbox side-channel failed: hookId=${n}, gitServer=${e.params.gitServerId}, message=${s}`)});const g=_n(e.params.gitServerId,l);if(!g)return c(403,{error:`No PAT configured for git server ${e.params.gitServerId}`});try{const t=En(e.params.gitServerId),s=t?.apiUrl;if(!s)return c(400,{error:`GitLab API URL is not configured for git server ${e.params.gitServerId}`});let o;if(i)if(o=p.projectTriggerTokens?.[i],o)we.info(`[GITLAB WEBHOOK] pipeline trigger token reused: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`);else{const t=function(e){const t=Wi(e);return t?.path_with_namespace?t.id?{projectId:t.id}:{projectPath:t.path_with_namespace}:null}(e.body);if(!t)return c(400,{error:"GitLab webhook payload is missing project information"});we.info(`[GITLAB WEBHOOK] ensuring pipeline trigger token: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}, mode=create_or_reuse`);const a=new Mn(s,g,{gitServerId:e.params.gitServerId}),r=await a.executeOperation("ensurePipelineTriggerToken",t);if(!r||"object"!=typeof r||"string"!=typeof r.token)return c(502,{error:"Failed to create GitLab pipeline trigger token"});o=r.token,function(e,t,n){Tn.saveGitLabWebhookBridgeSecrets(e,t,n)}(e.params.gitServerId,{webhookSecret:d,projectTriggerTokens:{...p.projectTriggerTokens??{},[i]:o}},l),we.info(`[GITLAB WEBHOOK] pipeline trigger token stored: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`)}return we.info(`[GITLAB WEBHOOK] triggering pipeline: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}`),c(200,await async function({gitServerId:e,payload:t,config:n,pat:s}){const a=Ji(t),i=eo(e,t,n);if(!i)return{status:"ignored",eventType:a,reason:to(t)};if(!n.apiUrl)throw{status:400,message:"GitLab API URL is required"};const o=new Mn(n.apiUrl,s,{gitServerId:e});let r;try{r=await o.executeOperation("triggerPipeline",i.operationPayload)}catch(e){const t=function(e){const t=e;return{message:"string"==typeof t?.message?t.message:e instanceof Error?e.message:"Failed to trigger GitLab pipeline",detail:"string"==typeof t?.detail?t.detail:void 0,upstreamStatus:"number"==typeof t?.status?t.status:void 0}}(e);return{status:"failed",eventType:a,action:i.action,reason:"pipeline_trigger_failed",errorMessage:t.message,errorDetail:t.detail,upstreamStatus:t.upstreamStatus}}return{status:"triggered",eventType:a,action:i.action,pipeline:r}}({gitServerId:e.params.gitServerId,payload:e.body,pat:g,config:{apiUrl:s,triggerToken:o}}))}catch(t){const s=t,a="number"==typeof s.status&&s.status>=400&&s.status<600?s.status:500,i="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return we.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, message=${i}`),c(a,{error:i})}}),y.post("/schedule",{schema:{body:tt.object({task:tt.string(),type:tt.enum(["once","recurring"]),due:tt.string().optional(),cron:tt.string().optional(),timezone:tt.string().optional(),timeType:tt.enum(["utc","local"]).optional()}),response:{200:tt.object({id:tt.string(),task:tt.string(),type:tt.enum(["once","recurring"]),due:tt.string().optional(),cron:tt.string().optional(),timezone:tt.string().optional(),timeType:tt.enum(["utc","local"]).optional(),createdAt:tt.string()}),400:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(t,n)=>{const s=e.companionScheduler;if(!s)return n.code(503).send({error:"Companion scheduler not available"});const{task:a,type:i,due:o,cron:r,timezone:c,timeType:l}=t.body;return"once"!==i||o?"recurring"!==i||r?s.addScheduledTask({task:a,type:i,due:o,cron:r,timezone:c,timeType:l}):n.code(400).send({error:'"cron" is required for recurring tasks'}):n.code(400).send({error:'"due" is required for one-time tasks'})}),y.get("/schedule",{schema:{response:{200:tt.object({tasks:tt.array(tt.object({id:tt.string(),task:tt.string(),type:tt.enum(["once","recurring"]),due:tt.string().optional(),cron:tt.string().optional(),timezone:tt.string().optional(),timeType:tt.enum(["utc","local"]).optional(),createdAt:tt.string()}))}),503:tt.object({error:tt.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),y.delete("/schedule/:id",{schema:{params:tt.object({id:tt.string()}),response:{200:tt.object({success:tt.boolean()}),404:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?s.deleteScheduledTask(t.params.id)?{success:!0}:n.code(404).send({error:`Task ${t.params.id} not found`}):n.code(503).send({error:"Companion scheduler not available"})});const w=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);y.options("/channels",async(e,t)=>(x(t),t.send())),y.options("/channels/platforms",async(e,t)=>(x(t),t.send())),y.options("/channels/wechat/login/qrcode",async(e,t)=>(x(t),t.send())),y.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(x(t),t.send())),y.options("/channels/:id",async(e,t)=>(x(t),t.send())),y.options("/channels/:id/connect",async(e,t)=>(x(t),t.send())),y.options("/channels/:id/disconnect",async(e,t)=>(x(t),t.send())),y.options("/channels/:id/contacts",async(e,t)=>(x(t),t.send())),y.options("/channels/:id/bindings",async(e,t)=>(x(t),t.send())),y.options("/channels/:id/bindings/:bindingId",async(e,t)=>(x(t),t.send())),y.options("/channels/task-message",async(e,t)=>(x(t),t.send())),y.options("/channels/group-history",async(e,t)=>(x(t),t.send())),y.get("/channels",{schema:{response:{200:tt.object({channels:tt.array(Ri)}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)return{channels:n.getChannels()}}),y.get("/channels/platforms",{schema:{response:{200:tt.object({platforms:tt.array(tt.enum(Ci))})}}},async(e,t)=>(x(t),{platforms:[...Ci]})),y.get("/channels/wechat/login/qrcode",{schema:{response:{200:tt.object({qrcode:tt.string(),qrcodeContent:tt.string(),qrcodeTerminal:tt.string(),baseUrl:tt.string()}),502:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);try{return await Ai.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return we.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),y.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:tt.object({qrcode:tt.string()}),response:{200:tt.object({status:tt.string(),token:tt.string().optional(),baseUrl:tt.string().optional(),ilinkBotId:tt.string().optional(),ilinkUserId:tt.string().optional()}),502:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);try{return await Ai.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return we.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),y.post("/channels",{schema:{body:Ni,response:{200:Ri,503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)return n.addChannel(e.body)}),y.delete("/channels/:id",{schema:{params:tt.object({id:tt.string()}),response:{200:tt.object({success:tt.boolean()}),404:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),y.post("/channels/:id/connect",{schema:{params:tt.object({id:tt.string()}),response:{200:Ri,404:tt.object({error:tt.string()}),500:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return await n.connectChannel(e.params.id)}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),y.post("/channels/:id/disconnect",{schema:{params:tt.object({id:tt.string()}),response:{200:Ri,404:tt.object({error:tt.string()}),500:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return await n.disconnectChannel(e.params.id,{disable:!0})}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),y.get("/channels/:id/contacts",{schema:{params:tt.object({id:tt.string()}),response:{200:tt.object({contacts:tt.array(Oi)}),404:tt.object({error:tt.string()}),500:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return{contacts:await n.getContacts(e.params.id)}}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("not found")?404:500;return t.code(s).send({error:n})}}),y.get("/channels/:id/bindings",{schema:{params:tt.object({id:tt.string()}),response:{200:tt.object({bindings:tt.array(Di)}),404:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return{bindings:n.getBindings(e.params.id)}}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(404).send({error:n})}}),y.post("/channels/task-message",{schema:{body:tt.object({taskId:tt.string(),content:tt.string().optional(),attachments:tt.array(tt.object({filePath:tt.string(),fileName:tt.string().optional(),mimeType:tt.string().optional(),kind:tt.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:tt.object({channelId:tt.string(),chatId:tt.string()}).optional()}),response:{200:tt.object({success:tt.boolean()}),404:tt.object({error:tt.string()}),503:tt.object({error:tt.string()}),500:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{const s={content:e.body.content,attachments:e.body.attachments};return e.body.target?(await n.sendMessageToChannel(e.body.target,s),{success:!0}):await n.sendMessageToTaskChannel(e.body.taskId,s)?{success:!0}:t.code(404).send({error:`No channel binding for task ${e.body.taskId}`})}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),y.post("/channels/group-history",{schema:{body:tt.object({taskId:tt.string(),limit:tt.number().int().positive().max(100).optional(),beforeSeq:tt.number().int().positive().optional(),afterSeq:tt.number().int().nonnegative().optional(),target:tt.object({channelId:tt.string(),chatId:tt.string(),platform:tt.string().optional(),chatType:tt.string().optional(),chatName:tt.string().optional()})}),response:{200:tt.object({historyXml:tt.string(),hasMoreBefore:tt.boolean(),hasMoreAfter:tt.boolean()}),400:tt.object({error:tt.string()}),503:tt.object({error:tt.string()}),500:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return void 0!==e.body.beforeSeq&&void 0!==e.body.afterSeq?t.code(400).send({error:"Use beforeSeq or afterSeq, not both"}):n.getChannelGroupHistory(e.body.target,{limit:e.body.limit,beforeSeq:e.body.beforeSeq,afterSeq:e.body.afterSeq})}catch(e){const n=e instanceof Error?e.message:String(e),s=n.includes("only available")?400:500;return t.code(s).send({error:n})}}),y.delete("/channels/:id/bindings/:bindingId",{schema:{params:tt.object({id:tt.string(),bindingId:tt.string()}),response:{200:tt.object({success:tt.boolean()}),404:tt.object({error:tt.string()}),503:tt.object({error:tt.string()})}}},async(e,t)=>{x(t);const n=w(t);if(n)try{return n.removeBinding(e.params.id,e.params.bindingId)?{success:!0}:t.code(404).send({error:`Binding ${e.params.bindingId} not found`})}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(404).send({error:n})}}),y.post("/list",{schema:{response:{200:tt.object({children:tt.array(tt.object({startedBy:tt.string(),taskId:tt.string(),pid:tt.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),y.post("/stop-session",{schema:{body:tt.object({sessionId:tt.string()}),response:{200:tt.object({success:tt.boolean()})}}},async e=>{const{sessionId:t}=e.body;return we.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),y.post("/stop",{schema:{response:{200:tt.object({status:tt.string()})}}},async()=>(we.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{we.debug("[CONTROL SERVER] Triggering daemon shutdown"),i()},50),{status:"stopping"})),"127.0.0.1"!==g&&we.warn(`[CONTROL SERVER] Listening on ${g}; ensure daemon control endpoints are protected by network policy`);const b=e=>new Promise((t,n)=>{v.listen({port:e,host:g},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{e=await b(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw we.info("[CONTROL SERVER] Failed to start:",t),t;we.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await b(0)}const t=parseInt(e.split(":").pop());we.info(`[CONTROL SERVER] Started on port ${t}`),h({port:t,host:g,webhookHost:f,stop:async()=>{await v.close(),we.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw we.info("[CONTROL SERVER] Failed to start:",e),e})})}function wo(e,t={}){const n=be(),s=T(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw we.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return Xe(process.execPath,a,t)}const bo=[{version:1,fileName:"001_init.sql"}];function ko(e){var t;return function(e,t){const n=new It(e),s=new kt;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=De(Tt(import.meta.url)),t=[Ne(e,"migrations"),Ne(process.cwd(),"dist","migrations"),Ne(process.cwd(),"src","worker","history","migrations")];for(const e of t)if($e(e))return e;throw new Error(`Task history migrations directory not found at ${t[0]}`)}(),n=e.pragma("user_version",{simple:!0}),s=function(e,t){const n=Ne(e,t);return _e(n,"utf8")}(t,bo[0].fileName);e.exec(s),n<bo[0].version&&e.pragma(`user_version = ${bo[0].version}`)}(n);const a=n.prepare("\n INSERT OR IGNORE INTO task_message (\n event_id,\n task_id,\n sender_type,\n sender_id,\n sender_name,\n message,\n created_at\n ) VALUES (\n @eventId,\n @taskId,\n @senderType,\n @senderId,\n @senderName,\n @message,\n @createdAt\n );\n "),i=n.prepare("SELECT local_sequence FROM task_message WHERE event_id = ?"),o=n.prepare("\n INSERT OR IGNORE INTO task_event (\n event_id,\n task_id,\n chat_id,\n sequence,\n event_type,\n event_data,\n created_at\n ) VALUES (\n @eventId,\n @taskId,\n @chatId,\n @sequence,\n @eventType,\n @eventData,\n @createdAt\n );\n "),r=n.prepare("\n UPDATE task_event\n SET sequence = ?\n WHERE event_id = ? AND (sequence IS NULL OR sequence < ?)\n "),c=n.prepare("\n SELECT * FROM task_event\n WHERE sequence > ? AND event_type = 'task-message'\n ORDER BY sequence ASC\n LIMIT ?\n "),l=n.prepare("\n SELECT 1 as has_row\n FROM task_event\n WHERE sequence > ? AND event_type = 'task-message'\n LIMIT 1\n "),p=n.prepare("\n SELECT * FROM task_message\n ORDER BY local_sequence DESC\n LIMIT ?\n "),d=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence ASC\n LIMIT ?\n "),u=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence < ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),m=n.prepare("\n SELECT 1 as has_row\n FROM task_message\n WHERE local_sequence < ?\n LIMIT 1\n "),h=n.prepare("\n SELECT 1 as has_row\n FROM task_message\n WHERE local_sequence > ?\n LIMIT 1\n "),g=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),f=n.prepare("\n SELECT agent_id, session_id, last_sequence\n FROM task_agent_session\n "),v=n.prepare("\n INSERT INTO task_agent_session (agent_id, task_id, session_id, last_sequence, updated_at)\n VALUES (?, ?, ?, NULL, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n session_id = excluded.session_id,\n updated_at = excluded.updated_at\n "),y=n.prepare("\n INSERT INTO task_agent_session (agent_id, task_id, session_id, last_sequence, updated_at)\n VALUES (?, ?, '__pending__', ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n last_sequence = CASE\n WHEN task_agent_session.last_sequence IS NULL OR task_agent_session.last_sequence < excluded.last_sequence\n THEN excluded.last_sequence\n ELSE task_agent_session.last_sequence\n END,\n updated_at = excluded.updated_at\n ");return{saveMessage:e=>{const n=e.eventId??G(),o=(new Date).toISOString(),r=a.run({eventId:n,taskId:t,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,message:JSON.stringify(e.message),createdAt:o}).changes>0,c=i.get(n),l=c?.local_sequence??null;return r&&null!==l&&s.emit("message-saved",{eventId:n}),{eventId:n,localSequence:l,inserted:r}},saveTaskEvent:e=>{const t=e.eventId??G(),n=(new Date).toISOString(),s={...e.eventData,eventId:t};return o.run({eventId:t,taskId:e.taskId,chatId:e.chatId,sequence:e.sequence,eventType:e.eventType,eventData:JSON.stringify(s),createdAt:n}),t},updateTaskEventSequence:(e,t)=>{r.run(t,e,t)},pageTaskEventsAfter:(e,t)=>{const n=c.all(e,t).map(To),s=n.at(-1)?.sequence??null;return{data:n,hasMore:null!==s&&Boolean(l.get(s))}},getLatestTaskEvent:e=>{if(0===e.length)return null;const t=e.map(()=>"?").join(","),s=n.prepare(`\n SELECT * FROM task_event\n WHERE event_type IN (${t})\n ORDER BY created_at DESC, rowid DESC\n LIMIT 1\n `).get(...e);return s?To(s):null},pageRecentMessages:e=>{const t=p.all(e).map(Io).reverse(),n=t[0]?.localSequence??null;return{data:t,hasMore:!!n&&Boolean(m.get(n))}},pageMessagesAfter:(e,t)=>{const n=d.all(e,t).map(Io),s=n.at(-1)?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},pageMessagesBefore:(e,t)=>{const n=u.all(e,t).map(Io).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(m.get(s))}},pageRecentMessagesAfter:(e,t)=>{const n=g.all(e,t).map(Io).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(m.get(s))}},getAgentSessions:()=>{const e=f.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.session_id);return t},getAgentLastSequences:()=>{const e=f.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.last_sequence);return t},upsertAgentSession:(e,n)=>{v.run(e,t,n,(new Date).toISOString())},updateAgentLastSequence:(e,n)=>{y.run(e,t,n,(new Date).toISOString())},on:(e,t)=>{s.on(e,t)},off:(e,t)=>{s.off(e,t)},close:()=>{s.removeAllListeners(),n.close()}}}((t=e.dataDir,Ne(t,"data.bin")),e.taskId)}function Io(e){const t=JSON.parse(e.message);return{localSequence:e.local_sequence,eventId:e.event_id,senderType:e.sender_type,senderId:e.sender_id,senderName:e.sender_name,message:t,createdAt:e.created_at}}function To(e){const t=JSON.parse(e.event_data);return{eventId:e.event_id,taskId:e.task_id,chatId:e.chat_id,sequence:e.sequence??null,eventType:e.event_type,eventData:t,createdAt:e.created_at}}const So={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".svg":"image/svg+xml",".ico":"image/x-icon",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".md":"text/markdown",".csv":"text/csv",".json":"application/json",".xml":"application/xml",".html":"text/html",".css":"text/css",".js":"application/javascript",".ts":"application/typescript",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".rar":"application/vnd.rar",".mp3":"audio/mpeg",".mp4":"video/mp4",".wav":"audio/wav",".avi":"video/x-msvideo"},Eo={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/bmp":".bmp","image/svg+xml":".svg","image/x-icon":".ico","application/pdf":".pdf","text/plain":".txt","text/html":".html","text/csv":".csv","application/json":".json","video/mp4":".mp4","audio/mpeg":".mp3"};async function Ao(e,t,n=!1){try{const s=await fetch(e);if(!s.ok)throw new Error(`Failed to download file: ${s.status} ${s.statusText}`);if(!s.body)throw new Error("Response body is null");const a=function(e){try{const t=new URL(e),n=E(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=E(s);if(e)return e}return""}catch{return""}}(e),i=s.headers.get("content-type"),o=i?.split(";")[0].trim()||function(e){const t=e.toLowerCase();return So[t]||"application/octet-stream"}(a),r=a||function(e){return Eo[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=S(t);c=n&&E(n)?n:`${ue()}${r||".dat"}`}catch{c=`${ue()}${r||".dat"}`}else c=`${ue()}${r||".dat"}`;const p=T(t,c),d=s.body,u=l(p);return await qe(d,u),{filePath:p,mimeType:o,filename:c}}catch(t){throw new Error(`Failed to download file from ${e}: ${t instanceof Error?t.message:String(t)}`)}}async function Co(e,t){const{attachmentsDir:n,log:s}=t;if(!Array.isArray(e.message.content))return e;const a=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","IMAGE",`Downloading image to local attachment: ${s}`);const{filePath:a,mimeType:i}=await Ao(s,t,!0);return n?.("info","IMAGE",`Image saved to: ${a}`),{type:"text",text:`Image file: ${a}\nType: ${i}`}}catch(t){return n?.("error","IMAGE",`Error downloading image to file: ${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n,s):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","DOCUMENT",`Downloading document from: ${s}`);const{filePath:a,mimeType:i,filename:o}=await Ao(s,t,!0);return n?.("info","DOCUMENT",`Document downloaded to: ${a}`),{type:"text",text:`Document: ${a}\nTitle: ${e.title||o}\nType: ${i}`}}catch(t){return n?.("error","DOCUMENT",`Error processing document: ${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n,s):e));return{...e,message:{...e.message,content:a}}}const _o="Agentrix-DevOps",$o="main";function Po(e){return(e.supportedFeatures??[]).includes(J)}function Mo(e){return"zh-Hans"===e.preferredLanguage||`${process.env.AGENTRIX_LANG??""} ${process.env.LANG??""}`.toLowerCase().includes("zh")?"zh-Hans":"en"}function Ro(e){return"zh-Hans"===e?{header:"初始化",question:"检测到当前项目尚未完成 Agentrix DevOps 初始化,或缺少本地初始化状态。是否先运行 Agentrix DevOps init,以便后续开发任务可以读取项目环境、启动方式和本地状态?",multiSelect:!1,options:[{label:"先初始化",description:"先运行 Agentrix DevOps init,再继续开发需求"},{label:"跳过,直接继续",description:"不运行初始化,直接开始当前开发任务"}]}:{header:"Init",question:"This project is missing Agentrix DevOps initialization or local init state. Run Agentrix DevOps init first so the development task can read project environment, startup, and local state guidance?",multiSelect:!1,options:[{label:"Initialize first",description:"Run Agentrix DevOps init before the development request"},{label:"Skip and continue",description:"Start the current development task without initialization"}]}}function No(e){return"zh-Hans"===e?{header:"下一步",question:"初始化已经完成,是否继续实现您的需求?如果需要修改,请告诉我。",multiSelect:!1,options:[{label:"继续实现需求",description:"启动新的开发 session 并继续原需求"},{label:"停止任务",description:"停留在当前初始化结果,不启动开发 session"},{label:"输入修改建议",description:"把你的修改建议发送给 Agentrix DevOps init session",additionalInput:{enabled:!0,required:!0,placeholder:"请输入需要 Agentrix DevOps 调整的内容"}}]}:{header:"Next",question:"Initialization is complete. Continue implementing your request, stop, or provide modification suggestions?",multiSelect:!1,options:[{label:"Continue request",description:"Start a fresh development session and continue the original request"},{label:"Stop task",description:"Stay in the initialization result without starting implementation"},{label:"Provide changes",description:"Send modification suggestions to the Agentrix DevOps init session",additionalInput:{enabled:!0,required:!0,placeholder:"Describe what Agentrix DevOps should adjust"}}]}}function Do(e,t){return T(xe.resolveDataDir(e,t),"devops-init")}function Oo(e,t){return T(Do(e,t),"original-input.json")}function Uo(e,t){return T(Do(e,t),"handoff.json")}function jo(e){const t=Do(e.userId,e.taskId);p(t,{recursive:!0}),u(Oo(e.userId,e.taskId),JSON.stringify(e,null,2))}function qo(e,t){const n=Oo(e,t);return r(n)?JSON.parse(c(n,"utf-8")):null}function Lo(e,t){const n=Uo(e,t);if(!r(n))return null;const s=JSON.parse(c(n,"utf-8"));return f(n),s}class Ho{pidToTrackedSession;taskToStartPromise;sandboxPool;channelManager=null;socketClientProvider=null;constructor(e){this.pidToTrackedSession=new Map,this.taskToStartPromise=new Map,this.sandboxPool=e||null}setChannelManager(e){this.channelManager=e}setSocketClientProvider(e){this.socketClientProvider=e}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}getAliveSessionByTaskId(e){for(const[t,n]of this.pidToTrackedSession.entries())if(n.taskId===e){if(this.isProcessAlive(t))return n;this.pidToTrackedSession.delete(t)}}getCurrentSessions(){return Array.from(this.pidToTrackedSession.values())}getSessionByPid(e){return this.pidToTrackedSession.get(e)}registerTaskWorker(e,t){const n=t.pid;if(!n)return void we.warn(`[SESSION] Missing PID for task ${e}`);we.info(`[SESSION] Registered task ${e}, PID: ${n}`);const s=this.pidToTrackedSession.get(n);if(!(s&&s.taskId===e||s)){const t={startedBy:"cli",taskId:e,pid:n};this.pidToTrackedSession.set(n,t)}}async decryptTaskMessage(e){if(!e.dataEncryptionKey)return;const t=await xe.getSecretKey();if(!t)return;const n=H(L(e.dataEncryptionKey),t);if(!n)return void we.warn("[SESSION] Failed to decrypt data encryption key");if(e.dataEncryptionKey=O(n),"task-message"!==e.event)return;const s=e.eventData;if(!s.encryptedMessage)return;const a=Y(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:we.warn("[SESSION] Failed to decrypt task message")}async persistCreateTaskStart(e){const t=xe.resolveDataDir(e.userId,e.taskId),n=xe.resolveAttachmentsDir(e.userId,e.taskId),s=ko({dataDir:t,taskId:e.taskId});try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:t.sequence??0});let a=null;if(t.message){let e=t.message;Q(e)&&(e=await Co(e,{attachmentsDir:n,log:(e,t,n)=>we["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),a=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return a}finally{s.close()}}async persistResumeTaskStart(e){const t=xe.resolveDataDir(e.userId,e.taskId),n=xe.resolveAttachmentsDir(e.userId,e.taskId),s=ko({dataDir:t,taskId:e.taskId}),a=e.eventData.sequence;if(null==a)throw new Error(`Missing resume sequence for task ${e.taskId}`);try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:a});let i=null;if(t.message){let e=t.message;Q(e)&&(e=await Co(e,{attachmentsDir:n,log:(e,t,n)=>we["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),i=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return i}finally{s.close()}}async processTaskMessageAttachments(e){if("task-message"!==e.event)return;const t=e.eventData;if(!t.message||!Q(t.message))return;const n=xe.resolveAttachmentsDir(e.userId,e.taskId),s=await Co(t.message,{attachmentsDir:n,log:(e,t,n)=>we["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)});e.eventData={...t,message:s}}trackWorkerProcess(e,t){const n={startedBy:"daemon",pid:t.pid,childProcess:t,taskId:e.taskId};this.pidToTrackedSession.set(t.pid,n),t.on("exit",(n,s)=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId),this.maybeContinueAfterDevOpsInit(e).catch(t=>{we.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after DevOps worker exit:`,t)})}),t.on("error",n=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId)})}async maybeContinueAfterDevOpsInit(e){const t=Lo(e.userId,e.taskId);t&&(we.info(`[DEVOPS_INIT] Consumed handoff for task ${e.taskId}, action=${t.action}`),"continue"===t.action&&await this.startOriginalWorkerAfterDevOpsInit(e.userId,e.taskId))}async startOriginalWorkerAfterDevOpsInit(e,t){const n=qo(e,t);if(!n)return void we.warn(`[DEVOPS_INIT] Missing original task input for ${t}; cannot continue original worker`);if(we.info(`[DEVOPS_INIT] Starting original worker for task ${t} after Agentrix DevOps init`),this.syncOriginalWorkerAgentSession(n),"agentSessionId"in n)return void this.restoreOriginalWorkerAfterSlashDevOpsInit(n);let s=null;s=await this.persistCreateTaskStart(n),this.positionOriginalWorkerHistoryCursor(n,s),xe.writeTaskInput(n);const a={eventId:G(),status:"success",opCode:n.eventId};await this.startWorkerInternal(n,"create-task",a)}restoreOriginalWorkerAfterSlashDevOpsInit(e){const t=ko({dataDir:xe.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const n=t.pageRecentMessages(1).data[0]?.localSequence??0;t.updateAgentLastSequence(e.agentId,n),we.info(`[DEVOPS_INIT] Restored original worker ${e.agentId} for task ${e.taskId} at sequence ${n}; waiting for the next user message`)}finally{t.close()}xe.writeTaskInput(e)}positionOriginalWorkerHistoryCursor(e,t){if(null===t)return void we.warn(`[DEVOPS_INIT] Original worker message for task ${e.taskId} has no local sequence; cannot isolate DevOps init history`);const n=ko({dataDir:xe.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const s=function(e){return null===e?null:Math.max(0,e-1)}(t);if(null===s)return;n.updateAgentLastSequence(e.agentId,s),we.info(`[DEVOPS_INIT] Positioned original worker ${e.agentId} at sequence ${s} for task ${e.taskId}`)}finally{n.close()}}syncOriginalWorkerAgentSession(e){const t=this.socketClientProvider?.();if(t){if("agentSessionId"in e&&e.agentSessionId)return t.send("update-task-agent-session-id",{eventId:G(),taskId:e.taskId,agentSessionId:e.agentSessionId,cwd:e.cwd??e.userCwd}),void we.info(`[DEVOPS_INIT] Restored original agent session for task ${e.taskId}`);t.send("reset-task-session",{eventId:G(),taskId:e.taskId}),we.info(`[DEVOPS_INIT] Cleared DevOps init agent session for task ${e.taskId}`)}else we.warn(`[DEVOPS_INIT] No daemon socket client available to sync task session for ${e.taskId}`)}completeDevOpsInit(e){we.info(`[DEVOPS_INIT] Completion received for task ${e.taskId}, action=${e.action}`),function(e,t,n){const s=Do(e,t);p(s,{recursive:!0}),u(Uo(e,t),JSON.stringify({action:n,createdAt:(new Date).toISOString()},null,2))}(e.userId,e.taskId,e.action);const t=this.getAliveSessionByTaskId(e.taskId)?.pid;setTimeout(()=>{const n=this.getAliveSessionByTaskId(e.taskId);n&&n.pid===t&&this.stopSession(e.taskId),"continue"===e.action&&this.continueDevOpsInitWhenStopped(e.userId,e.taskId,t).catch(t=>{we.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after completion signal:`,t)})},100)}startDevOpsInit(e){this.startDevOpsInitAsync(e).catch(t=>{we.error(`[DEVOPS_INIT] Failed to start slash-command DevOps init for task ${e.taskId}:`,t)})}async startDevOpsInitAsync(e){const t=xe.readTaskInput(e.userId,e.taskId);jo(t);const n=await this.buildDevOpsWorkerInput(t,!0);xe.writeTaskInput(n),await this.persistCreateTaskStart(n),this.stopSession(e.taskId),this.startWorkerWhenPreviousStops(n,"create-task")}async startWorkerWhenPreviousStops(e,t){for(let n=0;n<20;n+=1){if(await new Promise(e=>setTimeout(e,250)),this.getAliveSessionByTaskId(e.taskId))continue;const n={eventId:G(),status:"success",opCode:e.eventId};return void await this.startWorkerInternal(e,t,n)}we.warn(`[DEVOPS_INIT] Timed out waiting to start switched worker for task ${e.taskId}`)}async continueDevOpsInitWhenStopped(e,t,n){for(let s=0;s<20;s+=1){await new Promise(e=>setTimeout(e,250));const s=this.getAliveSessionByTaskId(t);if(s&&s.pid!==n)return void we.info(`[DEVOPS_INIT] Original worker for task ${t} is already running with PID ${s.pid}`);if(s)continue;const a=Lo(e,t);if(!a)return void we.info(`[DEVOPS_INIT] Handoff for task ${t} was already consumed`);if(we.info(`[DEVOPS_INIT] Consumed handoff for task ${t} from completion path, action=${a.action}`),"continue"!==a.action)return;return void await this.startOriginalWorkerAfterDevOpsInit(e,t)}we.warn(`[DEVOPS_INIT] Timed out waiting to continue original worker for task ${t}`)}shouldLookupChannelReplyTarget(e){const t="task-message"===e.event?e.eventData:null;return"channel"===t?.senderType||"companion"===e.agentType&&"work"===e.taskType&&!e.parentTaskId}resolveChannelReplyTarget(e){return e.channelReplyTarget?e.channelReplyTarget:this.shouldLookupChannelReplyTarget(e)?this.channelManager?.getReplyTargetForTask(e.taskId)??null:null}buildWorkerEnv(e){return{...process.env,...e?{AGENTRIX_CHANNEL_REPLY_TARGET:JSON.stringify(e)}:{}}}async startWorker(e,t){const n={eventId:G(),status:"success",opCode:e.eventId};await this.decryptTaskMessage(e),await this.processTaskMessageAttachments(e),"create-task"===t?e=await this.resolveDevOpsInitCreateInput(e):"resume-task"===t&&(e=this.stripStaleDevOpsAgentSession(e)),xe.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const s=this.taskToStartPromise.get(e.taskId);if(s)return we.info(`[SESSION] Task ${e.taskId} is already starting, skip duplicate ${t}`),s;const a=this.startWorkerInternal(e,t,n).finally(()=>{this.taskToStartPromise.get(e.taskId)===a&&this.taskToStartPromise.delete(e.taskId)});return this.taskToStartPromise.set(e.taskId,a),a}stripStaleDevOpsAgentSession(e){if(e.agentId===_o||!Po(e))return e;const t=qo(e.userId,e.taskId);if(!t||"agentSessionId"in t)return e;we.warn(`[DEVOPS_INIT] Clearing stale DevOps init agentSessionId for resumed original worker on task ${e.taskId}`);const{agentSessionId:n,...s}=e;return this.syncOriginalWorkerAgentSession(s),s}async resolveDevOpsInitCreateInput(e){if(!Po(e)||e.agentId===_o)return e;if(this.isLocalDirectoryDevOpsTarget(e)){if(!function(e,t={}){const n=t.checkLocalState??!0,s=T(e,".agentrix"),a=T(s,"env"),i=T(a,"init"),o=T(i,"state","local"),c=!r(s),l=!r(T(a,"README.md")),p=!r(T(i,"README.md")),d=!(!n||r(o)&&0!==function(e){try{return g(e)}catch{return[]}}(o).length);return{needsInit:c||l||p||d,missingAgentrixDir:c,missingEnvReadme:l,missingEnvModeDocs:p,missingLocalInitState:d}}(xe.resolveProjectCWD(e.userCwd,e.userId,e.taskId),{checkLocalState:!0}).needsInit)return we.info(`[DEVOPS_INIT] Local project init state complete for task ${e.taskId}; starting original worker`),e}else{if(!this.isCodeRepositoryDevOpsTarget(e))return we.info(`[DEVOPS_INIT] No project directory or code repository selected for task ${e.taskId}; skipping Agentrix DevOps init`),e;we.info(`[DEVOPS_INIT] Code repository target selected for task ${e.taskId}; starting Agentrix-DevOps without local init-state precheck`)}jo(e);const t=await this.buildDevOpsWorkerInput(e,!1);return we.info(`[DEVOPS_INIT] Starting Agentrix-DevOps worker before original ${e.agentType}/${e.agentId} worker for task ${e.taskId}`),t}isLocalDirectoryDevOpsTarget(e){return"directory"===e.repositorySourceType&&Boolean(e.userCwd)}isCodeRepositoryDevOpsTarget(e){return"git-server"===e.repositorySourceType&&Boolean(e.repositoryId||e.gitUrl)}async buildDevOpsWorkerInput(e,t){const{agentDir:n}=await async function(){const e=T(xe.agentrixAgentsHomeDir,_o),t=T(xe.agentrixHomeDir,"tmp","agentrix-agent-devops-init"),n=`${e}.tmp-${Date.now()}`,s=`${e}.backup-${Date.now()}`;p(T(xe.agentrixHomeDir,"tmp"),{recursive:!0}),r(T(t,".git"))?(lt("git",["fetch","--depth=1","origin",`${$o}:refs/remotes/origin/${$o}`],{cwd:t,stdio:"pipe"}),lt("git",["checkout",$o],{cwd:t,stdio:"pipe"}),lt("git",["reset","--hard",`origin/${$o}`],{cwd:t,stdio:"pipe"})):(h(t,{recursive:!0,force:!0}),lt("git",["clone","--depth=1","--branch",$o,"https://github.com/xmz-ai/agentrix-agent.git",t],{stdio:"pipe"}));const a=T(t,"agentrix-dev-init");if(!r(T(a,"agent.json")))throw new Error(`Agentrix DevOps agent definition not found at ${a}`);h(n,{recursive:!0,force:!0}),v(a,n,{recursive:!0}),Ns(n);try{r(e)&&m(e,s),m(n,e),h(s,{recursive:!0,force:!0})}catch(t){throw h(e,{recursive:!0,force:!0}),r(s)&&m(s,e),h(n,{recursive:!0,force:!0}),t}return{agentDir:e}}(),s=["Run Agentrix DevOps initialization for the current project.","You are running as the Agentrix-DevOps agent in a platform-managed pre-initialization worker before the user development request starts.",`User preferred language / ask-user language: ${"zh-Hans"===Mo(e)?"Chinese (Simplified, zh-Hans)":"English (en)"}. When you need to ask the user questions or produce user-visible completion/status text, use this language preference.`,"The Agentrix platform has already asked the user whether to run this initialization before this prompt was delivered to you.","Check whether `.agentrix` and `.agentrix/env` are already initialized; if initialization already exists, do not overwrite it, only fill missing or stale environment guidance and local initialization state.","Focus on the local development/validation mode, commands, environment variables, authentication state, and safety constraints needed by future development tasks.","Ask the user with the normal Agentrix `ask_user` tool whenever user-answerable information is required.","Maintain project iteration memory and automated testing guidance so future Agentrix development workers can continue with concrete commands and known local constraints.","This is a pre-development initialization flow. Do not assume the platform treats a normal response or turn result as completion.","A normal assistant response, result message, or end of turn is not completion.","When, and only when, you have confirmed initialization is complete, call the `complete_devops_init` Agentrix tool. The platform will ask the user what to do next only after that tool is called.","If the user chooses to stop after initialization, remain available in this Agentrix-DevOps init session.","If the user later says they want to exit init, return to the development agent, continue the original request, or stop staying in the init session, call `complete_devops_init` again so the platform can ask and switch state."].join(" "),a=e.eventData,i=this.toCreateTaskInput(e);return{...i,eventId:t?G():i.eventId,agentId:_o,agentType:"claude",agentDir:n,eventData:{...a,eventId:G(),senderType:"system",senderId:"agentrix-devops-init",senderName:"Agentrix DevOps init",message:{uuid:Et(),type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:"new"},encryptedMessage:void 0}}}toCreateTaskInput(e){if(!("agentSessionId"in e))return e;const{agentSessionId:t,...n}=e;return n}async startWorkerInternal(e,t,n){const s=this.getAliveSessionByTaskId(e.taskId);if(s)return we.info(`[SESSION] Task ${e.taskId} already has worker PID ${s.pid}, skip duplicate ${t}`),n.message=`Worker already running (PID ${s.pid})`,n;const a=xe.resolveProjectCWD(e.userCwd,e.userId,e.taskId),i=["worker","--type",e.agentType||"claude","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","120"],o=this.resolveChannelReplyTarget(e),r=this.buildWorkerEnv(o);let c;if(this.sandboxPool?.isEnabled())try{if(!await this.sandboxPool.createWorkerSandbox(e.taskId,e.userId,a))throw new Error("Failed to create sandbox instance");const{projectPath:t}=await import("./logger-DnKC_QlD.mjs").then(function(e){return e.d}),{join:n}=await import("path"),s=["--no-warnings","--no-deprecation",n(t(),"dist","index.mjs"),...i],o=`"${process.execPath}" ${s.map(e=>`"${e}"`).join(" ")}`,l=await this.sandboxPool.wrapWorkerCommand(e.taskId,o);we.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${l}`),c=Xe(l,{shell:!0,cwd:a,detached:!0,stdio:["ignore","pipe","pipe"],env:r}),we.info(`[SESSION] Worker started with sandbox, PID: ${c.pid}`)}catch(t){return we.error(`[SESSION] Failed to setup sandbox for task ${e.taskId}:`,t),n.status="failed",n.message=`Sandbox setup failed: ${t instanceof Error?t.message:String(t)}`,n}else c=wo(i,{cwd:a,detached:!0,stdio:["ignore","pipe","pipe"],env:r}),we.info(`[SESSION] Worker started without sandbox, PID: ${c.pid}`);return process.env.DEBUG&&(c.stdout?.on("data",e=>{we.debug(`[Daemon] worker stdout: ${e.toString()}`)}),c.stderr?.on("data",e=>{we.debug(`[Daemon] worker stderr: ${e.toString()}`)})),c.pid?(we.info(`[SESSION] Worker started, PID: ${c.pid}`),this.trackWorkerProcess(e,c),n):(n.status="failed",n.message="Failed to start worker - no PID",n)}stopSession(e){for(const[t,n]of this.pidToTrackedSession.entries())if(n.taskId===e){try{(n.childProcess?n.childProcess:{kill:e=>process.kill(t,e)}).kill("SIGTERM"),we.info(`[SESSION] Task ${e} stopped`);const s=setTimeout(()=>{const n=this.pidToTrackedSession.get(t);if(n&&n.taskId===e&&this.isProcessAlive(t))try{process.kill(t,"SIGKILL"),we.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){we.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){we.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return we.warn(`[SESSION] Task ${e} not found`),!1}pruneStaleSessions(){for(const[e,t]of this.pidToTrackedSession.entries())try{process.kill(e,0)}catch(t){this.pidToTrackedSession.delete(e)}}shutdown(){we.info("[SESSION] Shutting down all sessions");for(const[e,t]of this.pidToTrackedSession.entries())try{"daemon"===t.startedBy&&t.childProcess?t.childProcess.kill("SIGTERM"):process.kill(e,"SIGTERM")}catch(t){we.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};xe.writeTaskInput(e);try{const n=wo(["worker","--type","hive-publish","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{we.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{we.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;we.info(`[SESSION] Hive publish worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start hive-publish worker: ${e instanceof Error?e.message:String(e)}`,t}}async startHiveInstallWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};xe.writeTaskInput(e);try{const n=wo(["worker","--type","hive-install","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{we.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{we.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;we.info(`[SESSION] Hive install worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start hive-install worker: ${e instanceof Error?e.message:String(e)}`,t}}async startDeploymentWorker(e){const t={eventId:G(),status:"success",opCode:e.eventId};xe.writeTaskInput(e);try{const n=wo(["worker","--type","deployment","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","10"],{cwd:process.cwd(),detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env}});if(process.env.DEBUG&&(n.stdout?.on("data",e=>{we.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{we.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;we.info(`[SESSION] Deployment worker started, PID: ${n.pid}`);const s={taskId:e.taskId,userId:e.userId};return this.trackWorkerProcess(s,n),t}catch(e){return t.status="failed",t.message=`Failed to start deployment worker: ${e instanceof Error?e.message:String(e)}`,t}}}class Go{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=Ze()}async initialize(e){if(this.settings=e,!e.enabled)return we.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!At(this.platform))return we.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL(xe.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new Ct,await this.networkManager.initialize(t),we.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw we.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=xe.resolveUserWorkSpaceDir(t),a=xe.getStatePaths().logsDir,i=this.settings.filesystem||{},o=this.settings.env||{},r={...i,allowWrite:[...i.allowWrite||[],s,n,a]};if("linux"===this.platform&&i.allowRead){const e=Re.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new _t(this.networkManager,c);return this.workerSandboxes.set(e,l),we.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return we.error(`[SANDBOX] Failed to create sandbox for task ${e}:`,t),null}}async wrapWorkerCommand(e,t){const n=this.workerSandboxes.get(e);if(!n)throw new Error(`No sandbox found for task ${e}`);const s=await n.wrapWithSandbox(t);return we.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),we.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){we.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),we.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,we.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class Bo{constructor(e,t,n={}){this.client=e,this.machineId=t;const s=xe.agentrixAgentsHomeDir,a=T(s,"companion","claude");this.stateFilePath=n.stateFilePath??T(a,"state.json"),this.initialDelayMs=n.initialDelayMs??6e4}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;companionState=null;stateFilePath;initialDelayMs;started=!1;cronJobs=new Map;start(){this.started?this.reloadStateAndReschedule():(this.started=!0,this.loadState(),this.companionState?(we.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):we.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),we.info(`[COMPANION SCHEDULER] Starting with interval ${this.intervalMs}ms`),this.initialDelay=setTimeout(()=>{this.initialDelay=null,this.tick(),this.scheduleNext()},this.initialDelayMs))}stop(){this.started=!1,this.initialDelay&&(clearTimeout(this.initialDelay),this.initialDelay=null),this.timer&&(clearTimeout(this.timer),this.timer=null);for(const[e,t]of this.cronJobs)t.stop(),we.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),we.info("[COMPANION SCHEDULER] Stopped")}scheduleNext(){this.started&&(this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.timer=null,this.tick(),this.scheduleNext()},this.intervalMs))}reloadStateAndReschedule(){this.loadState()}reschedulePendingHeartbeatTimer(){this.initialDelay&&(clearTimeout(this.initialDelay),this.initialDelay=null),this.scheduleNext(),we.info(`[COMPANION SCHEDULER] Rescheduled pending heartbeat timer with interval ${this.intervalMs}ms`)}setHeartbeatTaskId(e){this.heartbeatTaskId=e,this.saveStateField("heartbeatTaskId",e)}clearHeartbeatTaskId(){this.heartbeatTaskId=null,this.saveStateField("heartbeatTaskId",void 0),we.info("[COMPANION SCHEDULER] Cleared heartbeat task ID")}recordInteraction(e){if(!this.companionState?.chatId||e!==this.companionState.chatId)return;const t=(new Date).toISOString();this.saveStateField("lastInteractionTimestamp",t),we.debug(`[COMPANION SCHEDULER] Recorded interaction at ${t}`)}loadState(){try{if(r(this.stateFilePath)){this.companionState=JSON.parse(c(this.stateFilePath,"utf-8"));const e=this.intervalMs,t=this.companionState?.heartbeatIntervalMs??9e5;t!==this.intervalMs&&(we.info(`[COMPANION SCHEDULER] Interval changed: ${this.intervalMs}ms -> ${t}ms`),this.intervalMs=t,this.started&&(this.timer||this.initialDelay)&&e!==this.intervalMs&&this.reschedulePendingHeartbeatTimer()),this.enabled=this.companionState?.heartbeatEnabled??!1,this.heartbeatTaskId=this.companionState?.heartbeatTaskId??null,we.info(`[COMPANION SCHEDULER] Loaded state: agentId=${this.companionState?.agentId}, chatId=${this.companionState?.chatId??"none"}, enabled=${this.enabled}, interval=${this.intervalMs}ms, taskId=${this.heartbeatTaskId??"none"}`)}}catch(e){we.warn("[COMPANION SCHEDULER] Failed to load state.json",e)}}saveStateField(e,t){try{let n={};r(this.stateFilePath)&&(n=JSON.parse(c(this.stateFilePath,"utf-8"))),void 0===t?delete n[e]:n[e]=t;const s=_(this.stateFilePath);r(s)||p(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),we.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){we.warn(`[COMPANION SCHEDULER] Failed to save state field: ${e}`,t)}}getTodayDateString(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}addScheduledTask(e){const t={id:ue(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),we.info(`[COMPANION SCHEDULER] Added scheduled task: id=${t.id}, type=${t.type}, task="${t.task}"`),t}listScheduledTasks(){return this.loadState(),this.companionState?.scheduledTasks??[]}deleteScheduledTask(e){this.loadState();const t=this.companionState?.scheduledTasks??[],n=t.findIndex(t=>t.id===e);if(-1===n)return!1;t.splice(n,1),this.saveStateField("scheduledTasks",t);const s=this.cronJobs.get(e);return s&&(s.stop(),this.cronJobs.delete(e)),we.info(`[COMPANION SCHEDULER] Deleted scheduled task: id=${e}`),!0}startCronJob(e){try{const t={},n="utc"===e.timeType;let s;if(e.due){if(n){const n=new Date(e.due);s=`${n.getUTCMinutes()} ${n.getUTCHours()} ${n.getUTCDate()} ${n.getUTCMonth()+1} *`,t.timezone="Etc/UTC"}else{const n=e.due.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/);if(!n)return void we.warn(`[COMPANION SCHEDULER] Cannot parse due date: ${e.due}, skipping: ${e.id}`);s=`${parseInt(n[5])} ${parseInt(n[4])} ${parseInt(n[3])} ${parseInt(n[2])} *`,e.timezone&&(t.timezone=e.timezone)}"once"===e.type&&(t.maxRuns=1)}else{if(!e.cron)return void we.warn(`[COMPANION SCHEDULER] Invalid task entry, skipping: ${e.id}`);s=e.cron,n?t.timezone="Etc/UTC":e.timezone&&(t.timezone=e.timezone)}const a=new $t(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),we.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){we.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){we.info(`[COMPANION SCHEDULER] Scheduled task fired: id=${e.id}, task="${e.task}"`),this.loadState();const t=this.companionState;t?.chatId&&(this.client.send("task-message",{eventId:G(),taskId:t.chatId,chatId:t.chatId,from:"machine",message:{type:"companion_reminder",content:`Scheduled task due: ${e.task}`,timestamp:(new Date).toISOString()},senderType:"system",senderId:"system",senderName:"system"}),"once"===e.type&&this.deleteScheduledTask(e.id))}restoreScheduledTasks(){const e=this.companionState?.scheduledTasks??[];if(0===e.length)return;let t=0;for(const n of e)"once"===n.type&&n.due&&new Date(n.due).getTime()<Date.now()?we.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);we.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}tick(){if(this.loadState(),!this.companionState)return void we.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");if(!this.enabled)return void we.debug("[COMPANION SCHEDULER] Heartbeat disabled, skipping");const e=this.companionState,t=[],n=new Date;e.lastInteractionTimestamp&&(!e.lastHeartbeatTimestamp||new Date(e.lastInteractionTimestamp).getTime()>new Date(e.lastHeartbeatTimestamp).getTime())&&t.push("new_interaction");const s=this.getTodayDateString();if(e.lastHeartbeatDate!==s&&t.push("first_today"),0===t.length)return void we.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");we.info(`[COMPANION SCHEDULER] Heartbeat triggered: ${t.join(", ")}`);const a=("number"==typeof e.heartbeatTriggerCount?e.heartbeatTriggerCount:0)+1,i=a%5==0,o=i?"memory_organization":void 0;this.saveStateField("lastHeartbeatTimestamp",n.toISOString()),this.saveStateField("lastHeartbeatDate",s),this.saveStateField("heartbeatTriggerCount",a);const r=n.toLocaleString(),c={type:"companion_heartbeat",timestamp:n.toISOString(),triggerTime:r,triggerReasons:t,heartbeatTriggerCount:a,maintenanceMode:i,maintenanceModeType:o};this.heartbeatTaskId?(we.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:G(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:c,senderType:"system",senderId:"system",senderName:"system"})):(we.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:G(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n.toISOString(),triggerTime:r,triggerReasons:t,heartbeatTriggerCount:a,maintenanceMode:i,maintenanceModeType:o}))}}class Fo{constructor(e,t){this.client=e,this.machineId=t;const n=xe.agentrixAgentsHomeDir,s=T(n,"companion"),a=T(s,"claude");this.bootstrapPath=T(a,"BOOTSTRAP.md"),this.countPath=T(s,"BOOTSTRAP.count"),this.stateFilePath=T(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?we.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):(we.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):we.debug("[COMPANION BOOTSTRAP] BOOTSTRAP.md not found, companion already initialized")}stop(){this.timer&&(clearTimeout(this.timer),this.timer=null)}scheduleNext(){this.timer=setTimeout(()=>this.tick(),this.intervalMs)}tick(){if(!r(this.bootstrapPath))return void we.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void we.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return we.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),we.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:G(),machineId:t.machineId,agentId:t.agentId,chatId:t.chatId,userId:t.userId}),this.scheduleNext()}readCount(){try{if(r(this.countPath)){const e=parseInt(c(this.countPath,"utf-8").trim(),10);return isNaN(e)?0:e}}catch{}return 0}writeCount(e){try{u(this.countPath,String(e),"utf-8")}catch(e){we.warn("[COMPANION BOOTSTRAP] Failed to write BOOTSTRAP.count:",e)}}loadState(){try{if(r(this.stateFilePath)){const e=JSON.parse(c(this.stateFilePath,"utf-8"));if(e?.agentId&&e?.machineId&&e?.userId&&e?.chatId)return e}}catch{}return null}}function Wo(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function zo(e){if("string"==typeof e)return e;if(!e||"object"!=typeof e)return;const t=e;return"string"==typeof t.text?t.text:void 0}function Ko(e){if(!e)return(new Date).toISOString();const t=Number(e);if(Number.isFinite(t))return new Date(t>1e10?t:1e3*t).toISOString();const n=new Date(e);return Number.isNaN(n.getTime())?(new Date).toISOString():n.toISOString()}function Vo(e){if(!e||"object"!=typeof e)return;const t=e;for(const e of["name","sender_name","user_name","nickname"]){const n=t[e];if("string"==typeof n&&n.trim())return n}}function Xo(e){const t=e?.response?.status,n=e?.response?.data,s=e?.response?.headers?.["x-tt-logid"]||e?.response?.headers?.["x-request-id"];return[t?`status=${t}`:void 0,n?`data=${JSON.stringify(n)}`:void 0,s?`logId=${s}`:void 0,e?.message||e?.msg||String(e)].filter(Boolean).join(", ")}function Jo(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class Yo{id;platform="lark";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};client;wsClient=null;messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;botOpenId;constructor(e){var t;this.id=e.id,this.credentials={appId:Wo((t=e.credentials).appId,"appId"),appSecret:Wo(t.appSecret,"appSecret")},this.client=new Pt.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:Pt.AppType.SelfBuild,domain:Pt.Domain.Feishu})}get state(){return this.connectionState}async connect(){if("connected"===this.connectionState||"connecting"===this.connectionState)return;this.setState("connecting"),await this.fetchBotIdentity(),this.wsClient=new Pt.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:Pt.Domain.Feishu,loggerLevel:Pt.LoggerLevel.info,onReady:()=>{we.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{we.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{we.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{we.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new Pt.EventDispatcher({}).register({"im.message.receive_v1":async e=>{const t=this.normalizeMessage(e);t&&await(this.messageHandler?.(t))}});try{await this.wsClient.start({eventDispatcher:e})}catch(e){const t=e instanceof Error?e:new Error(String(e));throw this.setState("error",t),t}}async disconnect(){this.wsClient&&(this.wsClient.close({force:!0}),this.wsClient=null),this.setState("disconnected")}async sendMessage(e,t){const n=await this.client.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:e,msg_type:"text",content:JSON.stringify({text:t})}});if(n.code&&0!==n.code)throw new Error(n.msg||`Lark sendMessage failed with code ${n.code}`)}async sendChannelMessage(e,t){try{const n=t.content?.trim();n&&await this.sendMessage(e,n);for(const n of t.attachments??[])await this.sendAttachment(e,n)}catch(e){throw new Error(`Lark sendChannelMessage failed: ${Xo(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:y(t.filePath)}});if(!n?.image_key)throw new Error("Lark image upload did not return image_key");return void await this.sendRawMessage(e,"image",{image_key:n.image_key})}const n=t.fileName||S(t.filePath),s=await this.client.im.file.create({data:{file_type:this.resolveLarkFileType(n,t.mimeType),file_name:n,file:y(t.filePath)}});if(!s?.file_key)throw new Error("Lark file upload did not return file_key");await this.sendRawMessage(e,"file",{file_key:s.file_key})}async getChatName(e){try{const t=await this.client.im.chat.get({path:{chat_id:e}});return t.code&&0!==t.code?(we.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return we.warn(`[CHANNEL][LARK] Failed to get chat name for ${e}`,t),e}}async getUserName(e){const t=function(e){return e.startsWith("on_")?"union_id":e.startsWith("ou_")?"open_id":"user_id"}(e);try{const n=await this.client.request({url:"/open-apis/contact/v3/users/basic_batch",method:"POST",params:{user_id_type:t},data:{user_ids:[e]}});if(n.code&&0!==n.code)return we.warn(`[CHANNEL][LARK] contact.user.basic_batch failed: code=${n.code}, msg=${n.msg}`),e;const s=n.data?.users?.[0];return s?.name||s?.i18n_name?.zh_cn||s?.i18n_name?.en_us||s?.i18n_name?.ja_jp||e}catch(t){return we.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${Xo(t)}`),e}}async getContacts(){const e=[];for await(const t of await this.client.im.chat.listWithIterator({params:{page_size:50,sort_type:"ByActiveTimeDesc"}}))for(const n of t?.items??[])n.chat_id&&e.push({id:n.chat_id,name:n.name||n.chat_id,avatar:n.avatar,description:n.description,chatStatus:n.chat_status,external:n.external});return e}async downloadFile(e,t={}){try{const n=function(e){const[t,n,s]=e.split(":").map(decodeURIComponent);if(!t||!n||!s)throw new Error("Invalid Lark resource key");return{messageId:t,resourceType:n,fileKey:s}}(e),s=pn(t.fileName||n.fileKey),a=await this.client.im.messageResource.get({path:{message_id:n.messageId,file_key:n.fileKey},params:{type:n.resourceType}});return await a.writeFile(s),s}catch(e){return we.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${Xo(e)}`),null}}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async sendRawMessage(e,t,n){const s=await this.client.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:e,msg_type:t,content:JSON.stringify(n)}});if(s.code&&0!==s.code)throw new Error(s.msg||`Lark send ${t} failed with code ${s.code}`)}async fetchBotIdentity(){try{const e=await this.client.request({url:"/open-apis/bot/v3/info",method:"GET"});if(e.code&&0!==e.code)return void we.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){we.warn(`[CHANNEL][LARK] bot identity lookup failed: ${Xo(e)}`)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}resolveLarkFileType(e,t){const n=E(e).toLowerCase().replace(/^\./,"");return"pdf"===n||"application/pdf"===t?"pdf":["doc","docx"].includes(n)?"doc":["xls","xlsx","csv"].includes(n)?"xls":["ppt","pptx"].includes(n)?"ppt":"mp4"===n||"video/mp4"===t?"mp4":"opus"===n||"audio/opus"===t?"opus":"stream"}normalizeMessage(e){const t=e?.message;if(!t?.message_id||!t?.chat_id)return we.warn(`[CHANNEL][LARK] Ignoring malformed message event: channel=${this.id}`),null;const n=function(e){try{return JSON.parse(e)}catch{return e}}(t.content??""),s=n&&"object"==typeof n?n:{},a=t.message_type,i="string"==typeof s.file_key?s.file_key:void 0,o="string"==typeof s.image_key?s.image_key:void 0,r=(c=t.mentions,l=this.credentials.appId,p=this.botOpenId,!!Array.isArray(c)&&c.some(e=>{if(!e||"object"!=typeof e)return!1;const t=e;if("bot"===("string"==typeof t.mentioned_type?t.mentioned_type.toLowerCase():void 0))return!0;const n=t.id;if(n&&"object"==typeof n){const e=n;return e.open_id===p||e.app_id===l||e.open_id===l||e.user_id===l}return t.app_id===l||t.open_id===l||t.user_id===l}));var c,l,p;return{id:t.message_id,channelId:this.id,platform:"lark",chatId:t.chat_id,chatType:t.chat_type,senderId:e?.sender?.sender_id?.open_id??e?.sender?.sender_id?.user_id??e?.sender?.sender_id?.union_id,senderType:e?.sender?.sender_type,senderName:Vo(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:zo(n),fileKey:i?Jo(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?Jo(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:Ko(t.create_time??e?.create_time??e?.ts),raw:e}}}const Qo="https://api.telegram.org",Zo=4e4,er=1e3;function tr(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function nr(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function sr(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function ar(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function ir(e){return e.photo?.[e.photo.length-1]?.file_id}class or{id;platform="telegram";capabilities={sendText:!0,sendImage:!0,sendFile:!0,sendAudio:!1,sendVideo:!1};messageHandler=null;stateHandler=null;connectionState="disconnected";credentials;polling=!1;pollController=null;pollPromise=null;retryTimer=null;resolveRetrySleep=null;retryDelayMs=er;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=nr(e.token)??nr(e.botToken)??nr(e.bot_token);return{token:t||tr(t,"token")}}(e.credentials)}get state(){return this.connectionState}async connect(){"connected"!==this.connectionState&&"connecting"!==this.connectionState&&(this.setState("connecting"),this.botUser=await this.request("getMe",{},{timeoutMs:Zo}),this.polling=!0,this.retryDelayMs=er,this.pollPromise=this.pollLoop(),this.setState("connected"),we.info(`[CHANNEL][TELEGRAM] Connected: channel=${this.id}`))}async disconnect(){this.polling=!1,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=null,this.resolveRetrySleep?.()),this.resolveRetrySleep=null,this.pollController?.abort(),this.pollController=null,await(this.pollPromise?.catch(()=>{})),this.pollPromise=null,this.setState("disconnected")}async sendMessage(e,t){await this.request("sendMessage",{chat_id:e,text:t},{timeoutMs:Zo})}async sendChannelMessage(e,t){const n=t.attachments??[],s=t.content?.trim();if(0===n.length)return void(s&&await this.sendMessage(e,s));const a=1===n.length?s:void 0;s&&!a&&await this.sendMessage(e,s);for(let t=0;t<n.length;t+=1)await this.sendAttachment(e,n[t],0===t?a:void 0)}async sendAttachment(e,t,n){const s=this.resolveOutgoingKind(t),a="image"===s?"sendPhoto":"sendDocument",i="image"===s?"photo":"document",o=t.fileName||S(t.filePath),r=await ft(t.filePath),c=new FormData;c.append("chat_id",e),c.append(i,new Blob([r],{type:t.mimeType||"application/octet-stream"}),o),n&&c.append("caption",n),await this.requestForm(a,c,{timeoutMs:Zo})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:Zo});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||S(n.file_path);return await un(`${Qo}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return we.warn(`[CHANNEL][TELEGRAM] Failed to download file: channel=${this.id}, fileKey=${e}`,t),null}}async getChatName(e){try{const t=await this.request("getChat",{chat_id:e},{timeoutMs:Zo});return t.title||sr(t)||t.username||e}catch(t){return we.warn(`[CHANNEL][TELEGRAM] Failed to get chat name for ${e}`,t),e}}async getUserName(e){try{const t=await this.request("getChat",{chat_id:e},{timeoutMs:Zo});return sr(t)||t.username||e}catch(t){return we.warn(`[CHANNEL][TELEGRAM] Failed to get user name for ${e}`,t),e}}onMessage(e){this.messageHandler=e}onStateChange(e){this.stateHandler=e}setState(e,t){this.connectionState=e,this.stateHandler?.(e,t)}async pollLoop(){for(;this.polling;)try{const e=await this.request("getUpdates",{offset:this.offset,timeout:30,allowed_updates:["message"]},{timeoutMs:Zo,isPoll:!0});this.retryDelayMs=er,"connected"!==this.connectionState&&this.setState("connected");for(const t of e){this.offset=Math.max(this.offset??0,t.update_id+1);const e=this.normalizeMessage(t);e&&await(this.messageHandler?.(e))}}catch(e){if(!this.polling)break;if(this.isAbortError(e))continue;const t=e instanceof Error?e:new Error(String(e));we.warn(`[CHANNEL][TELEGRAM] Poll failed: channel=${this.id}, message=${t.message}`),this.setState("error",t),await this.sleepWithCancel(this.retryDelayMs),this.retryDelayMs=Math.min(2*this.retryDelayMs,3e4),this.polling&&this.setState("connecting")}}async request(e,t,n){const s=new AbortController;n.isPoll&&(this.pollController=s);const a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=await fetch(`${Qo}/bot${this.credentials.token}/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:s.signal}),a=await n.json().catch(()=>({}));if(!n.ok||!a.ok){const e=a.error_code?`code=${a.error_code}`:void 0,t=a.description||`HTTP ${n.status}`;throw new Error([e,t].filter(Boolean).join(", "))}if(void 0===a.result)throw new Error(`Telegram ${e} response is missing result`);return a.result}finally{clearTimeout(a),n.isPoll&&this.pollController===s&&(this.pollController=null)}}async requestForm(e,t,n){const s=new AbortController,a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=await fetch(`${Qo}/bot${this.credentials.token}/${e}`,{method:"POST",body:t,signal:s.signal}),a=await n.json().catch(()=>({}));if(!n.ok||!a.ok){const e=a.error_code?`code=${a.error_code}`:void 0,t=a.description||`HTTP ${n.status}`;throw new Error([e,t].filter(Boolean).join(", "))}if(void 0===a.result)throw new Error(`Telegram ${e} response is missing result`);return a.result}finally{clearTimeout(a)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}sleepWithCancel(e){return new Promise(t=>{this.resolveRetrySleep=t,this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.resolveRetrySleep=null,t()},e)})}isAbortError(e){return e instanceof Error&&"AbortError"===e.name}isTriggeredMessage(e){const t=this.botUser?.id,n=this.botUser?.username?.toLowerCase(),s=e.text??e.caption??"",a=e.text?e.entities:e.caption_entities,i=Boolean(void 0!==t&&e.reply_to_message?.from?.id===t);let o=!1;if(n){o=s.toLowerCase().includes(`@${n}`);for(const e of a??[]){if("mention"!==e.type&&"bot_command"!==e.type)continue;const t=s.slice(e.offset,e.offset+e.length).toLowerCase();if(t===`@${n}`||t.endsWith(`@${n}`)){o=!0;break}}}return{mentionedBot:o,replyToBot:i,triggered:o||i}}normalizeMessage(e){const t=e.message;if(!t?.chat?.id||!t.message_id)return we.warn(`[CHANNEL][TELEGRAM] Ignoring malformed message event: channel=${this.id}`),null;const n=String(t.chat.id),s=void 0===t.from?.id?void 0:String(t.from.id),a=this.isTriggeredMessage(t);return{id:String(t.message_id||e.update_id||ue()),channelId:this.id,platform:"telegram",chatId:n,chatType:(i=t.chat.type,"private"===i?"p2p":"group"===i||"supergroup"===i?"group":i),senderId:s,senderName:t.from?sr(t.from):void 0,type:ar(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:ir(t),mentionedBot:a.mentionedBot,replyToBot:a.replyToBot,triggered:a.triggered,rawContent:t.text??t.caption??t.photo??t.document??t.voice,timestamp:new Date(1e3*t.date).toISOString(),raw:e};var i}}function rr(e){const t=mr(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${lr({seq:t.seq.toString(),at:t.at,senderType:t.senderType??void 0,senderId:t.senderId??void 0,senderName:t.senderName??void 0})}>${t.text}</msg>\n`},...t.nonTextBlocks]},parent_tool_use_id:null,session_id:""}:null}function cr(e){const t=mr(e);return t?`<msg ${lr({seq:t.seq.toString(),at:t.at,senderType:t.senderType??void 0,senderId:t.senderId??void 0,senderName:t.senderName??void 0})}>\n${t.text}\n</msg>`:null}function lr(e){return Object.entries(e).filter(([,e])=>void 0!==e&&""!==e).map(([e,t])=>`${e}="${function(e){return e.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}(t)}"`).join(" ")}function pr(e){const t=[];for(const n of e){const e=cr(n);e&&t.push(e)}return t.join("\n")}function dr(e){return`Ask user: ${e.questions.map((e,t)=>{const n=e.options?.map(e=>e.label).filter(Boolean),s=n&&n.length>0?` options: ${n.join(", ")}`:"";return`Q${t+1}[${e.header}] ${e.question}${s}`}).join(" | ")}`}function ur(e){const t=e.status?` status=${e.status}`:"",n=e.reason?` reason=${e.reason}`:"",s=e.answers?.length?e.answers.join(", "):"no answers",a=e.details?.filter(Boolean).join(" | ");return`Ask user response:${t}${n} answers: ${s}${a?` details: ${a}`:""}`}function mr(e){const{text:t,nonTextBlocks:n}=(s=e.message,Z(s)?{text:dr(s),nonTextBlocks:[]}:ee(s)?{text:ur(s),nonTextBlocks:[]}:te(s)?function(e){switch(e.type){case"user":case"assistant":return function(e){if("string"==typeof e)return{text:e,nonTextBlocks:[]};if(Array.isArray(e)){const t=[],n=[];for(const s of e)"text"!==s.type||"string"!=typeof s.text?n.push(s):t.push(s.text);return{text:t.join("\n"),nonTextBlocks:n}}return{text:"",nonTextBlocks:[]}}(e.message.content);case"result":return"success"===e.subtype?{text:e.result,nonTextBlocks:[]}:{text:Array.isArray(e.errors)?e.errors.filter(e=>"string"==typeof e).join("\n").trim():"",nonTextBlocks:[]}}return{text:"",nonTextBlocks:[]}}(s):{text:"",nonTextBlocks:[]});var s;return t?{seq:e.localSequence,at:e.createdAt,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,text:t,nonTextBlocks:n}:null}class hr{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=T(xe.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=T(xe.agentrixHomeDir,"channels","group-history"),this.loadState()}stateFilePath;groupHistoryFilePath;adapters=new Map;reconnectTimers=new Map;pendingMessages=new Map;store={version:1,channels:[],bindings:[]};stopping=!1;createTaskLocks=new Map;async start(){this.loadState(),this.store.companionDataEncryptionKey||await this.fetchCompanionEncryptionKeys();const e=this.store.channels.filter(e=>e.enabled);for(const t of e)try{await this.connectChannel(t.id)}catch(e){we.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}we.info(`[CHANNEL] Manager started: machineId=${this.machineId}, channels=${this.store.channels.length}, enabled=${e.length}`)}async stop(){this.stopping=!0;for(const e of this.reconnectTimers.values())clearTimeout(e);this.reconnectTimers.clear();for(const e of this.pendingMessages.values())clearTimeout(e.timer);this.pendingMessages.clear();for(const e of this.adapters.values())await e.disconnect().catch(t=>{we.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),we.info("[CHANNEL] Manager stopped")}getChannels(){return this.loadState(),this.store.channels.map(e=>({...e,credentials:this.redactCredentials(e.credentials)}))}addChannel(e){this.loadState();const t=(new Date).toISOString(),n={id:ue(),platform:e.platform,name:e.name,credentials:e.credentials,enabled:e.enabled??!1,connectionState:"disconnected",createdAt:t,updatedAt:t};return this.store.channels.push(n),this.saveState(),we.info(`[CHANNEL] Added channel: id=${n.id}, platform=${n.platform}`),{...n,credentials:this.redactCredentials(n.credentials)}}async removeChannel(e){this.loadState();const t=this.store.channels.findIndex(t=>t.id===e);return-1!==t&&(await this.disconnectChannel(e,{disable:!0}).catch(()=>{}),this.store.channels.splice(t,1),this.store.bindings=this.store.bindings.filter(t=>t.channelId!==e),this.saveState(),we.info(`[CHANNEL] Removed channel: id=${e}`),!0)}async connectChannel(e){this.loadState();const t=this.requireChannel(e);let n;this.clearReconnect(e),this.updateChannel(e,{enabled:!0,connectionState:"connecting",lastError:void 0});try{const s=this.adapters.get(e);s&&"disconnected"!==s.state&&(await s.disconnect().catch(t=>{we.warn(`[CHANNEL] Failed to reset adapter before reconnect: channel=${e}`,t)}),this.adapters.delete(e),this.clearReconnect(e)),n=this.getOrCreateAdapter(t),await n.connect()}catch(t){const n=t instanceof Error?t.message:String(t);throw this.updateChannel(e,{connectionState:"error",lastError:n}),t}return this.updateChannel(e,{enabled:!0,connectionState:n.state,lastConnectedAt:"connected"===n.state?(new Date).toISOString():t.lastConnectedAt,lastError:"error"===n.state?"Connection failed":void 0}),this.getChannel(e)}async disconnectChannel(e,t={}){this.loadState(),this.requireChannel(e),this.clearReconnect(e),t.disable&&this.updateChannel(e,{enabled:!1});const n=this.adapters.get(e);return n&&(await n.disconnect(),this.adapters.delete(e)),this.updateChannel(e,{enabled:!t.disable&&this.requireChannel(e).enabled,connectionState:"disconnected",lastDisconnectedAt:(new Date).toISOString()}),this.getChannel(e)}async getContacts(e){this.loadState();const t=this.requireChannel(e);return this.getOrCreateAdapter(t).getContacts()}getBindings(e){return this.loadState(),this.requireChannel(e),this.store.bindings.filter(t=>t.channelId===e)}async sendMessageToTaskChannel(e,t){this.loadState();const n=this.getReplyTargetForTask(e);return n?(await this.sendMessageToChannel(n,t),we.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):(we.debug(`[CHANNEL] No channel binding for task ${e}`),!1)}getReplyTargetForTask(e){this.loadState();const t=this.store.bindings.find(t=>t.taskId===e);if(!t)return null;const n=this.store.channels.find(e=>e.id===t.channelId);return{channelId:t.channelId,chatId:t.chatId,...n?.platform?{platform:n.platform}:{},...t.chatName?{chatName:t.chatName}:{}}}async sendMessageToChannel(e,t){const n=this.getOrCreateAdapter(this.requireChannel(e.channelId));"connected"!==n.state&&await this.connectChannel(e.channelId);const s="string"==typeof t?{content:t}:t,a=s.content?.trim(),i=s.attachments??[];if(!a&&0===i.length)throw new Error("Channel message requires content or attachments");const o=i.map(e=>({...e,kind:this.resolveAttachmentKind(e)}));for(const e of o)if(!this.isAttachmentKindSupported(n,e.kind))throw new Error(`Channel platform ${n.platform} does not support sending ${e.kind} attachments`);if(o.length>0){if(!n.sendChannelMessage)throw new Error(`Channel platform ${n.platform} does not support outgoing attachment messages`);await n.sendChannelMessage(e.chatId,{content:s.content,attachments:o})}else n.sendChannelMessage?await n.sendChannelMessage(e.chatId,{content:s.content}):await n.sendMessage(e.chatId,s.content??"")}getChannelGroupHistory(e,t={}){if("group"!==e.chatType?.toLowerCase())throw new Error("Channel group history is only available for external group chats");const n=Math.max(1,Math.min(t.limit??30,100)),s=this.buildGroupHistoryRef(e),a=this.openGroupHistoryDb(s);try{const i="number"==typeof t.beforeSeq?a.pageMessagesBefore(t.beforeSeq,n):"number"==typeof t.afterSeq?a.pageMessagesAfter(t.afterSeq,n):a.pageRecentMessages(n);return{historyXml:this.formatExternalGroupHistoryXml(s,i.data,e.chatName||e.chatId,{markTriggered:!1}),hasMoreBefore:"number"!=typeof t.afterSeq&&i.hasMore,hasMoreAfter:"number"==typeof t.afterSeq&&i.hasMore}}finally{a.close()}}removeBinding(e,t){this.loadState(),this.requireChannel(e);const n=this.store.bindings.findIndex(n=>n.channelId===e&&n.id===t);return-1!==n&&(this.store.bindings.splice(n,1),this.saveState(),we.info(`[CHANNEL] Removed binding: channel=${e}, binding=${t}`),!0)}getChannel(e){const t=this.requireChannel(e);return{...t,credentials:this.redactCredentials(t.credentials)}}getOrCreateAdapter(e){const t=this.adapters.get(e.id);if(t)return t;const n=this.createAdapter(e);return n.onMessage(e=>this.routeMessage(e)),n.onStateChange?.((t,n)=>this.handleAdapterState(e.id,t,n)),this.adapters.set(e.id,n),n}createAdapter(e){if("lark"===e.platform)return new Yo({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new Ai({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new or({id:e.id,credentials:e.credentials});throw new Error(`Unsupported channel platform: ${e.platform}`)}resolveAttachmentKind(e){return e.kind&&"auto"!==e.kind?e.kind:e.mimeType?.startsWith("image/")?"image":e.mimeType?.startsWith("audio/")?"audio":e.mimeType?.startsWith("video/")?"video":"file"}isAttachmentKindSupported(e,t){const n=e.capabilities;return!n||("image"===t?!0===n.sendImage||!0===n.sendFile:"audio"===t?!0===n.sendAudio||!0===n.sendFile:"video"===t&&!0===n.sendVideo||!0===n.sendFile)}async routeMessage(e){we.info(`[CHANNEL] routeMessage raw: ${JSON.stringify(e)}`);const t=await this.downloadMessageAttachments(e),n=this.getPendingMessageKey(t);if(this.isAttachmentOnlyMessage(t))return void this.bufferPendingMessage(n,t);const s=this.takePendingMessages(n),a=s.length>0?this.mergePendingMessages(s,t):t;await this.routeRoutableMessage(a)}async routeRoutableMessage(e){this.loadState();let t=e;if(this.isGroupMessage(e)){if(await this.saveGroupHistoryMessage(e),!this.isGroupMessageTriggered(e))return void we.info(`[CHANNEL] Stored passive group message only: channel=${e.channelId}, chat=${e.chatId}, message=${e.id}`);const n=await this.resolveChatName(e),s=this.loadRecentGroupHistory(e,30);t=this.injectExternalGroupHistory(e,s,n)}const{binding:n,isNew:s}=await this.getOrCreateBindingForMessage(t);we.info(`[CHANNEL] routeMessage: isNew=${s}, taskId=${n.taskId}`),s||await this.forwardMessageToTask(t,n)}async flushPendingMessages(e){const t=this.takePendingMessages(e);for(const e of t)await this.routeRoutableMessage(e)}bufferPendingMessage(e,t){const n=this.pendingMessages.get(e);n&&clearTimeout(n.timer);const s=setTimeout(()=>{this.flushPendingMessages(e).catch(t=>{we.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),we.info(`[CHANNEL] Buffered attachment-only message: key=${e}, count=${(n?.messages.length??0)+1}`)}takePendingMessages(e){const t=this.pendingMessages.get(e);return t?(clearTimeout(t.timer),this.pendingMessages.delete(e),t.messages):[]}mergePendingMessages(e,t){const n=[...e.flatMap(e=>e.attachmentPaths??[]),...t.attachmentPaths??[]];return{...t,attachmentPaths:n,mentionedBot:t.mentionedBot||e.some(e=>e.mentionedBot),replyToBot:t.replyToBot||e.some(e=>e.replyToBot),triggered:t.triggered||e.some(e=>e.triggered),rawContent:{pendingMessages:e,textMessage:t.rawContent}}}isGroupMessage(e){return"group"===e.chatType?.toLowerCase()}isGroupMessageTriggered(e){return!0===e.mentionedBot||!0===e.replyToBot||!0===e.triggered}async saveGroupHistoryMessage(e){const t=this.openGroupHistoryDb(e);try{const n=await this.resolveGroupMessageSenderName(e);t.saveMessage({eventId:this.getGroupHistoryEventId(e),message:this.buildGroupHistorySdkMessage(e),senderType:"channel",senderId:e.senderId||"channel-user",senderName:n})}finally{t.close()}}loadRecentGroupHistory(e,t){const n=this.openGroupHistoryDb(e);try{const s=this.getGroupHistoryEventId(e),a=n.pageRecentMessages(500).data,i=a.findIndex(e=>e.eventId===s),o=i>=0?a.slice(0,i+1):a,r=this.findPreviousTriggerIndex(o,s),c=r>=0?r+1:0;return o.slice(c).slice(-t)}finally{n.close()}}injectExternalGroupHistory(e,t,n){return{...e,text:this.formatExternalGroupHistoryXml(e,t,n)}}formatExternalGroupHistoryXml(e,t,n,s={markTriggered:!0}){const a=[`<external_group_history ${[`platform="${this.escapeXmlAttribute(e.platform)}"`,`chatName="${this.escapeXmlAttribute(n)}"`,`chatId="${this.escapeXmlAttribute(e.chatId)}"`].join(" ")}>`];return t.forEach((t,n)=>{const i=lr({seq:t.localSequence.toString(),id:t.eventId,at:t.createdAt,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName,mentionedBot:this.getHistoryEntryTriggerFlags(t).mentionedBot?"true":void 0,replyToBot:this.getHistoryEntryTriggerFlags(t).replyToBot?"true":void 0,triggered:!1===s.markTriggered?void 0:t.eventId===this.getGroupHistoryEventId(e)?"true":void 0});a.push(` <msg ${i}>`),a.push(` ${this.escapeXmlText(this.formatHistoryMessageContent(t))}`),a.push(" </msg>")}),a.push("</external_group_history>"),a.join("\n")}formatHistoryMessageContent(e){const t=e.message;if(!t||"object"!=typeof t||"user"!==t.type)return"[non-text message]";const n=t.message.content;return"string"==typeof n?n.trim()||"[non-text message]":Array.isArray(n)&&n.filter(e=>e&&"object"==typeof e&&"text"===e.type&&"string"==typeof e.text).map(e=>e.text).join("\n\n").trim()||"[non-text message]"}buildGroupHistorySdkMessage(e){const t=e.attachmentPaths?.length?`[attachments: ${e.attachmentPaths.join(", ")}]`:void 0;return{type:"user",message:{role:"user",content:[e.text?.trim(),t,e.text?.trim()||t?void 0:`[${e.type}]`].filter(Boolean).join("\n\n")},parent_tool_use_id:null,session_id:"",__channelGroupHistory:{mentionedBot:!0===e.mentionedBot,replyToBot:!0===e.replyToBot,triggered:this.isGroupMessageTriggered(e)}}}async resolveGroupMessageSenderName(e){if(e.senderName?.trim())return e.senderName.trim();const t=e.senderId?.trim(),n=this.adapters.get(e.channelId);if(t&&n?.getUserName)try{const e=await n.getUserName(t);if(e&&e!==t)return e}catch(n){we.debug(`[CHANNEL] Failed to resolve group sender name: channel=${e.channelId}, sender=${t}`,n)}return t||`${e.platform}:${e.chatId}`}getHistoryEntryTriggerFlags(e){const t=e.message.__channelGroupHistory;if(!t||"object"!=typeof t)return{mentionedBot:!1,replyToBot:!1,triggered:!1};const n=t;return{mentionedBot:!0===n.mentionedBot,replyToBot:!0===n.replyToBot,triggered:!0===n.triggered}}isTriggeredHistoryEntry(e){const t=this.getHistoryEntryTriggerFlags(e);return t.triggered||t.mentionedBot||t.replyToBot}findPreviousTriggerIndex(e,t){for(let n=e.length-1;n>=0;n-=1){const s=e[n];if(s.eventId!==t&&this.isTriggeredHistoryEntry(s))return n}return-1}openGroupHistoryDb(e){const t=this.getGroupHistoryDataDir(e);return r(t)||p(t,{recursive:!0}),ko({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return T(this.groupHistoryFilePath,this.encodePathPart(e.channelId),this.encodePathPart(e.chatId))}getGroupHistoryTaskId(e){return`channel-group:${e.channelId}:${e.chatId}`}getGroupHistoryEventId(e){return`channel-group:${e.channelId}:${e.chatId}:${e.id}`}buildGroupHistoryRef(e){const t="telegram"===e.platform||"wechat"===e.platform||"lark"===e.platform?e.platform:"lark";return{id:"__history_page__",channelId:e.channelId,platform:t,chatId:e.chatId,chatType:e.chatType,type:"text",timestamp:(new Date).toISOString()}}encodePathPart(e){return Buffer.from(e).toString("base64url")}escapeXmlText(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}escapeXmlAttribute(e){return this.escapeXmlText(e).replace(/"/g,""").replace(/'/g,"'")}getPendingMessageKey(e){return`${e.channelId}:${e.chatId}`}isAttachmentOnlyMessage(e){const t="string"==typeof e.text&&e.text.trim().length>0,n=Boolean(e.fileKey||e.imageKey||e.attachmentPaths?.length);return!t&&n&&("image"===e.type||"file"===e.type)}async downloadMessageAttachments(e){const t=this.adapters.get(e.channelId);if(!t?.downloadFile)return e;const n=[e.imageKey,e.fileKey].filter(e=>Boolean(e)),s=[...new Set(n)];if(0===s.length)return e;const a=[];for(const n of s){const s=await t.downloadFile(n,{fileName:e.fileName});s&&(we.info(`[CHANNEL] Downloaded attachment: channel=${e.channelId}, chat=${e.chatId}, path=${s}`),a.push(s))}return a.length>0?{...e,attachmentPaths:[...e.attachmentPaths??[],...a]}:e}async forwardMessageToTask(e,t){if(we.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void we.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void we.warn(`[CHANNEL] Task ${t.taskId} is pending, skipping message forward`);const n=this.readCompanionState(),s=n?.chatId||t.taskId,{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e);this.client.send("task-message",{eventId:G(),taskId:t.taskId,chatId:s,from:"machine",message:a,encryptedMessage:i,messageType:"text",senderType:"channel",senderId:e.senderId||"channel-user",senderName:e.senderName||`${e.platform}:${e.chatId}`,channelReplyTarget:{channelId:e.channelId,chatId:e.chatId,platform:e.platform,chatType:e.chatType,chatName:t.chatName}}),we.info(`[CHANNEL] Forwarded message to task ${t.taskId}`)}async buildEncryptedMessage(e){const t=e.attachmentPaths??[],n=t.length>0?`[User sent the following attachments: ${t.join(", ")}]`:void 0,s={type:"user",message:{role:"user",content:[n,e.text||(n?void 0:`[${e.type}]`)].filter(Boolean).join("\n\n")}};let a,i=s;if(this.store.companionDataEncryptionKey)try{const e=await xe.getSecretKey();if(e){const t=H(L(this.store.companionDataEncryptionKey),e);t&&(a=ne(s,t),i=void 0)}}catch(e){we.warn("[CHANNEL] Failed to encrypt message, sending plaintext",e)}return{plainMessage:i,encryptedMessage:a}}async getOrCreateBindingForMessage(e){const t=this.store.bindings.find(t=>t.channelId===e.channelId&&t.chatId===e.chatId);if(t)return{binding:t,isNew:!1};const n=await this.resolveChatName(e),s=await this.createTaskForChat(e,n),a=(new Date).toISOString(),i={id:ue(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.store.bindings.push(i),this.saveState(),we.info(`[CHANNEL] Auto-created binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0}}async createTaskForChat(e,t){const n=this.createTaskLocks.get(e.chatId);if(n)return n;const s=this.doCreateTaskForChat(e,t);this.createTaskLocks.set(e.chatId,s);try{return await s}finally{this.createTaskLocks.delete(e.chatId)}}async doCreateTaskForChat(e,t){const n=this.readCompanionState();if(!n)return we.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${ue()}`;if(this.store.companionDataEncryptionKey||await this.fetchCompanionEncryptionKeys(),!this.client.connected)return we.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${ue()}`;const{plainMessage:s,encryptedMessage:a}=await this.buildEncryptedMessage(e);try{const i=await this.client.sendWithAck("channel-task-create",{eventId:G(),userId:n.userId,chatId:n.chatId,agentId:n.agentId,machineId:n.machineId,customTitle:"wechat"===e.platform?"wechat bot":`${e.platform}/${t}`,taskType:"work",supportedFeatures:["sub-task"],taskAgentIds:[n.agentId],dataEncryptionKey:this.store.companionDataEncryptionKey,ownerEncryptedDataKey:this.store.companionOwnerEncryptedDataKey,message:s,encryptedMessage:a,senderType:"channel",senderId:e.senderId||"channel-user",senderName:e.senderName||`${e.platform}:${e.chatId}`,channelReplyTarget:{channelId:e.channelId,chatId:e.chatId,platform:e.platform,chatType:e.chatType,chatName:t}});return"success"===i?.status&&i.taskId?(we.info(`[CHANNEL] Created task ${i.taskId} for chat ${e.chatId}`),i.taskId):(we.error(`[CHANNEL] API task creation failed: ${i?.message||"unknown"}`),`pending-api-error-${ue()}`)}catch(e){return we.error("[CHANNEL] Failed to create task via API",e),`pending-error-${ue()}`}}async resolveChatName(e){try{we.info(`[CHANNEL] resolveChatName: chatType=${e.chatType}, senderId=${e.senderId}, channelId=${e.channelId}`);const t=this.adapters.get(e.channelId),n="p2p"===e.chatType?.toLowerCase();if(n){if(e.senderName)return e.senderName;if(e.senderId&&t?.getUserName){const n=await t.getUserName(e.senderId);if(we.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if(we.info(`[CHANNEL] resolveChatName: getChatName returned "${n}"`),n&&n!==e.chatId)return n}return!n&&e.senderName?e.senderName:e.senderId||e.chatId}catch(t){return we.warn(`[CHANNEL] Failed to resolve chat name for ${e.chatId}: ${t?.message||String(t)}`),e.senderName||e.senderId||e.chatId}}async fetchCompanionEncryptionKeys(){const e=this.readCompanionState();if(e)if(this.client.connected)try{const t=await this.client.sendWithAck("get-task-encryption-keys",{eventId:G(),taskId:e.chatId});"success"===t?.status&&t.dataEncryptionKey?(this.store.companionDataEncryptionKey=t.dataEncryptionKey,this.store.companionOwnerEncryptedDataKey=t.ownerEncryptedDataKey,this.saveState(),we.info("[CHANNEL] Fetched and stored companion encryption keys")):we.warn(`[CHANNEL] Failed to fetch encryption keys: ${t?.message||"unknown"}`)}catch(e){we.warn("[CHANNEL] Error fetching companion encryption keys",e)}else we.debug("[CHANNEL] Socket not connected, skipping encryption key fetch")}readCompanionState(){const e=T(xe.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return we.warn("[CHANNEL] Companion state.json not found"),null;try{const t=JSON.parse(c(e,"utf-8"));return t.userId&&t.agentId&&t.chatId&&t.machineId?{userId:t.userId,agentId:t.agentId,chatId:t.chatId,machineId:t.machineId}:(we.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return we.warn("[CHANNEL] Failed to read companion state.json",e),null}}handleAdapterState(e,t,n){this.loadState();const s=this.store.channels.find(t=>t.id===e);s&&(this.updateChannel(e,{connectionState:t,lastConnectedAt:"connected"===t?(new Date).toISOString():s.lastConnectedAt,lastDisconnectedAt:"disconnected"===t?(new Date).toISOString():s.lastDisconnectedAt,lastError:n?.message}),this.stopping||"disconnected"!==t&&"error"!==t||!s.enabled||this.scheduleReconnect(e))}scheduleReconnect(e){if(this.reconnectTimers.has(e))return;const t=setTimeout(()=>{this.reconnectTimers.delete(e),this.connectChannel(e).catch(t=>{we.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),we.info(`[CHANNEL] Scheduled reconnect: channel=${e}, delayMs=30000`)}clearReconnect(e){const t=this.reconnectTimers.get(e);t&&(clearTimeout(t),this.reconnectTimers.delete(e))}requireChannel(e){const t=this.store.channels.find(t=>t.id===e);if(!t)throw new Error(`Channel ${e} not found`);return t}updateChannel(e,t){const n=this.requireChannel(e);Object.assign(n,t,{updatedAt:(new Date).toISOString()}),this.saveState()}loadState(){try{if(!r(this.stateFilePath))return void(this.store={version:1,channels:[],bindings:[]});const e=JSON.parse(c(this.stateFilePath,"utf-8"));this.store=qi.parse(e)}catch(e){we.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=_(this.stateFilePath);r(e)||p(e,{recursive:!0}),u(this.stateFilePath,JSON.stringify(this.store,null,2),"utf-8")}redactCredentials(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,"string"==typeof t&&t.length>0?"********":t]))}}async function gr(){Object.assign(we,Ie({type:"daemon"}));const{requestShutdown:e,shutdownPromise:t}=function(){const{processType:e,onShutdownRequest:t}={processType:"daemon"},n=`[${e.toUpperCase()}]`;let s;const a=new Promise(e=>{s=(s,a)=>{we.info(`${n} Requesting shutdown (source: ${s}, errorMessage: ${a})`),t&&t(s,a),setTimeout(()=>process.exit(1),1e3),e({source:s,errorMessage:a})}}),i=e=>{process.on(e,()=>{s("os-signal")})};return i("SIGINT"),i("SIGTERM"),process.on("uncaughtException",e=>{we.info(`${n} FATAL: Uncaught exception`,e),we.info(`${n} Stack trace: ${e.stack}`),s("exception",e.message)}),process.on("unhandledRejection",e=>{we.info(`${n} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);we.info(`${n} Stack trace: ${t.stack}`),s("exception",t.message)}),process.on("exit",e=>{we.info(`${n} Process exiting with code: ${e}`)}),{requestShutdown:s,shutdownPromise:a}}();console.log("[DAEMON RUN] Starting daemon process..."),we.debug("[DAEMON RUN] Environment",ls()),await Jt()&&(console.log("Daemon already running..."),process.exit(0));let n=await xe.acquireDaemonLock(5,200);for(;!n;)await Qt(),n=await xe.acquireDaemonLock(5,200),n||(we.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{(function(){if(xe.disableCaffeinate)return we.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return we.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(es&&!es.killed)return we.debug("[caffeinate] Caffeinate already running"),!0;try{return es=Xe("caffeinate",["-im"],{stdio:"ignore",detached:!1}),es.on("error",e=>{we.debug("[caffeinate] Error starting caffeinate:",e),es=null}),es.on("exit",(e,t)=>{we.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),es=null}),we.info(`[caffeinate] Started with PID ${es.pid}`),function(){if(ss)return;ss=!0;const e=()=>{ns()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{we.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{we.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return we.info("[caffeinate] Failed to start caffeinate:",e),!1}})()&&we.debug("[DAEMON RUN] Sleep prevention enabled");const s=await nn();we.debug("[DAEMON RUN] Auth and machine setup complete");const a=new Go;await a.initialize(xe.getSandboxSettings());const i=new Ho(a);let o,r,c;i.setSocketClientProvider(()=>o?.client);const{port:l,host:p,webhookHost:d,stop:u}=await xo({getChildren:()=>i.getCurrentSessions(),stopSession:e=>i.stopSession(e),startDevOpsInit:e=>i.startDevOpsInit(e),completeDevOpsInit:e=>i.completeDevOpsInit(e),requestShutdown:()=>e("agentrix-cli"),registerSession:(e,t)=>i.registerTaskWorker(e,t),getSocketClient:()=>o?.client,credentials:s,get companionScheduler(){return r},get channelManager(){return c}});try{await us(),we.debug("[DAEMON RUN] Openers detected")}catch(e){we.warn("[DAEMON RUN] Failed to detect openers",e)}const m={pid:process.pid,port:l,host:p,webhookHost:d,startTime:(new Date).toLocaleString(),cliVersion:ke.version,logPath:Te({type:"daemon"})};xe.writeDaemonState(m),we.debug("[DAEMON RUN] Daemon state written");const h=new Zn({machineId:s.machineId,serverUrl:xe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:se(s.token,s.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:G(),machineId:s.machineId,timestamp:Date.now().toString(),controlPort:l})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>we.debug(`[DAEMON SOCKET] ${e}`,...t)},i,{requestShutdown:e}),g=new hr(h.client,s.machineId);c=g,i.setChannelManager(g),await h.connect(),o=h,we.info("[DAEMON RUN] Machine client connected to server");const f=new Bo(h.client,s.machineId);r=f,f.start(),await g.start(),h.setCompanionInteractionCallback(e=>{f.recordInteraction(e)});const v=new Fo(h.client,s.machineId);v.start(),h.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&f.setHeartbeatTaskId(e.taskId)});const y=async(e,t)=>{await g.stop(),f.stop(),v.stop(),await h.disconnect(),await u(),await a.shutdown(),await Yt(),await ns(),await xe.releaseDaemonLock(n),we.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};we.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const x=await t;await y(x.source,x.errorMessage)}catch(e){(function(e){return e instanceof Error&&e.message.includes("Machine binding revoked")})(e)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again.")),we.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",e),process.exit(1)}}const fr="\n\n[Tool result truncated to 1024 bytes]";function vr(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(fr,"utf8");return n>t?xr(fr,t):`${xr(e,t-n)}${fr}`}function yr(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function xr(e,t){let n="",s=0;for(const a of e){const e=Buffer.byteLength(a,"utf8");if(s+e>t)break;n+=a,s+=e}return n}const wr={senderType:"system",senderId:"system",senderName:"system"};class br{client;context;historyDb;getPermissionMode;outbox=new Map;usageOutbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new on(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir,logger:t.logger},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.initHandlers()}getPermissionModeSnapshot(){return this.getPermissionMode?.()??null}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Worker connection timeout after 10 seconds"))},1e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.client.disconnect()}sendTaskMessage(e,t,n){const s=G();return this.historyDb.saveMessage({eventId:s,message:t,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}),this.sendTaskEvent(e,t,n),s}sendWorkerInitializing(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd,...void 0!==e?.deployingAgent&&{deployingAgent:e.deployingAgent},...void 0!==e?.upgradingAgent&&{upgradingAgent:e.upgradingAgent}};this.client.send("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.client.send("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.client.send("worker-ready",n)}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.client.send("worker-running",n)}sendPermissionMode(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.client.send("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:G(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.client.send("worker-exit",t)}async sendErrorMessageAndExit(e){await this.sendTerminalErrorResultAndWait(e),this.sendWorkerExit("error"),await this.disconnect()}async sendTerminalErrorResultAndWait(e,t){const n=this.sendTerminalErrorResult(e,t);await this.waitForEventAcks(n,2e3)}sendTerminalErrorResult(e,t){const n=this.sendSystemErrorMessage(e,t),s=this.sendTaskEvent(wr,function(e){return{type:"result",subtype:"error_during_execution",duration_ms:0,duration_api_ms:0,is_error:!0,num_turns:0,stop_reason:null,total_cost_usd:0,usage:{input_tokens:0,output_tokens:0,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:0,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"},modelUsage:{},permission_denials:[],errors:[e],uuid:crypto.randomUUID(),session_id:""}}(e),{groupId:t?.groupId});return[n,s]}sendSystemErrorMessage(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:`System Error\n\n${e}`,metadata:{messageType:"system_error"}}]}};return this.sendTaskEvent(wr,n,{groupId:t?.groupId})}sendAssistantMessage(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:e}]}};this.sendTaskEvent(wr,n,{groupId:t?.groupId})}sendAskUser(e,t,n){return this.sendTaskMessage(e,{type:"ask_user",questions:t},{groupId:n?.groupId})}sendAskUserResponse(e,t){return this.sendTaskMessage(wr,t,{opCode:e})}sendTaskEvent(e,t,n){const s=function(e,t=1024){const n=e,s=n?.message?.content;if(!Array.isArray(s))return e;let a=!1;const i=s.map(e=>{if("tool_result"!==e?.type||!("content"in e))return e;const n=function(e,t=1024){if("string"==typeof e)return vr(e,t);const n=yr(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?vr(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:yr(e);var t}).join("\n"),t):vr(n,t)}(e.content,t);return n===e.content?e:(a=!0,{...e,content:n})});return a?{...n,message:{...n.message,content:i}}:e}(t),{eventId:a,opCode:i,artifacts:o,navigateToTaskId:r}=n||{},c=a??G(),l={eventId:c,taskId:this.context.taskId,chatId:this.context.chatId,from:"worker",messageType:s.type,message:s,encryptedMessage:void 0,opCode:i,groupId:n?.groupId,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName,artifacts:o,navigateToTaskId:r};this.historyDb.saveTaskEvent({eventType:"task-message",eventId:c,eventData:l,taskId:this.context.taskId,chatId:this.context.chatId,sequence:"number"==typeof l.sequence?l.sequence:null});const p=this.buildTaskUsageReport(s,c);if(this.context.dataEncryptionKey){const e=ne(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,l),p&&(this.usageOutbox.set(c,p),this.client.send("task-usage-report",p)),this.client.send("task-message",l),c}waitForEventAcks(e,t){const n=e.filter(e=>this.outbox.has(e));return 0===n.length?Promise.resolve():new Promise(e=>{let s=n.length;const a=t=>{this.ackWaiters.delete(t),s-=1,s<=0&&(clearTimeout(i),e())},i=setTimeout(()=>{for(const e of n)this.ackWaiters.delete(e);e()},t);for(const e of n)this.ackWaiters.set(e,()=>a(e))})}buildTaskUsageReport(e,t){if("result"!==e.type)return null;const n=e.modelUsage;if(!n||"object"!=typeof n)return null;const s={};for(const[e,t]of Object.entries(n)){if(!e||!t||"object"!=typeof t)continue;const n=t,a={inputTokens:this.normalizeUsageCount(n.inputTokens),outputTokens:this.normalizeUsageCount(n.outputTokens),cacheReadInputTokens:this.normalizeUsageCount(n.cacheReadInputTokens),cacheCreationInputTokens:this.normalizeUsageCount(n.cacheCreationInputTokens),webSearchRequests:this.normalizeUsageCount(n.webSearchRequests)};Object.values(a).some(e=>e>0)&&(s[e]=a)}return 0===Object.keys(s).length?null:{eventId:G(),taskId:this.context.taskId,resultEventId:t,modelUsage:s}}normalizeUsageCount(e){return"number"!=typeof e||!Number.isFinite(e)||e<=0?0:Math.trunc(e)}sendUpdateTaskAgentSessionId(e){const t={eventId:G(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.client.send("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:G(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.client.send("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:G(),taskId:this.context.taskId,title:e};this.client.send("change-task-title",t),we.info(`[AGENT] Title changed to: ${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:G(),taskId:this.context.taskId,agentId:e,...t};this.client.send("update-agent-info",n),we.info(`[AGENT] Agent info updated: ${JSON.stringify(t)}`)}sendResetTaskSession(){const e={eventId:G(),taskId:this.context.taskId};this.client.send("reset-task-session",e),we.info(`[AGENT] Session reset requested for task ${this.context.taskId}`)}async sendMergeRequest(e,t){const n={eventId:G(),taskId:this.context.taskId,summary:e,description:t};we.info(`[MERGE] Sending merge-request event for task ${this.context.taskId}`);const s=await this.client.sendWithAck("merge-request",n);if(!s.success)throw new Error(`Failed to create pull request: ${s.error||"Unknown error"}`);return we.info(`[MERGE] Pull request created: #${s.data.pullRequestNumber}`),{pullRequestNumber:s.data.pullRequestNumber,pullRequestUrl:s.data.pullRequestUrl}}async sendMergePr(){const e={eventId:G(),taskId:this.context.taskId,mergeMethod:"squash"};return we.info(`[MERGE-PR] Sending merge-pr event for task ${this.context.taskId}`),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:G(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};we.info(`[REPO] Sending repository association request: ${e}/${t}/${n}`),this.client.send("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:G(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},{"cancel-task":async e=>{e.taskId===t.taskId&&(we.info(`[WORKER] Task ${t.taskId} cancelled`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&(we.info(`[WORKER] Task ${t.taskId} stopped: ${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;let a=e.message??null;if(!a&&e.encryptedMessage&&t.dataEncryptionKey&&(a=Y(e.encryptedMessage,t.dataEncryptionKey)??null),!a)return;e.channelReplyTarget&&"object"==typeof a&&(a.__channelReplyTarget=e.channelReplyTarget);const i={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&Q(a)&&(a=await Co(a,{attachmentsDir:t.attachmentsDir,log:t.logger})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(a,i))return void we.debug(`[WORKER] Dropping incoming task-message before persistence: eventId=${e.eventId}`);if(!n.saveMessage({eventId:e.eventId,message:a,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return we.debug(`[WORKER] Ignoring duplicate incoming task-message: eventId=${e.eventId}`),void s(e.eventId);const o={...e,message:a,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:o,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(a,i)},"task-info-update":async e=>{e.taskId===t.taskId&&t.onTaskInfoUpdate&&await t.onTaskInfoUpdate(e)},"worker-status-request":async e=>{e.taskId===t.taskId&&t.onWorkerStatusRequest&&await t.onWorkerStatusRequest(e)},"sub-task-result-updated":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskResultUpdated&&await t.onSubTaskResultUpdated(e)},"sub-task-ask-user":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskAskUser&&await t.onSubTaskAskUser(e)}});var t,n,s;this.client.onEvent("cancel-task",e["cancel-task"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEvent("task-message",e["task-message"]),this.client.onEvent("task-info-update",e["task-info-update"]),this.client.onEvent("worker-status-request",e["worker-status-request"]),this.client.onEvent("sub-task-result-updated",e["sub-task-result-updated"]),this.client.onEvent("sub-task-ask-user",e["sub-task-ask-user"]),this.client.onEvent("event-ack",e=>{const t=e.data?.sequence;void 0!==e.opCode&&(this.outbox.delete(e.opCode),this.usageOutbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.()),void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(this.outbox.size>0){we.info(`[WORKER] Reconnected — flushing ${this.outbox.size} outbox message(s)`);for(const[e,t]of this.outbox.entries()){const n=this.usageOutbox.get(e);n&&this.client.send("task-usage-report",n),this.client.send("task-message",t)}}}else this.hasConnectedOnce=!0})}}const kr=ht(ct),Ir="xmz-ai",Tr="agentrix-hive",Sr="https://github.com/xmz-ai/agentrix-hive.git",Er="github";class Ar{logger;socketClient;taskId;userId;chatId;rootTaskId;parentTaskId;workingDirectory;taskAgents;serverUrl;taskDataKey;agentHomeDir;constructor(e){this.logger=e.logger,this.socketClient=e.socketClient,this.taskId=e.taskId,this.userId=e.userId,this.chatId=e.chatId,this.rootTaskId=e.rootTaskId,this.parentTaskId=e.parentTaskId,this.workingDirectory=e.workingDirectory,this.agentHomeDir=e.agentHomeDir,this.taskAgents=e.taskAgents,this.serverUrl=e.serverUrl,this.taskDataKey=e.taskDataKey}async call(e,t,n){const s=G();try{const a=await this.socketClient.sendWithAck("rpc-call",{eventId:s,taskId:this.taskId,method:e,path:t,query:n?.query,body:n?.body});if(!a.success){const n=a.error||{code:"unknown",message:"Unknown error"};throw new Error(`RPC ${e} ${t} failed: ${n.message} (${n.code})`)}return a.data}catch(n){throw new Error(`RPC ${e} ${t} error: ${n.message}`)}}log(e){this.logger.info(e)}getWorkspace(){return this.workingDirectory}getAgentHomeDir(){return this.agentHomeDir}getUserId(){return this.userId}getTaskId(){return this.taskId}getChatId(){return this.chatId}getRootTaskId(){return this.rootTaskId}getParentTaskId(){return this.parentTaskId}getTaskAgents(){return this.taskAgents}async createDraftAgent(e){return this.call("POST","/v1/draft-agent",{body:{...e,userId:this.userId,taskId:this.taskId}})}async updateDraftAgent(e,t){return this.call("PATCH",`/v1/draft-agent/${e}`,{body:t})}async startSubTask(e){const t={userId:this.userId,chatId:this.chatId,agentId:e.agentId,parentTaskId:this.taskId,customTitle:e.title,cwd:e.cwd,forceUserCwd:e.forceUserCwd};return this.taskDataKey?t.encryptedMessage=ne(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async startIndependentTask(e){const t={userId:this.userId,chatId:this.chatId,agentId:e.agentId,sourceTaskId:this.taskId,customTitle:e.title,cwd:e.cwd,forceUserCwd:e.forceUserCwd,autoNavigate:e.autoNavigate};return this.taskDataKey?t.encryptedMessage=ne(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async startGroupTask(e){const t={userId:this.userId,chatId:e.chatId??this.chatId,parentTaskId:this.taskId,customTitle:e.title,todos:e.todos};return this.taskDataKey?t.encryptedMessage=ne(e.message,this.taskDataKey):t.message=e.message,{taskId:(await this.call("POST","/v1/tasks/start",{body:t})).taskId}}async createGroupChat(e){return this.call("POST","/v1/agent-group-chats",{body:{agentIds:e}})}async sendMessage(e){await this.call("POST",`/v1/tasks/${e.taskId}/send-message`,{body:{message:e.message,target:e.target,fromTaskId:this.taskId,senderType:"agent",senderId:this.taskId,senderName:"agent"}})}async showModal(e){await this.call("POST",`/v1/tasks/${e.taskId}/show-modal`,{body:{modalName:e.modalName,modalData:e.modalData}})}async getTaskSession(e){return this.call("GET",`/v1/tasks/${e}/session`)}async findSubTaskByAgent(e){const t=await this.call("GET","/v1/tasks/find-by-agent",{query:{parentTaskId:this.taskId,agentId:e}});return t.taskId?{taskId:t.taskId}:null}async listSubTasks(){return(await this.call("GET","/v1/tasks/sub-tasks",{query:{parentTaskId:this.taskId}})).tasks}async listTasks(e){return(await this.call("GET","/v1/tasks/recent",{query:{chatId:this.chatId,...e?.limit&&{limit:e.limit},...e?.status&&{status:e.status}}})).tasks}async prepareHiveRepository(){const e=await async function(){const e=xe.resolveRepoStoreCheckoutDir(Er,Ir,Tr),t=xe.resolveRepoStoreLockPath(Er,Ir,Tr),n=await xe.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await xa(e)){if(!$a(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await Sa(Sr,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await La(e,"origin",qa(Sr));try{return await kr("git",["pull","--ff-only"],{cwd:e}),{path:e,pullSucceeded:!0}}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}}finally{await xe.releaseFileLock(t,n)}}();return e.pullSucceeded||this.logger.warn(`[Agent-Context] Hive repository update failed; continuing when local copy is usable: ${e.error}`),e}async recordHiveInstall(e,t){return this.call("POST",`/v1/hive/listings/${e}/record-install`,{body:t})}async installHiveListing(e,t){return this.call("POST",`/v1/hive/listings/${e}/install`,{body:t})}async publishToHive(e){return this.call("POST","/v1/hive/publish",{body:e})}async updateHiveListingVersion(e,t){return this.call("POST",`/v1/hive/listings/${e}/update-version`,{body:t})}async createHiveReview(e,t){return this.call("POST",`/v1/hive/listings/${e}/reviews`,{body:t})}async createHiveComment(e,t){return this.call("POST",`/v1/hive/listings/${e}/comments`,{body:t})}async listAgents(){return this.call("GET","/v1/user-agents")}async uploadFile(e){this.logger.info("[Agent-Context] Uploading file...");const t=await Ae.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||wn.lookup(e.name)||"application/octet-stream",a=(await this.call("POST","/v1/files/upload-urls",{body:{count:1}})).files[0],i=a.url;this.logger.info(`[Agent-Context] FileUploadUrl: ${i}`);const o=await Ae.promises.readFile(e.path),r=await fetch(i,{method:"PUT",headers:{"Content-Type":s},body:o});if(!r.ok)throw new Error(`Failed to upload file to S3: ${r.status} ${r.statusText}`);let c;return await this.call("POST","/v1/files/confirm-upload",{body:{fileId:a.id,name:e.name,size:n,contentType:s,visibility:e.visibility||"private"}}),c="public"===e.visibility?`${this.serverUrl}/v1/files/public/${a.id}`:i.split("?")[0],{fileId:a.id,name:e.name,size:n,contentType:s,url:c}}}function Cr(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=Y(e.encryptedResultMessage,t);s&&"result"===s.type&&(n={type:"result",result:"result"in s?s.result:"",is_error:s.is_error})}const s={...e,resultMessage:n};let a=`<sub-task-result-updated>\n${JSON.stringify(s,null,2)}\n</sub-task-result-updated>`;return a+=n.result.trim().length>0?'\n<system-reminder>The result is already shown to user as a card. Just acknowledge briefly (e.g., "Done!"). Only elaborate if error or needs user action.</system-reminder>':"\n<system-reminder>The sub-task result was empty. You can use reply_to_sub_task to ask it to continue, retry, or resend the result.</system-reminder>",{type:"user",message:{role:"user",content:a}}}function _r(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=Y(e.encryptedMessage,t);s&&"ask_user"===s.type&&(n=s)}return{type:"user",message:{role:"user",content:`<sub-task-ask-user>\n${JSON.stringify({taskId:e.taskId,agentId:e.agentId,agentName:e.agentName,taskName:e.taskName,questions:n?.questions??[]},null,2)}\n</sub-task-ask-user>\n<system-reminder>A sub-task agent is asking the user questions. You should answer these questions on behalf of the user based on the task context and instructions. Use the reply_to_sub_task tool to send your answers back.</system-reminder>`}}}function $r(){const e=new Set;return{filter(t){const n=t;if(!n.message||!n.message.content||"string"==typeof n.message.content)return t;const s=n.message.content.filter(t=>!("tool_result"===t.type&&e.has(t.tool_use_id)||"user"===n.type&&"tool_result"!==t.type));return 0===s.length?null:(n.message.content=s,n)},clear(){e.clear()}}}function Pr({workClient:e}){return ut("change_title","Change the session title to better describe what you are working on.\n\n## When to Use\n- Call it at the start of a session to set a descriptive title\n- Call it again when the title becomes outdated or too generic\n\nGood titles help users find conversations later.",{title:tt.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function Mr(e){return ut("publish_task_preview_url","Publish the frontend preview URL for the current Agentrix task.\n\nUse this on a local machine when the user provided a service startup port or relevant startup documentation for a frontend app, and you have started or reused the local environment after completing the task.\nThe URL is recorded on the current task only. It must be an absolute http or https URL; localhost URLs are allowed.",{previewUrl:tt.string().describe("Absolute http(s) URL for the current task preview, such as http://localhost:5173")},async t=>(await async function(e,t){const n=X.parse({previewUrl:t}),s=await fetch(`${xe.serverUrl}/v1/tasks/${encodeURIComponent(e.taskId)}/preview-url`,{method:"PUT",headers:{Authorization:`Bearer ${e.credentials.token}`,"Content-Type":"application/json","X-Agentrix-Task":e.taskId},body:JSON.stringify(n)});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`Failed to publish task preview URL (${s.status}): ${e||s.statusText}`)}}(e,t.previewUrl),{content:[{type:"text",text:`Task preview URL published: ${t.previewUrl.trim()}`}]}))}function Rr({agentContext:e,log:t}){return ut("emit_to_task","Send a message to a sub-task. Use this to:\n1. Answer a sub-task's ask_user questions: set answers array (one answer per question).\n2. Send follow-up instructions: set instructions only (no answers).",{taskId:tt.string().describe("Sub-task ID to send the message to"),instructions:tt.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:tt.array(tt.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async n=>{try{let t;return t=n.answers&&n.answers.length>0?{type:"ask_user_response",answers:n.answers}:{type:"user",message:{role:"user",content:n.instructions??""}},await e.sendMessage({taskId:n.taskId,message:t,target:"agent"}),{content:[{type:"text",text:`${n.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${n.taskId}.`}]}}catch(e){return t("error","TASK",`Failed to send message to sub-task ${n.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Nr({historyDb:e}){return ut("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:tt.number().int().min(0).optional().describe("Pagination cursor for older history. Omit this field, or pass 0, to read the latest messages. Only pass a positive sequence value that was returned by the previous result as “Use sequence=N to load earlier messages”; it means return messages before that local sequence, not start at that position."),limit:tt.number().int().min(1).max(50).default(20).describe("Maximum number of messages to return.")},async t=>{const n=t.limit??20,s=null!=t.sequence&&t.sequence>0,a=s?e.pageMessagesBefore(t.sequence,n):e.pageRecentMessages(n);if(0===a.data.length)return{content:[{type:"text",text:s?"No earlier messages found.":"No task history messages found."}]};let i=pr(a.data);return a.hasMore&&(i+=`\n\nMore messages available. Use sequence=${Math.min(...a.data.map(e=>e.localSequence))} to load earlier messages.`),{content:[{type:"text",text:i}]}})}function Dr({agentContext:e}){return ut("get_task_agents","List the agents available for the current task and return taskAgents info.",{},async()=>{const t=e.getTaskAgents();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No task agents available."}]}})}function Or({agentContext:e,log:t}){return ut("list_sub_task","List direct sub tasks for the current task with taskId, title, and cwd.",{},async()=>{try{const t=await e.listSubTasks();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No sub tasks found."}]}}catch(e){return t("error","TASK","Failed to list sub tasks:",e),{content:[{type:"text",text:`Failed to list sub tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Ur({agentContext:e,agentId:t,log:n,setPendingNavigateTaskId:s}){return ut("create_task","Delegate a task to an agent for execution.\n\n**Modes**:\n- Sub-task (default): Creates under current task, linked via parentTaskId.\n- Independent (independent=true): Creates a top-level task with no parent binding. Optionally set autoNavigate=true to auto-switch the user's App UI to the new task.\n\nIf agentId is provided, delegates to that specific agent. Otherwise, creates a task for yourself.\nAlways provide a concise task title in \"title\".\nThe task runs asynchronously - you'll be notified when complete via <sub-task-result-updated> message.\nUse for: multi-step implementations, analysis, code reviews, or any work that takes >30 seconds.\nAfter calling this tool, continue responding to user - don't wait for task completion.",{agentId:tt.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:tt.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:tt.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:tt.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:tt.string().optional().describe("Working directory for the task. Pass your current cwd when the sub-task needs to read/write the same project files as you. If omitted, a new isolated workspace is created (scoped by taskId)."),useWorktree:tt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:tt.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:tt.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async a=>{try{if(a.autoNavigate&&!a.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const i=a.agentId||t;let o;return a.independent?(o=await e.startIndependentTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,autoNavigate:a.autoNavigate}),a.autoNavigate&&s(o.taskId),n("info","TASK",`Created independent task ${o.taskId} for agent ${i} (autoNavigate: ${a.autoNavigate??!1})`)):(o=await e.startSubTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree}),n("info","TASK",`Created sub-task ${o.taskId} for agent ${i}`)),{content:[{type:"text",text:`🚀 Task created: ${o.taskId}\n${a.agentId?`Agent: ${i}\n`:""}${a.independent?"Mode: Independent\n":""}Summary: ${a.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return n("error","TASK","Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function jr({agentContext:e,log:t}){return ut("create_solo_task","Create a single-agent async task in group chat.\n\n## When to Use (sparingly)\n- Long-running background work (>5 minutes)\n- Work that needs separate tracking/progress monitoring\n- Complex multi-step projects with explicit deliverables\n\n## Prefer invoke Instead\nFor most requests, use `invoke` - it's simpler and the agent responds directly in chat.\nOnly use this tool when background tracking is truly needed.\n\nAfter creating: You'll receive <sub-task-result-updated> when task completes.",{title:tt.string().min(1).max(200).describe("Task title"),instructions:tt.string().describe("Instructions for the owner agent"),briefSummary:tt.string().optional().describe("One-line summary shown to user immediately"),agentId:tt.string().describe("Target agent ID"),cwd:tt.string().optional().describe("Working directory for the sub-task. Pass your current cwd when the sub-task needs to read/write the same project files as you. If omitted, a new isolated workspace is created (scoped by sub-task taskId)."),useWorktree:tt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:n.agentId,message:{type:"user",message:{role:"user",content:n.instructions}},title:n.title,cwd:n.cwd,forceUserCwd:!n.useWorktree})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","TASK","Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function qr({agentContext:e,log:t,agentId:n}){return ut("create_group_task","Create a multi-agent async task plan in group chat.\n\n## When to Use (sparingly)\n- Long-running background work requiring multiple agents (>5 minutes)\n- Complex multi-step projects with explicit deliverables\n- Work that needs separate tracking/progress monitoring\n\n## Prefer invoke Instead\nFor most requests, use `invoke` - it's simpler and agents respond directly in chat.\nOnly use this tool when background tracking with multiple agents is truly needed.\n\nThe planner becomes the task owner; todos are embedded in the task.\nAfter creating: You'll receive <sub-task-result-updated> when task completes.",{title:tt.string().min(1).max(200).describe("Task title"),requirement:tt.string().describe("Overall requirement"),briefSummary:tt.string().optional().describe("One-line summary shown to user immediately"),todos:tt.array(tt.object({agentId:tt.string().describe("Agent ID responsible for the todo"),title:tt.string().min(1).max(200).describe("Todo title"),instructions:tt.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:n.title,todos:n.todos,message:{type:"user",message:{role:"user",content:n.requirement}}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","DISPATCH","Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Lr({askUser:e,log:t}){return ut("ask_user",'Ask the user questions when you need clarification or user input. Supports 1-4 questions with 2-4 options each. Use this when you need user decisions or additional information. An "Other" option with free text input is automatically added.',{questions:tt.array(tt.object({question:tt.string().describe("The complete question to ask the user"),header:tt.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:tt.boolean().describe("Set to true to allow multiple option selections"),options:tt.array(tt.object({label:tt.string().describe("Option label (1-5 words)"),description:tt.string().describe("Explanation of what this option means")})).min(2).max(4).describe("Available choices (2-4 options)")})).min(1).max(4).describe("Questions to ask (1-4 questions)")},async n=>{try{const t=n.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(t);return"answered"!==(s.status??"answered")?{content:[{type:"text",text:"The user did not provide an answer within the expected time. \n<system-reminder>Please abort the session, and decide whether to retry when the user provides a new message later.</system-reminder>"}],isError:!0}:{content:[{type:"text",text:`User answers:\n${s.answers.map(e=>e.startsWith("other:")?`Other: "${e.slice(6)}"`:e).join("\n")}`}]}}catch(e){return t("error","ASK_USER","Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function Hr({invokeAgent:e}){return ut("invoke",'Let an agent respond to the conversation (talk).\n\n**Use for**: Q&A, explanations, opinions, discussions, debates.\n**Do NOT use for**: Work producing files/code → use assign instead.\n\n**hint parameter**: Optional. Use to reduce agent\'s attention cost or provide meta-context:\n- ✅ Role assignment: hint="You argue FOR REST" (first turn of debate)\n- ✅ Focus guidance: hint="Focus on security aspects"\n- ✅ Long/busy chat: hint="Respond to Alice\'s caching question"\n- ✅ Multi-topic: hint="Re: the API design discussion"\n- ❌ Short, clear context: agent can easily find what to respond to\n\nAgent sees hint (if provided) + conversation history and responds in chat.',{agentId:tt.string().describe("Target agent ID"),hint:tt.string().optional().describe("Optional context/instruction for the agent")},async t=>(e(t.agentId,t.hint),{content:[{type:"text",text:`Invoked ${t.agentId}. The agent will respond in the chat later.`}]}))}function Gr({workClient:e,agentId:t,uploadFile:n,log:s}){return ut("update_agent_info","Update your display name, avatar, and signature in the platform.\nCall this after onboarding when the user has chosen your name and emoji/image.\nThis syncs your identity to the platform so the App displays your chosen name and avatar.\n\nFor avatar: provide a local image file path. The image will be uploaded to the platform.\nFor signature: a short status line or tagline shown under your name.",{displayName:tt.string().optional().describe("Your display name"),avatarPath:tt.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:tt.string().optional().describe("Short status line or tagline shown under your name")},async a=>{let i;if(a.avatarPath)try{i=(await n({name:"avatar.png",path:a.avatarPath,visibility:"public"})).fileId}catch(e){return s("error","TOOL","Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:a.displayName,avatar:i,signature:a.signature});const o=[];return a.displayName&&o.push(`name → ${a.displayName}`),i&&o.push("avatar → uploaded"),a.signature&&o.push(`signature → ${a.signature}`),{content:[{type:"text",text:`Profile updated: ${o.join(", ")}`}]}})}function Br({assign:e,log:t}){return ut("assign","Assign work to an agent (do the work).\n\n**Use for**: Code, files, reports, artifacts (agent produces output).\n**Do NOT use for**: Q&A, explanations → use invoke instead.\n\nProgress streams to chat in real-time.",{agentId:tt.string().describe("Target agent ID"),instruction:tt.string().describe("Task instruction for the agent"),acknowledgment:tt.string().optional().describe('Agent\'s quick reply shown immediately (e.g., "starting now", "On it")')},async t=>(e(t.agentId,t.instruction,t.acknowledgment),{content:[{type:"text",text:`Assigned work to ${t.agentId}.`}]}))}function Fr({agentContext:e,log:t}){return ut("list_tasks","List recent tasks in the current chat.\nUse this to review what tasks have been running, completed, or are still active.\nReturns a lightweight summary of each task (id, title, state, agent, duration, timestamps).",{limit:tt.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:tt.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async n=>{try{const t=await e.listTasks({limit:n.limit??10,status:n.status??"all"});return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return t("error","TASK","Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Wr({chatHistoryDb:e}){return ut("read_conversation","Read messages from the main conversation between you and the user. Omit before to read the latest messages; only pass before when paginating to older messages.",{limit:tt.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:tt.number().int().min(0).optional().describe("Pagination cursor for older conversation history. Omit this field, or pass 0, to read the latest messages. Only pass a positive before value that was returned by the previous result as “Use before=N to load earlier messages”; it means return messages before that sequence, not start at that position.")},async t=>{if(!e)return{content:[{type:"text",text:"Chat history not available in this mode."}],isError:!0};const n=t.limit??50,s=null!=t.before&&t.before>0?e.pageMessagesBefore(t.before,n):e.pageRecentMessages(n);if(0===s.data.length)return{content:[{type:"text",text:"No conversation messages found."}]};let a=pr(s.data);return s.hasMore&&(a+=`\n\nMore messages available. Use before=${Math.min(...s.data.map(e=>e.localSequence))} to load earlier messages.`),{content:[{type:"text",text:a}]}})}function zr({agentContext:e,log:t}){return ut("send_reminder","Send an internal reminder to your main self (本体) in the primary chat.\nThis is for companion shadow (heartbeat task) use only.\n\nThe reminder is invisible to the user — it only wakes up the main companion worker.\nThe main companion will see the reminder in its conversation context and decide how to act.\n\nKeep content concise (one sentence). For detailed analysis, write to a file and pass filePath.",{content:tt.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:tt.string().optional().describe("Path to detailed analysis file in workspace, if any")},async n=>{try{const t=e.getChatId();return await e.sendMessage({taskId:t,message:{type:"companion_reminder",content:n.content,filePath:n.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return t("error","COMPANION","Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Kr({uploadFile:e,log:n}){return ut("upload_file","Upload a local file to the platform and get a public URL.\nUse this to share images, documents, or other files with the user.\nReturns a public URL that can be embedded in markdown (e.g., ).",{filePath:tt.string().describe("Absolute path to the local file to upload"),name:tt.string().optional().describe("Display name for the file (defaults to filename)")},async s=>{try{const n=t("path"),a=s.name||n.basename(s.filePath);return{content:[{type:"text",text:(await e({name:a,path:s.filePath,visibility:"public"})).url}]}}catch(e){return n("error","TOOL","File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const Vr=2147483648,Xr=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function Jr({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a,log:i}){return ut("send_channel_message","Send a user-facing message back to the external channel that started this task.\n\nFor channel-bound tasks, normal successful final results are NOT automatically forwarded to the external channel after this tool has been used. You MUST call this tool for anything the external user should see. Before ending the task, ensure the external user has received an appropriate message through this tool. If you end without calling it, the user may see no model-directed response; that is considered a failed channel interaction even if the internal task result is complete.\n\nUse this for user-facing conversational output: acknowledgements, progress updates for long work, questions/choices/permission requests, clear failures or limitations, final answers, and user-facing deliverable notes.\n\nMessages should feel like natural conversation: short, clear, useful. Do not send internal reasoning, verbose logs, stack traces, debug dumps, internal-only summaries, temporary paths, environment variables, tokens, secrets, or private data. Avoid excessive implementation detail unless the user is explicitly collaborating technically and needs it.\n\nAttachments are part of this channel message. Attach only deliverables the user is meant to consume, save, view, or forward: generated images, PDFs, spreadsheets, reports, slide decks, archives, audio/video, or requested exports/packages.\n\nDo NOT send files merely because they were created, edited, read, downloaded, or used. A file created or modified while completing work is not automatically a deliverable; decide based on user intent. Do not decide based on file location or directory: a file inside the workspace can be a deliverable, and a file outside the workspace can still be unsafe or inappropriate. Logs, caches, temporary files, build artifacts, intermediate screenshots, debug outputs, and internal workflow files should not be sent unless the user explicitly asked for them. When modifying files, summarize changes in text unless the user asked to receive, export, package, or forward those files. Never send files containing secrets, credentials, tokens, private data, or local environment details. If the deliverable status is uncertain or sending might expose unintended content, ask for confirmation with this tool first.\n\nThe tool automatically sends to the original channel/chat for this task. Do not provide channel IDs or chat IDs.",{content:tt.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:tt.array(tt.object({filePath:tt.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:tt.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:tt.enum(["auto","image","file","audio","video"]).optional().describe("Attachment kind. Use auto unless you know the exact type.")})).optional().describe("Optional user-facing deliverable files to send with the message.")},async o=>{const r=s?.()??null;if(!r)return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel, so no channel message can be sent."}],isError:!0};a?.();try{const s=o.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await Qr(n));return t}(o.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const i=await Vt(e,{content:s||void 0,attachments:a.length>0?a:void 0},r);return i?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:i.error}}),{content:[{type:"text",text:`Failed to send channel message: ${i.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,mimeType:e.mimeType,kind:e.kind}))}}),{content:[{type:"text",text:a.length>0?`Sent channel message with ${a.length} attachment(s).`:"Sent channel message."}]})}catch(e){return i("warn","CHANNEL","Channel message send rejected or failed:",e),{content:[{type:"text",text:`Failed to send channel message: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Yr({taskId:e,getChannelReplyTarget:t}){return ut("get_channel_group_history","Read older saved history for the external group chat bound to this task.\n\nUse this only when the automatically injected recent group history is not enough to understand context. This tool is read-only and automatically reads the current external channel group; do not provide channel IDs or chat IDs.\n\nThe result is XML-style history with sender metadata. Use it to understand context/history.",{limit:tt.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:tt.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:tt.number().int().nonnegative().optional().describe("Return messages after this local sequence number for newer pages. Do not combine with beforeSeq.")},async n=>{const s=t?.()??null;if(!s||"group"!==s.chatType?.toLowerCase())return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel group chat."}],isError:!0};if(void 0!==n.beforeSeq&&void 0!==n.afterSeq)return{content:[{type:"text",text:"Use beforeSeq or afterSeq, not both."}],isError:!0};const a=await async function(e,t,n={}){return await Ft("/channels/group-history",{taskId:e,target:t,...n})}(e,s,{limit:n.limit,beforeSeq:n.beforeSeq,afterSeq:n.afterSeq});return a?.error?{content:[{type:"text",text:`Failed to read channel group history: ${a.error}`}],isError:!0}:{content:[{type:"text",text:`${[`hasMoreBefore=${Boolean(a.hasMoreBefore)}`,`hasMoreAfter=${Boolean(a.hasMoreAfter)}`].join(" ")}\n\n${a.historyXml??"<external_group_history />"}`}]}})}async function Qr(e){if(!P(e.filePath))throw new Error("filePath must be absolute");const t=await Rt(e.filePath).catch(e=>{throw new Error(`filePath does not exist or cannot be read: ${e instanceof Error?e.message:String(e)}`)});if(!t.isFile())throw new Error("filePath must point to a regular file");if(t.size<=0)throw new Error("file is empty");if(t.size>Vr)throw new Error(`file is too large for channel delivery (${t.size} bytes; max 2147483648 bytes)`);const n=e.fileName||S(e.filePath),s=S(e.filePath);if(Xr.test(s)||Xr.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=wn.lookup(n)||wn.lookup(e.filePath)||"application/octet-stream",i="string"==typeof a?a:"application/octet-stream",o=e.kind||"auto";return{filePath:e.filePath,fileName:e.fileName,kind:o,mimeType:i}}function Zr({agentContext:e,log:t}){return ut("list_agents","List all available agents for the current user, including system agents and user-created agents (both published and draft).",{},async()=>{try{const{agents:t,draftAgents:n}=await e.listAgents(),s=e=>`- **${e.displayName||e.name}** (${e.id})\n Type: ${e.type}\n`+(e.developerName?` Developer: ${e.developerName}\n`:"")+` ${e.description||"No description"}\n`;let a="# Available Agents\n\n";return t.length>0&&(a+="## Published Agents\n\n",a+=t.map(s).join("\n")),n.length>0&&(a+="\n## Draft Agents\n\n",a+=n.map(s).join("\n")),0===t.length&&0===n.length&&(a+="No agents available."),{content:[{type:"text",text:a}]}}catch(e){return t("error","AGENTS","Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*ec(e){yield e}function tc({visionModel:e,log:t}){return ut("analyze_image","Analyze a local image file and return a description of its contents.\nUse this tool when you need to understand the content of an image file on the local filesystem.\nThe primary model does not support vision, so this tool delegates to a vision-capable model.",{imagePath:tt.string().describe("Absolute path to the image file to analyze"),prompt:tt.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async n=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const t=(await Mt(n.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[n.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=n.prompt||"Describe this image in detail.",i=dt({prompt:ec({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:t}},{type:"text",text:a}]},parent_tool_use_id:null,session_id:""}),options:{model:e,permissionMode:"bypassPermissions",maxTurns:1,tools:[]}});let o="";for await(const e of i)if("result"===e.type){o=e.result??"";break}return{content:[{type:"text",text:o||"No description returned."}]}}catch(e){return t("error","VISION","Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function nc({log:e}){return ut("schedule_task",'Create, list, or delete scheduled tasks (reminders and recurring jobs).\nTasks are managed by the daemon scheduler and fire as reminders to the main companion.\n\nUse action "create" to schedule a new task:\n- For one-time tasks: provide "due" (ISO 8601 timestamp)\n- For recurring tasks: provide "cron" (standard 5-field cron expression)\n- Set timeType to "utc" if the time is in UTC, or "local" (default) if in the user\'s timezone\n\nUse action "list" to see all scheduled tasks.\nUse action "delete" with an "id" to remove a task.',{action:tt.enum(["create","list","delete"]).describe("Operation to perform"),task:tt.string().optional().describe("Task description (required for create)"),type:tt.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:tt.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:tt.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:tt.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:tt.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:tt.string().optional().describe("Task ID (required for delete)")},async t=>{try{const e=await xe.readDaemonState();if(!e?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${e.port}`;if("list"===t.action){const e=await fetch(`${n}/schedule`),t=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${t.error}`}],isError:!0};const s=t.tasks??[];return 0===s.length?{content:[{type:"text",text:"No scheduled tasks."}]}:{content:[{type:"text",text:s.map(e=>`- [${e.id}] ${"once"===e.type?`once at ${e.due}`:`recurring: ${e.cron}`} — "${e.task}"`).join("\n")}]}}if("create"===t.action){if(!t.task||!t.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const e=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:t.task,type:t.type,due:t.due,cron:t.cron,timezone:t.timezone,timeType:t.timeType})}),s=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0};const a="once"===s.type?`due=${s.due}`:`cron=${s.cron}`;return{content:[{type:"text",text:`Scheduled: id=${s.id}, ${a}`}]}}if("delete"===t.action){if(!t.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const e=await fetch(`${n}/schedule/${t.id}`,{method:"DELETE"}),s=await e.json();return e.ok?{content:[{type:"text",text:`Deleted: ${t.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${t.action}`}],isError:!0}}catch(t){return e("error","SCHEDULE","Schedule task failed:",t),{content:[{type:"text",text:`Failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}})}function sc({agentContext:e,log:t}){return ut("hive_prepare_repository","Prepare the Agentrix Hive source repository in the local global repo store.\n\nUse this before discovering community agents or skills. This tool only clones/pulls\nthe repository and returns the absolute checkout path. It does not search and does\nnot define the repository layout. After calling it, use Explore with a\ntask-specific goal to find relevant candidates; do not catalog the whole repo\nunless the user explicitly asks for a catalog. If pullSucceeded is false, inspect\nerror and continue with the existing local checkout when it is usable.",{},async()=>{try{const t=await e.prepareHiveRepository();return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Failed to prepare Hive repository:",e),{content:[{type:"text",text:`Failed to prepare Hive repository: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function ac({agentContext:e,log:t}){return ut("hive_publish","Publish a newly created agent or skill to Agentrix Hive after the user explicitly agrees.\n\nUse this for content created by this agent/user. Do not use it to republish\nsomeone else's Hive content that was installed locally. To change an owned\nexisting listing, use hive_update. To suggest changes for someone else's listing,\nmodify locally if needed and leave a hive_comment.",{type:tt.enum(["agent","skill"]),draftAgentId:tt.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:tt.string().optional().describe("Absolute local skill directory for skill publishing"),name:tt.string().optional().describe("Listing name, lowercase kebab-case"),displayName:tt.string().optional().describe("Human-readable listing name"),description:tt.string().optional(),readme:tt.string().optional(),category:tt.string().optional(),tags:tt.array(tt.string()).optional(),authorType:tt.enum(["user","agent"]).default("user"),authorId:tt.string(),machineId:tt.string().optional(),cloudId:tt.string().optional()},async n=>{try{const t=await e.publishToHive(n);return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function ic({agentContext:e,log:t}){return ut("hive_update","Publish a new version for an owned Hive listing after the user explicitly agrees.\n\nUse this only when the listing belongs to the user/agent. Do not use it for\nsomeone else's installed Hive content; for those, keep changes local and leave a\nhive_comment with concrete suggestions.",{listingId:tt.string().describe("Owned HiveListing ID to update"),version:tt.string().optional().describe("Optional new version; defaults to next patch version"),changelog:tt.string().optional(),sourceDir:tt.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:tt.string().optional(),cloudId:tt.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.updateHiveListingVersion(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function oc({agentContext:e,log:t}){return ut("hive_record_install","Record a Hive agent or skill after installing it locally.\n\nDo not use this tool to install. First prepare the Hive repository, inspect the\nsource for safety and relevance, ask the user if needed, and perform the local\nagent/skill install yourself. Then read the HiveListing ID from\nagentrix-hive-id.txt in the Hive source directory and pass it as listingId.",{listingId:tt.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:tt.string().describe("Absolute local directory where the agent or skill was installed"),name:tt.string().optional().describe("Optional local name for installed agent"),machineId:tt.string().optional(),cloudId:tt.string().optional(),installedVersion:tt.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.recordHiveInstall(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function rc({agentContext:e,log:t}){return ut("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:tt.string().describe("HiveListing ID"),rating:tt.number().int().min(1).max(5),comment:tt.string().optional().describe("Markdown review text")},async n=>{try{const t=await e.createHiveReview(n.listingId,{rating:n.rating,comment:n.comment??null});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function cc({agentContext:e,log:t}){return ut("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:tt.string().describe("HiveListing ID"),content:tt.string().min(1).describe("Markdown comment content"),parentId:tt.string().optional().describe("Parent comment ID for replies")},async n=>{try{const t=await e.createHiveComment(n.listingId,{content:n.content,parentId:n.parentId});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function lc(e){if(e)return e.replace(/\/+$/g,"")||"/"}function pc(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,branchName:e.branchName,cwd:lc(e.cwd)||"",userCwd:lc(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function dc(e,t){return t??`agentrix/${e}`}async function uc(e){if(!e)return null;const t=await Sn();return t?_n(e,t):null}async function mc(e,t){const n=Cn(t);if(!n)return void console.warn("[GIT] No PAT user metadata found, skipping git config");const s=n.username,a=n.email||`${n.username}@gitlab.local`;await async function(e,t,n){await va("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await va("git",["config","user.email",n],{cwd:e,windowsHide:!0})}(e,s,a),console.log(`[GIT] Set local git config user.name=${s} user.email=${a}`)}async function hc(e,t,n){const s=await uc(n);s?await async function(e,t){const n=za();try{await va("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:Ka(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await va("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,env:Va(),windowsHide:!0})}(t,e)}async function gc(e,t,n,s,a,i){const o=dc(n,i),c=qa(t),l=await xa(e);if(!$a(e)&&!l)throw new Error(`Directory ${e} exists but is not a git repository`);const d=await uc(a);return $a(e)?(d?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=_(n);r(s)||p(s,{recursive:!0});const a=za();try{await va("git",["-c","credential.helper=","clone",t,n],{env:Ka(a,e),windowsHide:!0})}finally{f(a)}}(d,c,e),a&&await mc(e,a)):await Sa(t,e),await ja(e,"origin",c),await Ea(e,o,s),await Ca(e)):(await La(e,"origin",c),await hc(e,t,a),a&&await mc(e,a),await Ea(e,o,s),await Ca(e))}async function fc(e,t,n,s={}){const a=await uc(s.gitServerId);a?await async function(e,t,n,s=!1){const a=za();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await va("git",i,{cwd:t,env:Ka(a,e),windowsHide:!0})}finally{f(a)}}(a,e,t,n):s.gitUrl?await async function(e,t,n,s=!1){const a=["-c","credential.helper=","push",e,n];s&&a.push("--force"),await va("git",a,{cwd:t,env:Va(),windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=ya(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function vc(e,t,n){const s=n.trim();if(!s)return;const a=xe.resolveDataDir(e,t),i=T(a,"patch.diff");return await yt(a,{recursive:!0}),await vt(i,`${s}\n`),i}async function yc(e,t,n){await xe.writeLastSentArtifactVersion(e,t,n)}function xc(e,t){return`Please generate pull request metadata for the changes made in this task.\n\nInitial commit hash: ${e}\n${t?`\n\nAdditional instructions:\n${t}`:""}\n\nProvide a concise title (conventional commits format), a detailed description, and a user-facing summary message.`}function wc(e,t,n){return{type:"result",subtype:n?"error_during_execution":"success",duration_ms:0,duration_api_ms:0,is_error:n,num_turns:0,result:e,stop_reason:null,total_cost_usd:0,usage:{input_tokens:0,output_tokens:0,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:0,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"},modelUsage:{},permission_denials:[],terminal_reason:n?`exit_code_${t}`:"completed",session_id:"",uuid:Et()}}function bc(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:Et()}}function kc(e){const t="```sh\n",n="\n```";return`${t}${vr(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function Ic(e,t,n,s=6e4){return new Promise(a=>{const i=Xe("/bin/bash",["-c",e],{cwd:t,env:process.env,shell:!1});let o=null,r=!1;s>0&&(o=setTimeout(()=>{r=!0,i.kill("SIGTERM"),setTimeout(()=>{i.killed||i.kill("SIGKILL")},1e3)},s));let c="";i.stdout?.on("data",e=>{c+=e.toString()}),i.stderr?.on("data",e=>{c+=e.toString()}),i.on("close",(e,t)=>{let i,l,p;if(o&&clearTimeout(o),r){i=124,p=!0;const e=`\n[Command timed out after ${s/1e3} seconds]`;l=c?`${c}${e}`:e.trim()}else i=null!==e?e:"SIGTERM"===t?143:1,p=0!==i,l=c;const d=kc(l);n.onOutput(bc(d)),n.onOutput(wc(d,i,p)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=kc(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(bc(t)),n.onOutput(wc(t,1,!0)),n.onComplete(1),a(1)})})}class Tc{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="running";messageIdCounter=0;isStopped=!1;runStartTime=Date.now();commandRunning=!1;isDebouncing=!1;agentRunningMap=new Map;backgroundTaskMap=new Map;anonymousBackgroundTaskCount=0;lastActiveAgentsSignature=null;idleTimeoutHandle=null;idleTimeoutMs;constructor(e){this.config=e,this.idleTimeoutMs=Math.max(0,e.idleTimeoutMs??0)}parseMessage(e){if("user"!==e.type)return{type:"normal",content:"",originalMessage:e};const t=("string"==typeof e.message.content?e.message.content:"").trim();return t.startsWith("!")&&!t.startsWith("![")?{type:"bash-command",content:t.slice(1).trim(),originalMessage:e}:"![merge-request]"===t?{type:"merge-request",content:t,originalMessage:e}:"![merge-pr]"===t?{type:"merge-pr",content:t,originalMessage:e}:"![new]"===t?{type:"new-session",content:t,originalMessage:e}:"![agentrix-dev-init]"===t?{type:"agentrix-dev-init",content:t,originalMessage:e}:"![plan]"===t?{type:"plan-mode",content:t,originalMessage:e}:{type:"normal",content:t,originalMessage:e}}async enqueue(e){if(this.isStopped)return void this.log("warn","COORDINATOR","Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void this.log("warn","COORDINATOR","Ignoring malformed user message (missing content)");const t=this.parseMessage(e),n={id:"msg-"+ ++this.messageIdCounter,type:t.type,priority:"normal",content:t.content,originalMessage:e,timestamp:Date.now()};this.messageQueue.push(n),this.log("info","COORDINATOR",`Enqueued message ${n.id} (type: ${n.type}, queue: ${this.messageQueue.length})`),this.tryUpdateWorkerState(),this.tryProcessNext()}async tryProcessNext(){if(!this.isStopped)if(0!==this.messageQueue.length)try{const e=this.messageQueue.shift();this.log("info","COORDINATOR",`Processing message ${e.id} (type: ${e.type})`),await this.processMessage(e),this.log("info","COORDINATOR",`Completed message ${e.id}`)}catch(e){this.log("error","COORDINATOR",`Error processing message: ${e}`)}finally{this.tryUpdateWorkerState(),this.isStopped||this.tryProcessNext()}else this.tryUpdateWorkerState()}async processMessage(e){switch(e.type){case"normal":await this.processNormalMessage(e);break;case"bash-command":await this.processBashCommand(e);break;case"merge-request":await this.processMergeRequest(e);break;case"merge-pr":await this.processMergePr(e);break;case"new-session":await this.processNewSession(e);break;case"agentrix-dev-init":await this.processAgentrixDevInit(e);break;case"plan-mode":await this.processPlanMode(e);break;default:this.log("warn","COORDINATOR",`Unknown message type: ${e.type}`)}}async processNormalMessage(e){this.log("info","COORDINATOR","Processing normal message for SDK");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){this.log("info","COORDINATOR",`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){this.log("info","COORDINATOR","Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){this.log("info","COORDINATOR","Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){this.log("info","COORDINATOR","Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processAgentrixDevInit(e){this.log("info","COORDINATOR","Processing agentrix-dev-init command"),await this.processCommand(async()=>{await(this.config.handlers.onAgentrixDevInit?.(e.originalMessage))},e)}async processPlanMode(e){this.log("info","COORDINATOR","Processing plan-mode command"),await this.processCommand(async()=>{if(!this.config.handlers.onPlanMode)return;const t=await this.config.handlers.onPlanMode(e.originalMessage);t&&this.enqueueAgentMessage(t)},e)}async processCommand(e,t){await this.waitWorkerIdle(),this.setCommandRunning(!0),this.markCommandMessageProcessed(t);try{await e()}finally{this.setCommandRunning(!1)}}markCommandMessageProcessed(e){const t=e.originalMessage.__localSequence;void 0!==t&&this.config.onCommandMessageProcessed?.(t)}async waitWorkerIdle(){for(;"idle"!==this.getExecutionState();){if(this.isStopped)throw new Error("Coordinator stopped while waiting for idle");this.log("debug","COORDINATOR","Waiting for worker idle state"),await new Promise(e=>setTimeout(e,100))}}setWorkerState(e){if(this.workerState===e)return;const t=this.workerState;if(this.log("info","COORDINATOR",`Worker state: ${t} → ${e}`),this.workerState=e,"running"===e&&"idle"===t&&(this.runStartTime=Date.now(),this.config.workClient.sendWorkRunning(this.getActiveAgents()),this.lastActiveAgentsSignature=this.getActiveAgentsSignature(),this.clearIdleTimer()),"idle"===e&&"running"===t){let e;this.runStartTime&&(e=Date.now()-this.runStartTime,this.runStartTime=null),this.config.workClient.sendWorkerReady(e),this.lastActiveAgentsSignature=null,this.startIdleTimer(),this.config.onBecameIdle?.()}}updateAgentRunning(e){this.setAgentRunning("default","Agent",e)}setAgentRunning(e,t,n){const s="running"===this.workerState,a=this.lastActiveAgentsSignature;n?this.agentRunningMap.set(e,{agentId:e,agentName:t,startedAt:Date.now()}):this.agentRunningMap.delete(e);const i=this.getActiveAgentsSignature();this.lastActiveAgentsSignature=i,this.tryUpdateWorkerState(),s&&"running"===this.workerState&&i!==a&&this.config.workClient.sendWorkRunning(this.getActiveAgents())}setBackgroundTaskRunning(e,t){e&&(t?this.backgroundTaskMap.set(e,{taskId:e,startedAt:Date.now()}):!this.backgroundTaskMap.delete(e)&&this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,this.log("debug","COORDINATOR",`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Anonymous background task completed (count: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState()}getActiveAgents(){return Array.from(this.agentRunningMap.values()).map(({agentId:e,agentName:t})=>({agentId:e,agentName:t}))}getActiveAgentsSignature(){const e=this.getActiveAgents().slice().sort((e,t)=>e.agentId.localeCompare(t.agentId));return JSON.stringify(e)}enqueueAgentMessage(e){if(this.isStopped)this.log("warn","COORDINATOR","Ignoring agent message - coordinator is stopped");else if(this.agentMessageQueue.push(e),this.agentMessageResolver){const e=this.agentMessageResolver;this.agentMessageResolver=null,e(this.agentMessageQueue.shift())}}hasAgentMessages(){return this.agentMessageQueue.length>0}getAgentQueueLength(){return this.agentMessageQueue.length}async waitForAgentMessage(){return this.isStopped?null:this.agentMessageQueue.length>0?this.agentMessageQueue.shift():new Promise(e=>{this.agentMessageResolver=e})}cancelAgentWait(){if(!this.agentMessageResolver)return;const e=this.agentMessageResolver;this.agentMessageResolver=null,e(null)}setCommandRunning(e){this.commandRunning!==e&&(this.commandRunning=e,this.tryUpdateWorkerState())}hasExecutionWork(){return this.commandRunning||this.agentRunningMap.size>0||this.backgroundTaskMap.size>0||this.anonymousBackgroundTaskCount>0||this.isDebouncing}getExecutionState(){return this.hasExecutionWork()?"running":"idle"}setDebouncing(e){this.isDebouncing!==e&&(this.isDebouncing=e,this.tryUpdateWorkerState())}tryUpdateWorkerState(){if(this.isStopped)return;const e=this.messageQueue.length>0||this.agentMessageQueue.length>0,t=this.hasExecutionWork(),n=!e&&!t;this.setWorkerState(n?"idle":"running")}startIdleTimer(){0!==this.idleTimeoutMs&&(this.idleTimeoutHandle||(this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(this.log("info","COORDINATOR","Idle timeout reached, stopping task"),this.cancelAgentWait(),this.config.onIdleTimeout?.())},this.idleTimeoutMs)))}clearIdleTimer(){this.idleTimeoutHandle&&(clearTimeout(this.idleTimeoutHandle),this.idleTimeoutHandle=null)}getStatus(){return{state:this.workerState}}isActivelyExecuting(){return this.hasExecutionWork()}stop(){this.log("info","COORDINATOR","Stopping coordinator"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait()}log(e,t,n){this.config.logger&&this.config.logger(e,t,n)}}function Sc(e,t){const n={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:t}]}};e.sendTaskMessage(wr,n)}async function Ec(e){const{workingDirectory:t,workClient:n,repositoryId:s,gitServerId:a,gitUrl:i,logger:o,allowInteractive:r=!0,askUser:c,commitChanges:l}=e;if(o.info("[MERGE-PR] Executing merge-pr command"),s){try{const e=await Ua(t),s=await Aa(t),p=await async function(e,t){const n=ya(e);try{return(await n.log([`origin/${t}..HEAD`])).total>0}catch{return!0}}(t,e);if(s||p){if(!r)throw new Error("merge-pr requires user input to resolve git state, which is not supported in oneshot execution mode");const d=await async function(e,t,n,s){let a="";a=e&&t?"You have uncommitted changes and unpushed commits. What would you like to do?":e?"You have uncommitted changes. What would you like to do?":"You have unpushed commits. What would you like to do?";const i=[{question:a,header:"Git Status",multiSelect:!1,options:[{label:"Pause",description:"Stop operation, handle git state manually"},{label:"Push",description:"Push changes and review before merging"},{label:"Push and Merge",description:"Push changes and merge PR immediately"}]}];try{const e=(await n(i)).answers[0];return e.startsWith("other:")?(s.info(`[MERGE-PR] User provided custom input: ${e}, defaulting to Pause`),"Pause"):{Pause:"Pause",Push:"Push","Push and Merge":"PushAndMerge"}[e]||"Pause"}catch(e){return s.error("[MERGE-PR] Ask user failed:",e),"Pause"}}(s,p,c,o);if("Pause"===d)return void Sc(n,"Operation paused. Please handle git state and run merge again.");if(("Push"===d||"PushAndMerge"===d)&&(s&&(o.info("[MERGE-PR] Generating commit message with agent"),await l(),o.info("[MERGE-PR] Committed changes with agent-generated message")),o.info(`[MERGE-PR] Pushing branch ${e} to remote`),await fc(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===d))return void Sc(n,"✅ All changes pushed to remote. You can now review and run merge again if everything looks good.")}const d=await n.sendMergePr();if(d.success)Sc(n,`✅ PR merged successfully! Branch ${e} has been merged into the target branch.`);else{let e;switch(d.errorType){case"github_conflict":e="Merge conflict detected. Please resolve conflicts manually on GitHub and try again.";break;case"pr_not_open":e="PR is not open. The PR may have already been merged or closed.";break;case"permission_denied":e="Permission denied. You may not have permission to merge this PR.";break;case"merge_failed":e=`Merge failed: ${d.error||"Unknown error"}`;break;default:e=`Failed to merge PR: ${d.error||"Unknown error"}`}n.sendSystemErrorMessage(e)}}catch(e){o.error("[MERGE-PR] Failed:",e);const t=e instanceof Error?e.message:"Unknown error";n.sendSystemErrorMessage(`Failed to push or merge: ${t}`)}o.info("[MERGE-PR] Worker ready after merge-pr execution")}else n.sendSystemErrorMessage("Cannot merge: task has no git repository configured.")}function Ac(e,t){const n=e.updates?.repositoryId;return"string"==typeof n&&0!==n.length&&t.repositoryId!==n&&(t.repositoryId=n,xe.writeTaskInput(t),!0)}function Cc(e,t,n,s={}){const a=n.sendAskUser(e),i=s.timeoutMs??18e5,o=s.onTimeout;return new Promise((e,s)=>{const r=setTimeout(()=>{t.delete(a);const i={type:"ask_user_response",answers:[],status:"timeout",reason:"timeout"};n.sendAskUserResponse(a,i),"abort_task"===o?(n.onTimeoutMessage?.("ask_user timed out. Task cancelled."),n.stopTask?.("ask_user_timeout"),s(new Error("Ask user request timed out"))):e(i)},i);t.set(a,t=>{clearTimeout(r),e(function(e){const t=e.status??"answered";return e.status&&e.reason?e:{...e,status:t,reason:e.reason??("timeout"===t?"timeout":"user")}}(t))})})}function _c(e){return{type:"system",subtype:"init",apiKeySource:"temporary",betas:[],claude_code_version:"codex",cwd:e.cwd,tools:[],mcp_servers:[],model:e.model??"unknown",permissionMode:"default",slash_commands:[],output_style:"codex",skills:[],plugins:[],uuid:ue(),session_id:e.sessionId}}function $c(e,t){const n=ue();return t.set(e,n),n}function Pc(e,t){return t.get(e)||e}function Mc(e,t){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"item.started"===e.type?function(e,t){switch(e.type){case"command_execution":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:$c(e.id,t),name:"Bash",input:{command:e.command}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"file_change":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:$c(e.id,t),name:"Edit",input:{changes:e.changes.map(e=>({kind:e.kind,path:e.path}))}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"mcp_tool_call":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:$c(e.id,t),server_name:e.server,name:e.tool,input:e.arguments}]},parent_tool_use_id:null,session_id:""}}(e,t);case"web_search":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:$c(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);default:return null}}(e.item,t):"item.completed"===e.type?function(e,t){switch(e.type){case"agent_message":return function(e){return{type:"assistant",message:{id:e.id,type:"message",container:null,role:"assistant",content:[{citations:null,type:"text",text:e.text}],model:"",usage:{},stop_reason:null,context_management:null,stop_sequence:null},parent_tool_use_id:null,session_id:"",uuid:ue().toString()}}(e);case"reasoning":default:return null;case"command_execution":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:Pc(e.id,t),content:"failed"===e.status?"Command execution failed":e.aggregated_output||""}]},parent_tool_use_id:null,session_id:""}}(e,t);case"file_change":return function(e,t){const n=t.get(e.id),s=n??$c(e.id,t),a=!n;(e.changes||[]).map(e=>`${e.kind}: ${e.path}`);const i={type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:s,name:"Edit",input:{changes:(e.changes||[]).map(e=>({kind:e.kind,path:e.path}))}}]},parent_tool_use_id:null,session_id:""},o={type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:s,content:"failed"===e.status?"File changes failed":"File changes completed"}]},parent_tool_use_id:null,session_id:""};return a?[i,o]:o}(e,t);case"mcp_tool_call":return function(e,t){const n=Pc(e.id,t),s="failed"===e.status&&e.error;return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:n,is_error:s,content:s?e.error.message:e.result?.content||""}]},parent_tool_use_id:null,session_id:""}}(e,t);case"web_search":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:Pc(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"todo_list":return function(e){return{type:"assistant",message:{role:"assistant",content:`📋 Todo List:\n${e.items.map(e=>`${e.completed?"✓":"○"} ${e.text}`).join("\n")}`},parent_tool_use_id:null,session_id:""}}(e);case"error":return function(e){return{type:"assistant",message:{role:"assistant",content:`❌ Error: ${e.message}`},parent_tool_use_id:null,session_id:""}}(e)}}(e.item,t):null}let Rc,Nc,Dc;function Oc(e){let t=null,n=!1;for(let s=0;s<e.length;s+=1){const a=e[s];if(n)n=!1;else if("\\"!==a||'"'!==t)if('"'!==a&&"'"!==a||null!==t)if(a!==t){if("#"===a&&null===t)return e.slice(0,s)}else t=null;else t=a;else n=!0}return e}function Uc(e){const t=e.trim();if(!t)return null;if(t.startsWith('"'))try{return JSON.parse(t)}catch{return null}const n=t.match(/^'([^']*)'$/);return n?n[1]:t.match(/^[A-Za-z0-9._:/@+-]+$/)?t:null}function jc(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||T(n.homedir(),".codex");return T(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(Nc===e&&void 0!==Rc)return Rc;if(Nc=e,Rc=null,!r(e))return Rc;let t;try{t=c(e,"utf8")}catch{return Rc}for(const e of t.split(/\r?\n/)){const t=Oc(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=Uc(n[1])?.trim();return Rc=s||null,Rc}return Rc}()}class qc{createCodex(e){const t={},n=function(){if(void 0!==Dc)return Dc??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return Dc=e,e;Dc=null}();n&&(t.codexPathOverride=n),e.env&&(t.env=Ks(e.env));const s=function(e){const t=[];var n;e.modeConfig.supportChangeTitle&&e.codexAgentrixEventMcp&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Ds(`\n ## Title Setting Protocol:\n - MUST set a descriptive title as your FIRST action when the user makes a request\n - Use the Agentrix event broker MCP tool for this: server "${(n={serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.titleToolName}).serverName}", tool "${n.toolName}"\n - This is mandatory when the tool is available; do this before any other work\n - Update the title if the conversation direction changes substantially\n `)),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.previewToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(function(e){return Ds(`\n ## Task Preview URL Protocol:\n - If the user provided a service startup port, relevant startup documentation, or you started/reused a frontend service yourself, publish the preview URL for the current Agentrix task whenever you know the running service port.\n - Use the Agentrix event broker MCP tool for this: server "${e.serverName}", tool "${e.toolName}".\n - Publish only absolute http or https URLs. Local preview URLs such as http://localhost:5173 are valid.\n - Do not publish URLs for backend-only services or endpoints that are not user-facing frontend previews.\n `)}({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.previewToolName}));const s=e.projectAgentrixGuidance?.systemPromptAppend?.trim();return s&&t.push(s),t.length>0?t.join("\n\n"):void 0}(e);return s&&(t.config={...t.config??{},developer_instructions:s}),function(e,t){const n=t.codexAgentrixEventMcp;if(!n)return;const s=e.config??{},a=s.mcp_servers&&"object"==typeof s.mcp_servers&&!Array.isArray(s.mcp_servers)?s.mcp_servers:{};e.config={...s,mcp_servers:{...a,[n.serverName]:{url:n.url,bearer_token_env_var:n.tokenEnvVar}}}}(t,e),new Nt(Object.keys(t).length>0?t:void 0)}getAgentConfiguration(){return null}getHooks(){}getMcpServers(){}async executeHook(e,t,n){}async run(e,t){const n=t.abortController,s=this.createCodex(t),a=jc(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),r=await o.run("string"==typeof e?e:Js(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});return Ys({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:r.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:r.finalResponse??"",structuredOutput:Qs(r.finalResponse??"",Boolean(t.structuredOutputSchema))})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=jc(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),{events:r}=await o.runStreamed("string"==typeof e?e:Js(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let c=t.agentSessionId||"",l="",p={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const d=new Map,u={get:e=>d.get(e),set:(e,t)=>{d.set(e,t)}};for await(const e of r){if("thread.started"===e.type&&(c=e.thread_id,yield _c({sessionId:c,cwd:t.cwd,model:a??void 0})),"turn.completed"===e.type){e.usage&&(p=e.usage);break}if("turn.failed"===e.type)throw new Error(e.error.message);if("error"===e.type)throw new Error(e.message);if("item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(l=e.item.text),"item.started"===e.type||"item.completed"===e.type){const t=Mc(e,u);if(!t)continue;const n=Array.isArray(t)?t:[t];for(const e of n)yield e}}const m=Ys({sessionId:c,model:a??"unknown",numTurns:1,usage:p,result:l,structuredOutput:Qs(l,Boolean(t.structuredOutputSchema))});yield m}loop(e){const t=e.abortController,n=this.createCodex(e),s=jc(e.model),a={workingDirectory:e.cwd,model:s??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let i=e.agentSessionId?n.resumeThread(e.agentSessionId,a):n.startThread(a),o=!1;const r=[];let c=null,l=e.agentSessionId??null,p=0;const d=()=>{if(!o&&(o=!0,c)){const e=c;c=null,e(null)}},u=e=>"string"==typeof e?e:Js(e),m=async function*(){try{for(;!o&&!t.signal.aborted;){const n=r.length>0?r.shift():await new Promise(e=>{c=e});if(!n)break;let a="";const d=new Map,m={get:e=>d.get(e),set:(e,t)=>{d.set(e,t)}},{events:h}=await i.runStreamed(u(n),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of h){if(o)break;if("thread.started"!==t.type){if("turn.completed"===t.type){l&&(yield Ys({sessionId:l,model:s??"unknown",numTurns:p+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:a,structuredOutput:Qs(a,Boolean(e.structuredOutputSchema))}));break}if("turn.failed"===t.type)throw new Error(t.error.message);if("error"===t.type)throw new Error(t.message);if("item.started"===t.type||"item.completed"===t.type){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(a=t.item.text);const e=Mc(t,m);if(!e)continue;const n=Array.isArray(e)?e:[e];for(const e of n)yield e}}else l=t.thread_id,yield _c({sessionId:l,cwd:e.cwd,model:s??void 0})}p+=1}}finally{d()}}();return t.signal.addEventListener("abort",d,{once:!0}),{push:e=>{if(console.log("CodexRunner.loop.push:",JSON.stringify(e,null,2)),!o){if(c){const t=c;return c=null,void t(e)}r.push(e)}},events:m,stop:d}}}const Lc=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification","RepositoryInit"];function Hc(e){const t={};for(const n of Lc){const s=e[n];"function"==typeof s&&(t[n]=s,console.log(`[Hook Loader] ✓ Loaded hook: ${n}`))}const n=Object.keys(t).length;return 0===n?console.warn("[Hook Loader] No valid hooks found in module"):console.log(`[Hook Loader] Successfully loaded ${n} hook(s)`),t}class Gc{static pool=new Map;static async create(e,t,n){const s=this.pool.get(t);if(s)return s;let a;if("claude"===e||"companion"===e){const s=await async function(e){const{agentId:t,agentDir:n,logger:s}=e;if(!t||"default"===t)return{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};try{ua(s,"info",`Loading agent: ${t}`);const e=await Fe({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return ua(s,"warn",`No claude configuration found for agent ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};const a=e.claude,i=a.plugins.map(e=>({type:"local",path:e})),o=n||We().resolveAgentDir(t),r=a.config.sdkMcpTools?.map(e=>T(o,"claude",e)),c={customSystemPrompt:a.systemPrompt,customModel:a.config.model,customFallbackModel:a.config.fallbackModel,customMaxTurns:a.config.maxTurns,customExtraArgs:a.config.extraArgs,customPermissionMode:a.config.settings?.permissionMode,customPlugins:i,systemPromptMode:a.config.systemPrompt?.mode??"append",customPRPromptTemplate:a.prPromptTemplate,prPromptMode:a.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:r};return ua(s,"info",`Agent ${t} loaded successfully (${i.length} plugins)`),c}catch{return ua(s,"error",`Failed to load agent: ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}}}({agentId:t,agentDir:n?.agentDir,logger:n?.logger});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=ae(),a=t||s.resolveAgentDir(e),i=T(a,"claude");return await async function(e,t){const n=Ne(e,"hooks");if(!$e(n))return{};const s=[Ne(n,"dist","index.mjs"),Ne(n,"dist","index.js"),Ne(n,"index.mjs"),Ne(n,"index.js")];let a=null;for(const e of s)if($e(e)){a=e;break}if(!a)return console.warn(`[Hook Loader] Hooks not built: ${n}`),console.warn("[Hook Loader] To build hooks, run:"),console.warn(`[Hook Loader] cd ${n}`),console.warn("[Hook Loader] npm install && npm run build"),console.warn("[Hook Loader] Or place hooks directly in:"),console.warn(`[Hook Loader] ${Ne(n,"index.js")} or ${Ne(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${St(a).href}?t=${Date.now()}`,n=await import(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),Hc(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return Hc(n)}catch(e){throw console.error(`[Hook Loader] Failed to load hooks from ${a}:`,e),new Error(`Hook loading failed: ${e instanceof Error?e.message:String(e)}`)}}(i,n)}catch(e){return void console.warn("[AgentRunners] Failed to load hooks:",e)}}(t,n.agentDir,n.context)),n?.context&&s.customSdkMcpTools&&s.customSdkMcpTools.length>0&&(o=await async function(e,t,n){const s={};for(const a of e)try{n&&n("info","MCP",`Loading SDK MCP tools from: ${a}`);const e=await import(a),i=e.default||e;if(!i){n&&n("warn","MCP",`No default export found in ${a}`);continue}const o="function"==typeof i?i(t):i,r=o.name;s[r]=o,n&&n("info","MCP",`Loaded MCP server: ${r}`)}catch(e){n&&n("error","MCP",`Failed to load SDK MCP tools from ${a}: ${e instanceof Error?e.message:String(e)}`)}return s}(s.customSdkMcpTools,n.context,n.logger)),a=new da(t,e,s,i,o)}else a=new qc;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class Bc{constructor(e){this.workingDirectory=e}async listFiles(e=3){const t=[];return this.listFilesRecursively(this.workingDirectory,t,"",e,0),t}async readFile(e){try{const t=Me.join(this.workingDirectory,e);return Ae.existsSync(t)?Ae.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=Me.join(this.workingDirectory,e);return Ae.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=Ae.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?oe.includes(o.name)||this.listFilesRecursively(Me.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class Fc{constructor(e){this.params=e}state=null;async setup(){const{options:e,handlers:t}=this.params,{userId:n,taskId:s,cwd:a}=e;if(!a)throw new Error("[WORKSPACE] Missing cwd for workspace setup");const i=xe.getWorkspaceState(n,s),o=e.repositorySourceType,r={...e,repositorySourceType:o},{initialCommitHash:c,isGitRepository:l,setupAction:p,useWorktree:d,initPolicyUpdates:u}=await this.ensureWorkspace(r,t,i);await xe.writeWorkspaceState(n,s,{initialized:!0,initializedAt:(new Date).toISOString(),cwd:a,repositorySourceType:r.repositorySourceType,useWorktree:d,userCwd:e.userCwd,forceUserCwd:e.forceUserCwd,gitUrl:e.gitUrl,baseBranch:e.baseBranch,taskRepositoryId:e.taskRepositoryId,initialCommitHash:c,initPolicies:{...i?.initPolicies,...u}});const m=await async function(e,t,n,s){return async function(e,t,n,s){if(!await xa(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await Aa(e),i=await Ca(e),o=s||xe.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await Oa(e,o),c=r?await vc(t,n,r.patch):void 0,l=await xe.readLastSentArtifactVersion(t,n),p=!!r&&r.artifactVersion!==l;return{currentCommitHash:i,currentArtifactVersion:r?.artifactVersion,hadUncommittedChanges:a,hasNewArtifacts:p,lastSentArtifactVersion:l??void 0,patchPath:c,diffStats:r?.stats}}(e,t,n,s)}(a,n,s,c);return this.state={cwd:a,initialCommitHash:c,isGitRepository:l,setupAction:p,gitStateResult:m},l&&!e.taskRepositoryId&&await async function(e,t){try{const n=await Ga(e);if(!n)return void console.log("[REPO] No origin remote found, skipping repository association");if(!t?.onRepositoryDetected)return;console.log(`[REPO] Detected remote: ${n.host}/${n.owner}/${n.repo}`),t.onRepositoryDetected(n)}catch(e){console.error("[REPO] Failed to send repository association:",e)}}(a,t),this.state}getState(){if(!this.state)throw new Error("[WORKSPACE] Workspace not initialized");return this.state}getCwd(){return this.getState().cwd}getInitialCommitHash(){return this.getState().initialCommitHash}getGitStateResult(){return this.getState().gitStateResult}async prepareResultArtifacts(e={}){const{cwd:t,initialCommitHash:n,isGitRepository:s}=this.getState(),{userId:a,taskId:i}=this.params.options;if(!s||!n)return{};const o=await Oa(t,n);if(!o)return{};try{await vc(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new Bc(e);return ie(t)}(t),c=await xe.readLastSentArtifactVersion(a,i);return c&&c===o.artifactVersion?{artifactVersion:o.artifactVersion}:{artifactVersion:o.artifactVersion,artifacts:{artifactVersion:o.artifactVersion,stats:o.stats,preview:r}}}async ensureWorkspace(e,t,n){const s=e.repositorySourceType;return"git-server"===s?this.ensureGitServerWorkspace(e,t,n):"directory"===s?this.ensureDirectoryWorkspace(e,t,n):this.ensureTemporaryWorkspace(e,t,n)}async ensureGitServerWorkspace(e,t,n){const{cwd:s,gitUrl:a,taskId:i,baseBranch:o,branchName:c,gitServerId:l}=e;if(!a)throw new Error("[WORKSPACE] gitUrl is required for git-server mode");const p=e.forceUserCwd||!1===e.useWorktree,d="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await xa(s),m=$a(s);if(p)return this.ensureDirectGitServerWorkspace(e,t,n,u,m);if(Boolean(e.taskRepositoryId&&l)&&(!u||d)){const p=await async function(e,t,n,s,a,i){const o=lc(e)||e,c=qa(n),l=Ha(c);if(!l)throw new Error(`Unable to resolve repository owner/name from git URL: ${c}`);const p=xe.resolveRepoStoreCheckoutDir(s,l.owner,l.repo),d=xe.resolveRepoStoreLockPath(s,l.owner,l.repo),u=await xe.acquireFileLock(d);if(!u)throw new Error(`Timed out waiting for repo store lock at ${d}`);try{await async function(e,t,n,s){const a=qa(t);if(!await xa(e)){if(!$a(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await Ia(e)}await La(e,"origin",a),await hc(e,t,n);const i=await async function(e,t="origin"){const{stdout:n}=await va("git",["for-each-ref","--format=%(refname:short)",`refs/remotes/${t}`],{cwd:e,maxBuffer:10485760,windowsHide:!0});return n.split("\n").map(e=>e.trim()).filter(Boolean).map(e=>e.replace(`${t}/`,"")).filter(e=>"HEAD"!==e)}(e),o=function(e,t){if(t&&e.includes(t))return t;if(e.includes("main"))return"main";if(e.includes("master"))return"master";if(e.length>0)return e[0];throw new Error("Cannot create worktree: repository has no remote branches to base the workspace on.")}(i,s);return await async function(e,t,n){await va("git",["checkout","-B",t,n],{cwd:e,windowsHide:!0})}(e,o,`origin/${o}`),{baseBranch:o}}(p,n,s,a);const e=dc(t,i),c=await wa(p),l=c.find(e=>lc(e.path)===o);if(l){if(l.branch&&l.branch!==e)throw new Error(`Worktree at ${o} is already attached to branch ${l.branch}. Remove it before retrying: git worktree remove ${o}`);return s&&await mc(o,s),{initialCommitHash:await Ca(o)}}const d=c.find(t=>t.branch===e&&lc(t.path)!==o);if(d)throw new Error(`Branch ${e} is already attached to worktree ${d.path}. Remove it before retrying.`);const u=gt(p),m=(await u.branchLocal()).all.includes(e);if(r(o)&&!$a(o))throw new Error(`Worktree directory already exists at ${o}. This may be from a previous task. To clean up: git worktree remove ${o} OR rm -rf ${o}`);try{m?await u.raw(["worktree","add",o,e]):await ba(p,o,e,"HEAD")}catch(e){try{await ka(p,o,!0)}catch{}throw e}return await mc(o,s),{initialCommitHash:await Ca(o)}}finally{await xe.releaseFileLock(d,u)}}(s,i,a,l,o,c);return u?{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}:{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,p.initialCommitHash,"none"),isGitRepository:!0,setupAction:"worktree",autoCommitPolicy:"enabled",useWorktree:!0}}if(!u){if(!m)throw new Error(`[WORKSPACE] Directory ${s} exists but is not a git repository.`);const e=await gc(s,a,i,o,l,c)||await Ca(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await ja(s,"origin",qa(a)),{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:n?.useWorktree??!1}}async ensureDirectGitServerWorkspace(e,t,n,s,a){const{cwd:i,gitUrl:o,taskId:r,baseBranch:c,branchName:l,gitServerId:p}=e;if(!o)throw new Error("[WORKSPACE] gitUrl is required for git-server direct directory mode");if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const e=await gc(i,o,r,c,p,l)||await Ca(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await this.assertDirectGitServerRemoteMatches(i,o),{...await this.tryResolveDirtyRepo(e,t,n,{defaultBranchMismatchAction:"Keep"}),setupAction:"reuse",useWorktree:!1}}async assertDirectGitServerRemoteMatches(e,t){const n=Ha(qa(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${qa(t)}`);const s=await Ga(e);if(!s)throw new Error(`[WORKSPACE] Direct directory ${e} must have an origin remote matching the selected repository.`);const a=n.host.toLowerCase(),i=s.host.toLowerCase(),o=n.owner.toLowerCase(),r=s.owner.toLowerCase(),c=n.repo.toLowerCase(),l=s.repo.toLowerCase();if(a!==i||o!==r||c!==l)throw new Error(`[WORKSPACE] Direct directory ${e} points to ${s.host}/${s.owner}/${s.repo}, but the selected repository is ${n.host}/${n.owner}/${n.repo}.`)}async ensureDirectoryWorkspace(e,t,n){const{cwd:s,taskId:i,userCwd:o}=e;if(await xa(s))return this.tryResolveDirtyRepo(e,t,n);if(!$a(s))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};{if(!o)return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};const t=o.replace(/^~/,a());if($a(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await xa(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await _a(t)||await Ta(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=lc(t)||t;if(!await xa(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await _a(i))throw new Error(`Cannot create worktree: repository at ${i} has no commits. Please create an initial commit first: cd ${i} && git add . && git commit -m 'Initial commit'`);const c=dc(n,s),l=(await wa(i)).find(e=>lc(e.path)===o);if(l){if(l.branch&&l.branch!==c)throw new Error(`Worktree at ${o} is already attached to branch ${l.branch}. Remove it before retrying: git worktree remove ${o}`);return{initialCommitHash:await Ca(o)}}const p=gt(i),d=(await p.branchLocal()).all.includes(c);if(r(o)&&!$a(o))throw new Error(`Worktree directory already exists at ${o}. This may be from a previous task. To clean up: git worktree remove ${o} OR rm -rf ${o}`);try{d?await p.raw(["worktree","add",o,c]):await ba(i,o,c,"HEAD")}catch(e){try{await ka(i,o,!0)}catch{}throw e}return{initialCommitHash:await Ca(o)}}(t,s,i,e.branchName)}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}}async ensureTemporaryWorkspace(e,t,n){const{cwd:s,taskId:a}=e;if(!await xa(s)){await async function(e,t,n){const s=await async function(e,t,n){await Ia(e);const s=function(e,t){return{hook_event_name:"RepositoryInit",workspace_path:e,task_id:t}}(e,t);return n?.onRepositoryInit&&await n.onRepositoryInit(s),await Ta(e),await Ca(e)}(e,t,n);return{initialCommitHash:s}}(s,a,t),await Ea(s,dc(a,e.branchName),e.baseBranch);const i=await Ca(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,i,"none"),isGitRepository:!0,setupAction:"init",autoCommitPolicy:"enabled",useWorktree:!1}}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:n?.useWorktree??!1}}async tryResolveDirtyRepo(e,t,n,s={}){let a=null,i="enabled";const o={};if(await async function(e){return!!await xa(e)&&await Aa(e)}(e.cwd)){const s=this.getPersistedInitPolicy(n,"uncommittedChanges",["Ignore","Commit","Stash"]),r=s?{action:s,remember:!0}:function(e){if(e.channelReplyTarget)return!0;const t=e.eventData;return"object"==typeof t&&null!==t&&"senderType"in t&&"channel"===t.senderType}(e)?{action:"Ignore",remember:!0}:t?.onUncommittedChanges?await t.onUncommittedChanges():{action:"Ignore",remember:!1},c=r.action;if(await async function(e,t){switch(t){case"Ignore":console.log("[GIT] User chose to ignore uncommitted changes");break;case"Stash":console.log("[GIT] Stashing uncommitted changes"),await async function(e){const t=ya(e);await t.stash(["push"])}(e);break;case"Commit":console.log("[GIT] Committing uncommitted changes with agent-generated message");break;case"Abort":throw new Error("Task aborted by user due to uncommitted changes")}}(e.cwd,c),"Abort"===c)throw new Error("Task aborted by user due to uncommitted changes");if("Commit"===c){if(!t?.onCommitUncommittedChanges)throw new Error("Unable to commit uncommitted changes during workspace setup");await t.onCommitUncommittedChanges()}!s&&r.remember&&(o.uncommittedChanges=c),a=c,"Ignore"===c&&(i="disabled_by_ignore")}let r;if(await _a(e.cwd)||await Ta(e.cwd),"Ignore"===a){const t=dc(e.taskId,e.branchName);r=await Ua(e.cwd)===t?"none":"kept"}else r=await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch");const c=await Ca(e.cwd);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,c,r),isGitRepository:!0,setupAction:"reuse",autoCommitPolicy:i,useWorktree:n?.useWorktree??!1,initPolicyUpdates:o}}getPersistedInitPolicy(e,t,n){const s=e?.initPolicies?.[t];return s&&n.includes(s)?s:null}resolveInitialCommitHash(e,t,n){return e?"kept"===n?t:e:t}async tryResolveBranchMismatch(e,t,n,s,a){const i=dc(e.taskId,e.branchName),o=await Ua(e.cwd);if(o===i)return"none";const r=this.getPersistedInitPolicy(n,"branchMismatch",["Switch","Keep"]),c=r?{action:r,remember:!0}:t?.onBranchMismatch?await t.onBranchMismatch({currentBranch:o,expectedBranch:i,workingDirectory:e.cwd}):{action:a,remember:!1};if("Abort"===c.action)throw new Error("Task aborted by user due to branch mismatch");return!r&&c.remember&&(s.branchMismatch=c.action),"Keep"===c.action?"kept":(await Ea(e.cwd,i,e.baseBranch),"switched")}}const Wc=tt.object({title:tt.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:tt.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:tt.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),zc=nt(Wc,{target:"draft-07"}),Kc=nt(Wc);function Vc(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?Wc.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=Xc(e),n=JSON.parse(t);return Wc.parse(n)}(t.result??"")}function Xc(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class Jc{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const Yc=[{name:"/merge-request",sendAs:"![merge-request]",description:"Create a pull request for current task changes"},{name:"/merge-pr",sendAs:"![merge-pr]",description:"Merge the current pull request"},{name:"/new",sendAs:"![new]",description:"Start a new session for this task"},{name:"/agentrix-dev-init",sendAs:"![agentrix-dev-init]",description:"Run Agentrix DevOps initialization for this project"}];function Qc(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function Zc(e=[]){const t=[],n=new Set;for(const e of Yc.map(e=>({id:`cli_builtin:${e.name}`,name:e.name,kind:"cli_builtin",sendAs:e.sendAs,description:e.description})))t.push(e),n.add(e.name);const s=Array.from(new Set(e.map(Qc).filter(Boolean)));s.sort((e,t)=>e.localeCompare(t));for(const e of s)n.has(e)||t.push({id:`sdk:${e}`,name:e,kind:"sdk",sendAs:e});return t}const el=tt.object({message:tt.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),tl=nt(el,{target:"draft-07"}),nl=nt(el);async function sl(e){if(!await Aa(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await Ca(e.workingDirectory),n=await async function(e){const t=e.runner.runStreamed("Generate a git commit message for the current uncommitted changes.\n\nRequirements:\n- Follow this repository's commit message conventions.\n- Keep the subject line specific and concise.\n- Add a body only if it materially improves clarity.\n- Return only the commit message.",{cwd:e.workingDirectory,model:e.model,abortController:e.abortController,modeConfig:e.modeConfig,disableClaudePlanModeTools:e.disableClaudePlanModeTools,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?tl:nl}});let n=null;for await(const s of t){if("result"===s.type){n=s;break}await(e.onStreamMessage?.(s))}if(!n)throw new Error("Commit message generation did not return a result message");return function(e){if("success"!==e.subtype)throw new Error("Commit message generation failed before structured output was returned");const t=e,n=(t.structured_output?el.parse(t.structured_output):el.parse(JSON.parse(Xc(t.result??"")))).message.trim();if(!n)throw new Error("Commit message generation returned an empty message");return n}(n)}(e),s=await async function(e,t){const n=t.trim();if(!n)throw new Error("Commit message cannot be empty");const[s,...a]=n.split(/\n\s*\n/).map(e=>e.trim()).filter(Boolean);if(!s)throw new Error("Commit subject cannot be empty");const i=ya(e);await i.add(["--all"]);const o=["commit","-m",s];for(const e of a)o.push("-m",e);return await i.raw(o),await Ca(e)}(e.workingDirectory,n);if(await Aa(e.workingDirectory))throw new Error("Commit completed but working tree is still dirty");if(s===t)throw new Error("Commit completed but HEAD did not change");return{commitHash:s,message:n}}function al(e){if(e)return{type:"json_schema",schema:e}}async function il(e,t){await o.promises.mkdir(t,{recursive:!0});const n=await o.promises.readdir(e,{withFileTypes:!0});for(const s of n){const n=I.join(e,s.name),a=I.join(t,s.name);s.isDirectory()?await il(n,a):await o.promises.copyFile(n,a)}}function ol(e){return"oneshot"===function(e){return e.workerExecutionMode??re}(e)}async function rl(e){const t=T(e,".agentrix"),n=T(t,"prompt.md"),s=T(t,"plugins"),[a,i]=await Promise.all([cl(n),ll(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function cl(e){try{if(!(await x.stat(e)).isFile())return;const t=(await x.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(pl(e))return;throw e}}async function ll(e){let t;try{t=await x.readdir(e,{withFileTypes:!0})}catch(e){if(pl(e))return[];throw e}const n=[];for(const s of t.sort((e,t)=>e.name.localeCompare(t.name))){if(!s.isDirectory())continue;const t=T(e,s.name),a=T(t,".claude-plugin","plugin.json");try{(await x.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(pl(e))continue;throw e}}return n}function pl(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}function dl(e){const t=e,n=ce({machineId:t.machineId??null,cloudId:t.cloudId??null});return function(e){const t=e;return Boolean(t.machineId||t.cloudId)}(e)?"local"===n:!Boolean(process.env.CLOUD_AUTH_TOKEN?.trim())&&"cloud"!==n}const ul=Symbol("companionHeartbeatContext");class ml{constructor(e,t,n){this.credentials=e,this.options=t,this.workingDirectory=n;const s=this.options.input,{taskId:a,userId:i}=s;this.logger=Ie({type:"worker",taskId:a}),this.currentAgentSessionId="agentSessionId"in s?s.agentSessionId:void 0;const o=s.taskAgents||[];this.taskAgentsMap=new Map(o.map(e=>[e.id,e]));const r=this.taskAgentsMap.size>1;this.primaryAgentId=r?"planner":s.agentId,this.primaryAgentName=r?"planner":this.taskAgentsMap.get(s.agentId)?.name??"unknown";const c=this.createWorkerClientConfig(i,a,n),l=xe.resolveDataDir(i,a);this.historyDb=ko({dataDir:l,taskId:a}),this.workClient=new br(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new Ar({logger:this.logger,socketClient:this.workClient.client,taskId:s.taskId,userId:s.userId,chatId:s.chatId,rootTaskId:s.rootTaskId||s.taskId,parentTaskId:s.parentTaskId||null,workingDirectory:this.workingDirectory,agentHomeDir:xe.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:xe.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const p={...pc(this.options.input),cwd:this.workingDirectory};this.workspace=new Fc({options:p,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=$r();logger;workClient;workspace;coordinator;agentContext;runner;agentQueues=new Map;currentAgentSessionId;currentGroupId=null;historyDb;chatHistoryDb=null;agentrixTools;pendingNavigateTaskId=null;pendingPermissions=new Map;grantedPermissions=new Set;loopPermissionModeSetter=null;configuredPermissionMode="bypassPermissions";desiredPermissionMode=null;activePermissionMode=null;lastBroadcastPermissionMode=null;taskAgentsMap;messageSavedListener=null;messageDebounceHandle=null;messageDebounceMs=1e4;lastProcessedSequence=0;primarySessionReady=!1;pendingPrimaryLastSequence=null;primaryAgentId;primaryAgentName;exitReason="completed";pendingChannelReplies=[];channelMessageInvocationCount=0;projectAgentrixGuidance={claudePlugins:[]};newMessageGroupId(){return`group-${crypto.randomUUID()}`}refreshGroupId(){this.currentGroupId=this.newMessageGroupId()}getConfiguredPermissionMode(){if(this.isOneShotExecution())return"bypassPermissions";const e=this.runner?.getAgentConfiguration()?.customPermissionMode;return e??"bypassPermissions"}isOneShotExecution(){return ol(this.options.input)}initializePermissionModeState(){this.configuredPermissionMode=this.getConfiguredPermissionMode(),this.desiredPermissionMode??=this.configuredPermissionMode}getPermissionModeSnapshot(){return this.desiredPermissionMode??this.configuredPermissionMode??null}broadcastPermissionMode(e){this.lastBroadcastPermissionMode!==e&&(this.lastBroadcastPermissionMode=e,this.workClient.sendPermissionMode(e))}confirmPermissionModeApplied(e){this.desiredPermissionMode=e,this.activePermissionMode=e,this.broadcastPermissionMode(e)}async applyPermissionMode(e){this.loopPermissionModeSetter&&(await this.loopPermissionModeSetter(e),this.confirmPermissionModeApplied(e))}async flushDesiredPermissionMode(){const e=this.getPermissionModeSnapshot();e&&this.loopPermissionModeSetter&&this.activePermissionMode!==e&&await this.applyPermissionMode(e)}async requestPermissionMode(e){this.desiredPermissionMode=e,this.broadcastPermissionMode(e),await this.flushDesiredPermissionMode()}async restoreConfiguredPermissionMode(){await this.requestPermissionMode(this.configuredPermissionMode)}shouldProcessMessage(e){const t=e.message,n=this.getRunnerMode(),s="group_chat"===n||"group_work"===n,a=ee(t);return!!le(t)||!!pe(t)||!(!te(t)&&!a)&&"agent"!==e.senderType&&(s?e.senderId!==this.primaryAgentId:!!a||"system"===e.senderType&&"user"===t.type||"user"===t.type)}shouldDropHeartbeatWhileBusy(){return this.coordinator.isActivelyExecuting()}async processPendingMessages(){const e=this.historyDb.pageMessagesAfter(this.lastProcessedSequence,100),t=this.getRunnerMode(),n="group_chat"===t||"group_work"===t,s=[];for(const t of e.data)if(this.lastProcessedSequence=t.localSequence,this.shouldProcessMessage(t)){if(n&&this.isUnsupportedGroupPlanCommand(t)){this.log("info","PLAN","Ignoring unsupported ![plan] command in group mode");continue}s.push(t)}if(s.length>0){this.deduplicateHeartbeats(s);const e=this.mergeConsecutiveHumanMessages(s);n?await this.processMessagesAsGroup(e):await this.processMessagesIndividually(e)}e.hasMore&&await this.processPendingMessages()}isUnsupportedGroupPlanCommand(e){const t=e.message;return!(!te(t)||"user"!==t.type)&&"![plan]"===Js(t).trim()}deduplicateHeartbeats(e){let t=-1;for(let n=e.length-1;n>=0;n--)le(e[n].message)&&(-1===t?t=n:(e.splice(n,1),t--))}mergeConsecutiveHumanMessages(e){if(0===e.length)return[];const t=[];let n=0;for(;n<e.length;){const s=e[n];if("human"===s.senderType){const a=[s];for(;n+1<e.length;){const t=e[n+1];if("human"!==t.senderType||t.senderId!==s.senderId)break;a.push(t),n++}1===a.length?t.push(s):t.push(this.createMergedHumanMessage(a))}else t.push(s);n++}return t}createMergedHumanMessage(e){const t=[],n=[];for(const s of e){const e=s.message;if(!te(e)||"user"!==e.type)continue;const a=e.message.content;if("string"==typeof a)t.push(a);else if(Array.isArray(a))for(const e of a)"text"===e.type?t.push(e.text):n.push(e)}const s=t.join(""),a=n.length>0?[{type:"text",text:s},...n]:s,i=e[0],o=e[e.length-1];return{localSequence:o.localSequence,eventId:o.eventId,senderType:i.senderType,senderId:i.senderId,senderName:i.senderName,createdAt:o.createdAt,message:{type:"user",message:{role:"user",content:a},parent_tool_use_id:null,session_id:i.message?.session_id||""}}}async processMessagesAsGroup(e){const t=[],n=[];for(const s of e){const e=rr(s);if(e){const s=e.message.content;if("string"==typeof s)t.push(s);else if(Array.isArray(s))for(const e of s)"text"===e.type?t.push(e.text):n.push(e)}}if(0===t.length)return;const s=Math.max(...e.map(e=>e.localSequence)),a=t.join(" "),i={type:"user",message:{role:"user",content:n.length>0?[{type:"text",text:a},...n]:a},parent_tool_use_id:null,session_id:""};this.attachInputMetadata(i,{localSequence:s,isChannelInput:e.some(e=>"channel"===e.senderType),channelReplyTarget:this.extractChannelReplyTarget(e)}),await this.coordinator.enqueue(i)}async processMessagesIndividually(e){for(const t of e){const e=this.formatSingleMessage(t);e&&(this.attachInputMetadata(e,{localSequence:t.localSequence,isChannelInput:"channel"===t.senderType,channelReplyTarget:this.extractChannelReplyTarget([t])}),delete e.__channelReplyTarget,await this.coordinator.enqueue(e))}}attachInputMetadata(e,t){e.__localSequence=t.localSequence,e.__isChannelInput=t.isChannelInput,t.channelReplyTarget&&(e.__channelReplyTarget=t.channelReplyTarget)}extractChannelReplyTarget(e){for(let t=e.length-1;t>=0;t--){const n=e[t].message.__channelReplyTarget;if(this.isChannelReplyTarget(n))return n}return null}formatSingleMessage(e){const t=e.message;if(le(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionHeartbeatPrompt(e)},parent_tool_use_id:null,session_id:""};return n[ul]=e,n}if(pe(t)){const e=t;let n=`[reminder from shadow] ${e.content}`;return e.filePath&&(n+=`\nDetailed analysis: ${e.filePath}`),{type:"user",message:{role:"user",content:n},parent_tool_use_id:null,session_id:""}}return te(t)&&"user"===t.type?t:null}buildCompanionHeartbeatPrompt(e){const t=this.options.input,n=t.rootTaskId||t.taskId;return["[heartbeat] You are being awakened by a scheduled companion heartbeat.","","Review target:","Always review the recent context of this companion chat and its root chat task before deciding what to do. Do not limit the review to a generic workspace scan.",...[`heartbeat timestamp: ${e.timestamp}`,e.triggerTime?`local trigger time: ${e.triggerTime}`:void 0,e.triggerReasons?.length?`trigger reasons: ${e.triggerReasons.join(", ")}`:void 0,"number"==typeof e.heartbeatTriggerCount?`heartbeat trigger count: ${e.heartbeatTriggerCount}`:void 0,`current worker taskId: ${t.taskId}`,t.chatId?`companion chatId: ${t.chatId}`:void 0,n?`root chat taskId: ${n}`:void 0].filter(e=>Boolean(e)).map(e=>`- ${e}`),"","Use the available conversation-reading tools for the companion chat/root chat task when needed. Follow the current heartbeat mode instructions from your system prompt. If there is nothing actionable after review, respond briefly and exit."].join("\n")}extractCompanionHeartbeatPromptPlaceholders(e){const t=e[ul];if(t)return delete e[ul],{IS_MEMORY_ORGANIZATION_HEARTBEAT:!0===t.maintenanceMode&&"memory_organization"===t.maintenanceModeType?"true":"false"}}async prepareMessageForRunner(e){return Co(e,{attachmentsDir:xe.resolveAttachmentsDir(this.options.input.userId,this.taskId),log:(e,t,n,...s)=>{this.log(e,t,n,...s)}})}setupMessageSavedListener(){this.messageSavedListener=()=>{this.triggerMessageProcessing()},this.historyDb.on("message-saved",this.messageSavedListener)}triggerMessageProcessing(){const e=this.getRunnerMode();"group_chat"===e||"group_work"===e?this.scheduleProcessPendingMessages():this.processPendingMessages()}scheduleProcessPendingMessages(){this.coordinator?.setDebouncing(!0),this.messageDebounceHandle&&clearTimeout(this.messageDebounceHandle),this.messageDebounceHandle=setTimeout(async()=>{this.messageDebounceHandle=null,await this.processPendingMessages(),this.coordinator?.setDebouncing(!1)},this.messageDebounceMs)}async start(){let e="completed";try{if(await this.initialize(),!await this.maybeConfirmAgentrixDevOpsInit())return;await this.handleEvent(),await this.runClaude()}catch(t){if(!(t instanceof mt)){e="error",this.log("warn","AGENT","Fatal error:",t);const n=t instanceof Error?t.message:String(t);await this.reportFatalError(n)}}finally{await this.exitWorker("error"===e?"error":this.exitReason)}}async autoInstallAgent(e){const t=this.options.input,n=t.agentGitUrl,s=t.agentGitSubDir;if(n)try{this.log("info","AGENT",`Auto-installing agent ${e} from git`),await Rs({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){this.log("warn","AGENT",`Auto-install failed for agent ${e}: ${t}`)}else this.log("warn","AGENT",`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=xe.agentrixAgentsHomeDir,a=T(s,`${e}.new`),i=T(s,`${e}-bak`);try{this.log("info","AGENT",`Applying upgrade for ${e}`),Ns(n),m(n,a),await il(t,i),h(t,{recursive:!0,force:!0}),m(a,t),$e(i)&&h(i,{recursive:!0,force:!0}),this.log("info","AGENT",`Upgrade applied for ${e}`)}catch(n){this.log("warn","AGENT",`Upgrade failed for ${e}: ${n}`),!$e(t)&&$e(i)&&m(i,t),$e(a)&&h(a,{recursive:!0,force:!0})}}async initialize(){const e=this.options.input,t=xe.resolveAgentDir(e.agentId),n=T(t,"upgrade"),s=Boolean(e.agentGitUrl),a=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&s&&!$e(t)),i=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!a&&$e(n));await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:a,upgradingAgent:i}),a&&await this.autoInstallAgent(e.agentId),i&&await this.applyAgentUpgrade(e.agentId,t,n);const o=await Gc.create(e.agentType,e.agentId,{agentDir:e.agentDir,logger:this.log.bind(this),context:this.agentContext});this.runner=o,this.initializePermissionModeState();const r=await this.workspace.setup();this.projectAgentrixGuidance=await rl(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${r.setupAction} at ${this.workingDirectory} (${r.initialCommitHash||"none"})`),this.setEnvironmentVariables(),this.lastProcessedSequence=this.historyDb.getAgentLastSequences().get(this.primaryAgentId)??0,this.log("info","HISTORY",`Starting from sequence ${this.lastProcessedSequence} (tracking: ${this.primaryAgentId})`),this.currentAgentSessionId&&(this.historyDb.upsertAgentSession(this.primaryAgentId,this.currentAgentSessionId),this.primarySessionReady=!0),this.setupMessageSavedListener(),this.workClient.sendWorkerInitialized(),this.workClient.sendTaskSlashCommandsUpdate(Zc())}createWorkspaceHandlers(e){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onRepositoryInit:async e=>{await(this.runner?.executeHook("RepositoryInit",e))},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:this.commitCurrentChangesWithAgent.bind(this),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onRepositoryInit:async e=>{await(this.runner?.executeHook("RepositoryInit",e))},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:this.commitCurrentChangesWithAgent.bind(this),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await Wt(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}setEnvironmentVariables(){this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.ANTHROPIC_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.ANTHROPIC_AUTH_TOKEN=this.options.input.api_key)}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new Tc({workerType:"claude",workClient:e,onCommandMessageProcessed:e=>{this.markPrimaryMessageProcessed(e)},handlers:{onNormalMessage:async e=>e,onBashCommand:async(e,t)=>{await this.executeBashCommand(e)},onMergeRequest:async e=>{await this.executeMergeRequest()},onMergePr:async()=>{await this.executeMergePr()},onNewSession:async()=>{await this.executeNewSession()},onAgentrixDevInit:async()=>{await Kt(this.taskId,this.options.input.userId),this.stopTask("event")},onPlanMode:async()=>this.isOneShotExecution()?(this.workClient.sendSystemErrorMessage("![plan] is not supported in oneshot execution mode",{groupId:this.currentGroupId??void 0}),null):(await this.requestPermissionMode("plan"),null)},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=Cr(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}if("sub-task-ask-user"===e){const e=t,n=_r(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}this.isOneShotExecution()?(await this.processPendingMessages(),this.coordinator.hasAgentMessages()||this.isStopping||this.stopTask("oneshot_complete")):this.triggerMessageProcessing(),"task-message"===e&&t?.eventId&&this.workClient.sendEventAck(t.eventId)}async executeMergeRequest(){this.log("info","MERGE","Executing merge-request command");const e=this.getRunnerMode(),t="group_chat"===e||"group_work"===e;try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await Aa(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await Ca(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Ma(this.workingDirectory,a,e)).files.length){const e="No changes to create PR: no files changed since task started";return void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}const i=await Ua(this.workingDirectory);this.log("info","MERGE",`Pushing branch ${i} to remote`),await fc(this.workingDirectory,i,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","Successfully pushed branch to remote");const o=this.runner?.getAgentConfiguration(),r=xc(a,(o?.customPRPromptTemplate?(n=o.customPRPromptTemplate,s={initialCommitHash:a,currentCommitHash:"",branchName:""},n.replace(/\{\{initialCommitHash\}\}/g,s.initialCommitHash).replace(/\{\{currentCommitHash\}\}/g,s.currentCommitHash).replace(/\{\{branchName\}\}/g,s.branchName)):void 0)??void 0);this.log("debug","MERGE",`PR prompt: ${r.substring(0,200)}...`);const c=this.runner;let l=null;const p=c.runStreamed(r,{cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:zc}});for await(const e of p){if(this.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){l=e;break}const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}if(!l)throw new Error("Merge-request did not return a result message");if("success"!==l.subtype)throw new Error("Merge-request did not return a successful result message");const d=Vc(l),u=await this.workClient.sendMergeRequest(d.title,d.description),m=`${d.userMessage}\n\n✅ Pull request created successfully!\nNumber: #${u.pullRequestNumber}\nURL: ${u.pullRequestUrl}`,h={input_tokens:l.usage.input_tokens??0,cached_input_tokens:l.usage.cache_read_input_tokens??0,output_tokens:l.usage.output_tokens??0,reasoning_output_tokens:0};this.workClient.sendTaskMessage(this.getChatSenderMeta(),Ys({sessionId:l.session_id,model:this.options.input.model??"unknown",numTurns:l.num_turns,usage:h,result:m}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.workClient.sendSystemErrorMessage(`❌ Merge-request failed: ${t}\n\nPlease check git status and try again, or create the PR manually.`,{groupId:this.currentGroupId??void 0})}var n,s}async executeBashCommand(e){if(!xe.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await Ic(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await Ec({workingDirectory:this.workingDirectory,workClient:this.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.logger,askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(){this.log("info","MERGE","Generating commit message with agent"),await sl({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),schemaTarget:"claude",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.taskAgentsMap.size>1?e:this.messageFilter.filter(e);null!==t&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}isAgentrixDevOpsInitWorker(){return this.options.input.agentId===_o}async maybeConfirmAgentrixDevOpsInit(){if(!this.isAgentrixDevOpsInitWorker())return!0;const e=Mo(this.options.input),t=(await this.askUser([Ro(e)],{onTimeout:"abort_task"})).answers[0]??"";return("zh-Hans"===e?"先初始化"===t:"Initialize first"===t)||(await zt(this.taskId,this.options.input.userId,"continue"),!1)}getAgentrixExtraTools(){if(this.isAgentrixDevOpsInitWorker())return[ut("complete_devops_init","Notify the Agentrix platform that Agentrix DevOps initialization is complete or that the user wants to leave the Agentrix-DevOps init session after it has completed. Call this only after project memory, environment guidance, local initialization state, and automated testing readiness are complete, or when the user explicitly asks to exit init/return to the development agent after choosing to stop. Do not call this because a normal response turn is ending.",{summary:tt.string().describe("Short user-visible summary of what initialization completed")},async e=>{const t=Mo(this.options.input),n=await this.askUser([No(t)],{onTimeout:"abort_task"}),s=function(e,t){const n=e.trim();return"zh-Hans"===t?"继续实现需求"===n||"继续"===n?"continue":"输入修改建议"===n||"修改建议"===n?"modify":"停止任务"===n||"停止"===n?"stop":null:"Continue request"===n||"Continue"===n?"continue":"Provide changes"===n||"Modify"===n?"modify":"Stop task"===n||"Stop"===n?"stop":null}(n.answers[0]??"",t);if(this.log("info","DEVOPS_INIT",`Post-init user decision: ${s??"unrecognized"} (answer=${JSON.stringify(n.answers[0]??"")})`),!s)return{content:[{type:"text",text:"The platform could not recognize the user post-init choice. Ask the user again or call complete_devops_init again after confirming the next action. Do not stop this DevOps init session yet."}]};if("modify"===s){const e=n.details?.[0]?.trim();return{content:[{type:"text",text:e?`The user wants additional Agentrix DevOps init changes before completion:\n${e}`:"The user wants additional Agentrix DevOps init changes before completion. Continue the same initialization session."}]}}return await zt(this.taskId,this.options.input.userId,"continue"===s?"continue":"stop"),setImmediate(()=>this.stopTask("event")),{content:[{type:"text",text:"continue"===s?`Agentrix DevOps initialization completed: ${e.summary}. The platform is switching back to the original development agent.`:`Agentrix DevOps initialization completed: ${e.summary}. The task will stop without starting the development agent.`}]}})]}async runClaude(){if(this.log("info","AGENT",`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void this.log("info","AGENT",`Skipping Claude run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runClaudeOneShot();const e=this.currentAgentSessionId,t=this.runner,n=this.getRunnerModeConfig(),s="group_chat"===n.mode||"group_work"===n.mode,a=this.createPermissionHandler(),i=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.initializePermissionModeState();const o=t.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:e,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:n,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableTaskPreviewUrl:dl(this.options.input),allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),visionModel:this.options.input.visionModel,canUseTool:a,hooks:i,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});this.loopPermissionModeSetter=o.setPermissionMode??null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.broadcastPermissionMode(this.getPermissionModeSnapshot()),await this.flushDesiredPermissionMode(),(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(!e){if(this.isStopping)break;continue}this.updateAgentRunning(!0),o.push(await this.prepareMessageForRunner(e));const t=e.__localSequence;if(void 0!==t&&(this.markPrimaryMessageProcessed(t),delete e.__localSequence),Boolean(e.__isChannelInput)){const t=e.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(t)?t:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}delete e.__isChannelInput,delete e.__channelReplyTarget}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of o.events)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,s);this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude agent finished for task ${this.taskId}`)}async runClaudeOneShot(){const e=this.runner,t=this.getRunnerModeConfig(),n="group_chat"===t.mode||"group_work"===t.mode,s=this.createPermissionHandler(),a=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.loopPermissionModeSetter=null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.initializePermissionModeState(),this.broadcastPermissionMode(this.getPermissionModeSnapshot());const i=await this.coordinator.waitForAgentMessage();if(!i)return this.isStopping||this.stopTask("oneshot_complete"),this.resetPrimaryPermissionState(),void this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&(this.markPrimaryMessageProcessed(o),delete i.__localSequence),Boolean(i.__isChannelInput)){const e=i.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(e)?e:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}delete i.__isChannelInput,delete i.__channelReplyTarget,this.updateAgentRunning(!0);try{const o=this.extractCompanionHeartbeatPromptPlaceholders(i),r=await this.prepareMessageForRunner(i),c=e.runStreamed(r,{cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:this.currentAgentSessionId,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:t,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableTaskPreviewUrl:dl(this.options.input),allowAskUser:!1,supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),visionModel:this.options.input.visionModel,canUseTool:s,hooks:a,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema(),promptPlaceholders:o});for await(const e of c)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,n);this.isStopping||this.stopTask("oneshot_complete")}finally{this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e,t){if("system"===e.type&&"init"===e.subtype)return this.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.workClient.sendTaskSlashCommandsUpdate(Zc(e.slash_commands??[]),e.session_id),this.currentAgentSessionId=e.session_id,this.historyDb.upsertAgentSession(this.primaryAgentId,e.session_id),this.primarySessionReady=!0,null!==this.pendingPrimaryLastSequence&&(this.historyDb.updateAgentLastSequence(this.primaryAgentId,this.pendingPrimaryLastSequence),this.pendingPrimaryLastSequence=null),this.refreshGroupId(),void this.updateAgentRunning(!0);if("result"===e.type)return await this.handleSdkResultMessage(e),this.refreshGroupId(),void this.updateAgentRunning(!1);"system"===e.type&&"task_notification"===e.subtype&&this.handleBackgroundTaskNotification(e);const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}resetPrimaryPermissionState(){this.loopPermissionModeSetter=null,this.activePermissionMode=null}updateAgentRunning(e){this.coordinator?.setAgentRunning(this.primaryAgentId,this.primaryAgentName,e)}markPrimaryMessageProcessed(e){this.historyDb.updateAgentLastSequence(this.primaryAgentId,e),this.primarySessionReady||(this.pendingPrimaryLastSequence=null===this.pendingPrimaryLastSequence?e:Math.max(this.pendingPrimaryLastSequence,e))}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}async handleAskUserQuestionPermission(e){const t=e,n=Array.isArray(t.questions)?t.questions:[];if(0===n.length)return this.log("warn","PERMISSION","AskUserQuestion missing questions"),{behavior:"deny",message:"AskUserQuestion missing questions"};const s=n.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]}));try{const e=await this.askUser(s),a={};for(let t=0;t<n.length;t+=1){const s=n[t]?.question;if(!s)continue;const i=e.answers?.[t];"string"==typeof i&&(a[s]=i)}return{behavior:"allow",updatedInput:{...t,answers:a}}}catch(e){return this.log("warn","PERMISSION",`AskUserQuestion failed: ${e}`),{behavior:"deny",message:"AskUserQuestion failed"}}}createPermissionHandler(){return async(e,t)=>{if("AskUserQuestion"===e)return this.handleAskUserQuestionPermission(t);if("ExitPlanMode"===e)return this.handleExitPlanModePermission(t);if(this.grantedPermissions.has(e))return this.log("info","PERMISSION",`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return this.log("info","PERMISSION",`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;this.log("info","PERMISSION",`Requesting permission for "${e}"`);const a=new Promise(e=>{s=e});this.pendingPermissions.set(e,a);try{const n=await this.requestToolPermission(e);return s(n),"allow"===n?(this.grantedPermissions.add(e),{behavior:"allow",updatedInput:t}):{behavior:"deny",message:"Permission denied by user"}}catch(e){return s("deny"),{behavior:"deny",message:"Permission request failed"}}finally{this.pendingPermissions.delete(e)}}}async handleExitPlanModePermission(e){const t=e.planFilePath??e.filePath;let n,s;if(t){const e=this.workspace.getCwd(),a=e.endsWith("/")?e:e+"/";n=t.startsWith(a)?t.slice(a.length):void 0;try{const e=await Pe.readFile(t,"utf-8");s=e.length>8e3?e.slice(0,8e3)+"\n\n…(truncated)":e}catch{}}!s&&"string"==typeof e.plan&&e.plan&&(s=e.plan);const a=[{question:"Review the plan and choose how to proceed.",header:"Plan Review",multiSelect:!1,options:[{label:"Approve",description:"Approve the plan and start implementation"},{label:"Revise",description:"Need to revise the plan",additionalInput:{enabled:!0,required:!1,placeholder:"Describe what should change."}},{label:"Cancel",description:"Cancel this plan"}],planFilePath:n,planContent:s}];try{const t=await this.askUser(a,{onTimeout:"abort_task"}),n=t.answers[0],s=t.details?.[0]?.trim();return"Approve"===n?{behavior:"allow",updatedInput:e}:"Revise"===n?{behavior:"deny",message:s?`The user wants to revise the plan. Revision notes: ${s}. Please reconsider and update the plan, then call ExitPlanMode again when ready.`:"The user wants to revise the plan. Please reconsider and update the plan, then call ExitPlanMode again when ready."}:(await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"User cancelled plan review",interrupt:!0})}catch{return await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"Plan review failed or was interrupted"}}}async requestToolPermission(e){const t=[{question:`Tool "${e}" is requesting permission to execute. Allow this operation?`,header:"Permission",multiSelect:!1,options:[{label:"Allow",description:"Allow this tool to execute"},{label:"Deny",description:"Deny this tool execution"}]}];try{return"Allow"===(await this.askUser(t,{onTimeout:"abort_task"})).answers[0]?"allow":"deny"}catch(e){return this.log("warn","PERMISSION",`Permission request failed: ${e}`),"deny"}}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.workClient;return Cc(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>n.sendAssistantMessage(e,{groupId:this.currentGroupId??void 0}),stopTask:e=>this.stopTask(e)},t)}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}getRunnerMode(){const e=this.taskAgentsMap.size>1,t=this.options.input.taskType,n=!(!process.env.AGENTRIX_COMPANION_HOME&&!process.env.AGENTRIX_COMPANION_WORKSPACE);return"shadow"===t?"companion_shadow":n&&"chat"===t?"companion_chat":e?"chat"===t?"group_chat":"group_work":"chat"===t?"chat":"work"}getGroupAgents(){if(!(this.taskAgentsMap.size<=1))return Array.from(this.taskAgentsMap.values()).map(e=>({id:e.id,name:e.name,description:e.description}))}getRunnerModeConfig(){return{mode:this.getRunnerMode(),supportChangeTitle:this.supportChangeTitle,groupAgents:this.getGroupAgents()}}shouldDisableClaudePlanModeTools(){const e=this.options.input.taskType;return"chat"===e||"shadow"===e||this.isChannelBoundTask()||Boolean(this.options.input.parentTaskId)}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}getStructuredOutputSchema(){return al(this.options.input.outputSchema)}createAgentrixTools(){const e=this.taskAgentsMap.size>1;if("companion_shadow"===this.getRunnerMode()){const e=this.options.input.chatId,t=this.options.input.userId,n=xe.resolveDataDir(t,e);this.chatHistoryDb=ko({dataDir:n,taskId:e})}return{createTask:Ur(t={agentContext:this.agentContext,workClient:this.workClient,uploadFile:e=>this.agentContext.uploadFile(e),credentials:this.credentials,taskId:this.taskId,chatId:this.options.input.chatId,agentId:this.primaryAgentId,isGroup:e,historyDb:this.historyDb,chatHistoryDb:this.chatHistoryDb??void 0,askUser:e=>this.askUser(e),log:this.log.bind(this),onChannelMessageInvoked:()=>{this.channelMessageInvocationCount+=1},invokeAgent:(e,t)=>this.invokeAgent(e,t),assign:(e,t,n)=>this.assignWork(e,t,n),setPendingNavigateTaskId:e=>{this.pendingNavigateTaskId=e},getChannelReplyTarget:()=>this.getInjectedChannelReplyTarget(),supportedFeatures:this.options.input.supportedFeatures,visionModel:this.options.input.visionModel}),createSoloTask:jr(t),createGroupTask:qr(t),replyToSubTask:Rr(t),changeTaskTitle:Pr(t),publishTaskPreviewUrl:Mr(t),askUser:Lr(t),getTaskHistory:Nr(t),getTaskAgents:Dr(t),listSubTask:Or(t),invoke:Hr(t),assign:Br(t),updateAgentInfo:Gr(t),sendReminder:zr(t),listTasks:Fr(t),readConversation:Wr(t),uploadFile:Kr(t),sendChannelMessage:Jr(t),getChannelGroupHistory:Yr(t),listAgents:Zr(t),analyzeImage:tc(t),scheduleTask:nc(t),prepareHiveRepository:sc(t),publishToHive:ac(t),updateHiveListingVersion:ic(t),recordHiveInstall:oc(t),createHiveReview:rc(t),createHiveComment:cc(t)};var t}resolveTaskAgentName(e){return this.taskAgentsMap.get(e)?.name||""}getChatSenderMeta(){return{senderType:"agent",senderId:this.primaryAgentId,senderName:this.primaryAgentName}}sendAgentErrorMessage(e,t,n,s){const a=t||e,i={type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:`System Error\n\n${a}: ${n}`}]}};this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:a},i,{groupId:s?.groupId})}async invokeAgent(e,t){const n=this.buildSubAgentHistoryContext(e,t);if(!n)return!1;const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new Jc,this.agentQueues.set(e,i));const o=this.resolveTaskAgentName(e),r=this.getRunnerMode(),c="group_chat"===r||"group_work"===r;return i.run(async()=>{this.coordinator?.setAgentRunning(e,o,!0);const t=this.newMessageGroupId();try{const s=await Gc.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),p=this.buildSystemHooks({trackBackgroundTasks:!1}),d=$r(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:dl(this.options.input),allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:l,hooks:p,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});let m=n.message;if("codex"===a&&!n.sessionId){const t=[zs(e,i),"=== CONVERSATION STREAM START FROM HERE ===",Js(n.message)].join("\n\n").trim();t&&(m=t)}"string"==typeof m?u.push(m):u.push(await this.prepareMessageForRunner(m));const h=n.lastSequence;let g=!1;n.sessionId&&(this.historyDb.updateAgentLastSequence(e,h),g=!0);let f=!1;for await(const n of u.events){if("system"===n.type&&"init"===n.subtype){this.historyDb?.upsertAgentSession(e,n.session_id),g||(this.historyDb.updateAgentLastSequence(e,h),g=!0);continue}if("result"===n.type){this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},n,{groupId:t}),f=!0;break}const s=c?n:d.filter(n);s&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},s,{groupId:t})}}catch(t){this.log("error","INVOKE",`Invoke failed for ${e}:`,t)}finally{this.coordinator?.setAgentRunning(e,o,!1)}}),!0}async assignWork(e,t,n){const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new Jc,this.agentQueues.set(e,i));const o=this.resolveTaskAgentName(e),r=this.getRunnerMode(),c="group_chat"===r||"group_work"===r;return i.run(async()=>{this.coordinator?.setAgentRunning(e,o,!0);const s=this.newMessageGroupId();var i;n&&this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},(i=n,{type:"assistant",session_id:"",uuid:crypto.randomUUID(),parent_tool_use_id:null,message:{role:"assistant",content:[{type:"text",text:i}]}}),{groupId:this.newMessageGroupId()});try{const n=await Gc.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),p=$r(),d=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:dl(this.options.input),allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:r,hooks:l,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});d.push(t);let u=!1;for await(const t of d.events){if("system"===t.type&&"init"===t.subtype)continue;if("result"===t.type){this.workClient.sendTaskMessage({senderType:"agent",senderId:e,senderName:o},t,{groupId:s}),u=!0;break}const n=c?t:p.filter(t);n&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},n,{groupId:s})}}catch(t){this.log("error","RUN_TASK",`Run task failed for ${e}:`,t);const n=t instanceof Error?t.message:String(t);this.sendAgentErrorMessage(e,o,`I meet some error: ${n}`,{groupId:s})}finally{this.coordinator?.setAgentRunning(e,o,!1)}})}buildSubAgentHistoryContext(e,t){const n=this.historyDb;if(!n)return this.log("warn","HISTORY","Task history DB unavailable; delegate cannot build context."),null;const s=n.getAgentSessions().get(e),a=n.getAgentLastSequences().get(e)??0,i=n.pageRecentMessagesAfter(a,20);if(0===i.data.length&&!t)return null;const o=this.mergeConsecutiveHumanMessages(i.data),r=this.buildHistoryMessages(o,t);return r?{message:r,sessionId:s,lastSequence:i.data.length>0?i.data[i.data.length-1].localSequence:a}:null}buildHistoryMessages(e,t){const n=[];for(const t of e){const e=cr(t);e&&n.push(e)}if(0===n.length&&!t)return null;let s=n.join("\n");return t&&(s=`<hint>\n${t}\n</hint>\n\n${s}`),{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}buildSystemHooks(e){const t=e?.trackBackgroundTasks??!0,n=e?.trackPrimaryAgentStop??!1,s={};return t&&(s.PostToolUse=async e=>(this.syncPermissionModeFromPostToolUse(e),this.trackBackgroundTaskFromPostToolUse(e),{})),n&&(s.Stop=async()=>(this.updateAgentRunning(!1),{})),s}trackBackgroundTaskFromPostToolUse(e){if(!e||"object"!=typeof e)return void this.log("debug","TASK","PostToolUse hook input is not an object");const t=e,n=t.tool_input;if(!n||!0!==n.run_in_background)return;const s=this.extractBackgroundTaskId(t.tool_response);if(!s)return this.log("debug","TASK",`PostToolUse(${t.tool_name}) run_in_background=true but no task_id found, using anonymous tracking`),void this.coordinator?.setAnonymousBackgroundTaskRunning(!0);this.coordinator?.setBackgroundTaskRunning(s,!0),this.log("info","TASK",`Background task started: ${s} (tool: ${t.tool_name})`)}syncPermissionModeFromPostToolUse(e){if(!e||"object"!=typeof e)return;const t=(n=e.tool_name,s=this.configuredPermissionMode,"EnterPlanMode"===n?"plan":"ExitPlanMode"===n?s:null);var n,s;t&&this.confirmPermissionModeApplied(t)}handleBackgroundTaskNotification(e){this.updateAgentRunning(!0),this.coordinator?.setBackgroundTaskRunning(e.task_id,!1),this.log("info","TASK",`Background task ${e.task_id} ${e.status}`)}extractBackgroundTaskId(e){const t=new Set,n=new Set,s=e=>{if("string"!=typeof e)return;const n=e.trim();n&&t.add(n)},a=e=>{if(null==e)return;if("string"==typeof e)return void(e=>{const t=/(task[_-]?id|agent[_-]?id|shell[_-]?id)["'\s:=]+([A-Za-z0-9._:-]+)/gi;let n;for(;null!==(n=t.exec(e));)s(n[2])})(e);if("object"!=typeof e)return;if(n.has(e))return;if(n.add(e),Array.isArray(e)){for(const t of e)a(t);return}const t=e;"string"==typeof t.task_id&&s(t.task_id),"string"==typeof t.taskId&&s(t.taskId),"string"==typeof t.agent_id&&s(t.agent_id),"string"==typeof t.agentId&&s(t.agentId),"string"==typeof t.shell_id&&s(t.shell_id),"string"==typeof t.shellId&&s(t.shellId);for(const e of Object.values(t))a(e)};a(e);const i=[...t];return i.length>1&&this.log("warn","TASK",`Multiple background task ids extracted (${i.join(", ")}), using first id ${i[0]}`),i[0]}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.taskAgentsMap.get(s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:xe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(this.credentials.token,this.credentials.machineId,t),dataEncryptionKey:this.options.dataEncryptionKey??null,keepAliveConfig:{intervalMs:2e4,event:"worker-alive",payloadGenerator:()=>{const e=this.coordinator?.getStatus(),n="running"===e?.state?"worker-running":"worker-ready";return{eventId:G(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString(),activeAgents:this.coordinator?.getActiveAgents(),permissionMode:this.getPermissionModeSnapshot()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>this.logger.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:xe.resolveAttachmentsDir(e,t),logger:(e,t,n,...s)=>{this.log(e,t,n,...s)},stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!le(e)||!this.shouldDropHeartbeatWhileBusy()||(this.log("debug","WORKER","Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(ee(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{Ac(e,this.options.input)},onWorkerStatusRequest:async()=>{const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning():"idle"===e&&this.workClient.sendWorkerReady()},onSubTaskResultUpdated:async e=>{const t=Cr(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=_r(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`),this.coordinator&&this.coordinator.stop(),this.workClient&&(this.workClient.sendWorkerExit(e),await this.workClient.disconnect()),this.historyDb&&this.historyDb.close(),this.chatHistoryDb&&this.chatHistoryDb.close(),process.exit(0)}async reportFatalError(e){await this.workClient.sendTerminalErrorResultAndWait(e,{groupId:this.currentGroupId??void 0})}log(e,t,n,...s){this.logger&&this.logger[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}const s=this.getRunnerMode(),a="group_chat"===s||"group_work"===s,i=this.pendingNavigateTaskId;if(this.pendingNavigateTaskId=null,a?this.workClient.sendTaskEvent(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}):this.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}),n)try{await yc(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}await this.forwardResultToChannelIfNeeded(e)}async forwardResultToChannelIfNeeded(e){if("result"!==e.type)return;const t=this.pendingChannelReplies.shift(),n=void 0===t?this.getInjectedChannelReplyTarget():t.target??this.getInjectedChannelReplyTarget();if(void 0===t&&!n)return;const s="success"===e.subtype,a=t?this.channelMessageInvocationCount>t.channelMessageInvocationCountAtStart:this.channelMessageInvocationCount>0;if(s&&a)return;const i=this.extractResultTextForChannel(e);if(!i)return;const o=await Vt(this.taskId,i,n),r=s;this.historyDb.saveTaskEvent({taskId:this.taskId,chatId:this.options.input.chatId,eventType:"channel-message-send",sequence:null,eventData:{status:o?.error?"error":"sent",delivery:r?"fallback":"error-forward",reason:r?"send_channel_message_not_invoked":"task_failed",channelId:n?.channelId,hasContent:!0,attachments:[],...o?.error?{error:o.error}:{}}}),o?.error&&this.log("debug","CHANNEL",`Claude reply was not sent to channel: ${o.error}`)}getInjectedChannelReplyTarget(){const e=process.env.AGENTRIX_CHANNEL_REPLY_TARGET;if(!e)return null;try{const t=JSON.parse(e);if("string"==typeof t.channelId&&"string"==typeof t.chatId)return{channelId:t.channelId,chatId:t.chatId,..."string"==typeof t.platform?{platform:t.platform}:{},..."string"==typeof t.chatType?{chatType:t.chatType}:{},..."string"==typeof t.chatName?{chatName:t.chatName}:{}}}catch(e){this.log("debug","CHANNEL","Ignoring invalid channel reply target:",e)}return null}isChannelBoundTask(){return null!==this.getInjectedChannelReplyTarget()}isChannelGroupBoundTask(){return"group"===this.getInjectedChannelReplyTarget()?.chatType?.toLowerCase()}getExternalChannelPromptContext(){const e=this.getInjectedChannelReplyTarget();if(e)return{platform:e.platform,chatType:e.chatType,chatName:e.chatName,chatId:e.chatId}}isChannelReplyTarget(e){return Boolean(e&&"object"==typeof e&&"string"==typeof e.channelId&&"string"==typeof e.chatId)}extractResultTextForChannel(e){if("success"===e.subtype){const t=e.result;if("string"!=typeof t)return null;const n=t.trim();return n.length>0?n:null}const t=e.errors,n=Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0).join("\n").trim():"",s=e.subtype;return`Task failed: ${n||("string"==typeof s?s:"Unknown error")}`}}class hl{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>lc(e)||e;if(n)return l(n);const p=xe.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.shouldUseWorktree(e)?l(p):e}return l(p)}static async shouldUseWorktree(e){try{return!$a(e)&&await xa(e)}catch{return!1}}}var gl=hn(Se);class fl{constructor(e,t){this.credentials=e,this.options=t}context;threadId=null;isStopping=!1;filteredToolUseIds=new Set;currentModel=null;dataEncryptionKey=null;abortController=new AbortController;coordinator;logger;askUserAwaiter=new Map;workClient;workspace;historyDb=null;currentGroupId=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return ol(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${ue()}`}async start(){try{await this.initialize(),await this.handleEvent(),await this.runCodex(),await this.exitWorker(this.exitReason)}catch(e){if(!this.isStopping){this.isStopping=!0,this.askUserAwaiter.clear(),this.coordinator?.stop(),this.log("warn","AGENT","Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}this.log("info","AGENT",`Task ${this.taskId} stopped gracefully`),await this.exitWorker(this.exitReason)}finally{process.exit(0)}}async initialize(){const e=this.options.input.taskId,t=this.options.input.userId;this.logger=this.createLogger({type:"worker",taskId:e}),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const n=pc(this.options.input),s=await hl.calculateFinalCwd(n),a={...n,cwd:s};this.log("info","INIT",`Phase 1: Working directory: ${s}`);const i=this.createWorkerClientConfig(t,e,s),o=xe.resolveDataDir(t,e);this.historyDb=ko({dataDir:o,taskId:e});const r=new br(i.config,{...i.handlers,historyDb:this.historyDb});this.workClient=r,this.log("info","INIT","Phase 2: WorkerClient created");const c=1e3*Math.max(0,this.options.idleTimeoutSecond??0);this.coordinator=this.createMessageCoordinator(r,c),this.log("info","INIT","Phase 3: Coordinator created"),await r.connect(),r.sendWorkerInitializing(),this.log("info","INIT","Phase 4: Connected to server"),this.log("info","INIT","Phase 5: Skipped (no AgentContext for Codex)"),this.log("info","INIT","Phase 6: Skipped (no custom resources for Codex)");const l=new Fc({options:a,handlers:this.createWorkspaceHandlers(r,s)}),{initialCommitHash:p,gitStateResult:d,setupAction:u}=await l.setup();this.workspace=l,this.projectAgentrixGuidance=await rl(s),this.log("info","INIT","Phase 7: Workspace setup complete"),r.sendWorkerInitialized(),r.sendTaskSlashCommandsUpdate(Zc()),this.log("info","INIT","Phase 8: Initialization finalized"),await this.registerWithDaemon(s),this.log("info","INIT","Phase 9: Registered with daemon"),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${u} at ${s} (${p||"none"})`),this.context={credentials:this.credentials,options:this.options,workClient:r,workingDirectory:s,initialCommitHash:p,logger:this.logger},process.env.AGENTRIX_WORKING_DIR=s,process.env.AGENTRIX_WORKING_USER=t,process.env.AGENTRIX_WORKING_TASK=e,this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.OPENAI_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.CODEX_API_KEY=this.options.input.api_key),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,this.log("info","AGENT",`Resuming thread: ${this.threadId}`))}createWorkspaceHandlers(e,t){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await Wt(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new Tc({workerType:"codex",workClient:e,handlers:{onNormalMessage:async e=>this.convertSDKMessageToCodexInput(e),onBashCommand:async(e,t)=>{await this.executeBashCommand(e)},onMergeRequest:async e=>{await this.executeMergeRequest()},onMergePr:async()=>{await this.executeMergePr()},onNewSession:async()=>{await this.executeNewSession()},onAgentrixDevInit:async()=>{await Kt(this.taskId,this.options.input.userId),this.stopTask("event")}},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){if("task-message"===this.options.input.event){const{eventId:e,message:t}=this.options.input.eventData;t&&te(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e&&this.workClient?.sendEventAck(e))}}async executeMergeRequest(){this.refreshGroupId(),this.log("info","MERGE","Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await Aa(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await Ca(this.context.workingDirectory),t=this.context.initialCommitHash,n=await Ua(this.context.workingDirectory);if(this.log("info","MERGE",`Pushing branch ${n} to remote`),await fc(this.context.workingDirectory,n,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","Successfully pushed branch to remote"),!t){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Ma(this.context.workingDirectory,t,e)).files.length){const e="No changes to create PR: no files changed since task started";return void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}const s=xc(t);this.log("debug","MERGE",`PR prompt: ${s.substring(0,200)}...`);const a=this.options.input.agentId??"default",i=await Gc.create("codex",a),o={mode:"work",supportChangeTitle:!1},r=i.runStreamed(s,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,abortController:this.abortController,modeConfig:o,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:Kc}});let c=null;for await(const e of r){if(this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){c=e;break}const t=this.filterMessages(e);null!==t&&this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}if(!c)throw new Error("Merge-request did not return a result message");const l=Vc(c);await this.createPullRequest(l.title,l.description),this.sendMessage(l.userMessage)}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){this.log("info","WORKER",`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!xe.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.context.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t=await Ic(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await Ec({workingDirectory:this.context.workingDirectory,workClient:this.context.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.context.logger,allowInteractive:!this.isOneShotExecution(),askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(e){const t=this.options.input.agentId??"default",n=await Gc.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");this.log("info","MERGE","Generating commit message with agent"),await sl({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},schemaTarget:"openai",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.filterMessages(e);null!==t&&this.getActiveWorkClient().sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return al(this.options.input.outputSchema)}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}async resolveCodexAgentrixEventMcp(){const e=await xe.readDaemonState();if(!e?.port)return this.log("debug","MCP","Agentrix event MCP broker unavailable: daemon state not found"),null;const t=dl(this.options.input),n=function(e,t){const n={taskId:t.taskId,userId:t.userId,machineId:t.machineId??e.machineId,nonce:de(16).toString("base64url"),taskPreviewEnabled:t.taskPreviewEnabled},s=(a=JSON.stringify(n),Buffer.from(a,"utf8").toString("base64url"));var a;return`${s}.${so(s,no(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId,taskPreviewEnabled:t});return{serverName:io,url:Bt(e,oo),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:ro,previewToolName:t?co:void 0,token:n}}buildCodexRunEnvironment(){if(this.codexAgentrixEventMcp)return{...process.env,[this.codexAgentrixEventMcp.tokenEnvVar]:this.codexAgentrixEventMcp.token}}async runCodex(){this.log("info","AGENT",`Starting Codex agent for task ${this.taskId}`),this.currentModel=jc(this.options.input.model),this.currentModel?this.log("info","AGENT",`Using model: ${this.currentModel}`):this.log("info","AGENT","Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await Gc.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void this.log("info","AGENT",`Skipping Codex run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runCodexOneShot(t,n);const s=t.loop({cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,enableTaskPreviewUrl:dl(this.options.input),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(e)this.refreshGroupId(),this.updateAgentRunning(!0),s.push(e);else if(this.isStopping)break}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.log("info","AGENT",`Codex agent finished for task ${this.taskId}`)}async runCodexOneShot(e,t){const n=await this.coordinator.waitForAgentMessage();if(!n)return this.isStopping||this.stopTask("oneshot_complete"),void this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId();const s=e.runStreamed(n,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:t,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,enableTaskPreviewUrl:dl(this.options.input),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.isStopping||this.stopTask("oneshot_complete")}finally{this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e){if("system"===e.type&&"init"===e.subtype)return this.threadId=e.session_id,this.context.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.context.workClient.sendTaskSlashCommandsUpdate(Zc(e.slash_commands??[]),e.session_id),this.log("info","AGENT",`Thread started: ${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);null!==t&&("result"===e.type?await this.handleSdkResultMessage(t):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"!==e.type?this.updateAgentRunning(!0):this.updateAgentRunning(!1)}filterMessages(e){const t=e,n=t?.message?.content;if(!n||"string"==typeof n)return e;const s=n.filter(e=>{return"tool_use"!==e.type||"agentrix"!==(n=e.server_name)&&n!==io?!("tool_result"===e.type&&this.filteredToolUseIds.has(e.tool_use_id)||"user"===t.type&&"tool_result"!==e.type):(this.filteredToolUseIds.add(e.id),!1);var n});return 0===s.length?null:(t.message.content=s,t)}sendMessage(e){const t={type:"assistant",message:{id:ue().toString(),type:"message",container:null,role:"assistant",content:[{citations:null,type:"text",text:e}],model:this.currentModel||"",usage:{},stop_reason:null,context_management:null,stop_sequence:null},parent_tool_use_id:null,session_id:"",uuid:ue().toString()};this.getActiveWorkClient().sendTaskMessage(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.getActiveWorkClient();return Cc(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>this.sendMessage(e),stopTask:e=>this.stopTask(e)},t)}getActiveWorkClient(){const e=this.context?.workClient??this.workClient;if(!e)throw new Error("[WORKER] WorkerClient not available");return e}resolveTaskAgentName(e){const t=this.options.input.taskAgents??[];return t.find(t=>t.id===e)?.name||""}getChatSenderMeta(){const e=this.options.input.agentId;return{senderType:"agent",senderId:e,senderName:this.resolveTaskAgentName(e)??""}}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t){this.log("info","MERGE",`Creating PR: ${e}`);try{const n=await this.context.workClient.sendMergeRequest(e,t);this.sendMessage(`✅ Pull request created successfully!\nNumber: #${n.pullRequestNumber}\nURL: ${n.pullRequestUrl}`)}catch(e){this.log("error","MERGE","Failed to create PR:",e),this.sendMessage(`❌ Failed to create pull request: ${e instanceof Error?e.message:"Unknown error"}`)}}async convertSDKMessageToCodexInput(e){const t=e.message.content;if("string"==typeof t)return t;if(Array.isArray(t)){const e=[],n=xe.resolveAttachmentsDir(this.options.input.userId,this.taskId);for(const s of t)if("text"===s.type&&s.text)e.push(s.text);else if("image"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:s}=await Ao(t,n,!1);this.log("info","IMAGE",`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){this.log("error","IMAGE",`Failed to download image from ${t}:`,e)}}else if("document"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:a,mimeType:i,filename:o}=await Ao(t,n,!0);this.log("info","DOCUMENT",`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){this.log("error","DOCUMENT",`Failed to download document from ${t}:`,e)}}const s=e.map(e=>e.trim()).filter(Boolean).join("\n\n").trim();if(s)return s}return""}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}updateAgentRunning(e){this.coordinator?.updateAgentRunning(e)}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.options.input.taskAgents?.find(e=>e.id===s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:xe.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:V(this.credentials.token,this.credentials.machineId,t),dataEncryptionKey:this.dataEncryptionKey,keepAliveConfig:{intervalMs:2e4,event:"worker-alive",payloadGenerator:()=>{const e=this.coordinator?.getStatus(),n="running"===e?.state?"worker-running":"worker-ready";return{eventId:G(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>(this.context?.logger??this.logger)?.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:xe.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(ee(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}te(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{Ac(e,this.options.input)},onWorkerStatusRequest:async()=>{if(!this.context?.workClient)return;if(!this.coordinator)return;const{state:e}=this.coordinator.getStatus();"running"===e?this.context.workClient.sendWorkRunning():"idle"===e&&this.context.workClient.sendWorkerReady()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`);const n=this.context?.workClient??this.workClient;n&&("error"===e&&t?await n.sendErrorMessageAndExit(t):(n.sendWorkerExit(e),await n.disconnect()),this.historyDb&&this.historyDb.close())}createLogger(e){const{createLogger:t}=gl;return t(e)}log(e,t,n,...s){const a=this.context?.logger??this.logger;a&&a[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}getCurrentModel(){return this.currentModel||"unknown"}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}if(this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0}),n)try{await yc(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}}}function vl(){const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(!e)return;if(e.includes("/")||e.includes("\\")||e.startsWith(".")){const t=I.isAbsolute(e)?e:I.resolve(e);return o.existsSync(t)?t:void 0}const t="win32"===process.platform?"where":"which",n=it(t,[e],{encoding:"utf-8"});return 0===n.status?n.stdout.split(/\r?\n/).map(e=>e.trim()).find(e=>e.length>0):void 0}function yl(e){const t=e.map(e=>e.toLowerCase().trim().replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")).filter(Boolean);return[...new Set(t)].slice(0,8)}function xl(e,t=""){const n=o.readdirSync(e,{withFileTypes:!0}),s=[];for(const a of n){const n=t?`${t}/${a.name}`:a.name;"node_modules"!==a.name&&".git"!==a.name&&(a.isDirectory()?s.push(...xl(I.join(e,a.name),n)):s.push(n))}return s}async function wl(e,t,n){const s=xl(e).map(e=>` - ${e}`).join("\n");return new Promise((a,i)=>{let o=!1,r=null;const c=e=>{o||(o=!0,clearTimeout(p),a(e))},l=e=>{o||(o=!0,clearTimeout(p),i(e))},p=setTimeout(()=>{c({approved:!1,reasons:["Review timed out after 10 minutes"],tags:[]})},6e5),d=(u=e=>{r=e,c(e)},ut("hive_publish_review","Submit your security review decision for this Hive publish request. You MUST call this tool exactly once after reviewing all source files.",{approved:tt.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:tt.array(tt.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:tt.array(tt.string()).describe("3-8 concise marketplace discovery tags describing the agent or skill capability. Use lowercase kebab-case.")},async e=>(u({approved:e.approved,reasons:e.reasons,tags:yl(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=pt({name:"hive_review",version:"1.0.0",tools:[d]}),h=[`Review the ${n} "${t}" for security issues before publishing to Hive.`,"",`Source directory: ${e}`,"","Files to review:",s,"","Read each file, then call mcp__hive_review__hive_publish_review with your decision."].join("\n"),g=dt({prompt:h,options:{systemPrompt:'You are a security reviewer for the Agentrix Hive marketplace.\nYour job is to review agent/skill source code before it is published to the public repository.\n\nYou MUST check for real publish-blocking security issues:\n1. **Hardcoded secrets**: API keys, tokens, passwords, private keys, credentials in any file\n2. **PII exposure**: emails, phone numbers, physical addresses, names of real people that appear to be user data or sensitive personal data\n3. **Data exfiltration**: suspicious network requests, unauthorized file uploads, sending user data to external servers\n4. **Malicious code**: eval/exec of untrusted input, shell injection, code that modifies files outside workspace\n5. **Dependency risks**: suspicious or known-malicious packages, typo-squatting package names\n6. **Permission abuse**: code or instructions that abuse permissions to access sensitive files, steal data, persist malware, or operate outside the intended agent/skill workflow\n\nAgentrix-specific review guidance:\n- Do NOT reject solely because an agent config uses permissionMode "bypassPermissions".\n- Do NOT reject solely because allowedTools includes Bash, WebFetch, Read, Write, Edit, or other normal Agentrix/Claude tools. These tools are part of the Agentrix runtime model.\n- Reject permission usage only when the source contains malicious or clearly unsafe behavior, such as reading secrets from home directories, scanning unrelated user files, silently uploading data, destructive shell commands, persistence, credential theft, or instructions to bypass user intent.\n- Generated/local build metadata such as avatar/upload-avatar.json may contain local file paths or localhost URLs from the creator\'s machine. Treat these as cleanup suggestions, not publish-blocking security issues, unless they contain secrets or sensitive personal data beyond ordinary development paths.\n- Ordinary repository paths, localhost URLs, sample usernames in paths, generated artifact paths, and non-secret build cache metadata are not enough to reject a publish request.\n- If you find non-blocking cleanup suggestions, include them in reasons while still approving.\n\nProcess:\n1. Read EVERY source file in the directory using the Read tool\n2. Analyze each file for the issues listed above\n3. Assign marketplace discovery tags for the source. Tags should describe what the agent/skill does, its domain, and useful capability filters.\n4. Call mcp__hive_review__hive_publish_review with your decision and tags.\n\nTag rules:\n- Provide 3-8 tags.\n- Use lowercase kebab-case, for example: web-design, code-review, react, testing, documentation.\n- Prefer functional/domain tags over generic labels.\n\nBe strict about real security issues, but do not reject normal Agentrix runtime configuration or harmless generated local metadata. Approve when there is no credible exploit, secret, malicious behavior, or sensitive user-data exposure.',permissionMode:"bypassPermissions",settingSources:["user","project","local"],maxTurns:30,cwd:e,mcpServers:{hive_review:m},pathToClaudeCodeExecutable:vl(),stderr:e=>{const t=String(e).trim();t&&console.error(`[HiveReview] Claude stderr: ${t}`)}}});(async()=>{try{for await(const e of g)if("result"===e.type&&e.is_error&&!r){const t=e.result;return void l(new Error(`Claude security review failed: ${t||"unknown Claude Code error"}`))}r||l(new Error("Claude security review finished without submitting a review decision"))}catch(e){l(e)}})()})}const bl=ht(ct);function kl(e,t,n){const s=xe.serverUrl.replace(/^http/,"ws");return Ue(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function Il(e,...t){const{stdout:n}=await bl("git",t,{cwd:e});return n.trim()}function Tl(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const Sl=ht(ct);function El(e,t,n){const s=xe.serverUrl.replace(/^http/,"ws");return Ue(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const Al=["claude","codex","deployment","companion","hive-publish","hive-install"],Cl={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=xe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const n=pc(t.input),s=await hl.calculateFinalCwd(n),a=new ml(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=xe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const n=new fl(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:xe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,sourcePath:a,targetAgentId:i,userId:r,name:c,avatar:l,isSystemAgent:p,supportLocal:d}=n;let u=null;try{if(console.log(`[Deployment] Starting deployment worker for task ${s}`),!o.existsSync(a))throw new Error(`Source path not found: ${a}`);const t=I.join(xe.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await il(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=xe.serverUrl.replace(/^http/,"ws");return Ue(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}(e,0,s),await new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("WebSocket connection timeout"))},1e4);u.on("connect",()=>{clearTimeout(n),console.log("[Deployment] Connected to server"),u.emit("deploy-agent-complete",{eventId:G(),taskId:s,targetAgentId:i,success:!0,name:c,avatar:l,isSystemAgent:p,supportLocal:d}),console.log("[Deployment] Sent deploy-agent-complete event"),setTimeout(()=>{e()},1e3)}),u.on("connect_error",e=>{clearTimeout(n),t(e)})})}catch(e){throw console.error("[Deployment] Deployment failed:",e),u&&u.connected&&(u.emit("deploy-agent-complete",{eventId:G(),taskId:s,targetAgentId:i,success:!1,error:e instanceof Error?e.message:String(e)}),await new Promise(e=>setTimeout(e,1e3))),e}finally{u&&u.disconnect(),process.exit(0)}}(e,i)}},"hive-publish":{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:xe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,listingId:a,userId:i,sourceDir:r,gitUrl:c,version:l}=n;let p,d,{repoDir:u,name:m}=n,h=n.displayName,g=n.description,f=n.readme,v=null,y=null;try{if(n.environmentVariables)for(const[e,t]of Object.entries(n.environmentVariables))null!=t&&(process.env[e]=String(t));if(console.log(`[HivePublish] Starting for task ${s}, name=${m}`),function(e,t){if(!o.existsSync(e))throw new Error(`Source directory not found: ${e}`);if(!o.statSync(e).isDirectory())throw new Error(`Source path is not a directory: ${e}`);if("skill"===t&&!o.existsSync(I.join(e,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${e}`)}(r,n.type),"skill"===n.type){const e=function(e){const t=I.join(e,"SKILL.md"),n=o.readFileSync(t,"utf-8"),s=n.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);if(!s)throw new Error("SKILL.md must start with YAML frontmatter containing name and description");const a=s[1],i=new Map;for(const e of a.split(/\r?\n/)){const t=e.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);t&&i.set(t[1],t[2].replace(/^["']|["']$/g,"").trim())}const r=i.get("name"),c=i.get("description");if(!r)throw new Error("SKILL.md frontmatter must include name");if(!c)throw new Error("SKILL.md frontmatter must include description");return{name:Tl(r),displayName:r,description:c,readme:n,repoDirName:Tl(r)}}(r);m=e.name,h=e.displayName,g=e.description,f=e.readme,u=I.posix.join(u,e.repoDirName),console.log(`[HivePublish] Parsed skill metadata name=${m}, displayName=${h}`)}y=I.join(xe.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(y,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await Il(y,"clone","--depth","1",c,".");const t=I.join(y,u);if(o.mkdirSync(I.dirname(t),{recursive:!0}),"skill"===n.type&&o.existsSync(t))throw new Error(`Skill already exists in Hive repository: ${u}`);o.existsSync(t)&&o.rmSync(t,{recursive:!0,force:!0}),console.log(`[HivePublish] Copying ${r} → ${u}`),await il(r,t),o.writeFileSync(I.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await Il(y,"add",".");const i=await async function(e){try{return await bl("git",["diff","--cached","--quiet"],{cwd:e}),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}(y);if(i){console.log("[HivePublish] Running Claude security review...");const e=await wl(r,m,n.type);if(p=e.reasons,d=e.tags,!e.approved)throw new Error(`Security review rejected: ${e.reasons.join("; ")}`);console.log("[HivePublish] Security review passed");const t=`publish: ${u} v${l}`;await Il(y,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await Il(y,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const x=await Il(y,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${x}`),v=kl(e,0,s),await new Promise((e,t)=>{const n=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);v.on("connect",()=>{clearTimeout(n),v.emit("hive-publish-complete",{eventId:G(),taskId:s,listingId:a,success:!0,gitCommitHash:x,hasChanges:i,tags:d,name:m,displayName:h,description:g,readme:f,repoDir:u}),console.log("[HivePublish] Sent hive-publish-complete (success)"),setTimeout(e,1e3)}),v.on("connect_error",e=>{clearTimeout(n),t(e)})})}catch(t){console.error("[HivePublish] Failed:",t);try{v=v??kl(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{v.emit("hive-publish-complete",{eventId:G(),taskId:s,listingId:a,success:!1,error:t instanceof Error?t.message:String(t),reviewReasons:p}),clearTimeout(n),setTimeout(e,1e3)};v.connected?i():(v.on("connect",i),v.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HivePublish] Failed to send error event")}throw t}finally{if(v&&v.disconnect(),y&&o.existsSync(y))try{o.rmSync(y,{recursive:!0,force:!0})}catch{}process.exit(0)}}(e,i)}},"hive-install":{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:xe.readTaskInput(n,s)};await async function(e,t){const n=t.input,{taskId:s,userId:a,sourceRepoDir:i,gitUrl:r,name:c,sourceType:l}=n,p=n.installDir??n.draftAgentDir;let d=null,u=null;try{console.log(`[HiveInstall] Starting for task ${s}, name=${c}`),u=I.join(xe.agentrixHomeDir,"tmp","hive-install",s),o.mkdirSync(u,{recursive:!0}),console.log("[HiveInstall] Cloning hive repo..."),await async function(e,...t){const{stdout:n}=await Sl("git",t,{cwd:e});return n.trim()}(u,"clone","--depth","1",r,".");const t=I.join(u,i);if(!o.existsSync(t))throw new Error(`Source directory not found in hive repo: ${i}`);if("skill"===l&&!o.existsSync(I.join(t,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${i}`);const n=(m=p).startsWith("~/")?I.join(process.env.HOME||"",m.slice(2)):I.isAbsolute(m)?m:I.join(xe.agentrixHomeDir,m);if(o.existsSync(n))throw new Error(`Target install directory already exists: ${n}`);if(o.mkdirSync(n,{recursive:!0}),console.log(`[HiveInstall] Copying ${i} → ${n}`),await il(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),Ns(n)}catch(e){try{o.rmSync(n,{recursive:!0,force:!0})}catch{}throw e}const a=I.join(n,".git");o.existsSync(a)&&(o.rmSync(a,{recursive:!0,force:!0}),console.log("[HiveInstall] Removed .git from installed directory")),console.log("[HiveInstall] Install completed successfully"),d=El(e,0,s),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);d.on("connect",()=>{clearTimeout(a),d.emit("hive-install-complete",{eventId:G(),taskId:s,success:!0,agentDir:n}),console.log("[HiveInstall] Sent hive-install-complete (success)"),setTimeout(e,1e3)}),d.on("connect_error",e=>{clearTimeout(a),t(e)})})}catch(t){console.error("[HiveInstall] Failed:",t);try{d=d??El(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{d.emit("hive-install-complete",{eventId:G(),taskId:s,success:!1,error:t instanceof Error?t.message:String(t)}),clearTimeout(n),setTimeout(e,1e3)};d.connected?a():(d.on("connect",a),d.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HiveInstall] Failed to send error event")}throw t}finally{if(d&&d.disconnect(),u&&o.existsSync(u))try{o.rmSync(u,{recursive:!0,force:!0})}catch{}process.exit(0)}var m}(e,i)}},companion:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=xe.readTaskInput(n,s),o=i.dataEncryptionKey?L(i.dataEncryptionKey):null;if(o&&32!==o.length)throw new Error("Invalid dataEncryptionKey: expected decrypted 32-byte key");const r={startedBy:t,idleTimeoutSecond:a,input:i,dataEncryptionKey:o};await async function(e,t){const{agentDir:n,homeDir:s}=await ci();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=pc(t.input),i=await hl.calculateFinalCwd(a),o=new ml(e,t,i);await o.start()}(e,r)}}};async function _l(){const e=function(){try{const e=Ne(be(),"package.json"),t=JSON.parse(_e(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}();try{const t=Je("npm view @agentrix/cli version",{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:5e3}).trim();return{hasUpgrade:function(e,t){const n=e.split(".").map(Number),s=t.split(".").map(Number);for(let e=0;e<Math.max(n.length,s.length);e++){const t=n[e]||0,a=s[e]||0;if(t>a)return 1;if(t<a)return-1}return 0}(t,e)>0,currentVersion:e,latestVersion:t}}catch(t){return{hasUpgrade:!1,currentVersion:e,latestVersion:null}}}function $l(){return"true"===process.env.AGENTRIX_DISABLE_AUTO_UPGRADE}async function Pl(e){try{const{execSync:t}=await import("child_process");return console.log(""),e||(console.log(D.blue("🔄 Checking for upgrades...")),e=await _l()),e.hasUpgrade?(console.log(D.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`)),t("npm install -g @agentrix/cli@latest",{stdio:"inherit"}),console.log(D.green("✓ Upgrade complete")),console.log(""),!0):(console.log(D.green("✓ Already on latest version")),console.log(""),!0)}catch(e){return console.log(""),console.log(D.yellow("⚠️ Auto-upgrade failed")),console.log(D.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}async function Ml(e,t){const n=`${xe.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function Rl(e){try{const t=c(T(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function Nl(e,t){const n=e=>e.split(".").map(e=>parseInt(e,10)||0),s=n(e),a=n(t);for(let e=0;e<Math.max(s.length,a.length);e++){const t=s[e]??0,n=a[e]??0;if(t>n)return!0;if(t<n)return!1}return!1}async function Dl(e){const t=xe.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>d(T(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=T(t,s),a=T(n,"upgrade");if(r(a))continue;const i=Rl(n);we.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await Ml(s,e);if(!t||!t.gitUrl){we.info(`[AGENT UPDATE] No git repo for ${s}, skipping`);continue}const n=`${a}.tmp-${Date.now()}`;try{const e=["git","clone","--depth=1","--branch",t.branch,t.gitUrl,n];rt(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?T(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=Rl(o);if(!c||i&&!Nl(c,i)){we.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}we.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),we.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){we.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}function Ol(){const e=xe.getStatePaths();return Re.join(Re.dirname(e.daemonStateFile),"upgrade-daemon.state.json")}function Ul(){try{const e=Ol();if(!Ce.existsSync(e))return null;const t=Ce.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function jl(e){try{const t=Ol();if(Ce.existsSync(t)){if("number"==typeof e){const t=Ul();if(!t||t.pid!==e)return}Ce.unlinkSync(t)}}catch{}}function ql(e){try{return process.kill(e,0),!0}catch{return!1}}function Ll(){const e=Ul();return!(!e||!ql(e.pid)&&(jl(),1))}function Hl(){const e=Ul();if(e)try{ql(e.pid)&&process.kill(e.pid,"SIGTERM")}catch{}finally{jl()}}async function Gl(){if($l())return"no-upgrade";const e=await _l();if(e.hasUpgrade&&await Pl(e))return await Qt(),await new Promise(e=>setTimeout(e,1e3)),wo(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),"upgraded";try{const e=await xe.readCredentials();e&&await Dl(e)}catch{}return"no-upgrade"}var Bl=Object.freeze({__proto__:null,isUpgradeDaemonRunning:Ll,startUpgradeDaemon:async function(){await async function(){!function(e){const t=Ol();Ce.writeFileSync(t,JSON.stringify(e,null,2))}({pid:process.pid,startedAt:(new Date).toISOString()}),process.on("SIGTERM",()=>{jl(process.pid),process.exit(0)}),process.on("SIGINT",()=>{jl(process.pid),process.exit(0)});try{"upgraded"===await Gl()&&(wo(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}for(;;){await new Promise(e=>setTimeout(e,216e5));try{"upgraded"===await Gl()&&(wo(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}}}()},stopUpgradeDaemon:Hl});function Fl(e,t){const n=e.trim();if(!n)throw new Error(`${t} is required`);let s;try{s=new URL(n)}catch{throw new Error(`${t} must be a valid URL`)}if("http:"!==s.protocol&&"https:"!==s.protocol)throw new Error(`${t} must use http or https`);return s.toString().replace(/\/+$/,"")}async function Wl(e,t){if(!Dt.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=Ut({input:Dt,output:Ot});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}async function zl(){const e=await Sn();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}function Kl(e){return"string"==typeof e&&e.trim()?e.trim():void 0}async function Vl(e){const t=await zl(),n=Fl(Kl(e["base-url"])??await Wl("GitLab base URL"),"baseUrl"),s=Fl(Kl(e["api-url"])??await Wl("GitLab API URL",function(e){return`${Fl(e,"baseUrl")}/api/v4`}(n)),"apiUrl"),a=(Kl(e["pat-file"])?function(e){if("-"===e)return c(0,"utf8").trim();if(!r(e))throw new Error(`File not found: ${e}`);return c(e,"utf8").trim()}(Kl(e["pat-file"])):void 0)??await async function(e){return Dt.isTTY&&Ot.isTTY&&"function"==typeof Dt.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{Dt.setRawMode(!1),Dt.pause(),Dt.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Ot.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Ot.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Ot.write(`${e}: `),Dt.setRawMode(!0),Dt.resume(),Dt.on("data",i)}):Wl(e)}("GitLab PAT");if(!a)throw new Error("GitLab PAT is required");let i;const o=await async function(e,t){const{result:n,user:s}=await He(e,t);return{valid:n.valid,username:n.username,scopes:n.scopes,meta:n.valid&&s?{username:s.username,email:s.email||"",lastValidatedAt:(new Date).toISOString(),expiresAt:n.expiresAt}:void 0}}(s,a);if(!o.valid)throw new Error(`PAT validation failed for ${s}/user`);i=o.meta;const l=await async function(e){const t=await async function(e){return await Ft("/git-server/register",e)}({name:new URL(e.baseUrl).hostname,baseUrl:e.baseUrl,apiUrl:e.apiUrl});if(t.error||!t.gitServer)throw new Error(`Backend Git server registration failed: ${t.error||"Daemon did not return a registered Git server"}`);return{id:t.gitServer.id,baseUrl:t.gitServer.baseUrl,apiUrl:t.gitServer.apiUrl}}({baseUrl:n,apiUrl:s});var p,d;i&&(p=l.id,d=i,Tn.savePatMeta(p,d)),function(e,t){Tn.saveGitServerConfig(e,t)}(l.id,{baseUrl:l.baseUrl,apiUrl:l.apiUrl}),function(e,t,n){Tn.savePat(e,t,n)}(l.id,a,t);const u=function(e,t){return Tn.ensureGitLabWebhookSecret(e,t)}(l.id,t),m=await async function(e){return await Ft("/git-server/complete",{gitServerId:e})}(l.id);if(m.error||!m.success)throw new Error(`Backend Git server completion failed: ${m.error||"Daemon did not confirm completion"}`);console.log(JSON.stringify({id:l.id,type:"gitlab",baseUrl:l.baseUrl,apiUrl:l.apiUrl,webhookEndpointPath:Ke(l.id),webhookUrl:ze(l.id,await xe.readDaemonState()),backendRegistered:!0,patConfigured:!0,patMeta:Cn(l.id),webhookSecret:u},null,2))}function Xl(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function Jl(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||xe.serverUrl}function Yl(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return w(T(t,e),b.X_OK),!0}catch{return!1}})}function Ql(e,t,n){return new Promise((s,a)=>{const i=ot(e,t,{stdio:"inherit",shell:n?.shell||!1,env:process.env});i.on("error",a),i.on("close",t=>{0===t?s():a(new Error(`${e} exited with code ${t}`))})})}async function Zl(e){try{return await xt(e),!0}catch{return!1}}function ep(e){return e.filter(e=>e.required&&!e.installed)}async function tp(e,t){Yl(e)?console.log(D.green(`✓ ${e} is installed`)):Yl("npm")?(console.log(D.blue(`Installing ${e} with npm...`)),await Ql("npm",["install","-g",t])):console.log(D.yellow(`npm is not available. Install ${t} manually.`))}async function np(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function sp(e,t,n=!0){const s=n?"Y/n":"y/N",a=(await e.question(`${t} (${s}): `)).trim().toLowerCase();return a?"y"===a||"yes"===a:n}async function ap(e,t,n,s){for(console.log(t),n.forEach((e,t)=>{const n=e.value===s?" default":"";console.log(` ${t+1}. ${e.label}${n}`)});;){const t=(await e.question("Select: ")).trim();if(!t)return s;const a=Number.parseInt(t,10);if(!Number.isNaN(a)&&n[a-1])return n[a-1].value;const i=n.find(e=>e.value===t);if(i)return i.value;console.log(D.yellow("Invalid selection"))}}function ip(e){return JSON.stringify(e)}async function op(e,t){const n=await async function(e){try{return(await ye.get(`${xe.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||Jl()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(D.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),Jl()}}(t),s=Ut({input:Dt,output:Ot});try{await async function(e,t,n){const s=T(xe.claudeConfigDir,"settings.json");if(!t&&await Zl(s)&&!await sp(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(D.gray("Skipped Claude config"));const a=await ap(e,"Configure Claude provider",[{value:"agentrix",label:"Agentrix API"},{value:"official",label:"Anthropic official API"},{value:"proxy",label:"Custom Anthropic-compatible proxy"},{value:"skip",label:"Skip Claude config"}],"agentrix");if("skip"===a)return void console.log(D.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await np(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await np(e,"Agentrix API key for Claude");else{const t=await np(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await np(e,"Anthropic auth token")}const o=await np(e,"Claude primary model","claude-sonnet-4-6"),r=await np(e,"Claude fast model","claude-haiku-4-5"),c=await np(e,"Claude subagent model",o||"claude-sonnet-4-6");i.ANTHROPIC_MODEL=o,i.CLAUDE_CODE_SUBAGENT_MODEL=c,i.ANTHROPIC_SMALL_FAST_MODEL=r,i.ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-6",i.ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4-6",i.ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5",await yt(xe.claudeConfigDir,{recursive:!0}),await vt(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(D.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=T(xe.codexHomeDir,"config.toml");if(!t&&await Zl(s)&&!await sp(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(D.gray("Skipped Codex config"));const a=await ap(e,"Configure Codex provider",[{value:"agentrix",label:"Agentrix API"},{value:"openai",label:"OpenAI official API"},{value:"custom",label:"OpenAI-compatible custom API"},{value:"skip",label:"Skip Codex config"}],"agentrix");if("skip"===a)return void console.log(D.gray("Skipped Codex config"));const i=await np(e,"Codex model","gpt-5.5"),o=await ap(e,"Codex API wire format",[{value:"responses",label:"Responses API"},{value:"chat",label:"Chat Completions API"}],"agentrix"===a?"responses":"chat"),r={};let c,l;"agentrix"===a?(c=n,l="AGENTRIX_API_KEY",r[l]=await np(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await np(e,"OpenAI API key")):(c=await np(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await np(e,"Custom API key")),await yt(xe.codexHomeDir,{recursive:!0}),await vt(s,function(e){const t=e.provider,n=[`model = ${ip(e.model)}`,`model_provider = ${ip(t)}`,'approval_policy = "never"',"","[sandbox_workspace_write]","writable_roots = []","network_access = true","exclude_tmpdir_env_var = false","","[features]","hide_agent_reasoning = false","show_raw_agent_reasoning = false",'file_opener = "vscode"',"",`[model_providers.${t}]`,`name = ${ip("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${ip(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${ip(s)}`)}return e.envKey&&n.push(`env_key = ${ip(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=xe.readOrInitSettings({sandbox:xe.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};xe.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(D.green(`✓ Wrote Codex config: ${s}`)),console.log(D.green(`✓ Wrote Codex env vars to ${xe.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function rp(e={}){console.log(D.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=rs(),t=[...ep(e.cli.filter(e=>"claude"!==e.name)),...ep(e.sandbox)];"linux"!==process.platform||Yl("rg")||t.push({name:"ripgrep",installed:!1,required:!0,description:"Fast code search tool",installCommand:"sudo apt install ripgrep"}),await async function(e){if(0===e.length)return void console.log(D.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(D.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(D.yellow(`- ${t.name}: ${t.installCommand||"install manually"}`));return}const t=[{name:"apt-get",installCommand:e=>["sudo","apt-get","update","&&","sudo","apt-get","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"dnf",installCommand:e=>["sudo","dnf","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"yum",installCommand:e=>["sudo","yum","install","-y",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}},{name:"pacman",installCommand:e=>["sudo","pacman","-S","--needed","--noconfirm",...e],packageNames:{git:"git",bubblewrap:"bubblewrap",socat:"socat",ripgrep:"ripgrep"}}].find(e=>Yl(e.name))||null;if(!t){console.log(D.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(D.yellow(`- ${t.name}: ${t.installCommand||"install manually"}`));return}const n=e.map(e=>t.packageNames[e.name]).filter(e=>Boolean(e));if(0===n.length)return;console.log(D.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await Ql(s.join(" "),[],{shell:!0}):await Ql(s[0],s.slice(1))}(t),await tp("claude","@anthropic-ai/claude-code@latest"),await tp("codex","@openai/codex@latest");const n=cs();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await nn();await op(Boolean(e.force),t),e.skipDaemon||await async function(){if(await Jt())console.log(D.green("✓ Daemon is already running"));else{console.log(D.blue("Starting Agentrix daemon...")),wo(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();for(let e=0;e<80;e++)if(await new Promise(e=>setTimeout(e,250)),await Xt())return void console.log(D.green("✓ Daemon started successfully"));console.log(D.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(D.green("\n✓ Agentrix CLI initialization complete"))}const cp=R(N(process.argv)).scriptName("agentrix").version(ke.version).usage("$0 <command> [options]").option("debug",{alias:"d",type:"boolean",describe:"Use local-debug mode (plaintext, for debugging)",global:!0}).help("help").alias("h","help").alias("v","version").strict().epilog("For more information, visit https://github.com/xmz-ai/agentrix-cli");xe.getStatePaths,cp.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(D.dim(`Current version: ${ke.version}`));const t=await Xt();await Pl()||process.exit(1);try{const e=await xe.readCredentials();e&&(console.log(D.dim("Checking agent updates...")),await Dl(e))}catch{}if(t){console.log(D.blue("Restarting daemon...")),await Qt(),await new Promise(e=>setTimeout(e,1e3)),wo(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await Xt()){e=!0;break}e?console.log(D.green("✓ Daemon restarted successfully")):console.log(D.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check."))}try{const{version:e}=await import("./logger-DnKC_QlD.mjs").then(function(e){return e._});console.log(D.green(`\n✓ Now running version: ${e}`))}catch{console.log(D.dim("\nRun 'agentrix --version' to see the new version"))}process.exit(0)}),cp.command("doctor","System diagnostics & troubleshooting",{},async e=>{await ps(),process.exit(0)}),cp.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await xe.readCredentials())return void console.log(D.yellow("Not currently authenticated"));console.log(D.blue("This will log you out of Agentrix")),console.log(D.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=Ee({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(D.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await Qt(),console.log(D.gray("Stopped daemon"))}catch{}await xe.clearCredentials(),console.log(D.gray("Removed credentials")),console.log(D.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(D.blue("Logout cancelled"))}()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),cp.command("stop","Stop the daemon",{},async e=>{Hl(),await Qt(),process.exit(0)}),cp.command("status","Show daemon and authentication status",{},async e=>{await ps("daemon"),console.log(""),await async function(){const e=await xe.readCredentials();if(console.log(D.bold("\nAuthentication Status\n")),!e)return void console.log(D.red("✗ Not authenticated"));console.log(D.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(D.gray(` Token: ${t}`)),e.machineId?(console.log(D.green("✓ Machine registered")),console.log(D.gray(` Machine ID: ${e.machineId}`)),console.log(D.gray(` Host: ${n.hostname()}`))):console.log(D.yellow("⚠️ Machine not registered")),console.log(D.gray(`\n Data directory: ${xe.agentrixHomeDir}`));try{await Xt()?console.log(D.green("✓ Daemon running")):console.log(D.gray("✗ Daemon not running"))}catch{console.log(D.gray("✗ Daemon not running"))}}(),process.exit(0)}),cp.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await Ft("/list")).children||[]}();0===e.length?console.log("No active sessions"):(console.log("Active sessions:"),console.log(JSON.stringify(e,null,2)))}catch(e){console.log("No daemon running")}process.exit(0)}),cp.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await is()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===e.type||"upgrade-daemon"===e.type)).map(e=>({pid:e.pid,command:e.command}))}(),t=[];let n=0;for(const{pid:s,command:a}of e)try{if(console.log(`Killing runaway process PID ${s}: ${a}`),"win32"===process.platform){const e=Qe.sync("taskkill",["/F","/PID",s.toString()],{stdio:"pipe"});if(e.error)throw e.error;if(0!==e.status)throw new Error(`taskkill exited with code ${e.status}`)}else process.kill(s,"SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),(await Ye()).find(e=>e.pid===s)&&(console.log(`Process PID ${s} ignored SIGTERM, using SIGKILL`),process.kill(s,"SIGKILL"));console.log(`Successfully killed runaway process PID ${s}`),n++}catch(e){const n=e.message;t.push({pid:s,error:n}),console.log(`Failed to kill process PID ${s}: ${n}`)}return{killed:n,errors:t}}();console.log(`Cleaned up ${e.killed} runaway processes`),e.errors.length>0&&console.log("Errors:",e.errors),process.exit(0)}),function(e){e.command("git-server","Manage local private GitLab server config",e=>e.command("add","Add a private GitLab server to local daemon config",e=>e.option("base-url",{type:"string",describe:"GitLab base URL, for example https://gitlab.example.com"}).option("api-url",{type:"string",describe:"GitLab API URL, defaults to <base-url>/api/v4"}).option("pat-file",{type:"string",nargs:1,describe:"Read GitLab PAT from a file, or - for stdin"}),async e=>{try{await Vl(e),process.exit(0)}catch(e){Xl(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await zl(),t=await xe.readDaemonState(),n=await async function(){return await Ft("/git-server/list")}();if(n.error)throw new Error(`Backend Git server list failed: ${n.error}`);const s=(n.gitServers??[]).filter(e=>"gitlab"===e.type&&"local_pat"===e.authModeDefault).map(n=>function(e,t,n){const s=En(e.id)??{},a=An(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:Ke(e.id),webhookUrl:ze(e.id,n),patConfigured:(i=e.id,Tn.hasPat(i)),patMeta:Cn(e.id),webhookSecret:a.webhookSecret,projectTriggerTokens:a.projectTriggerTokens??{}};var i}(n,e,t));console.log(JSON.stringify(s,null,2))}(),process.exit(0)}catch(e){Xl(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(cp),function(e){e.command("init","Initialize CLI dependencies, authentication, and LLM config",e=>e.option("skip-deps",{type:"boolean",default:!1,describe:"Skip dependency installation"}).option("skip-daemon",{type:"boolean",default:!1,describe:"Do not start the daemon after initialization"}).option("force",{type:"boolean",default:!1,describe:"Overwrite existing Claude/Codex config files without prompting"}),async e=>{try{await rp({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(cp),cp.command("kill <sessionId>","Stop a specific session",e=>e.positional("sessionId",{type:"string",describe:"Session ID to stop"}),async e=>{try{const t=await async function(e){return(await Ft("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?D.green("✓ Session stopped"):D.red("Failed to stop session"))}catch(e){console.log(D.red("No daemon running"))}process.exit(0)}),cp.command("daemon",!1,{},async e=>{try{await nn()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await gr(),process.exit(0)}),cp.command("worker",!1,e=>e.option("type",{type:"string",choices:Al,demandOption:!0,describe:"Worker type to start"}).option("started-by",{type:"string",choices:["daemon","terminal"],describe:"How the session was started"}).option("user-id",{type:"string",demandOption:!0,describe:"User ID for the worker"}).option("task-id",{type:"string",demandOption:!0,describe:"Task ID for the worker"}).option("idle-timeout",{type:"number",default:300,describe:"Idle timeout in seconds"}),async e=>{try{const t=e.type,n=Cl[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=await nn(),i=e["user-id"],o=e["task-id"],r=e["idle-timeout"];await n.run({credentials:a,startedBy:s,userId:i,taskId:o,idleTimeoutSecond:r})}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),cp.command("upgrade-daemon",!1,{},async e=>{const{startUpgradeDaemon:t}=await Promise.resolve().then(function(){return Bl});await t(),process.exit(0)}),cp.command("start","Start daemon (if not running) and show status",{},async e=>{try{await nn()}catch(e){console.error(D.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=cs();if(t.ok||(console.log(D.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(D.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(D.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await Jt()){console.log("Starting Agentrix background service..."),wo(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await Xt()){e=!0;break}e?(await new Promise(e=>setTimeout(e,1200)),await Xt()?console.log(D.green("✓ Daemon started successfully")):await async function(){const e=await async function(){const e=T(xe.getStatePaths().logsDir,"daemon.log");try{return(await ft(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(D.red("✗ Daemon exited shortly after startup")),!e)return;const t=e.split("\n").reverse().find(e=>e.includes("Machine binding revoked")||e.includes("Run `agentrix logout` and bind again"));t?console.log(D.yellow(t)):(console.log(D.gray("Recent daemon log:")),console.log(e))}()):console.log(D.yellow("⚠️ Daemon may still be starting..."))}if($l()){const e=await _l();e.hasUpgrade&&(n=e).hasUpgrade&&n.latestVersion&&(console.log(""),console.log(D.yellow("┌────────────────────────────────────────────────────┐")),console.log(D.yellow("│")+" "+D.bold("Upgrade Available")+" "+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+` Current: ${D.dim(n.currentVersion)} → Latest: ${D.green.bold(n.latestVersion)} `+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+" Run "+D.cyan.bold("agentrix upgrade")+" to upgrade "+D.yellow("│")),console.log(D.yellow("│")+" "+D.yellow("│")),console.log(D.yellow("│")+" To enable auto-upgrade, set: "+D.yellow("│")),console.log(D.yellow("│")+" "+D.dim("AGENTRIX_DISABLE_AUTO_UPGRADE=false")+" "+D.yellow("│")),console.log(D.yellow("└────────────────────────────────────────────────────┘")),console.log(""))}else Ll()||wo(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();var n;await ps("daemon"),process.exit(0)}),cp.demandCommand(1,"Please specify a command. Use --help to see available commands.").parse();
|