@agentrix/cli 0.47.0 → 0.48.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-C8KTAZ-P.mjs → logger-CVvo37Gw.mjs} +1 -1
- package/dist/{logger-ThMyEm0q.cjs → logger-oI3KZtBF.cjs} +1 -1
- package/dist/migrations/002_app_server_state.sql +3 -0
- package/package.json +2 -2
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 d,statSync as p,writeFileSync as u,renameSync as m,rmSync as h,readdirSync as g,unlinkSync as f,cpSync as y,lstatSync as v,symlinkSync as w,readlinkSync as b,accessSync as k,constants as x,createReadStream as I,realpathSync as S,copyFileSync as T,promises as C}from"node:fs";import*as A from"node:path";import _,{join as E,basename as $,extname as M,resolve as R,sep as P,dirname as D,relative as N,isAbsolute as O,normalize as U}from"node:path";import j from"yargs";import{hideBin as L}from"yargs/helpers";import q from"chalk";import{encodeBase64 as H,encryptMachineEncryptionKey as F,decodeBase64 as B,createKeyPairWithUit8Array as G,generateAESKey as W,decryptWithEphemeralKey as z,SocketAuthErrorDataSchema as K,createEventId as V,encryptFileContent as X,VisionPlanReviewWriteEventSchema as J,splitRtcChunkFrame as Y,RtcChunkFlags as Q,buildRtcChunkFrame as Z,decodeGitPath as ee,UpdateTaskPreviewUrlRequestSchema as te,AGENTRIX_DEV_INIT_FEATURE as ne,decryptSdkMessage as se,isSDKUserMessage as ae,isAskUserMessage as ie,isAskUserResponseMessage as oe,isSDKMessage as re,createKeyPair as ce,encryptAES as le,encryptWithEphemeralKey as de,encryptSdkMessage as pe,machineAuth as ue,getAgentContext as me,detectPreview as he,IGNORED_DIRECTORIES as ge,DEFAULT_WORKER_EXECUTION_MODE as fe,getTaskExecutionMode as ye,isCompanionHeartbeatMessage as ve,isCompanionMemoryOrganizationMessage as we,isCompanionReminderMessage as be,workerAuth as ke}from"@agentrix/shared";import{randomBytes as xe,randomUUID as Ie,createHash as Se,createDecipheriv as Te,createCipheriv as Ce,createHmac as Ae,timingSafeEqual as _e}from"node:crypto";import Ee from"axios";import{m as $e,i as Me,a as Re,l as Pe,p as De,c as Ne,b as Oe,d as Ue,g as je,e as Le}from"./logger-C8KTAZ-P.mjs";import{createInterface as qe}from"node:readline";import*as He from"fs";import{readFileSync as Fe,existsSync as Be,unlinkSync as Ge,openSync as We,writeFileSync as ze,closeSync as Ke,mkdtempSync as Ve,statSync as Xe,accessSync as Je,constants as Ye,readdirSync as Qe,mkdirSync as Ze,promises as et}from"fs";import*as tt from"path";import nt,{join as st,dirname as at,resolve as it,parse as ot,sep as rt}from"path";import ct from"open";import{io as lt}from"socket.io-client";import{EventEmitter as dt}from"node:events";import{pipeline as pt}from"node:stream/promises";import{createRequire as ut}from"node:module";import{spawn as mt,execSync as ht}from"child_process";import gt from"ps-list";import ft from"cross-spawn";import{getPlatform as yt}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import vt from"fastify";import{z as wt,toJSONSchema as bt}from"zod";import{validatorCompiler as kt,serializerCompiler as xt}from"fastify-type-provider-zod";import{spawnSync as It,spawn as St,execSync as Tt,execFile as Ct,execFileSync as At}from"node:child_process";import{createSdkMcpServer as _t,query as Et,tool as $t,AbortError as Mt}from"@anthropic-ai/claude-agent-sdk";import{replacePromptPlaceholders as Rt,loadAgentConfig as Pt,getAgentContext as Dt,GitServerLocalStore as Nt,deriveLocalGitServerEncryptionKey as Ot,validateGitLabPatToken as Ut,buildGitLabWebhookUrl as jt,buildGitLabWebhookEndpointPath as Lt}from"@agentrix/shared/node";import{mkdir as qt,readFile as Ht,writeFile as Ft,readdir as Bt,rm as Gt,unlink as Wt,lstat as zt,opendir as Kt,realpath as Vt,stat as Xt,access as Jt}from"node:fs/promises";import{promisify as Yt}from"node:util";import Qt from"simple-git";import{EventEmitter as Zt}from"events";import en from"better-sqlite3";import{fileURLToPath as tn,pathToFileURL as nn}from"url";import{Cron as sn}from"croner";import{memoryStore as an,normalizeGitLabWebhook as on,resolveGitLabApiUrl as rn,GitLabWebhookBridge as cn,gitlabPipelineTarget as ln,composeVariables as dn,defaultVariables as pn,staticVariables as un}from"@xmz-ai/gitlab-webhook-bridge";import{McpServer as mn}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as hn}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{createConnection as gn}from"node:net";import{Worker as fn}from"node:worker_threads";import{randomUUID as yn}from"crypto";import{isSupportedPlatform as vn,NetworkManager as wn,SandboxManager as bn}from"@xmz-ai/sandbox-runtime";import*as kn from"@larksuiteoapi/node-sdk";import{tmpdir as xn,homedir as In}from"os";import Sn from"ws";import{readFile as Tn,mkdir as Cn,appendFile as An,stat as _n}from"fs/promises";import{Codex as En}from"@openai/codex-sdk";import{stdin as $n,stdout as Mn}from"node:process";import{createInterface as Rn}from"node:readline/promises";import"winston";import"node:url";const Pn=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_GEMINI_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function Dn(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Nn(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 On(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=Dn(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=Dn(s)))}async function Un(e){return new Promise(t=>setTimeout(t,e))}function jn(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function Ln(e,t){const n=await $e.readDaemonState();if(!Me(n)){const e="No daemon running, no state file found";return Pe.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=jn(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 Pe.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${jn(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 Pe.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function qn(e,t){return await Ln("/session-started",{sessionId:e,metadata:t})}async function Hn(e,t,n){return await Ln("/devops-init-complete",{taskId:e,userId:t,action:n})}async function Fn(e,t){return await Ln("/devops-init-start",{taskId:e,userId:t})}async function Bn(e,t,n){const s="string"==typeof t?{content:t}:t;return await Ln("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function Gn(){const e=await $e.readDaemonState();if(!e||"failed"===e.status)return!1;try{return process.kill(e.pid,0),Me(e)}catch{return Re(e)?(Pe.debug("[DAEMON RUN] Starting daemon PID not running, cleaning up state"),await zn()):(Pe.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await zn()),!1}}async function Wn(){if(Pe.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await Gn())return Pe.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await $e.readDaemonState();if(!Me(e))return Pe.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=st(De(),"package.json"),n=JSON.parse(Fe(t,"utf-8")).version;return Pe.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return Pe.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function zn(){try{await $e.clearDaemonState(),Pe.debug("[DAEMON RUN] Daemon state file removed")}catch(e){Pe.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function Kn(){try{const e=await $e.readDaemonState();if(!Me(e)&&!Re(e))return void Pe.debug("No daemon state found");Pe.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await Ln("/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){Pe.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){Pe.debug("Error stopping daemon",e)}}function Vn(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function Xn(e,t){if(Ee.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?Vn(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?Vn(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?Vn(e.message):e instanceof Error?`${t}: ${e.message}`:t}function Jn(){return H(new Uint8Array(xe(32)))}async function Yn(e,t,n,s){try{const a={id:e.machineId,metadata:JSON.stringify(t)};if(s&&n){const t=function(e){const t=function(e){if(!e.machineAesKey)return null;try{const t=B(e.machineAesKey);return 32===t.length?t:null}catch{return null}}(e);if(t)return t;const n=W();return e.machineAesKey=H(n),n}(e);a.dataEncryptionKey=F(s.publicKey,t,B(n))}await Ee.post(`${$e.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(Xn(e,"Failed to sync machine data"))}}async function Qn(e){try{return(await Ee.get(`${$e.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})).data}catch(e){throw new Error(Xn(e,"Stored machine credentials are no longer valid"))}}async function Zn(){const e=await $e.readCredentials();if(e){const t=await Qn(e);let n=e;e.secret||(n={...e,secret:Jn()},await $e.writeCredentials(n),Pe.info("[AUTH] Generated missing local auth secret"));try{await Yn(n,$e.metadata()),Pe.info("[AUTH] Machine metadata synced")}catch(e){Pe.warn("[AUTH] Failed to sync machine metadata",e)}return Pe.info("[AUTH] Using existing credentials"),{...n,cloudId:t.cloudId}}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=$e.generateMachineId();n={token:t,secret:Jn(),machineId:e},Pe.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=$e.generateMachineId(),t=new Uint8Array(xe(32)),n=await G(t);try{console.log(`[AUTH] Sending auth request to: ${$e.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${H(n.publicKey).substring(0,20)}...`);const t={machineId:e};await Ee.post(`${$e.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(Xn(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:H(e,"base64"),machineId:t},s=JSON.stringify(n),a=H((new TextEncoder).encode(s),"base64url");return`${$e.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?(Pe.debug("[browser] Headless environment detected, skipping browser open"),!1):(Pe.debug(`[browser] Attempting to open URL: ${e}`),await ct(e),Pe.debug("[browser] Browser opened successfully"),!0)}catch(e){return Pe.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 Ee.get(`${$e.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=z(B(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${Xn(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 Un(1e3)}}finally{process.off("SIGINT",a)}return{token:null,userPublicKey:null}}(e,t)}(n,e);return s.token?{credentials:{token:s.token,secret:H(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}if(await Yn(n,$e.metadata(),a,s),await $e.writeCredentials(n),Pe.info("[AUTH] Machine setup completed"),t)try{const e=await Qn(n);return{...n,cloudId:e.cloudId}}catch(e){Pe.warn("[AUTH] Failed to resolve cloud id after setup",e)}return 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=Pn.has(t);(n||o)&&(e[t]=i,Nn(e,t,i),On(e,t,i))}}(e,function(e=process.env){const t=E(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?Dn(t):E(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))}();const es=Ne(import.meta.url),ts=new Set(["authorization","apikey","accesstoken","refreshtoken","machineaeskey","key","password","pat","secret","token"]);class ns{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 ss(e){if(!e||"object"!=typeof e)return{message:String(e??"unknown error")};const t=e,n=function(e){const t=K.safeParse(e);return t.success?t.data:null}(t.data);return n?{message:n.message||t.message||"Socket connection failed",...n.code?{code:n.code}:{},...n.action?{action:n.action}:{}}:{message:t.message||"unknown socket error"}}function as(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=ss(e);if(n.code||n.action)return[n.code?`[${n.code}]`:void 0,n.message,n.action].filter(Boolean).join(" ");const s=[];return t.message&&s.push(t.message),t.type&&s.push(`type=${t.type}`),void 0!==t.description&&s.push(`description=${os(t.description)}`),void 0!==t.data&&s.push(`data=${os(t.data)}`),void 0!==t.context&&s.push(`context=${os(t.context)}`),s.filter(Boolean).join(" ")||"unknown socket error"}function is(e,t=0){if(t>8)return"[MaxDepth]";if(Array.isArray(e))return e.map(e=>is(e,t+1));if(!e||"object"!=typeof e)return e;const n={};for(const[s,a]of Object.entries(e)){const e=s.replace(/[-_]/g,"").toLowerCase();n[s]=ts.has(e)?"[REDACTED]":is(a,t+1)}return n}function os(e){try{return JSON.stringify(is(e))}catch{return"[Unserializable]"}}function rs(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};const t=e,n=t.data&&"object"==typeof t.data&&!Array.isArray(t.data)?t.data:void 0,s={},a=["eventId","taskId","chatId","from","senderType","messageType","opCode","sequence","status"];for(const e of a)void 0!==t[e]&&(s[e]=t[e]);void 0!==n?.sequence&&(s.ackSequence=n.sequence),void 0!==t.message&&(s.hasMessage=!0),"string"==typeof t.encryptedMessage&&(s.encrypted=!0,s.encryptedMessageChars=t.encryptedMessage.length);const i=new Set(a),o=Object.keys(t).filter(e=>!i.has(e)&&"message"!==e&&"encryptedMessage"!==e);return o.length>0&&(s.extraKeys=o.sort()),s}class cs{socket=null;config;eventHandlers=new Map;eventEmitter=new dt;KeepAliveManager=null;healthCheckInterval=null;connectStartedAt=null;reconnectTimer=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new ns(e.keepAliveConfig))}connect(){if(this.socket)return void this.targetLogger.debug("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.connectStartedAt=Date.now(),this.socket=lt(e,a),this.setupSocketHandlers(),this.targetLogger.debug(`Connecting to ${e}`)}disconnect(){this.socket&&(this.targetLogger.info("Disconnecting"),this.clearReconnectTimer(),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.targetLogger.debug(`received event ${e}, summary: ${os(rs(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.targetLogger.debug(`received event with ack ${e}, summary: ${os(rs(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.targetLogger.debug(`send event ${e}, summary: ${os(rs(t))}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.targetLogger.warn("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.targetLogger.debug(`send event ${e}, summary: ${os(rs(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",()=>{const e=this.connectStartedAt?Date.now()-this.connectStartedAt:void 0;this.connectStartedAt=null,this.targetLogger.info(`socket.connected host=${this.config.serverUrl}${void 0!==e?` connectMs=${e}`:""}`),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.targetLogger.info(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck(),"io server disconnect"===e&&this.scheduleReconnect("server disconnect")}),this.socket.on("connect_error",e=>{this.targetLogger.warn(`Connection error: ${as(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.targetLogger.warn(`Socket error: ${as(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}scheduleReconnect(e){this.socket&&!this.reconnectTimer&&(this.targetLogger.info(`Scheduling reconnect after ${e}`),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.socket?.connect()},1e3),this.reconnectTimer.unref?.())}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}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.targetLogger.warn("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)}get targetLogger(){return this.config.logger??es}}const ls="attachment",ds={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function ps(){const e=E($e.agentrixHomeDir,"tmp","channel-files");return r(e)||d(e,{recursive:!0}),e}function us(e){const t=function(e){if(!e)return;return $(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||ls;return E(ps(),`${Ie()}-${t}`)}function ms(e){const t=R(ps()),n=R(e);if(n!==t&&!n.startsWith(`${t}${P}`))throw new Error("Access denied: channel attachment path is outside channel files directory");return n}async function hs(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=fs(t);return e?`${ls}${e}`:void 0}if(M(e))return e;const n=fs(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=us(n),a=l(s);return await pt(e.body,a),s}async function gs(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=$(new URL(e).pathname);return M(t)?t:void 0}catch{return}}(e);return hs(s,t||a)}function fs(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?ds[t]:void 0}var ys,vs,ws,bs={},ks={"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}},xs=(ws||(ws=1,function(e){var t,n,s,a=vs?ys:(vs=1,ys=ks),i=nt.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),d=s.indexOf(i.source);if("application/octet-stream"!==n[c]&&(l>d||l===d&&"application/"===n[c].substr(0,12)))continue}n[c]=e}}})}(bs)),bs);function Is(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return ms(decodeURIComponent(e))}return $e.resolveWorkspaceFilePath(e,t,n)}function Ss(e,t){e?e.send("workspace-file-response",t):Pe.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function Ts(e,t){e?e.send("workspace-file-mutation-response",t):Pe.error("[WORKSPACE] Cannot send workspace-file-mutation-response: client not available")}function Cs(e,t,n,s){return{eventId:V(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function As(e,t,n,s){return{eventId:V(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function _s(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,operation:r,content:c,createOnly:l}=t;Pe.debug(`[WORKSPACE] File mutation request: taskId=${n}, userId=${s}, relativePath=${a}, operation=${r}, createOnly=${!!l}`);try{if(a.startsWith("channel-attachment/"))return void Ts(e.client,As(o,n,"permission_denied","Channel attachments are read-only"));const t=Is(s,n,a);if(!function(e,t,n,s){const a=n.replace(/^\/+/,""),i="project"===a||a.startsWith("project/")?"project":"data"===a||a.startsWith("data/")?"data":"",o=A.normalize($e.resolveWorkspaceFilePath(e,t,i)),r=A.normalize(s);return r===o||r.startsWith(o+A.sep)}(s,n,a,t))return void Ts(e.client,As(o,n,"permission_denied","Path escapes workspace"));if("delete"===r)return await i.promises.rm(t,{force:!1}),void Ts(e.client,{eventId:V(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r}});if(void 0===c)return void Ts(e.client,As(o,n,"bad_request","File content is required"));await i.promises.mkdir(A.dirname(t),{recursive:!0});try{await i.promises.writeFile(t,c,l?{flag:"wx"}:void 0)}catch(t){if("EEXIST"===t.code)return void Ts(e.client,As(o,n,"file_exists","File already exists"));throw t}const d=await i.promises.stat(t);Ts(e.client,{eventId:V(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r,modifiedAt:d.mtime.toISOString()}})}catch(t){Pe.error(`[WORKSPACE] Failed to handle workspace-file-mutation-request: ${t.message}`,t);const s="ENOENT"===t.code?"file_not_found":"EACCES"===t.code?"permission_denied":"unknown_error";Ts(e.client,As(o,n,s,t.message))}}}function Es(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;Pe.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,d=Is(s,n,a);if(!i.existsSync(d))return Pe.warn(`[WORKSPACE] File not found: ${d}`),void Ss(e.client,Cs(o,n,"file_not_found","File or directory not found"));const p=await i.promises.stat(d),u=p.mtime.toISOString();if(c&&u===c)return void function(e,t,n,s){Pe.debug(`[WORKSPACE] File not modified: ${s}`),Ss(e,{eventId:V(),requestId:t,taskId:n,success:!0,notModified:!0})}(e.client,o,n,d);if(p.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=A.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}}));Ss(e,{eventId:V(),requestId:t,taskId:n,success:!0,data:{type:"directory",entries:c,metadata:{size:0,modifiedAt:a.mtime.toISOString()}}})}(e.client,o,n,d,p,t);{const s=xs.lookup(d)||"application/octet-stream";return p.size>t?void function(e,t,n,s,a,i,o){Pe.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),Ss(e,{eventId:V(),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,d,p,s,t):void await async function(e,t,n,s,a,o){const r=xs.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 $e.getSecretKey();if(!t)return Pe.warn("[WORKSPACE] Machine secret key not available"),null;const n=B(e);return z(n,t)||(Pe.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return Pe.warn("[WORKSPACE] Error decrypting dataEncryptionKey:",e),null}}(o));const d={type:"file",metadata:{size:a.size,mimeType:r,modifiedAt:a.mtime.toISOString()}};l?d.encryptedContent=X(c,l):d.content=c,Ss(e,{eventId:V(),requestId:t,taskId:n,success:!0,data:d})}(e.client,o,n,d,p,l)}}catch(t){Pe.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";Ss(e.client,Cs(o,n,s,t.message))}}}function $s(e,t){return{eventId:V(),status:"failed",opCode:e,message:t}}function Ms(e,t){const n=A.relative(t,e);if(n.startsWith("..")||A.isAbsolute(n))throw new Error("Vision Plan review path is outside the bound issue directory")}const Rs=100,Ps=[{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 Ds{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}withMetadata(e,t={}){return{data:e,metadata: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();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 Pe.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{data:await o.json(),headers:o.headers,status:o.status}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw Pe.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();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 Pe.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 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 Pe.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:Rs,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:Rs,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===Rs){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:Rs,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<Rs)break;t+=1}}return s}async executeOperation(e,t,n={}){return(await this.executeOperationWithMetadata(e,t,n)).data}async executeOperationWithMetadata(e,t,n={}){n.silent||Pe.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let s;switch(e){case"listRepos":s=this.withMetadata(await this.listRepos());break;case"listBranches":s=this.withMetadata(await this.listBranches(t.owner,t.name));break;case"createMergeRequest":s=this.withMetadata(await this.createMergeRequest(t));break;case"getMergeRequest":s=this.withMetadata(await this.getMergeRequest(t.owner,t.name,t.iid));break;case"listMergeRequests":s=this.withMetadata(await this.listMergeRequests(t.owner,t.name));break;case"triggerPipeline":s=this.withMetadata(await this.triggerPipeline(t));break;case"ensurePipelineTriggerToken":s=this.withMetadata(await this.ensurePipelineTriggerToken(t));break;case"requestGitlabApi":s=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":s=this.withMetadata({authMode:"local_pat",hasPat:!0});break;default:throw{status:400,message:`Unknown operation: ${e}`}}return n.silent||Pe.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,s.data)}`),s}catch(t){const s=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw n.silent||Pe.error(`${this.logPrefix()} operation failed: op=${e}, message=${s}`),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 Ps.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}`};if("GET"===t){const e=await this.requestWithResponse(a,t);return this.withMetadata(e.data,{status:e.status})}const i=await this.requestWithResponse(a,t,e.body);return this.withMetadata(i.data,{status:i.status})}}function Ns(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function Os(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function Us(e){return Ee.isAxiosError(e)?{message:e.message,status:e.response?.status,code:e.code}:{message:e instanceof Error?e.message:String(e)}}async function js(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 Ee.get(Ns(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 Ls(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){Pe.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${Os(Ns(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await js(e,a);return Pe.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=Us(t);Pe.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 qs(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 Hs(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}}(E($e.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:qs(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=E($e.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)}Pe.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${Os(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 Ls(e))n.add(t)}catch(t){const n=Us(t);s.push({source:e.source,baseUrl:Os(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?Pe.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):Pe.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function Fs(e,t){return{eventId:V(),status:"failed",opCode:e,message:t}}function Bs(e,t){Pe.info(`[GITLAB PROXY] reqId=${e.requestId}, gitServer=${e.gitServerId}, method=${t.method}, path=${t.path}, status=${t.status}, elapsedMs=${t.elapsedMs}`)}function Gs(e){return async(t,n)=>{if(Pe.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 Pe.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(Fs(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&Pe.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){Pe.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function Ws(e){return async(t,n)=>{Pe.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&&Pe.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){Pe.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function zs(e){return async(t,n)=>{if(Pe.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return Pe.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(Fs(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await Hs(t.agentType);if(0===e.length&&!s)return Pe.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(Fs(t.eventId,"No models available from configured endpoints"));Pe.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:V(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){Pe.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function Ks(e){return async t=>{Pe.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function Vs(e){return async(t,n)=>{Pe.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&&Pe.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){Pe.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function Xs(e){return async(t,n)=>{Pe.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&&Pe.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){Pe.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function Js(e){return async(t,n)=>{Pe.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&&Pe.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){Pe.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(Fs(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function Ys(e){return async t=>{Pe.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||Pe.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function Qs(e){return async t=>{const n=Date.now(),s=("string"==typeof(a=t.payload).method&&a.method.trim().length>0?a.method.trim():"GET").toUpperCase();var a;const i=function(e){return"string"==typeof e.path&&e.path.length>0?e.path:"-"}(t.payload),o=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?e.client.send("daemon-gitlab-response",s):Pe.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=t.accessToken?.trim();if(!e){const e=Date.now()-n;return Pe.warn(`[GITLAB PROXY] access token missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),Bs(t,{method:s,path:i,status:0,elapsedMs:e}),void o({success:!1,errorCode:"PAT_MISSING",errorMessage:`No access token provided for git server ${t.gitServerId}`,executionTimeMs:e})}const a=t.payload.apiUrl;if(!a){const e=Date.now()-n;return Pe.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),Bs(t,{method:s,path:i,status:0,elapsedMs:e}),void o({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:e})}const r=new Ds(a,e,{requestId:t.requestId,gitServerId:t.gitServerId}),c=await r.executeOperationWithMetadata(t.operation,t.payload,{silent:!0}),l=Date.now()-n;Bs(t,{method:s,path:i,status:c.metadata.status??200,elapsedMs:l}),o({success:!0,data:c.data,executionTimeMs:l})}catch(e){const a=e;let r="GITLAB_CONNECTIVITY_FAILED";401===a.status?r="PAT_INVALID":403===a.status?r="PAT_SCOPE_INSUFFICIENT":404===a.status&&(r="RESOURCE_NOT_FOUND");const c="string"==typeof a.message?a.message:"Unknown error",l="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,d=function(e){return"number"==typeof e.status?e.status:0}(a),p=Date.now()-n;Bs(t,{method:s,path:i,status:d,elapsedMs:p}),Pe.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${r}, status=${d}, message=${c}${l?`, detail=${l}`:""}`),o({success:!1,errorCode:r,errorMessage:c,executionTimeMs:p})}}}function Zs(e){return async(t,n)=>{e.machineControl?e.machineControl.handleCommand(t,n):n(Fs(t.eventId,"Machine control is not available"))}}function ea(e){return async(t,n)=>{if(e.workspaceStatusSync)try{await e.workspaceStatusSync.applyCacheUpdate(t),n({eventId:V(),status:"success",opCode:t.eventId})}catch(e){Pe.warn("[WORKSPACE SYNC] Failed to apply workspace cache update",e),n(Fs(t.eventId,e instanceof Error?e.message:"Failed to apply workspace cache update"))}else n(Fs(t.eventId,"Workspace sync is not available"))}}function ta(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)}const na=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function sa(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return ms(decodeURIComponent(e))}return $e.resolveWorkspaceFilePath(e,t,n)}class aa{client;machineId;machineControl;iceServers=[];sessions=new Map;rtcModule={};peerConstructor;constructor(e,t,n){this.client=e,this.machineId=t,this.machineControl=n;const s=ut(import.meta.url);try{this.rtcModule=s("node-datachannel"),this.peerConstructor=(a=this.rtcModule).RTCPeerConnection||a.PeerConnection||a.RTCConnection||a.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}catch(e){const t=e instanceof Error?e.message:String(e);Pe.warn(`[RTC] node-datachannel unavailable; RTC support disabled: ${t}`)}var a}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))):Pe.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:V()})}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),Pe.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void Pe.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId)){const n=this.sessions.get(e.sessionId);return Pe.info(`[RTC] Reusing session: session=${e.sessionId}, requested=${e.requestedChannels?.join(",")||"default"}, allowed=${n?.allowedChannels.join(",")||"none"}, task=${s??"none"}`),void this.sendMachineRtcResponse(e.sessionId,t,!0,void 0,n?.allowedChannels)}const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,allowedChannels:this.normalizeAllowedChannels(e),peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),Pe.info(`[RTC] Accepted session request: session=${e.sessionId}, requested=${e.requestedChannels?.join(",")||"default"}, allowed=${i.allowedChannels.join(",")||"none"}, rejected=${e.rejectedChannels?.join(",")||"none"}, task=${s??"none"}`),this.sendMachineRtcResponse(e.sessionId,t,!0,void 0,i.allowedChannels)}sendMachineRtcResponse(e,t,n,s,a=["file"]){Pe.info(`[RTC] Sending session response: session=${e}, accepted=${n}, allowed=${a.join(",")||"none"}, reason=${s??"none"}`),this.client.send("machine-rtc-response",{eventId:V(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0,allowedChannels:a}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void Pe.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,allowedChannels:["file"],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){Pe.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{Pe.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{Pe.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:V(),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:V(),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?.(()=>{Pe.info(`[RTC] Data channel open: session=${e.sessionId}, allowed=${e.allowedChannels.join(",")||"none"}, task=${e.allowedTaskId??"none"}`),e.lastActivity=Date.now(),ta(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?.(()=>{Pe.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{Pe.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{Y(new Uint8Array(t))}catch(e){Pe.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 Pe.warn("[RTC] Non-JSON message",n)}if(s&&"string"==typeof s.type){if(!this.isChannelAllowed(e,s.channel))return Pe.warn(`[RTC] Unauthorized channel message: session=${e.sessionId}, type=${s.type}, channel=${s.channel}, allowed=${e.allowedChannels.join(",")||"none"}`),void this.sendControl(e,{v:1,type:`${s.channel}.error`,channel:s.channel,requestId:s.requestId,streamId:s.streamId,timestamp:(new Date).toISOString(),error:{code:"forbidden",message:`RTC channel ${s.channel} is not authorized`}});if("file.request"!==s.type){if("file.mutate"!==s.type)return"storage.start"===s.type?(Pe.info(`[RTC][storage] Received start message: session=${e.sessionId}, request=${s.requestId}, stream=${s.streamId}`),void this.handleStorageStart(e,s)):"storage.cancel"===s.type?(Pe.info(`[RTC][storage] Received cancel message: session=${e.sessionId}, request=${s.requestId}, stream=${s.streamId}`),void this.handleStorageCancel(e,s)):void 0;this.handleFileMutation(e,s).catch(e=>{Pe.error("[RTC] Failed to handle file mutation",e)})}else this.handleFileRequest(e,s).catch(e=>{Pe.error("[RTC] Failed to handle file request",e)})}}normalizeAllowedChannels(e){const t=e.allowedChannels?.length?e.allowedChannels:["file"];return Array.from(new Set(t))}isChannelAllowed(e,t){return"control"===t||e.allowedChannels.includes(t)}handleStorageStart(e,t){if(!this.machineControl)return Pe.warn(`[RTC][storage] Rejecting start; machine control unavailable: session=${e.sessionId}`),void this.sendStorageError(e,t,"capability_missing","Machine control is not available");const n=t.payload;if(!n)return Pe.warn(`[RTC][storage] Rejecting start; missing payload: session=${e.sessionId}, request=${t.requestId}`),void this.sendStorageError(e,t,"operation_failed","Storage start payload is required");Pe.info(`[RTC][storage] Starting operation: session=${e.sessionId}, op=${n.opCode}, action=${n.action}, target=${n.target.cloudId?`${n.target.cloudId}:`:""}${n.target.machineId}, expiresAt=${n.expiresAt??"none"}`);const s={eventId:n.opCode,target:n.target,action:n.action,params:n.params,requestedAt:n.requestedAt,expiresAt:n.expiresAt},a=this.machineControl.startStorageManagement(s,n=>{this.sendStorageProgress(e,t,n)});if("success"!==a.status){const s=a.data;return Pe.warn(`[RTC][storage] Operation rejected: session=${e.sessionId}, op=${n.opCode}, code=${s?.errorCode??"operation_failed"}, message=${a.message??"none"}`),void this.sendStorageError(e,t,s?.errorCode??"operation_failed",a.message||"Storage operation failed")}Pe.info(`[RTC][storage] Operation accepted: session=${e.sessionId}, op=${n.opCode}, action=${n.action}`),this.sendControl(e,{v:1,type:"storage.accepted",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{opCode:n.opCode}})}handleStorageCancel(e,t){if(!this.machineControl||!t.payload?.opCode)return void Pe.warn(`[RTC][storage] Ignoring cancel; machine control or op missing: session=${e.sessionId}`);Pe.info(`[RTC][storage] Cancelling operation: session=${e.sessionId}, op=${t.payload.opCode}`);const n=this.machineControl.cancelStorageManagement(t.payload.opCode,n=>{this.sendStorageProgress(e,t,n)});if("success"!==n.status){const s=n.data;Pe.warn(`[RTC][storage] Cancel rejected: session=${e.sessionId}, op=${t.payload.opCode}, code=${s?.errorCode??"operation_failed"}, message=${n.message??"none"}`),this.sendStorageError(e,t,s?.errorCode??"operation_failed",n.message||"Storage cancel failed")}}sendStorageProgress(e,t,n){const s=n.result&&"object"==typeof n.result?n.result.phase:void 0,a=`[RTC][storage] Sending progress: session=${e.sessionId}, op=${n.opCode}, status=${n.status}, phase=${"string"==typeof s?s:"none"}, message=${n.message??n.errorMessage??"none"}`;"running"===n.status?Pe.debug(a):Pe.info(a),this.sendControl(e,{v:1,type:"storage.progress",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{progress:n}})}sendStorageError(e,t,n,s){Pe.warn(`[RTC][storage] Sending error: session=${e.sessionId}, request=${t.requestId}, code=${n}, message=${s}`),this.sendControl(e,{v:1,type:"storage.error",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:n,message:s}})}validateFilePayload(e,t){const n=t.payload;return n?n.userId!==e.workspaceUserId?(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"}}),null):e.allowedTaskId&&n.taskId!==e.allowedTaskId?(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"}}),null):n:null}assertWorkspacePath(e,t,n){if(n.startsWith("channel-attachment/"))throw Object.assign(new Error("Channel attachments are read-only"),{code:"permission_denied"});const s=sa(e,t,n);if(!function(e,t,n,s){const a=n.replace(/^\/+/,""),i="project"===a||a.startsWith("project/")?"project":"data"===a||a.startsWith("data/")?"data":"",o=A.normalize($e.resolveWorkspaceFilePath(e,t,i)),r=A.normalize(s);return r===o||r.startsWith(o+A.sep)}(e,t,n,s))throw Object.assign(new Error("Path escapes workspace"),{code:"permission_denied"});return s}async handleFileRequest(e,t){const n=this.validateFilePayload(e,t);if(!n)return;const s=sa(n.userId,n.taskId,n.relativePath);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 a=await i.promises.stat(s);if(!function(e,t){return!t||e.mtime.toISOString()!==t}(a,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(a.isDirectory()||"directory"===n.entryType){const n=await i.promises.readdir(s,{withFileTypes:!0}),o={entries:await Promise.all(n.map(async e=>{const t=A.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:a.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:o})}const o=1024*(n.maxFileSizeMB??na)*1024;if(a.size>o)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 r=xs.lookup(s)||"application/octet-stream",c={size:a.size,mimeType:"string"==typeof r?r:"application/octet-stream",modifiedAt:a.mtime.toISOString()};this.sendControl(e,{v:1,type:"file.meta",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:c}),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:a.size}})}async handleFileMutation(e,t){const n=this.validateFilePayload(e,t);if(n)try{const s=this.assertWorkspacePath(n.userId,n.taskId,n.relativePath);if("delete"===n.operation)return await i.promises.rm(s,{force:!1}),void this.sendMutationAck(e,t,{relativePath:n.relativePath,operation:n.operation});if(void 0===n.content)throw Object.assign(new Error("File content is required"),{code:"bad_request"});await i.promises.mkdir(A.dirname(s),{recursive:!0});try{await i.promises.writeFile(s,n.content,n.createOnly?{flag:"wx"}:void 0)}catch(e){if("EEXIST"===e.code)throw Object.assign(new Error("File already exists"),{code:"file_exists"});throw e}const a=await i.promises.stat(s);this.sendMutationAck(e,t,{relativePath:n.relativePath,operation:n.operation,modifiedAt:a.mtime.toISOString()})}catch(n){this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:n.code||"unknown_error",message:n.message||"File mutation failed"}})}}sendMutationAck(e,t,n){this.sendControl(e,{v:1,type:"file.mutation_ack",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:n})}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=Q.Binary|(0===o?Q.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);ta(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=Z({streamId:t,seq:o,flags:Q.End|Q.Binary,payloadLength:0},new Uint8Array);ta(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&ta(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){Pe.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 ia{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new cs(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client,machineControl:n.machineControl,workspaceStatusSync:n.workspaceStatusSync},this.rtcManager=new aa(this.client,s,n.machineControl),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 120 seconds"))},12e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{(function(e){return ss(e).message.includes("Machine route already has an active daemon socket")})(e)||(clearTimeout(n),t(e))}),this.client.connect()})}async disconnect(){this.client.connected&&(await this.client.flush(5e3).catch(()=>{}),await this.prepareServerDisconnect().catch(()=>{})),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":Gs(t=this.context),"resume-task":Ws(t),"list-models":zs(t),"stop-task":Ys(t),"deploy-agent":Vs(t),"hive-publish":Xs(t),"hive-install":Js(t),"shutdown-machine":Ks(t),"workspace-file-request":Es({client:t.client}),"workspace-file-mutation-request":_s({client:t.client}),"vision-plan-review-write":async(e,t)=>{const n="string"==typeof e?.eventId?e.eventId:"vision-plan-review-write";try{const s=J.parse(e);!function(e){if(!/^[A-Za-z0-9._-]+$/.test(e)||e.includes(".."))throw new Error("Invalid Vision Plan issue id")}(s.issueId);const a=`project/.agentrix/issues/${s.issueId}/review/user`;if(s.reviewDirRelativePath!==a)return void t($s(n,"Vision Plan review write path does not match the bound issue"));const o=$e.resolveWorkspaceFilePath(s.userId,s.taskId,a);Ms(o,$e.resolveWorkspaceFilePath(s.userId,s.taskId,`project/.agentrix/issues/${s.issueId}`));const r=await async function(e){await i.promises.mkdir(e,{recursive:!0});let t=(await i.promises.readdir(e).catch(()=>[])).reduce((e,t)=>{const n=/^(\d{3})(?:-|\.md$)/.exec(t);return n?Math.max(e,Number(n[1])):e},0)+1;for(;;){const n=`${String(t).padStart(3,"0")}-vision-plan-review.md`,s=A.join(e,n);try{const e=await i.promises.open(s,"wx");return await e.close(),s}catch(e){if("EEXIST"!==e.code)throw e;t+=1}}}(o);Ms(r,o),await i.promises.writeFile(r,s.content.endsWith("\n")?s.content:`${s.content}\n`,"utf8");const c=A.posix.join(a,A.basename(r)).replace(/^project\//,"");t({eventId:V(),status:"success",opCode:s.eventId,data:{relativePath:c}})}catch(e){Pe.error("[VisionPlanReviewWrite] Failed to write review:",e),t($s(n,e instanceof Error?e.message:"Failed to write Vision Plan review"))}},"daemon-gitlab-request":Qs(t),"machine-control-command":Zs(t),"workspace-cache-update":ea(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.onEventWithAck("machine-control-command",e["machine-control-command"]),this.client.onEventWithAck("workspace-cache-update",e["workspace-cache-update"]),this.client.onEvent("shutdown-machine",e["shutdown-machine"]),this.client.onEvent("workspace-file-request",e["workspace-file-request"]),this.client.onEvent("workspace-file-mutation-request",e["workspace-file-mutation-request"]),this.client.onEventWithAck("vision-plan-review-write",e["vision-plan-review-write"]),this.client.onEvent("daemon-gitlab-request",e["daemon-gitlab-request"])}async prepareServerDisconnect(){const e={eventId:V(),machineId:this.context.machineId,timestamp:(new Date).toISOString()},t=await(n=this.client.sendWithAck("machine-disconnect-prepare",e),new Promise((e,t)=>{const s=setTimeout(()=>{t(new Error("Timed out after 5000ms"))},5e3);n.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})}));var n;if("success"!==t.status)throw new Error(t.message||"Machine disconnect prepare failed")}}let oa=null;let ra=!1;async function ca(){if(ra)Pe.info("[caffeinate] Already stopping, skipping");else if(oa&&!oa.killed){ra=!0,Pe.info(`[caffeinate] Stopping caffeinate process PID ${oa.pid}`);try{oa.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),oa&&!oa.killed&&oa.kill("SIGKILL"),oa=null,ra=!1}catch(e){Pe.info("[caffeinate] Error stopping caffeinate:",e),ra=!1}}}let la=!1;function da(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(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function pa(){try{let e;e="win32"===process.platform?await async function(){try{const e=ht("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 gt()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=da(n);e&&t.push(e)}return t}catch(e){return[]}}function ua(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:ht(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function ma(){const e=yt(),t=function(){const e=ua("git"),t=ua("claude"),n=ua("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=ua("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=ua("bwrap"),t=ua("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 ha(){const e=ma(),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 ga(){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:$e.agentrixHomeDir,serverUrl:$e.serverUrl,logsDir:$e.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 fa(e){if(e||(e="all"),console.log(q.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(q.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${q.green(Oe.version)}`),console.log(`Platform: ${q.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${q.green(process.version)}`),console.log(""),console.log(q.bold("🔧 Daemon Spawn Diagnostics"));const e=De(),t=E(e,"bin","agentrix.mjs"),n=E(e,"dist","index.mjs");console.log(`Project Root: ${q.blue(e)}`),console.log(`Wrapper Script: ${q.blue(t)}`),console.log(`CLI Entrypoint: ${q.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?q.green("✓ Yes"):q.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?q.green("✓ Yes"):q.red("❌ No")}`),console.log(""),console.log(q.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${q.blue($e.agentrixHomeDir)}`),console.log(`Server URL: ${q.blue($e.serverUrl)}`),console.log(`Logs Dir: ${q.blue($e.getStatePaths().logsDir)}`),console.log(q.bold("\n🌍 Environment Variables"));const s=ga();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?q.green(s.AGENTRIX_HOME_DIR):q.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?q.green(s.AGENTRIX_SERVER_URL):q.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?q.yellow("ENABLED"):q.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?q.green(s.DEBUG):q.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?q.green(s.NODE_ENV):q.gray("not set")}`),console.log(q.bold("\n🔐 Authentication"));try{await $e.readCredentials()?console.log(q.green("✓ Authenticated (credentials found)")):console.log(q.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(q.red("❌ Error reading credentials"))}!function(e=!1){const t=ma(),n=yt();console.log(q.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(q.green(`✓ ${n.name}`),q.gray(`- ${n.description}`)),e&&n.path&&console.log(q.gray(` Location: ${n.path}`));else{const e=n.required?q.red("❌"):q.yellow("⚠️");console.log(`${e} ${n.name}`,q.gray(`- ${n.description}`)),n.installCommand&&console.log(q.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(q.bold("\n🔒 Sandbox Dependencies")),console.log(q.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(q.green(`✓ ${n.name}`),q.gray(`- ${n.description}`)),e&&n.path&&console.log(q.gray(` Location: ${n.path}`))):(console.log(q.red(`❌ ${n.name}`),q.gray(`- ${n.description}`)),n.installCommand&&console.log(q.blue(` Install: ${n.installCommand}`)))}else console.log(q.bold("\n🔒 Sandbox Dependencies")),console.log(q.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(q.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(q.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(q.red(` • ${t.name}`));console.log(q.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(q.bold("\n🤖 Daemon Status"));try{const t=await Gn(),n=await $e.readDaemonState();if(t&&Me(n)?(console.log(q.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(q.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(q.red("❌ Daemon is not running")),n){console.log(q.bold("\n📄 Daemon State:"));const e=$e.getStatePaths();console.log(q.blue(`Location: ${e.daemonStateFile}`)),console.log(q.gray(JSON.stringify(n,null,2)))}const s=await pa();if(s.length>0){console.log(q.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(q.blue(`\n${{daemon:"🤖 Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?q.cyan:e.includes("daemon")?q.blue:q.gray;console.log(` ${s(`PID ${t}`)}: ${q.gray(n)}`)})})}else console.log(q.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(q.bold("\n💡 Process Management")),console.log(q.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(q.red("❌ Error checking daemon status"))}}let ya=null;async function va(){const e=Sa(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(ya&&ya.expiresAt>Date.now()&&ya.overridesSignature===t)return ya.openers;const n=ba(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 ya={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function wa(e){const t=process.platform;if("darwin"===t)return function(e){const t=ka(e),n=[];if(t){const e=Ma(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"),xa(_a("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=Aa("powershell")?"powershell":Aa("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=ka(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${$a(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return xa(_a(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=ka(e);if(Aa("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return xa(_a("zenity",e,{captureOutput:!0}))}if(Aa("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),xa(_a("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 ba(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:()=>Ta("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>Ta("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>Ta("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>Ta("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>Ta("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?Aa("osascript")&&Ca("Terminal"):"win32"===e?Aa("wt")||Aa("powershell")||Aa("pwsh")||Aa("cmd"):"linux"===e&&Boolean(Ia())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(Aa("wt"))return void Ea("wt",["-d",e]);const t=Aa("powershell")?"powershell":Aa("pwsh")?"pwsh":null;return t?void Ea(t,["-NoExit","-Command",`Set-Location -LiteralPath '${$a(e)}'`]):void Ea("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=Ia();if(!t)throw new Error("No supported terminal is available");return void Ea(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!_a("osascript",["-e",'tell application "Terminal"',"-e",`do script "${Ma(`cd ${Ra(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?Aa("open"):"win32"===e||"linux"===e&&(Aa("xdg-open")||Aa("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return Aa("xdg-open")?void _a("xdg-open",[e]):void _a("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}_a("explorer",[e])}else _a("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?Aa("osascript"):"win32"===e?Aa("powershell")||Aa("pwsh"):"linux"===e&&Aa("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");_a("gio",["open","--ask",e])}else _a(Aa("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${$a(e)}'`]);else if(null===_a("osascript",["-e",`set targetPath to POSIX file "${Ma(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??Sa();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=>Ca(e)):_.isAbsolute(e)||e.includes(_.sep)?r(e):Aa(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!_a(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 ka(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!p(t).isDirectory())return}catch{return}return t}}function xa(e){if(!e)return null;return e.trim()||null}function Ia(){const e=Ra(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&Aa(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${Ra(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 ${Ra(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${Ra(t)} && exec ${e}`]}].find(e=>Aa(e.command))??null}function Sa(){try{const e=$e.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return Pe.warn("[OPENERS] Failed to read opener overrides",e),{}}}function Ta(e,t,s){return"darwin"===t?function(e,t){if(Aa("mdfind")){const t=_a("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(Aa("plutil")){const t=[_.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=_a("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){Pe.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>Ca(e))}(e,s):"win32"===t?function(e){return Aa("reg")&&(Boolean(_a("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean(_a("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(Aa("xdg-settings")){const t=_a("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(Aa("gio")){const t=_a("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function Ca(e){return"darwin"===process.platform&&Boolean(_a("open",["-Ra",e]))}function Aa(e){return"win32"===process.platform?Boolean(_a("where",[e])):Boolean(_a("sh",["-c",`command -v ${e}`]))}function _a(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&&Pe.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function Ea(e,t){St(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function $a(e){return e.replace(/'/g,"''")}function Ma(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Ra(e){return`'${e.replace(/'/g,"'\\''")}'`}function Pa(e,t){if(t){const n=N(t,e),s=!n||n.startsWith("..")||O(n)?$(e):n;return E(t,"versions",s)}let n=D(e),s=0;for(;s<10;){if(r(E(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return E(n,"versions",t)}const t=D(n);if(t===n)break;n=t,s++}const a=D(e),i=$(e);return E(a,`.${i}.version`)}function Da(e,t){const n=Pa(e,t);if(!r(n))return"0.0.0";try{return c(n,"utf-8").trim()}catch(e){return"0.0.0"}}function Na(e,t,n){try{const s=Pa(e,n),a=D(s);r(a)||d(a,{recursive:!0}),u(s,t,"utf-8")}catch(e){}}function Oa(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 Ua(e,t,n){const s=Da(e,n),a=Oa(t.metadata.version,s);if(!r(e)){const s=D(e);return r(s)||d(s,{recursive:!0}),u(e,t.content,"utf-8"),Na(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"),Na(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 ja(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 La(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=E($e.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),Tt(e.join(" "),{stdio:"pipe"}),a){const e=E(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 qa(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function qa(e){const t=[],n=E(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=E(n,e);p(s).isDirectory()&&r(E(s,"package.json"))&&t.push(s)}const s=E(e,"claude","hooks");r(s)&&r(E(s,"package.json"))&&t.push(s);for(const e of t)Tt("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),Tt("yarn build",{cwd:e,stdio:"pipe"})}function Ha(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 Fa=Ha("\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");function Ba(e){return Ha(`\n ## Task Preview URL Protocol:\n - Important: when a browser-viewable frontend preview URL is available, publishing it is required, not optional.\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 \`${e}\` 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 `)}function Ga(e){return Ha(`\n ## Agentrix Vision Artifact Protocol:\n - After you create or materially update the visual plan (\`plan/index.html\`), and again after you create or update the visual test report (\`test/index.html\`), use \`${e}\` to send the issue vision artifacts to the platform so the user can review them.\n - Pass only the repository root and issue id. The platform presents the available plan and test artifacts together.\n - Do not start the local Vision engine just to use this tool.\n - If this tool is unavailable, share the local artifact paths with the user and ask them to review.\n `)}function Wa(e){return Ha(`\n ## Agentrix Computer Use Protocol:\n - When the user explicitly asks you to operate this local computer, use \`${e}\`.\n - Use it for desktop apps, Finder, documents, windows, menus, dialogs, and other GUI operations.\n - Pass a concrete natural-language operation instruction. Do not invent low-level click coordinates or try to perform the GUI operation yourself.\n - When the operation references a file, directory, document, download, or save location, include the absolute path in the instruction.\n - Only use this tool for user-requested local computer control.\n `)}const za=Ha("\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 Ka(e){const t="group"===e?.chatType?.toLowerCase();return Ha(`\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 Ha(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?Ha("\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`)}Ka();const Va=Ha('\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'),Xa=Ha('\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'),Ja=Ha('\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'),Ya=Ha("\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"),Qa=Ha(`\n ${Ja}\n\n ${Va}\n\n ${Xa}\n`),Za=Ha('\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 ei(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 ti(e,t){const n=t.find(t=>t.id===e);if(!n)return ei(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(Za),a.join("\n")}function ni(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function si(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function ai(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function ii(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(si).map(e=>e.text).join("\n").trim():""}function oi(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n=Math.max(0,Math.trunc(e.durationMs??0)),s={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:n,duration_api_ms:n,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:s,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 ri(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 ci="agentrix",li="1.0.0",di=Yt(Ct),pi=Ne(import.meta.url),ui=["*","","!.gitignore","","!MEMORY.md","!USER.md","!SOUL.md","!IDENTITY.md","!SKILLS.md","!system_prompt.md","","!HEARTBEAT.md","!MEMORY_ORGANIZATION.md","!UPGRADES.md","!*.upgrade","","!memory/","!memory/**","!memory-changes/","!memory-changes/**","","!plugins/","!plugins/**","!versions/","!versions/**",""].join("\n"),mi=new Set(["MEMORY.md","USER.md","SOUL.md","IDENTITY.md","SKILLS.md","system_prompt.md","HEARTBEAT.md","MEMORY_ORGANIZATION.md","UPGRADES.md"]),hi=["memory","memory-changes","plugins","versions"],gi={GIT_AUTHOR_NAME:"Agentrix Companion",GIT_AUTHOR_EMAIL:"companion@agentrix.local",GIT_COMMITTER_NAME:"Agentrix Companion",GIT_COMMITTER_EMAIL:"companion@agentrix.local"};function fi(e){return function(e){return e.split(P).join("/")}(U(e)).replace(/^\.\//,"")}function yi(e,t){pi.warn(e,t)}async function vi(e,t){const{stdout:n}=await di("git",t,{cwd:e,encoding:"utf-8",windowsHide:!0,env:{...process.env,...gi}});return n}async function wi(e){try{return await vi(e,["diff","--cached","--quiet","--exit-code"]),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}async function bi(e,t,n){const s=["commit","-m",t];return n?.trim()&&s.push("-m",n.trim()),await vi(e,s),(await vi(e,["rev-parse","HEAD"])).trim()}async function ki(e){return(await vi(e,["ls-files"])).split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).filter(xi)}function xi(e){const t=fi(e);return!(!t||"."===t||t.startsWith("../")||t.includes("/../"))&&(!!mi.has(t)||!(t.includes("/")||!t.endsWith(".upgrade"))||hi.some(e=>t===e||t.startsWith(`${e}/`)))}function Ii(e,t){const n=U(e),s=U(t),a=O(s)?s:U(E(n,s)),i=fi(N(n,a));if(!i.startsWith("../")&&!O(i)&&xi(i))return{absolutePath:a,relativePath:i};if(!O(s)){const e=U(E(n,"memory",s)),t=fi(N(n,e));if(!t.startsWith("../")&&!O(t)&&xi(t))return{absolutePath:e,relativePath:t}}throw new Error(`Companion self-evolution path is not allowlisted: ${t}`)}async function Si(e){const{companionHome:t}=e;if(!t)return pi.warn("Skipping self-evolution git repo ensure: companion home is not set"),!1;if(!r(t))return pi.warn(`Skipping self-evolution git repo ensure: companion home does not exist (${t})`),!1;try{await qt(t,{recursive:!0});const e=r(E(t,".git"));return e||await vi(t,["init"]),await async function(e){const t=E(e,".gitignore");await Ht(t,"utf-8").catch(()=>{})!==ui&&await Ft(t,ui,"utf-8")}(t),e||(await Ti(t),await wi(t)&&await bi(t,"Initialize Companion self-evolution history","Initial snapshot before automatic Companion run checkpoints.")),!0}catch(e){return yi("Failed to ensure Companion self-evolution git repo",e),!1}}async function Ti(e){const t=await async function(e){const t=new Set;r(E(e,".gitignore"))&&t.add(".gitignore");for(const n of mi)r(E(e,n))&&t.add(n);const n=await Bt(e).catch(()=>[]);for(const s of n)!s.includes("/")&&s.endsWith(".upgrade")&&r(E(e,s))&&t.add(s);for(const n of hi)r(E(e,n))&&t.add(n);for(const n of await ki(e))t.add(n);return Array.from(t)}(e);0!==t.length&&await vi(e,["add","-A","--",...t])}function Ci(e){const t=["reasons:"];for(const n of e.reasons)t.push(`- ${n}`);return t.push("",`trigger: ${e.trigger}`,`source: ${e.source??"unspecified"}`),e.taskId&&t.push(`taskId: ${e.taskId}`),t.push(`action: ${e.action}`,`file: ${e.file}`),e.deletedFiles?.length&&t.push(`deletedFiles: ${e.deletedFiles.join(", ")}`),t.push(`notifiedCompanion: ${e.notifiedCompanion}`),t.join("\n")}async function Ai(e){const{companionHome:t,title:n,body:s,paths:a}=e;try{const e=await async function(e,t){const n=new Set(await ki(e)),s=Array.from(new Set(t.map(fi))).filter(xi).filter(t=>r(E(e,t))||n.has(t));return 0===s.length?[]:(await vi(e,["add","-A","--",...s]),s)}(t,a);return 0===e.length?(pi.warn("Skipping Companion memory change commit: no allowlisted paths to stage"),null):await wi(t)?await bi(t,n,s):null}catch(e){return yi("Failed to create Companion memory change semantic commit",e),null}}async function*_i(e){yield e}let Ei;const $i=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],Mi=["EnterPlanMode","ExitPlanMode"],Ri=new Set(Mi),Pi=["Glob","Grep","Read","Skill"],Di=["Read","Glob","Grep"],Ni=["Read","Glob","Grep","TodoWrite"];function Oi(e,t,n,s,a,i,o,l){const d=function(e){const{agentId:t,modeConfig:n,cwd:s,agentConfig:a,channelBound:i,channelContext:o,projectGuidance:l,promptPlaceholders:d,enableTaskPreviewUrl:p,enableVisionPlan:u,enableAgentrixComputerUse:m}=e,{mode:h,groupAgents:g}=n,f=a.customSystemPrompt,y=a.systemPromptMode??"append",v=function(e,t){const{mode:n,supportChangeTitle:s}=e,a=t?.enableTaskPreviewUrl??!0,i=[za];switch(n){case"work":s&&i.unshift(Fa),a&&i.push(Ba("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(Ga("mcp__agentrix__send_vision_artifact")),t?.enableAgentrixComputerUse&&i.push(Wa("mcp__agentrix__agentrix_computer_use"));break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":i.unshift(Ya),t?.enableAgentrixComputerUse&&i.push(Wa("mcp__agentrix__agentrix_computer_use"));break;case"group_work":s&&i.unshift(Fa),a&&i.push(Ba("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(Ga("mcp__agentrix__send_vision_artifact"))}return i.join("\n\n")}(n,{enableTaskPreviewUrl:p,enableVisionPlan:u,enableAgentrixComputerUse:m});if("group_chat"===h||"group_work"===h){const e=[Qa];return g&&g.length>0&&e.push(ei(g)),v&&e.push(v),i&&e.push(Ka(o)),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const w="reply"===h&&g&&g.length>0?ti(t,g):void 0,b={},k=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE,x="companion_shadow"===h?function(e){return"memory_organization"===e?.COMPANION_SHADOW_TASK?"memory_organization":"heartbeat"}(d):void 0;k&&(b.COMPANION_HOME=k,b.COMPANION_MODE="companion_shadow"===h?"shadow":"chat","companion_shadow"===h&&(b.AGENTRIX_MONITOR=function(){const e=$e.readSettings();if(!e||"object"!=typeof e)return"disable";const t=e["agentrix-monitor"];return t&&"object"==typeof t&&!0===t.enable?"enable":"disable"}(),b.COMPANION_SHADOW_TASK=x??"heartbeat")),Object.assign(b,d);const I=Object.keys(b).length>0?b:void 0,S=f?Rt(f,s,I):void 0,T="companion_shadow"===h?function(e,t){if(!e||!t)return;const n=E(e,"memory_organization"===t?"MEMORY_ORGANIZATION.md":"HEARTBEAT.md");if(!r(n))return;const s=c(n,"utf-8").trim();return s?[`## Injected Companion ${"memory_organization"===t?"Memory Organization":"Heartbeat"} Routine`,"",s].join("\n"):void 0}(k,x):void 0;if("replace"===y&&S){const e=[S];return w&&e.push(w),v&&e.push(v),i&&e.push(Ka(o)),T&&e.push(T),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const C=[];return w&&C.push(w),v&&C.push(v),i&&C.push(Ka(o)),S&&C.push(S),T&&C.push(T),l?.systemPromptAppend&&C.push(l.systemPromptAppend),{type:"preset",preset:"claude_code",append:C.length>0?C.join("\n\n"):void 0}}({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,enableVisionPlan:n.enableVisionPlan,enableAgentrixComputerUse:n.enableAgentrixComputerUse}),p=(u=function(e){switch(e){case"work":case"companion_shadow":return;case"chat":case"companion_chat":return[...$i];case"reply":return[...Pi];case"group_chat":return[...Di];case"group_work":return[...Ni]}}(n.modeConfig.mode),Boolean(n.disableClaudePlanModeTools)&&u?u.filter(e=>!Ri.has(e)):u);var u;const m=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),h=function(){if(void 0!==Ei)return Ei??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=O(t)?t:R(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 Ei=t,t}Ei=null}(),g=o?function(e){const{modeConfig:t,tools:n,agentType:s,allowAskUser:a=!0,supportedFeatures:i,channelBound:o,channelGroupBound:r,visionModel:c,enableTaskPreviewUrl:l=!0,enableVisionPlan:d=!1,enableComputerUse:p=!1,extraTools:u=[],serverName:m=ci,serverVersion:h=li}=e,{mode:g,supportChangeTitle:f}=t,y=[];switch(g){case"work":p&&y.push(n.computerUse),i?.includes("sub-task")&&(y.push(n.createTask),y.push(n.replyToSubTask),y.push(n.listSubTask)),f&&y.push(n.changeTaskTitle),a&&y.push(n.askUser),l&&y.push(n.publishTaskPreviewUrl),d&&y.push(n.sendVisionArtifact),y.push(n.getTaskHistory);break;case"chat":p&&y.push(n.computerUse),y.push(n.createTask),y.push(n.replyToSubTask),a&&y.push(n.askUser),y.push(n.getTaskHistory),y.push(n.listSubTask);break;case"group_chat":y.push(n.invoke),y.push(n.createSoloTask),y.push(n.createGroupTask),y.push(n.replyToSubTask),y.push(n.getTaskAgents),y.push(n.getTaskHistory);break;case"group_work":y.push(n.invoke),y.push(n.assign),f&&y.push(n.changeTaskTitle),l&&y.push(n.publishTaskPreviewUrl),d&&y.push(n.sendVisionArtifact),y.push(n.getTaskAgents),y.push(n.getTaskHistory);break;case"reply":y.push(n.getTaskHistory),a&&y.push(n.askUser);break;case"companion_chat":y.push(n.createTask),y.push(n.replyToSubTask),a&&y.push(n.askUser),y.push(n.getTaskHistory),y.push(n.uploadFile),y.push(n.listAgents),y.push(n.scheduleTask);break;case"companion_shadow":y.push(n.getTaskHistory),y.push(n.readConversation),y.push(n.listAgents),y.push(n.scheduleTask)}("companion_chat"===g||"companion_shadow"===g)&&(y.push(n.listTasks),y.push(n.sendReminder),y.push(n.recordMemoryChange),y.push(n.prepareHiveRepository),y.push(n.publishToHive),y.push(n.updateHiveListingVersion),y.push(n.recordHiveInstall),y.push(n.createHiveReview),y.push(n.createHiveComment)),"companion"===s&&y.push(n.updateAgentInfo),o&&"companion_shadow"!==g&&y.push(n.sendChannelMessage),r&&"companion_shadow"!==g&&y.push(n.getChannelGroupHistory),c&&"companion_shadow"!==g&&"reply"!==g&&y.push(n.analyzeImage),y.push(...u);const v=_t({name:m,version:h,tools:y}),w=y.map(e=>((e,t)=>`mcp__${e}__${t}`)(m,e.name));return{server:v,toolNames:w}}({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,enableVisionPlan:n.enableVisionPlan,enableComputerUse:n.enableAgentrixComputerUse,extraTools:n.agentrixExtraTools}):void 0,f={...g?.server?{agentrix:g.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:d,tools:p,...n.disableClaudePlanModeTools?{disallowedTools:[...Mi]}:{},mcpServers:f,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?ni(n.env):void 0,pathToClaudeCodeExecutable:h,maxTurns:s.customMaxTurns??n.maxTurns??l,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:m,outputFormat:n.structuredOutputSchema}}class Ui{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?ai(e):e;let a=null;await this.checkpointCompanionRun(t,"before_run");try{const e=Et({prompt:_i(s),options:Oi(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if("result"===t.type){a=t;break}if(!a)throw new Error("ClaudeRunner.run: missing result message");return a}finally{await this.checkpointCompanionRun(t,"after_run")}}async*runStreamed(e,t){const n=this.agentConfig,s="string"==typeof e?ai(e):e;await this.checkpointCompanionRun(t,"before_run");try{const e=Et({prompt:_i(s),options:Oi(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if(yield t,"result"===t.type)break}finally{await this.checkpointCompanionRun(t,"after_run")}}loop(e){const t=this,n=e.abortController,s=this.agentConfig,a=Oi(this.agentId,this.agentType,e,s,this.agentHooks,this.agentMcpServers,e.agentrixTools);let i=!1;const o=[];let r=null,c=null;const l=()=>{if(!i&&(i=!0,r)){const e=r;r=null,e(null)}},d=async function*(){for(;!i&&!n.signal.aborted;){if(o.length>0){yield o.shift();continue}const e=await new Promise(e=>{r=e});if(!e)break;yield e}},p=async function*(){try{await t.checkpointCompanionRun(e,"before_run");const n=Et({prompt:d(),options:a});c=n;for await(const e of n)yield e}finally{c=null,await t.checkpointCompanionRun(e,"after_run"),l()}}();return n.signal.addEventListener("abort",l,{once:!0}),{push:e=>{if(i)return;const t="string"==typeof e?ai(e):e;if(r){const e=r;return r=null,void e(t)}o.push(t)},events:p,stop:l,setPermissionMode:async e=>{c&&await c.setPermissionMode(e)},setModel:async e=>{c&&await c.setModel(e)}}}async checkpointCompanionRun(e,t){const n=e.modeConfig.mode;if("companion_chat"!==n&&"companion_shadow"!==n)return;const s=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE;var a;await async function(e){const{companionHome:t,mode:n,phase:s}=e;if("companion_chat"!==n&&"companion_shadow"!==n)return{committed:!1};try{if(!await Si({companionHome:t})||!t)return{committed:!1};if(await Ti(t),!await wi(t))return{committed:!1};const a="companion_shadow"===n?e.shadowTask??"unknown":"unknown",i=await bi(t,function(e,t,n){const s="before_run"===n?"before":"after";return"companion_shadow"===e?"unknown"===t?`checkpoint: ${s} companion_shadow run`:`checkpoint: ${s} companion_shadow ${t} run`:`checkpoint: ${s} companion_chat run`}(n,a,s),function(e,t,n){return[`mode: ${e}`,`shadow_task: ${"companion_shadow"===e?t:"unknown"}`,`phase: ${n}`].join("\n")}(n,a,s));return pi.info(`Created Companion self-evolution ${s} checkpoint ${i}`),{committed:!0,commit:i}}catch(e){return yi(`Failed to create Companion self-evolution ${s} checkpoint`,e),{committed:!1}}}({companionHome:s,mode:n,shadowTask:"companion_shadow"===n?(a=e.promptPlaceholders,"heartbeat"===a?.COMPANION_SHADOW_TASK?"heartbeat":"memory_organization"===a?.COMPANION_SHADOW_TASK?"memory_organization":"unknown"):void 0,phase:t})}}const ji=Ne(import.meta.url);function Li(){return`Companion probe timed out after ${Math.round(45)}s`}function qi(e){return e instanceof Error&&e.message?e.message:String(e)}function Hi(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 Fi(){const e=E($e.agentrixHomeDir,"tmp","companion-probe");d(e,{recursive:!0});const t=new Ui("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?Li():Hi(a)}:{success:!0}}catch(e){return{success:!1,error:s?Li():qi(e)}}finally{clearTimeout(a)}}const Bi=Yt(Ct);function Gi(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),Qt(t)}async function Wi(e){try{const t=Gi(e);return await t.checkIsRepo()}catch{return!1}}async function zi(e){const t=Gi(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 Ki(e,t,n,s="HEAD"){const a=D(t);if(r(a)||d(a,{recursive:!0}),r(t)&&!no(t))throw new Error(`Worktree directory already exists at ${t}`);const i=Gi(e);await i.raw(["worktree","add","-b",n,t,s])}async function Vi(e,t,n=!1){const s=Gi(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function Xi(e){const t=Gi(e);await t.init()}async function Ji(e){const t=Gi(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function Yi(e,t){const n=D(t);r(n)||d(n,{recursive:!0});const s=Gi();await s.clone(e,t)}async function Qi(e,t,n){const s=Gi(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(await ho(e).catch(()=>[])).includes(t)?await Bi("git",["checkout","-B",t,`origin/${t}`],{cwd:e,windowsHide:!0}):n?await Bi("git",["checkout","-b",t,n],{cwd:e,windowsHide:!0}):await s.checkoutLocalBranch(t)}async function Zi(e){const t=Gi(e);return!(await t.status()).isClean()}async function eo(e){const t=Gi(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function to(e){try{const t=Gi(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function no(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function so(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function ao(e,t,n){const s=Gi(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:so(ee(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function io(e,t){try{const{stdout:n}=await Bi("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 oo(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:so(ee(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function ro(e,t){return Se("sha256").update(`${e}\n${t}`).digest("hex")}async function co(e,t){const n=await io(e,["diff","--binary","--find-renames",t,"--"]),s=oo(await io(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await Bi("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=>io(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=oo((await Promise.all(a.map(t=>io(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:ro(t,r)}:null;var c}async function lo(e){const t=Gi(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function po(e,t,n){const s=Gi(e);await s.remote(["set-url",t,n])}function uo(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function mo(e,t,n){const s=Gi(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await po(e,t,n):await s.addRemote(t,n)}async function ho(e,t="origin"){const{stdout:n}=await Bi("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)}function go(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 fo(e){try{const t=Gi(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?go(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const yo="oauth2",vo="AGENTRIX_GIT_USERNAME",wo="AGENTRIX_GIT_PASSWORD";function bo(){const e=E(s(),`git-askpass-${Ie()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${vo}:-${yo}}" ;;\n *) printf '%s\\n' "\${${wo}:-}" ;;\nesac\n`,{mode:448}),e}function ko(e,t,n=yo){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[vo]:n,[wo]:t}}function xo(){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 Io=Yt(Ct),So="github",To="xmz-ai",Co="agentrix-agent",Ao="https://github.com/xmz-ai/agentrix-agent.git",_o="main";async function Eo(e,t,n){await Io("git",["clone","--depth=1","--branch",t,e,n]),await mo(n,"origin",uo(e))}async function $o(e){const t=$e.resolveRepoStoreCheckoutDir(So,To,Co),n=E(t,"companion"),s=$e.resolveRepoStoreLockPath(So,To,Co),a=await $e.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=`${$e.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||_o}}return{gitUrl:Ao,branch:_o}}(e);if(!await Wi(t)){if(!no(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await Eo(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 Io("git",["fetch","--depth=1",e,t],{cwd:n}),await Io("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await mo(n,"origin",uo(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=E(D(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await Eo(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 $e.releaseFileLock(s,a)}}function Mo(e){r(e)||d(e,{recursive:!0})}function Ro(e){return e.split("\\").join("/")}function Po(e,t){const n=E(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 Do(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 No(e){return E(e,"versions/.companion-template-language.json")}async function Oo(e){const t=$e.agentrixAgentsHomeDir,n=E(t,"companion"),s=E(n,"claude"),a=!r(E(n,"agent.json")),i=await $o(e?.credentials);let o=r(E(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 Fi();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(E(o,"agent.json")))y(o,n,{recursive:!0}),qa(n),console.log("[Companion] Installed from template repository");else try{await La({agentId:"companion",gitUrl:Ao,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(E(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await La({agentId:"companion",gitUrl:Ao,branch:"main",subDir:"companion"})),o=r(E(i.companionDir,"agent.json"))?i.companionDir:n}Mo(E(s,"memory"));const l=Do(e?.preferredLanguage),d=function(e,t,n){if(n)return{language:t,source:"initial-install",verified:!0};const s=function(e){const t=No(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=E(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"===d.source&&d.language!==l&&console.log(`[Companion] Using installed template language ${d.language}; requested language ${l} ignored for safe upgrades`),d.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=Do(e),a=Po("common",t),i=Po(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=E(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n,language:"common",sourcePath:s})}const d=E(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=E(s,i);if(p(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=Ro(N(e,a));t[o]=c(a,"utf-8")}};return n(e),t}(d);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:E(d,e)})}if(0===o.length)throw new Error(`Companion template files are missing in ${t}`);return{language:s,templates:o}}(d.language,o,a);!function(e,t,n){if("unverified"===n)return;const s=No(e);Mo(D(s)),u(s,JSON.stringify({language:t,source:n,updatedAt:(new Date).toISOString()},null,2),"utf-8")}(n,m,d.source);const f=[];for(const e of h){const t=Ua(E(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/")))&&(qa(n),console.log("[Companion] Rebuilt plugins after template updates"));const{pendingUpgrades:v,blockedUpgrades:w}=function(e,t,n={}){const s=[],a=[];for(const i of e){if("notify-user"!==i.metadata.updateStrategy)continue;const e=E(t,i.relativePath);if(!r(e))continue;const o=Da(e,t);if(Oa(i.metadata.version,o)>0){const r={template:i,targetPath:e,upgradePath:`${e}.upgrade`,versionPath:Pa(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:d.verified});if(v.length>0||w.length>0)try{const e=E(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:v,blockedUpgrades:w,agentDir:n,language:m,languageSource:d.source});u(e,t,"utf-8");for(const e of v)u(e.upgradePath,ja(e),"utf-8");console.log(`[Companion] Created UPGRADES.md with ${v.length} pending upgrade(s) and ${w.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 Uo=[{version:1,fileName:"001_init.sql"}];function jo(e){var t;return function(e,t){const n=new en(e),s=new Zt;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=at(tn(import.meta.url)),t=[st(e,"migrations"),st(process.cwd(),"dist","migrations"),st(process.cwd(),"src","worker","history","migrations")];for(const e of t)if(Be(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=st(e,t);return Fe(n,"utf8")}(t,Uo[0].fileName);e.exec(s),n<Uo[0].version&&e.pragma(`user_version = ${Uo[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 * FROM task_event\n WHERE event_type = 'task-message'\n ORDER BY COALESCE(sequence, 0) DESC, rowid DESC\n LIMIT ?\n "),d=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 "),u=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence ASC\n LIMIT ?\n "),m=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence < ?\n ORDER BY local_sequence DESC\n LIMIT ?\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 1 as has_row\n FROM task_message\n WHERE local_sequence > ?\n LIMIT 1\n "),f=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),y=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 "),w=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??V(),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??V(),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(qo),s=n.at(-1)?.sequence??null;return{data:n,hasMore:null!==s&&Boolean(d.get(s))}},pageRecentTaskEvents:e=>{const t=l.all(e);return{data:t.map(qo).reverse(),hasMore:t.length>=e}},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?qo(s):null},pageRecentMessages:e=>{const t=p.all(e).map(Lo).reverse(),n=t[0]?.localSequence??null;return{data:t,hasMore:!!n&&Boolean(h.get(n))}},pageMessagesAfter:(e,t)=>{const n=u.all(e,t).map(Lo),s=n.at(-1)?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(g.get(s))}},pageMessagesBefore:(e,t)=>{const n=m.all(e,t).map(Lo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},pageRecentMessagesAfter:(e,t)=>{const n=f.all(e,t).map(Lo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},getAgentSessions:()=>{const e=y.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.session_id);return t},getAgentLastSequences:()=>{const e=y.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)=>{w.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,st(t,"data.bin")),e.taskId)}function Lo(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 qo(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 Ho=[1,2,4,6,8,12,24];function Fo(e){return"number"==typeof e&&Ho.includes(e)}function Bo(e){return Fo(e)?e:4}class Go{constructor(e,t,n={}){this.client=e,this.machineId=t;const s=$e.agentrixAgentsHomeDir,a=E(s,"companion","claude");this.stateFilePath=n.stateFilePath??E(a,"state.json"),this.initialDelayMs=n.initialDelayMs??6e4,this.monitorCandidateChecker=n.monitorCandidateChecker}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;memoryOrganizationEnabled=!1;memoryOrganizationIntervalHours=4;memoryOrganizationTaskId=null;companionState=null;stateFilePath;initialDelayMs;monitorCandidateChecker;started=!1;cronJobs=new Map;start(){this.started?this.reloadStateAndReschedule():(this.started=!0,this.loadState(),this.companionState?(Pe.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):Pe.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),Pe.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(),Pe.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),Pe.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(),Pe.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),Pe.info("[COMPANION SCHEDULER] Cleared heartbeat task ID")}setMemoryOrganizationTaskId(e){this.memoryOrganizationTaskId=e,this.saveStateField("memoryOrganizationTaskId",e)}clearMemoryOrganizationTaskId(){this.memoryOrganizationTaskId=null,this.saveStateField("memoryOrganizationTaskId",void 0),Pe.info("[COMPANION SCHEDULER] Cleared memory organization task ID")}recordInteraction(e){if(!this.companionState?.chatId||e!==this.companionState.chatId)return;const t=(new Date).toISOString();this.saveStateField("lastInteractionTimestamp",t),Pe.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&&(Pe.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,this.memoryOrganizationEnabled=this.companionState?.memoryOrganizationEnabled??!1,this.memoryOrganizationIntervalHours=Bo(this.companionState?.memoryOrganizationIntervalHours),this.memoryOrganizationTaskId=this.companionState?.memoryOrganizationTaskId??null,Pe.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"}, memoryOrganizationEnabled=${this.memoryOrganizationEnabled}, memoryOrganizationIntervalHours=${this.memoryOrganizationIntervalHours}, memoryOrganizationTaskId=${this.memoryOrganizationTaskId??"none"}`)}}catch(e){Pe.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=D(this.stateFilePath);r(s)||d(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),Pe.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){Pe.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")}`}isMemoryOrganizationDue(e,t){if(!this.memoryOrganizationEnabled)return!1;if(!(e.agentId&&e.machineId&&e.userId&&e.chatId))return!1;if(!e.lastMemoryOrganizationTimestamp)return!0;const n=new Date(e.lastMemoryOrganizationTimestamp).getTime();if(Number.isNaN(n))return!0;const s=60*this.memoryOrganizationIntervalHours*60*1e3;return t.getTime()-n>=s}triggerMemoryOrganization(e,t){const n=t.toISOString();this.saveStateField("lastMemoryOrganizationTimestamp",n);const s=t.toLocaleString(),a={type:"companion_memory_organization",timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours};if(this.memoryOrganizationTaskId)return Pe.debug(`[COMPANION SCHEDULER] Sending memory organization to existing task ${this.memoryOrganizationTaskId}`),void this.client.send("task-message",{eventId:V(),taskId:this.memoryOrganizationTaskId,chatId:e.chatId,from:"machine",message:a,senderType:"system",senderId:"system",senderName:"system"});Pe.debug("[COMPANION SCHEDULER] Requesting initial memory organization task"),this.client.send("request-companion-memory-organization",{eventId:V(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours})}isMonitorEnabled(){try{const e=$e.readSettings();if(!e||"object"!=typeof e)return!1;const t=e["agentrix-monitor"];return Boolean(t&&"object"==typeof t&&!0===t.enable)}catch(e){return Pe.debug("[COMPANION SCHEDULER] Failed to read Agentrix Monitor settings",e),!1}}readMonitorControl(){try{const e=E($e.agentrixHomeDir,"monitor","control.json"),t=JSON.parse(c(e,"utf-8"));return t.base_url&&t.token?{baseUrl:t.base_url.replace(/\/+$/,""),token:t.token}:(Pe.debug("[COMPANION SCHEDULER] Agentrix Monitor control file is missing base_url or token"),null)}catch(e){return Pe.debug("[COMPANION SCHEDULER] Agentrix Monitor control file unavailable",e),null}}async listMonitorCandidates(e,t,n){n.set("agent_id",t.agentId),n.set("limit","5");const s=await fetch(`${e.baseUrl}/candidates?${n.toString()}`,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},signal:AbortSignal.timeout(5e3)});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`Monitor candidate query failed: ${s.status} ${e}`.trim())}const a=await s.json();return Array.isArray(a.candidates)?a.candidates:[]}async hasPendingMonitorCandidates(e){if(!this.isMonitorEnabled())return!1;if(!e.agentId)return!1;if(this.monitorCandidateChecker)return await this.monitorCandidateChecker(e);const t=this.readMonitorControl();if(!t)return!1;try{const n=[new URLSearchParams({status:"init",kind:"handoff"}),new URLSearchParams({status:"pending",kind:"memory"}),new URLSearchParams({status:"pending",kind:"knowledge"}),new URLSearchParams({status:"pending",kind:"automation"})];for(const s of n)if((await this.listMonitorCandidates(t,e,s)).length>0)return!0}catch(e){Pe.debug("[COMPANION SCHEDULER] Agentrix Monitor candidate check failed",e)}return!1}addScheduledTask(e){const t={id:Ie(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),Pe.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)),Pe.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 Pe.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 Pe.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 sn(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),Pe.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){Pe.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){Pe.info(`[COMPANION SCHEDULER] Scheduled task fired: id=${e.id}, task="${e.task}"`),this.loadState();const t=this.companionState;if(!t?.chatId)return;const n=t.chatTaskId??t.chatId;this.client.send("task-message",{eventId:V(),taskId:n,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()?Pe.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);Pe.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}async tick(){if(this.loadState(),!this.companionState)return void Pe.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");const e=this.companionState,t=[],n=new Date;if(this.isMemoryOrganizationDue(e,n)&&(Pe.info("[COMPANION SCHEDULER] Memory organization triggered"),this.triggerMemoryOrganization(e,n)),!this.enabled)return void Pe.debug("[COMPANION SCHEDULER] Heartbeat disabled, skipping");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){if(!await this.hasPendingMonitorCandidates(e))return void Pe.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");t.push("monitor_candidates")}Pe.info(`[COMPANION SCHEDULER] Heartbeat triggered: ${t.join(", ")}`);const a=("number"==typeof e.heartbeatTriggerCount?e.heartbeatTriggerCount:0)+1;this.saveStateField("lastHeartbeatTimestamp",n.toISOString()),this.saveStateField("lastHeartbeatDate",s),this.saveStateField("heartbeatTriggerCount",a);const i=n.toLocaleString(),o={type:"companion_heartbeat",timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a};this.heartbeatTaskId?(Pe.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:V(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:o,senderType:"system",senderId:"system",senderName:"system"})):(Pe.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:V(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a}))}}const Wo=new Nt({credentialsDir:E($e.agentrixHomeDir,"credentials")});async function zo(){const e=await $e.readCredentials();return e?.secret?Ot(e.secret):null}function Ko(e){return Wo.loadGitServerConfig(e)}function Vo(e,t){return Wo.loadGitLabWebhookBridgeSecrets(e,t)}function Xo(e,t,n){Wo.saveGitLabWebhookBridgeSecrets(e,t,n)}function Jo(e){return Wo.loadPatMeta(e)}function Yo(e,t){return Wo.loadPat(e,t)}const Qo="https://ilinkai.weixin.qq.com",Zo="https://novac2c.cdn.weixin.qq.com/c2c",er=1e3,tr=ut(import.meta.url)("qrcode-terminal");function nr(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function sr(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function ar(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 ir(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 or(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function rr(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 cr(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 lr(e){if(e.image_item?.media?.full_url)return dr(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 dr(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 dr(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 pr(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 ur(e){return e.retcode??e.ret??e.errcode}function mr(e,t){const n=ur(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function hr(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function gr(e){let t="";return tr.generate(e,{small:!0},e=>{t=e}),t}class fr{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=er;contextTokens=new Map;clientId=xe(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=sr(e.token)??sr(e.botToken)??sr(e.bot_token)??sr(e.apiKey)??sr(e.api_key);return{baseUrl:sr(e.baseUrl)??sr(e.base_url)??Qo,token:t||nr(t,"token"),routeTag:sr(e.routeTag)??sr(e.route_tag),getUpdatesBuf:sr(e.getUpdatesBuf)??sr(e.get_updates_buf)??"",channelVersion:sr(e.channelVersion)??sr(e.channel_version)??"1.0.0",pollTimeoutMs:ar(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:ar(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:sr(e.fileDownloadEndpoint)??sr(e.file_download_endpoint)??sr(e.downloadEndpoint)??sr(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||Qo,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${hr(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=ur(a);if(i&&0!==i)throw new Error(mr(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:gr(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||Qo,s=await fetch(`${hr(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=ur(a);if(i&&0!==i)throw new Error(mr(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=er,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),Pe.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()}-${xe(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=ur(s);if(a&&0!==a)throw new Error(mr(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.filePath),a=await Ht(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},d="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)}},p=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${xe(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[d]}},{timeoutMs:this.credentials.requestTimeoutMs}),u=ur(p);if(u&&0!==u)throw new Error(mr(p,"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=xe(16).toString("hex"),i=xe(16).toString("hex"),o=this.encryptWechatMedia(t,i),r=Se("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=ur(c);if(l&&0!==l)throw new Error(mr(c,"WeChat getuploadurl failed"));const d=this.extractUploadParam(c),p=await fetch(`${Zo}/upload?encrypted_query_param=${encodeURIComponent(d)}&filekey=${encodeURIComponent(a)}`,{method:"POST",headers:{"Content-Type":"application/octet-stream","Content-Length":String(o.length)},body:o});if(!p.ok){const e=await p.text().catch(()=>"");throw new Error(`WeChat CDN upload failed: HTTP ${p.status}: ${e||p.statusText}`)}const u=p.headers.get("x-encrypted-param");if(!u)throw new Error("WeChat CDN upload response missing x-encrypted-param");return{fullUrl:`${Zo}/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 gs(e,t.fileName);const s=await this.requestDownloadFile(e);return await hs(s,t.fileName||e)}catch(t){return Pe.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=ur(e);if(t&&0!==t)throw new Error(mr(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=er,"connected"!==this.connectionState&&this.setState("connected");for(const e of pr(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));Pe.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=us(t||e.fileName||"attachment");return await Ft(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=Te("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=Te("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=Ce("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 hr(this.credentials.baseUrl,e)}generateWechatUin(){const e=xe(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 Pe.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?dr(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?dr(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??Ie()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:or(n,["sender_name","nickname","user_name"]),type:cr(e),text:rr(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:lr(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:ir(e.timestamp??e.create_time),raw:e}}}const yr=["telegram","wechat","lark"],vr=wt.enum(yr),wr=wt.enum(["connecting","connected","disconnected","error"]),br=wt.enum(["text","image","file","voice"]),kr=wt.record(wt.string(),wt.unknown()),xr=wt.object({id:wt.string(),platform:vr,name:wt.string().optional(),credentials:kr,enabled:wt.boolean(),connectionState:wr,lastConnectedAt:wt.string().optional(),lastDisconnectedAt:wt.string().optional(),lastError:wt.string().optional(),createdAt:wt.string(),updatedAt:wt.string()}),Ir=wt.object({platform:vr,name:wt.string().optional(),credentials:kr,enabled:wt.boolean().optional()}),Sr=wt.object({id:wt.string(),channelId:wt.string(),chatId:wt.string(),taskId:wt.string(),chatName:wt.string().optional(),createdAt:wt.string(),updatedAt:wt.string()});wt.object({id:wt.string(),channelId:wt.string(),platform:vr,chatId:wt.string(),chatType:wt.string().optional(),senderId:wt.string().optional(),senderType:wt.string().optional(),senderName:wt.string().optional(),type:br,text:wt.string().optional(),fileKey:wt.string().optional(),fileName:wt.string().optional(),imageKey:wt.string().optional(),attachmentPaths:wt.array(wt.string()).optional(),mentionedBot:wt.boolean().optional(),replyToBot:wt.boolean().optional(),triggered:wt.boolean().optional(),rawContent:wt.unknown().optional(),timestamp:wt.string(),raw:wt.unknown().optional()});const Tr=wt.object({id:wt.string(),name:wt.string(),avatar:wt.string().optional(),description:wt.string().optional(),chatStatus:wt.string().optional(),external:wt.boolean().optional()}),Cr=wt.enum(["auto","image","file","audio","video"]),Ar=wt.object({filePath:wt.string(),fileName:wt.string().optional(),mimeType:wt.string().optional(),kind:Cr.optional()});wt.object({content:wt.string().optional(),attachments:wt.array(Ar).optional()});const _r=wt.object({version:wt.literal(1),channels:wt.array(xr),bindings:wt.array(Sr)});let Er=an();const $r=an();function Mr(e){return e.secret||e.token}function Rr(e,t){return Ae("sha256",t).update(e).digest("base64url")}function Pr(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&&_e(n,s)}(s,Rr(n,Mr(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 Dr=wt.object({repoRoot:wt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:wt.string().min(1).max(160).regex(/^[A-Za-z0-9._-]+$/).describe("Agentrix issue directory id, for example 478-vision-plan-agentrix-platform-bridge")});async function Nr(e,t){return{issueId:Dr.parse(e).issueId}}const Or="agentrix_event_broker",Ur="/mcp/agentrix-event-broker",jr="change_title",Lr="publish_task_preview_url",qr="send_vision_artifact";function Hr(e,t){return{changeTitle:(e,n)=>async function(e,t,n){const s=e?.();if(!s?.connected)throw new Error("Agentrix daemon machine socket is not connected");const a={eventId:V(),taskId:t.taskId,title:n},i=await s.sendWithAck("change-task-title",a);if("success"!==i.status)throw new Error(i.message||"Failed to change task title")}(t,e,n),publishTaskPreviewUrl:(t,n)=>async function(e,t,n){const s=await fetch(`${$e.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),sendVisionArtifact:async(e,n)=>{const s=await Nr(n,e.taskId),a=t?.();if(!a?.connected)throw new Error("Agentrix daemon machine socket is not connected");const i=await a.sendWithAck("vision-plan-card",{eventId:V(),taskId:e.taskId,issueId:s.issueId,repoRoot:n.repoRoot,createdAt:(new Date).toISOString()});if("success"!==i.status)throw new Error(i.message||"Failed to send Vision Plan card");return{issueId:s.issueId}}}}async function Fr(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 mn({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(jr,{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:wt.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(Lr,{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:wt.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=te.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}]}}),!0===e.context.visionPlanEnabled&&t.registerTool(qr,{title:"Send Agentrix vision artifacts",description:["Send the issue vision artifacts (visual plan and test report) to the Agentrix platform so the user can review them.","Use this after generating or materially updating the visual plan, and again after generating the visual test report.","Pass only the repository root and issue id."].join(" "),inputSchema:{repoRoot:wt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:wt.string().min(1).max(160).describe("Agentrix issue directory id")}},async({repoRoot:t,issueId:n})=>({content:[{type:"text",text:await async function(e,t,n){const s=Dr.parse(n);return`Agentrix vision artifacts sent for issue ${(await e.sendVisionArtifact(t,s)).issueId}.`}(e.dispatcher,e.context,{repoRoot:t,issueId:n})}]})),t}({context:Pr(n.credentials,s),dispatcher:n.dispatcher}),i=new hn({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){Pe.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(()=>{})}}class Br extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="MachineAesKeyUpdateError"}}function Gr(e){if(!e)return null;try{const t=B(e);return 32===t.length?t:null}catch{return null}}function Wr(e){return!!Gr(e.machineAesKey)}const zr=Ne(import.meta.url),Kr="agentrix-computer-use";function Vr(){const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return r(e)?{available:!0,path:e}:{available:!1,path:e};const t=It("win32"===process.platform?"where":"which",["codex"],{encoding:"utf8"}).stdout.split(/\r?\n/).map(e=>e.trim()).find(Boolean);return t?{available:!0,path:t}:{available:!1}}function Xr(e,t){const s=t?.trim();if(s)return r(s)?{available:!0,path:s}:{available:!1,path:s};const a=It("win32"===process.platform?"where":"which",[e],{encoding:"utf8"}).stdout.split(/\r?\n/).map(e=>e.trim()).find(Boolean);if(a)return{available:!0,path:a};for(const e of[E(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver","/Applications/CuaDriver.app/Contents/MacOS/cua-driver"])if(r(e))return{available:!0,path:e};return{available:!1}}function Jr(e){try{return p(e).isDirectory()}catch{return!1}}function Yr(e){return"boolean"==typeof e?e:void 0}function Qr(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Zr(e){return[E(e,"skills","cua-driver"),E(n.homedir(),".agents","skills","cua-driver")]}function ec(){const e=process.env.AGENTRIX_CUA_DRIVER_SKILL_SOURCE?.trim();if(e){const t=Qr(e);return r(E(t,"SKILL.md"))?t:null}const t=[E(n.homedir(),".agents","skills","cua-driver"),E(n.homedir(),".claude","skills","cua-driver"),E(n.homedir(),".openclaw","skills","cua-driver")].filter(e=>Boolean(e));for(const e of t){const t=R(Qr(e));if(r(E(t,"SKILL.md")))return t}return null}function tc(e=$e.readSettings()){const t=function(){const e=process.env.AGENTRIX_COMPUTER_USE_CODEX_HOME||process.env.AGENTRIX_CODEX_HOME_FOR_COMPUTER_USE;return e?.trim()?e.trim().replace(/^~(?=\/|$)/,n.homedir()):E(n.homedir(),".codex")}(),s=E($e.agentrixHomeDir,"computer-use","enabled"),a=function(e,t){if(n=process.env.AGENTRIX_COMPUTER_USE_ENABLED,["1","true","yes","on"].includes((n??"").trim().toLowerCase()))return"env";var n;const s=e;return!1===s?.agentrixComputerUse?.enabled?null:!0===s?.agentrixComputerUse?.enabled?"settings":r(t)?"marker":null}(e,s),i=Vr(),o=Xr("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH),l=E(t,"config.toml"),d=function(e){try{return c(e,"utf8")}catch{return""}}(l),p=d.length>0,u=/\[mcp_servers\.(["']?cua-driver["']?|cua_driver)\]/.test(d)||/cua-driver/.test(d);E(t,"skills","cua-driver");const m=null!==function(e){for(const t of Zr(e))if(Jr(t)&&r(E(t,"SKILL.md")))return t;return null}(t),h=ec()??void 0,g=function(e){if(!e||"darwin"!==process.platform)return{};const t=It(e,["doctor","--json"],{encoding:"utf8",timeout:1e4});try{const e=JSON.parse(t.stdout);return{accessibilityGranted:Yr(e.ax_granted),screenRecordingGranted:Yr(e.screen_recording_granted)}}catch(e){return 0!==t.status?{error:[t.stderr,t.stdout].map(e=>e?.trim()).filter(Boolean).join("\n")||"Failed to check Cua Driver permission status."}:{error:`Failed to parse Cua Driver permission status: ${e instanceof Error?e.message:String(e)}`}}}(o.path),f=[];return i.available||f.push("Codex CLI is not available. Install Codex or set AGENTRIX_CODEX_PATH to the codex executable."),o.available||f.push("Cua Driver CLI is not available. Install Cua Driver or set AGENTRIX_CUA_DRIVER_PATH to the cua-driver executable."),g.error&&f.push(`Cua Driver permission status could not be checked: ${g.error}`),!1===g.accessibilityGranted&&f.push("Cua Driver Accessibility permission is not granted. Install Agentrix Computer Use to open the macOS permission prompt, then grant Accessibility access."),!1===g.screenRecordingGranted&&f.push("Cua Driver Screen Recording permission is not granted. Install Agentrix Computer Use to open the macOS permission prompt, then grant Screen Recording access."),p&&u||f.push(`Cua Driver MCP is not configured in ${l}. Run: cua-driver mcp-config --client codex`),m||f.push(`Cua Driver Codex skill is missing. Checked ${Zr(t).join(" and ")}.`),{platform:process.platform,enabled:null!==a,enabledBy:a,codexHome:t,codexAvailable:i.available,codexPath:i.path,codexConfigPresent:p,cuaDriverAvailable:o.available,cuaDriverPath:o.path,cuaDriverAccessibilityGranted:g.accessibilityGranted,cuaDriverScreenRecordingGranted:g.screenRecordingGranted,cuaDriverMcpConfigured:u,cuaDriverSkillPresent:m,cuaDriverSkillSource:h,markerPath:s,missing:f}}function nc(e){const t=Xr("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH);if(!t.available||!t.path)return"cua-driver command is not available. Install Cua Driver CLI or set AGENTRIX_CUA_DRIVER_PATH.";const n=Vr();if(!n.available||!n.path)return"Codex CLI is not available. Install Codex or set AGENTRIX_CODEX_PATH to the codex executable.";d(e,{recursive:!0});const s=It(t.path,["mcp-config","--client","codex"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e,AGENTRIX_CODEX_HOME:e}});if(0!==s.status){const e=[s.stderr,s.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return"Failed to run `cua-driver mcp-config --client codex`"+(e?`:\n${e}`:".")}const a=It(n.path,["mcp","add","cua-driver","--",t.path,"mcp"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e}});if(0===a.status)return null;const i=[a.stderr,a.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return`Failed to run \`codex mcp add cua-driver -- ${t.path} mcp\`${i?`:\n${i}`:"."}`}function sc(e){const t=ec(),n=E(e,"skills","cua-driver");if(!t)return["Cua Driver skill source was not found.","Install or update Cua Driver so its installer auto-wires agent skills, or set AGENTRIX_CUA_DRIVER_SKILL_SOURCE to a directory containing SKILL.md."].join(" ");if(r(n)){if(r(E(n,"SKILL.md")))return null;try{return v(n).isSymbolicLink()?`Existing Cua Driver skill symlink at ${n} does not resolve to a valid skill.`:`Existing path ${n} is not a valid Cua Driver skill directory.`}catch(e){return`Failed to inspect existing Cua Driver skill path ${n}: ${e instanceof Error?e.message:String(e)}`}}try{return d(D(n),{recursive:!0}),w(t,n,"dir"),null}catch(e){return`Failed to create Cua Driver skill symlink ${n} -> ${t}: ${e instanceof Error?e.message:String(e)}`}}function ac(e){try{return(r(e)||v(e).isSymbolicLink())&&h(e,{recursive:!0,force:!0}),null}catch(t){return"ENOENT"===t.code?null:`Failed to remove ${e}: ${t instanceof Error?t.message:String(t)}`}}function ic(e){try{return v(e).isSymbolicLink()?(f(e),null):null}catch(t){return"ENOENT"===t.code?null:`Failed to remove symlink ${e}: ${t instanceof Error?t.message:String(t)}`}}function oc(e){try{if(!v(e).isSymbolicLink())return null;const t=b(e);return t.includes("CuaDriver.app")||t.includes("cua-driver")?(f(e),null):null}catch(t){return"ENOENT"===t.code?null:`Failed to remove Cua Driver skill symlink ${e}: ${t instanceof Error?t.message:String(t)}`}}function rc(){const e=tc(),t=[],s=[],a=function(e){try{return r(e)&&f(e),null}catch(t){return`Failed to remove Agentrix Computer Use marker at ${e}: ${t instanceof Error?t.message:String(t)}`}}(e.markerPath);a?s.push(a):"marker"===e.enabledBy?t.push("Removed Agentrix Computer Use enablement marker."):t.push("Agentrix Computer Use enablement marker is already absent or not the active source.");const i=function(){try{const e=$e.readSettings()??{};return $e.writeSettings({...e,agentrixComputerUse:{...e.agentrixComputerUse??{},enabled:!1}}),null}catch(e){return`Failed to disable Agentrix Computer Use in settings: ${e instanceof Error?e.message:String(e)}`}}();i?s.push(i):t.push("Disabled Agentrix Computer Use in settings.");const o=function(e){const t=[],s=[],a=e.cuaDriverPath;a&&(It(a,["stop"],{encoding:"utf8",timeout:1e4}),t.push("Stopped Cua Driver daemon if it was running."));const i=["/Applications/CuaDriver.app","/Applications/CuaDriverRs.app",E(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_updater.plist"),E(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_daemon.plist"),E(n.homedir(),"Library","LaunchAgents","com.trycua.cua-driver-rs.plist"),E(n.homedir(),"Library","Application Support","Cua Driver"),E(n.homedir(),"Library","Caches","cua-driver"),E(n.homedir(),".cua-driver-rs")];for(const e of i){const n=ac(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const e of[E(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver"]){const n=ic(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const a of[E(e.codexHome,"skills","cua-driver"),E(n.homedir(),".agents","skills","cua-driver")]){const e=oc(a);e?s.push(e):t.push(`Removed ${a}.`)}const o=function(e){const t=E(e,"config.toml");try{const n=Vr();if(n.available&&n.path&&It(n.path,["mcp","remove","cua-driver"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e}}),!r(t))return null;const s=c(t,"utf8"),a=s.replace(/\n?\[mcp_servers\.(?:"cua-driver"|'cua-driver'|cua-driver|cua_driver)\][\s\S]*?(?=\n\[[^\]]+\]|\s*$)/g,"").replace(/\n{3,}/g,"\n\n").trimEnd()+"\n";return a!==s&&u(t,a,"utf8"),null}catch(e){return`Failed to remove Cua Driver MCP config from ${t}: ${e instanceof Error?e.message:String(e)}`}}(e.codexHome);return o?s.push(o):t.push("Removed Cua Driver MCP config from Codex when present."),{actions:t,errors:s}}(e);t.push(...o.actions),s.push(...o.errors);const l=tc();"env"===l.enabledBy&&s.push("Agentrix Computer Use is still enabled by AGENTRIX_COMPUTER_USE_ENABLED. Remove that environment variable and restart the daemon to complete uninstall.");const d=0===s.length&&!l.enabled;return{success:d,status:l,actions:t,error:d?void 0:s.join("\n")||"Agentrix Computer Use is still enabled."}}function cc(e=$e.readSettings()){const t=tc(e);if(!t.enabled)return t;const n=[];if(!t.cuaDriverMcpConfigured){zr.info("computer_use.configure_mcp");const e=nc(t.codexHome);e&&n.push(e)}if(!t.cuaDriverSkillPresent){zr.info("computer_use.configure_skill");const e=sc(t.codexHome);e&&n.push(e)}const s=tc(e);return 0===n.length?s:{...s,missing:[...s.missing,...n.map(e=>`Automatic Cua Driver configuration failed: ${e}`)]}}function lc(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(/\/+$/,"")}function dc(e,t){if(void 0===e||""===e.trim())return t;const n=e.trim().toLowerCase();if(["true","1","yes"].includes(n))return!0;if(["false","0","no"].includes(n))return!1;throw new Error(`Invalid boolean value: ${e}`)}async function pc(e,t,n){const s=await Ut(n.apiUrl,n.pat,{log:{warn:(e,t)=>Pe.warn(e,t),error:(e,t)=>Pe.warn(e,t)}});if(!s.result.valid||!s.user)throw new Error(function(e,t){if(e.valid)return"";switch(e.status){case"insufficient_scope":{const t=e.missingScopes?.filter(Boolean).join(", ");return t?`GitLab PAT is missing required scopes: ${t}. Update or recreate the PAT with these scopes, then run the command again.`:"GitLab PAT is missing required scopes. Update or recreate the PAT with the required GitLab scopes, then run the command again."}case"expired":return"GitLab rejected this PAT because it is expired, revoked, or no longer accepted. Create a new GitLab PAT and run the command again.";case"network_error":return`Cannot reach the GitLab API at ${t}. Check the GitLab URL, network, VPN, or intranet access, then run the command again.`;case"invalid":return"Token is empty"===e.error?"GitLab PAT is required. Provide a token with --pat-file, stdin, or the interactive prompt.":"GitLab rejected this PAT. Check that you copied the full token, or create a new GitLab PAT and run the command again.";default:return e.error||`GitLab PAT validation failed for ${t}/user`}}(s.result,n.apiUrl));const a=await zo();if(!a)throw new Error("No Agentrix auth secret found for GitLab configuration");const i=await async function(e,t,n,s,a=15e3){if(!e.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:V(),method:t,path:n,body:s},o=await function(e,t,n){let s;const a=new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)});return Promise.race([e,a]).finally(()=>{s&&clearTimeout(s)})}(e.sendWithAck("machine-rpc-call",i),a,`Timed out waiting for machine RPC ${t} ${n}`);if(!o.success)throw new Error(o.error?.message||`Machine RPC failed: ${t} ${n}`);return o.data}(e,"POST","/v1/git-servers/machine-bind",{name:n.name,baseUrl:n.baseUrl,apiUrl:n.apiUrl,machineId:t.machineId,pat:n.pat,useAsProxy:n.useAsProxy});if(!i.success||!i.gitServer)throw new Error("Backend Git server bind failed");const o=i.gitServer,r={username:s.user.username,email:s.user.email||"",lastValidatedAt:(new Date).toISOString(),expiresAt:s.result.expiresAt};var c,l;!function(e,t){Wo.saveGitServerConfig(e,t)}(o.id,{baseUrl:o.baseUrl,apiUrl:o.apiUrl}),function(e,t,n){Wo.savePat(e,t,n)}(o.id,n.pat,a),c=o.id,l=r,Wo.savePatMeta(c,l);const d=function(e,t){return Wo.ensureGitLabWebhookSecret(e,t)}(o.id,a);return{success:!0,gitServer:o,machineId:i.machineId,proxyRegistered:i.proxyRegistered,webhookEndpointPath:Lt(o.id),webhookUrl:jt(o.id,await $e.readDaemonState()),patConfigured:!0,patMeta:r,webhookSecret:d}}async function uc(e,t){try{return await async function(e,t){const n=function(e=process.env){if(!dc(e.AGENTRIX_GITLAB_AUTO_CONFIG,!0))return null;const t=e.GITLAB_BASE_URL?.trim(),n=function(e){const t=e.GITLAB_TOKEN?.trim();if(t)return t;const n=e.GITLAB_TOKEN_FILE?.trim();if(!n)return null;if(!r(n))throw new Error(`GITLAB_TOKEN_FILE is not readable: ${n}`);return c(n,"utf8").trim()}(e);if(!t&&!n)return null;if(!t)throw new Error("GITLAB_BASE_URL is required when GITLAB_TOKEN is configured");if(!n)throw new Error("GITLAB_TOKEN or GITLAB_TOKEN_FILE is required when GITLAB_BASE_URL is configured");const s=lc(t,"GITLAB_BASE_URL"),a=lc(e.GITLAB_API_URL?.trim()||`${s}/api/v4`,"GITLAB_API_URL");return{name:e.AGENTRIX_GITLAB_NAME?.trim()||new URL(s).hostname,baseUrl:s,apiUrl:a,pat:n,useAsProxy:dc(e.AGENTRIX_GITLAB_USE_AS_PROXY,!0)}}();if(!n)return null;const s=await pc(e,t,n),a=s.gitServer,i={gitServerId:a.id,baseUrl:a.baseUrl,apiUrl:a.apiUrl,webhookEndpointPath:s.webhookEndpointPath,webhookUrl:s.webhookUrl,proxyRegistered:s.proxyRegistered};return Pe.info(`[GIT SERVER] auto-configured from environment: gitServer=${i.gitServerId}, proxyRegistered=${i.proxyRegistered}`),i}(e,t)}catch(e){return Pe.warn("[GIT SERVER] environment auto-config failed; daemon startup will continue",e),null}}function mc(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=E(e,a.name),i=p(s),o=N(t,s);n.push({name:a.name,path:o,size:i.size,modifiedAt:i.mtimeMs,isDirectory:a.isDirectory()}),a.isDirectory()&&n.push(...mc(s,t))}return n}function hc(){return E($e.agentrixAgentsHomeDir,"companion","claude")}function gc(e,t){const n=U(E(e,t));return n.startsWith(e)?{absolutePath:n,relativePath:N(e,n)}:null}function fc(e,t,n){const s=E(e,"memory-changes"),a=E(s,`${t.key}.jsonl`),i=`${t.key}T00:00:00.000Z`,o=r(a)?c(a,"utf-8").split("\n").map((e,n)=>{const s=e.trim();if(!s)return null;try{return function(e,t,n){const s=Array.isArray(e?.changes)?e.changes:[e],a=s.map(e=>e?.summary).filter(Boolean),i=s.flatMap(e=>Array.isArray(e?.reasons)?e.reasons:[]).filter(Boolean),o=s.map(e=>e?.file).filter(Boolean),r=s.map(e=>e?.action).filter(Boolean);return{id:n,createdAt:e?.time||e?.timestamp||e?.createdAt||t,title:e?.title||a[0]||"记忆已更新",summary:i.length?i.join("\n"):"",files:o,actions:r,source:e?.source,trigger:e?.trigger,commit:e?.commit}}(JSON.parse(s),i,`${t.key}-${n}`)}catch{return null}}).filter(Boolean):[],l=r(s)&&g(s).some(e=>/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(e)&&e.slice(0,10)<t.key);return{...n,nextAfter:t.nextAfter,events:o.sort((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime()),hasMore:l}}function yc(e,t){if(t.date){const n=function(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;const t=new Date(`${e}T00:00:00.000Z`);return Number.isNaN(t.getTime())?null:{key:e,nextAfter:t.toISOString()}}(t.date);return n?fc(e,n,{date:t.date}):null}if(t.after){const n=function(e){const t=function(e){const t=new Date(e);return Number.isNaN(t.getTime())?null:t}(e);if(!t)return null;const n=new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()));n.setUTCDate(n.getUTCDate()-1);const s=n.toISOString();return{key:n.toISOString().slice(0,10),nextAfter:s}}(t.after);return n?fc(e,n,{after:t.after}):null}return null}function vc(e,t){if(!r(E(e,".git")))return"";try{return At("git",["-C",e,...t],{encoding:"utf8",timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return""}}function wc(e,t,n){const s=n.replace(/[^0-9a-f]/gi,"");return s?vc(e,["show","--format=","--no-ext-diff",s,"--",t]):""}function bc(e){if(!e||"object"!=typeof e)return"";const t=e,n=(Array.isArray(t.changes)?t.changes:[]).map(e=>e&&"object"==typeof e?e.summary:null).filter(e=>"string"==typeof e&&e.trim().length>0);if(n.length)return n.join(";");const s=t.input;if(s&&"object"==typeof s){const e=bc(s);if(e)return e}for(const e of["result","summary","title","content","text","message"]){const n=t[e];if("string"==typeof n&&n.trim())return n;if(n&&"object"==typeof n){const e=bc(n);if(e)return e}}return""}function kc(e){if("string"==typeof e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{const e=bc(JSON.parse(t));if(e)return e}catch{}return e}if(!e||"object"!=typeof e)return"";const t=bc(e);if(t)return t;const n=e.content;return"string"==typeof n?kc(n):Array.isArray(n)?n.map(e=>kc(e)).filter(Boolean).join("\n"):""}function xc(e,t){return kc(e).trim()||t}function Ic(e){return!/(no\s+(memory\s+)?changes?\s+(needed|required|found|detected)|no\s+updates?\s+(needed|required|found|detected)|无需.*(更新|变更|修改|创建|新增|删除)|不需要.*(更新|变更|修改|创建|新增|删除)|没有.*(更新|变更|修改|创建|新增|删除)|无.*(更新|变更|修改|创建|新增|删除)|未.*(发现|检测到).*(更新|变更|修改|创建|新增|删除))/i.test(e)&&/更新|updated|created|deleted|修改|创建|新增|删除|memory change|memory changes/i.test(e)}function Sc(e){return!!e&&"object"==typeof e&&"companion_memory_organization"===e.type}function Tc(e){if(!e)return!1;if(Array.isArray(e))return e.some(Tc);if("object"!=typeof e)return!1;const t=e;return"tool_use"===t.type&&("mcp__agentrix__record_memory_change"===t.name||"record_memory_change"===t.name)||Object.values(t).some(Tc)}function Cc(e){if(!e||"object"!=typeof e)return"";const t=e;return"result"===t.type&&"string"==typeof t.result?t.result:""}function Ac(e,t,n=1){if(!e||!t)return[];try{const s=jo({dataDir:$e.resolveDataDir(e,t),taskId:t});try{return[...s.pageRecentMessages(50).data].reverse().filter(e=>"system"!==e.senderType&&kc(e.message).trim()).slice(0,n).map(e=>({summary:xc(kc(e.message),""),time:e.createdAt}))}finally{s.close()}}catch{return[]}}function _c(e,t=1){return Ac("string"==typeof e.userId?e.userId:null,"string"==typeof e.chatTaskId?e.chatTaskId:null,t).map(e=>({type:"chat",title:"Companion Chat",summary:e.summary,time:e.time}))}async function Ec(e,t,n=1){const s="string"==typeof e.chatId?e.chatId:null;if(!s)return[];try{const a=new URLSearchParams({chatId:s,limit:String(Math.min(Math.max(3*n,10),50))}),i=await jc(t,"GET",`/v1/tasks/recent?${a.toString()}`,void 0,1e4);return Array.isArray(i.tasks)?i.tasks.filter(e=>!["completed","cancelled","error"].includes(String(e.state))).slice(0,n).map(t=>{const n="string"==typeof t.taskId?t.taskId:"",s="string"==typeof t.title&&t.title.trim()?t.title.trim():"Task",a=Ac("string"==typeof e.userId?e.userId:null,n,1)[0];return{type:"task",title:s,summary:a?.summary||"",time:a?.time||t.updatedAt||t.createdAt||(new Date).toISOString()}}):[]}catch{return[]}}function $c(e,t=1){const n=E(e,"memory-changes");if(!r(n))return[];const s=g(n).filter(e=>/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(e)).sort().reverse(),a=[];for(const n of s){const s=n.slice(0,10),i=fc(e,{key:s,nextAfter:`${s}T00:00:00.000Z`},{date:s});for(const e of i.events){const n=xc(e.summary||e.files.join(", ")||e.title,"记忆已更新");if(a.push({type:"memory",title:e.title||"记忆已更新",summary:n,time:String(e.createdAt)}),a.length>=t)return a}}return a}function Mc(e,t){const n=[],s=jo({dataDir:$e.resolveDataDir(e,t),taskId:t});try{let e=!1,t=!1;for(const a of s.pageRecentTaskEvents(1e3).data){const s=a.eventData,i=s.message;if(Sc(i)){e=!0,t=!1;continue}if(!e)continue;Tc(i)&&(t=!0);const o="agent"===s.senderType?Cc(i):"";o&&(n.push({time:a.createdAt,summary:xc(o,"记忆整理已运行"),updated:t}),e=!1,t=!1)}}finally{s.close()}return n}function Rc(e,t,n=1){const s="string"==typeof e.userId?e.userId:null,a="string"==typeof e.chatTaskId?e.chatTaskId:null;if(!s||!a)return[];const i=("heartbeat"===t?[e.heartbeatTaskId,e.heartbeatShadowTaskId]:[e.memoryOrganizationTaskId,e.memoryOrganizationShadowTaskId]).filter(e=>"string"==typeof e&&e.length>0),o=[a,...i],r="heartbeat"===t?["heartbeat","心跳","reminder","待处理事项"]:["memory organization","memory-organization","记忆整理","companion_memory_organization","memory review","memory changes","记忆更新"],c=[];if("memory-organization"===t){for(const e of[...new Set(i)])try{c.push(...Mc(s,e))}catch{}if(c.length>0)return Pc(c,n)}for(const e of[...new Set(o)]){const n=i.includes(e);try{const a=jo({dataDir:$e.resolveDataDir(s,e),taskId:e});try{for(const e of a.pageRecentMessages(160).data){if("agent"!==e.senderType)continue;const s=kc(e.message);if(!s.trim())continue;if(!n&&!r.some(e=>s.toLowerCase().includes(e.toLowerCase())))continue;const a=xc(s,"heartbeat"===t?"Heartbeat 已运行":"记忆整理已运行");c.push({time:e.createdAt,summary:a,updated:Ic(s)})}}finally{a.close()}}catch{}}return Pc(c,n)}function Pc(e,t=1){const n=new Set;return e.sort((e,t)=>new Date(t.time).getTime()-new Date(e.time).getTime()).filter(e=>{const t=`${e.time}:${e.summary}`;return!n.has(t)&&(n.add(t),!0)}).slice(0,t)}function Dc(e){return"127.0.0.1"===e||"::1"===e||"::ffff:127.0.0.1"===e}const Nc=wt.object({id:wt.string(),type:wt.string(),name:wt.string(),baseUrl:wt.string(),apiUrl:wt.string(),oauthServerId:wt.string().nullable().optional(),ownerId:wt.string().nullable().optional(),authModeDefault:wt.string().optional(),executionMode:wt.string().optional(),syncMode:wt.string().optional(),networkMode:wt.string().optional(),githubAppName:wt.string().nullable().optional(),enabled:wt.boolean().optional(),createdAt:wt.string().optional(),updatedAt:wt.string().optional()}).passthrough(),Oc=wt.object({platform:wt.string(),enabled:wt.boolean(),enabledBy:wt.enum(["env","settings","marker"]).nullable(),codexHome:wt.string(),codexAvailable:wt.boolean(),codexPath:wt.string().optional(),codexConfigPresent:wt.boolean(),cuaDriverAvailable:wt.boolean(),cuaDriverPath:wt.string().optional(),cuaDriverAccessibilityGranted:wt.boolean().optional(),cuaDriverScreenRecordingGranted:wt.boolean().optional(),cuaDriverMcpConfigured:wt.boolean(),cuaDriverSkillPresent:wt.boolean(),cuaDriverSkillSource:wt.string().optional(),markerPath:wt.string(),missing:wt.array(wt.string())});function Uc(e){return e instanceof Error?e.message:"Unknown error"}async function jc(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:V(),method:t,path:n,body:s},o=await async function(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)}}(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 Lc(e){const{getChildren:t,stopSession:n,startDevOpsInit:s,completeDevOpsInit:a,requestShutdown:i,registerSession:o,credentials:l,getSocketClient:m,prepareGracefulRestart:h,clearGracefulRestartGate:g}=e;return new Promise(f=>{const y=$e.getDaemonControlHost(),v=$e.getDaemonWebhookHost(),w=vt({logger:!1});w.removeContentTypeParser("application/json"),w.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,{})}),w.setValidatorCompiler(kt),w.setSerializerCompiler(xt);const b=w.withTypeProvider();!function(e,t){const n=t.getSocketClient??(()=>{}),s={credentials:t.credentials,getSocketClient:n,dispatcher:t.dispatcher??Hr(t.credentials,n)};e.post(Ur,async(e,t)=>{try{await Fr(e,t,s)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return Pe.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(Ur,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(Ur,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(w,{credentials:l,getSocketClient:m});const I=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")};b.post("/session-started",{schema:{body:wt.object({sessionId:wt.string(),metadata:wt.any()}),response:{200:wt.object({status:wt.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return Pe.debug(`[CONTROL SERVER] Session started: ${t}`),o(t,n),{status:"ok"}}),b.post("/devops-init-complete",{schema:{body:wt.object({taskId:wt.string(),userId:wt.string(),action:wt.enum(["continue","stop"])}),response:{200:wt.object({status:wt.literal("ok")})}}},async e=>{const{taskId:t,userId:n,action:s}=e.body;return Pe.info(`[CONTROL SERVER] Agentrix DevOps init complete for task ${t}, action=${s}`),a?.({taskId:t,userId:n,action:s}),{status:"ok"}}),b.post("/devops-init-start",{schema:{body:wt.object({taskId:wt.string(),userId:wt.string()}),response:{200:wt.object({status:wt.literal("ok")})}}},async e=>{const{taskId:t,userId:n}=e.body;return Pe.info(`[CONTROL SERVER] Starting Agentrix DevOps init for existing task ${t}`),s?.({taskId:t,userId:n}),{status:"ok"}}),b.post("/prepare-graceful-restart",{schema:{body:wt.object({source:wt.string().optional(),reason:wt.string().optional()}).optional(),response:{200:wt.object({state:wt.enum(["pending_restart","restarting"]),activeSessions:wt.number()}),503:wt.object({error:wt.string()}),403:wt.object({error:wt.string()})}}},async(e,t)=>Dc(e.ip)?h?h({source:e.body?.source??"control-server",reason:e.body?.reason}):t.code(503).send({error:"Graceful restart gate is not available"}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),b.post("/clear-graceful-restart-gate",{schema:{response:{200:wt.object({success:wt.literal(!0)}),403:wt.object({error:wt.string()})}}},async(e,t)=>Dc(e.ip)?(g?.(),{success:!0}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),b.options("/ping",async(e,t)=>(I(t),t.send())),b.get("/ping",{schema:{response:{200:wt.object({status:wt.literal("ok"),machineId:wt.string(),timestamp:wt.string(),controlHost:wt.string(),webhookHost:wt.string(),hasMachineAesKey:wt.boolean()})}}},async(e,t)=>(I(t),{status:"ok",machineId:l.machineId,timestamp:(new Date).toISOString(),controlHost:y,webhookHost:v,hasMachineAesKey:Wr(l)})),b.get("/computer-use/status",{schema:{response:{200:wt.object({status:Oc}),403:wt.object({error:wt.string()})}}},async(e,t)=>Dc(e.ip)?{status:tc()}:t.code(403).send({error:"Computer Use status is only allowed from loopback"})),b.post("/computer-use/install",{schema:{response:{200:wt.object({success:wt.boolean(),status:Oc,actions:wt.array(wt.string()),error:wt.string().optional()}),403:wt.object({error:wt.string()})}}},async(e,t)=>{if(!Dc(e.ip))return t.code(403).send({error:"Computer Use installation is only allowed from loopback"});try{return function(){let e=tc();const t=[],n=[];if("darwin"!==process.platform)return{success:!1,status:e,actions:t,error:"Agentrix Computer Use currently requires macOS because Cua Driver is macOS-only."};if(!e.cuaDriverAvailable)return{success:!1,status:e,actions:t,error:"Cua Driver is not installed or not available. Install Cua Driver from Desktop first, or set AGENTRIX_CUA_DRIVER_PATH."};if(e.cuaDriverAvailable&&t.push(`Detected Cua Driver at ${e.cuaDriverPath??"PATH"}`),e.cuaDriverPath){const s=function(e){const t=It(e,["call","check_permissions",'{"prompt":true}',"--raw","--compact"],{encoding:"utf8",timeout:3e4});if(0===t.status)return null;const n=[t.stderr,t.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return"Failed to open Cua Driver permission prompt"+(n?`:\n${n}`:".")}(e.cuaDriverPath);s?n.push(s):t.push("Checked Cua Driver permissions and opened macOS permission prompts for any missing grants.")}if(e.cuaDriverMcpConfigured)t.push("Cua Driver MCP is already configured for Agentrix Computer Use.");else{const s=nc(e.codexHome);s?n.push(s):t.push("Configured Cua Driver MCP for Agentrix Computer Use.")}if(e=tc(),e.cuaDriverSkillPresent)t.push("Cua Driver skill is already available to Agentrix Computer Use.");else{const s=sc(e.codexHome);s?n.push(s):t.push("Linked Cua Driver skill for Agentrix Computer Use.")}const s=function(e){try{return d(D(e),{recursive:!0}),u(e,`${(new Date).toISOString()}\n`,"utf8"),null}catch(t){return`Failed to enable Agentrix Computer Use at ${e}: ${t instanceof Error?t.message:String(t)}`}}(e.markerPath);s?n.push(s):e.enabled?t.push("Agentrix Computer Use was already enabled."):t.push("Enabled Agentrix Computer Use.");const a=function(){try{const e=$e.readSettings()??{};return $e.writeSettings({...e,agentrixComputerUse:{...e.agentrixComputerUse??{},enabled:!0}}),null}catch(e){return`Failed to enable Agentrix Computer Use in settings: ${e instanceof Error?e.message:String(e)}`}}();a&&n.push(a);const i=tc(),o=0===n.length&&i.enabled&&0===i.missing.length;return{success:o,status:0===n.length?i:{...i,missing:[...i.missing,...n.map(e=>`Agentrix Computer Use install failed: ${e}`)]},actions:t,error:o?void 0:[...n,...i.missing].join("\n")||"Agentrix Computer Use is not ready."}}()}catch(e){return{success:!1,status:tc(),actions:[],error:Uc(e)}}}),b.post("/computer-use/uninstall",{schema:{response:{200:wt.object({success:wt.boolean(),status:Oc,actions:wt.array(wt.string()),error:wt.string().optional()}),403:wt.object({error:wt.string()})}}},async(e,t)=>{if(!Dc(e.ip))return t.code(403).send({error:"Computer Use uninstall is only allowed from loopback"});try{return rc()}catch(e){return{success:!1,status:tc(),actions:[],error:Uc(e)}}}),b.post("/machine/aes-key",{schema:{body:wt.object({machineId:wt.string(),machineAesKey:wt.string()}),response:{200:wt.object({success:wt.literal(!0),updated:wt.boolean(),hasMachineAesKey:wt.literal(!0)}),400:wt.object({error:wt.string()}),403:wt.object({error:wt.string()}),409:wt.object({error:wt.string()}),500:wt.object({error:wt.string()})}}},async(e,t)=>{if(!Dc(e.ip))return t.code(403).send({error:"machine AES key recovery is only allowed from loopback"});try{const t=await async function(e,t,n=$e){if(t.machineId!==e.machineId)throw new Br("machineId does not match daemon credentials",409);if(!Gr(t.machineAesKey))throw new Br("machineAesKey must decode to a 32-byte key",400);const s=await n.readCredentials()??e;if(s.machineId!==e.machineId)throw new Br("stored credentials machineId does not match daemon credentials",409);if(Wr(s))return e.machineAesKey=s.machineAesKey,{success:!0,updated:!1,hasMachineAesKey:!0};const a={...s,machineAesKey:t.machineAesKey};return await n.writeCredentials(a),e.machineAesKey=t.machineAesKey,{success:!0,updated:!0,hasMachineAesKey:!0}}(l,e.body);return Pe.info(t.updated?`[CONTROL SERVER] Recovered machine AES key stored for ${l.machineId}`:`[CONTROL SERVER] Machine AES key already present for ${l.machineId}`),t}catch(e){const n=e instanceof Br?e.statusCode:500,s=400===n||409===n?n:500,a=e instanceof Error?e.message:"Failed to store machine AES key";return Pe.warn(`[CONTROL SERVER] Failed to store recovered machine AES key: ${a}`),t.code(s).send({error:a})}}),b.options("/openers",async(e,t)=>(I(t),t.send())),b.get("/openers",{schema:{response:{200:wt.object({openers:wt.array(wt.object({id:wt.string(),label:wt.string(),kind:wt.enum(["system","file-manager","terminal","editor","ide"]),method:wt.enum(["scheme","cli"]),urlTemplate:wt.string().optional(),supported:wt.boolean()}))})}}},async(e,t)=>(I(t),{openers:await va()})),b.options("/open",async(e,t)=>(I(t),t.send())),b.options("/pick-directory",async(e,t)=>(I(t),t.send())),b.options("/validate-directory",async(e,t)=>(I(t),t.send())),b.post("/open",{schema:{body:wt.object({path:wt.string(),openerId:wt.string(),userId:wt.string().optional(),taskId:wt.string().optional()}),response:{200:wt.object({success:wt.boolean(),error:wt.string().optional()})}}},async(e,t)=>{I(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=ba(Sa()).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=_.resolve(e);if(!_.isAbsolute(s))throw new Error("Path must be absolute");if(!p(s).isDirectory())throw new Error("Path must be a directory");if(t&&n){const e=$e.getTaskCwd(t,n);if(e&&!function(e,t){const n=_.relative(t,e);return""===n||!n.startsWith("..")&&!_.isAbsolute(n)}(s,_.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 Pe.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),b.post("/pick-directory",{schema:{body:wt.object({defaultPath:wt.string().optional()}),response:{200:wt.object({path:wt.string().nullable(),error:wt.string().optional()})}}},async(e,t)=>{I(t);try{return{path:wa(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),b.post("/validate-directory",{schema:{body:wt.object({path:wt.string()}),response:{200:wt.object({ok:wt.boolean(),status:wt.enum(["active","missing","permission_lost"]),error:wt.string().optional()})}}},async(e,t)=>{I(t);try{if(!p(e.body.path).isDirectory())return{ok:!1,status:"missing",error:"Path is not a directory"};try{k(e.body.path,x.R_OK|x.W_OK)}catch{return{ok:!1,status:"permission_lost",error:"Directory is not readable and writable"}}return{ok:!0,status:"active"}}catch(e){return{ok:!1,status:"missing",error:e instanceof Error?e.message:"Directory is unavailable"}}}),b.post("/companion/ensure",{schema:{body:wt.object({preferredLanguage:wt.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:wt.object({agentDir:wt.string()})}}},async e=>await Oo({preferredLanguage:e.body?.preferredLanguage,credentials:l})),b.post("/companion/probe",{schema:{response:{200:wt.object({success:wt.boolean(),error:wt.string().optional()})}}},async()=>await Fi()),b.get("/companion/workspace/status",{schema:{response:{200:wt.object({exists:wt.boolean()})}}},async()=>{const e=hc();return{exists:r(e)}}),b.get("/companion/workspace",{schema:{response:{200:wt.object({files:wt.array(wt.object({name:wt.string(),path:wt.string(),size:wt.number(),modifiedAt:wt.number(),isDirectory:wt.boolean()}))})}}},async()=>{const e=hc();return r(e)?{files:mc(e,e)}:{files:[]}}),b.get("/companion/file",{schema:{querystring:wt.object({path:wt.string()}),response:{200:wt.object({content:wt.string()}),404:wt.object({error:wt.string()})}}},async(e,t)=>{const n=hc(),s=U(E(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),b.put("/companion/file",{schema:{body:wt.object({path:wt.string(),content:wt.string()}),response:{200:wt.object({success:wt.boolean()}),400:wt.object({error:wt.string()})}}},async(e,t)=>{const n=hc(),s=U(E(n,e.body.path));return s.startsWith(n)?(d(D(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),b.get("/companion/file/versions",{schema:{querystring:wt.object({path:wt.string(),limit:wt.coerce.number().int().positive().max(50).optional(),skip:wt.coerce.number().int().min(0).optional()}),response:{200:wt.object({versions:wt.array(wt.object({commit:wt.string(),shortCommit:wt.string(),subject:wt.string(),body:wt.string(),authoredAt:wt.string()})),hasMore:wt.boolean(),nextSkip:wt.number()}),404:wt.object({error:wt.string()})}}},async(e,t)=>{const n=hc(),s=gc(n,e.query.path);return s&&r(s.absolutePath)?function(e,t,n={}){const s=Math.min(Math.max(n.limit??10,1),50),a=Math.max(n.skip??0,0),i=vc(e,["log",`--max-count=${s+1}`,`--skip=${a}`,"--date=iso-strict","--pretty=format:%H%x1f%h%x1f%aI%x1f%s%x1f%b%x1e","--",t]).split("").map(e=>e.trim()).filter(Boolean).map(e=>{const[t,n,s,a,i]=e.split("");return{commit:t||"",shortCommit:n||"",authoredAt:s||"",subject:a||"没有详细变更说明",body:i?.trim()||""}}).filter(e=>e.commit.length>0);return{versions:i.slice(0,s),hasMore:i.length>s,nextSkip:a+Math.min(i.length,s)}}(n,s.relativePath,{limit:e.query.limit??10,skip:e.query.skip??0}):t.code(404).send({error:"File not found"})}),b.get("/companion/file/diff",{schema:{querystring:wt.object({path:wt.string(),commit:wt.string()}),response:{200:wt.object({commit:wt.string(),path:wt.string(),diff:wt.string()}),404:wt.object({error:wt.string()})}}},async(e,t)=>{const n=hc(),s=gc(n,e.query.path);return s&&r(s.absolutePath)?{commit:e.query.commit,path:s.relativePath,diff:wc(n,s.relativePath,e.query.commit)}:t.code(404).send({error:"File not found"})}),b.get("/companion/memory-events",{schema:{querystring:wt.object({after:wt.string().optional(),date:wt.string().optional()}),response:{200:wt.object({after:wt.string().optional(),date:wt.string().optional(),nextAfter:wt.string(),events:wt.array(wt.object({id:wt.string(),createdAt:wt.union([wt.string(),wt.number()]),title:wt.string(),summary:wt.string(),files:wt.array(wt.string()),actions:wt.array(wt.string()).optional(),source:wt.string().optional(),trigger:wt.string().optional(),commit:wt.string().optional()})),hasMore:wt.boolean()}),400:wt.object({error:wt.string()})}}},async(e,t)=>{const n=hc();if(!e.query.after&&!e.query.date)return t.code(400).send({error:"Use after or date"});return yc(n,e.query)||t.code(400).send({error:"Invalid after or date"})}),b.get("/companion/recent-activity",{schema:{querystring:wt.object({limit:wt.coerce.number().int().positive().max(50).optional()}),response:{200:wt.object({chats:wt.array(wt.object({type:wt.literal("chat"),title:wt.string(),summary:wt.string(),time:wt.string(),status:wt.string().optional()})),tasks:wt.array(wt.object({type:wt.literal("task"),title:wt.string(),summary:wt.string(),time:wt.string(),status:wt.string().optional()})),memories:wt.array(wt.object({type:wt.literal("memory"),title:wt.string(),summary:wt.string(),time:wt.string(),status:wt.string().optional()}))})}}},async e=>{const t=hc(),n=e.query.limit??1,s=E(t,"state.json");let a={};if(r(s))try{a=JSON.parse(c(s,"utf-8"))}catch{a={}}const[i,o,l]=await Promise.all([Ec(a,m?.(),n),Promise.resolve(_c(a,n)),Promise.resolve($c(t,n))]);return{chats:o,tasks:i,memories:l}}),b.get("/companion/config",{schema:{querystring:wt.object({recentLimit:wt.coerce.number().int().positive().max(50).optional()}),response:{200:wt.object({heartbeatIntervalMs:wt.number(),heartbeatEnabled:wt.boolean(),lastHeartbeatTimestamp:wt.string().nullable(),lastHeartbeatDate:wt.string().nullable(),lastMaintenanceHeartbeatTimestamp:wt.string().nullable(),heartbeatTriggerCount:wt.number(),lastInteractionTimestamp:wt.string().nullable(),memoryOrganizationEnabled:wt.boolean(),memoryOrganizationIntervalHours:wt.number(),allowedMemoryOrganizationIntervalHours:wt.array(wt.number()),lastMemoryOrganizationTimestamp:wt.string().nullable(),memoryOrganizationTaskId:wt.string().nullable(),heartbeatRecentRecords:wt.array(wt.object({time:wt.string(),summary:wt.string(),updated:wt.boolean()})),memoryOrganizationRecentRecords:wt.array(wt.object({time:wt.string(),summary:wt.string(),updated:wt.boolean()}))})}}},async e=>{const t=hc(),n=e.query.recentLimit??1,s=E(t,"state.json");let a=9e5,i=!1,o=null,l=null,d=null,p=0,u=null,m=!1,h=4,g=null,f=null,y={};if(r(s))try{y=JSON.parse(c(s,"utf-8")),"number"==typeof y.heartbeatIntervalMs&&(a=y.heartbeatIntervalMs),"boolean"==typeof y.heartbeatEnabled&&(i=y.heartbeatEnabled),"string"==typeof y.lastHeartbeatTimestamp&&(o=y.lastHeartbeatTimestamp),"string"==typeof y.lastHeartbeatDate&&(l=y.lastHeartbeatDate),"string"==typeof y.lastMaintenanceHeartbeatTimestamp&&(d=y.lastMaintenanceHeartbeatTimestamp),"number"==typeof y.heartbeatTriggerCount&&(p=y.heartbeatTriggerCount),"string"==typeof y.lastInteractionTimestamp&&(u=y.lastInteractionTimestamp),"boolean"==typeof y.memoryOrganizationEnabled&&(m=y.memoryOrganizationEnabled),h=Bo(y.memoryOrganizationIntervalHours),"string"==typeof y.lastMemoryOrganizationTimestamp&&(g=y.lastMemoryOrganizationTimestamp),"string"==typeof y.memoryOrganizationTaskId&&(f=y.memoryOrganizationTaskId)}catch{}const v=Rc(y,"heartbeat",n),w=Rc(y,"memory-organization",n);return{heartbeatIntervalMs:a,heartbeatEnabled:i,lastHeartbeatTimestamp:o,lastHeartbeatDate:l,lastMaintenanceHeartbeatTimestamp:d,heartbeatTriggerCount:p,lastInteractionTimestamp:u,memoryOrganizationEnabled:m,memoryOrganizationIntervalHours:h,allowedMemoryOrganizationIntervalHours:[...Ho],lastMemoryOrganizationTimestamp:g,memoryOrganizationTaskId:f,heartbeatRecentRecords:v,memoryOrganizationRecentRecords:w}}),b.put("/companion/config",{schema:{body:wt.object({heartbeatIntervalMs:wt.number().optional(),heartbeatEnabled:wt.boolean().optional(),memoryOrganizationEnabled:wt.boolean().optional(),memoryOrganizationIntervalHours:wt.number().optional()}),response:{200:wt.object({success:wt.boolean()}),400:wt.object({error:wt.string()})}}},async(t,n)=>{const s=hc(),a=E(s,"state.json");let i={};if(r(a))try{i=JSON.parse(c(a,"utf-8"))}catch{}const{heartbeatIntervalMs:o,heartbeatEnabled:l,memoryOrganizationEnabled:p,memoryOrganizationIntervalHours:m}=t.body;if(void 0!==o&&(i.heartbeatIntervalMs=o),void 0!==l&&(i.heartbeatEnabled=l),void 0!==p&&(i.memoryOrganizationEnabled=p),void 0!==m){if(!Fo(m))return n.code(400).send({error:`memoryOrganizationIntervalHours must be one of: ${Ho.join(", ")}`});i.memoryOrganizationIntervalHours=m}return d(D(a),{recursive:!0}),u(a,JSON.stringify(i,null,2),"utf-8"),e.companionScheduler?.reloadStateAndReschedule(),{success:!0}}),b.post("/agent/install",{schema:{body:wt.object({agentId:wt.string(),gitUrl:wt.string(),branch:wt.string().optional(),subDir:wt.string().optional()}),response:{200:wt.object({agentDir:wt.string()}),500:wt.object({error:wt.string()})}}},async(e,t)=>{try{return await La(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),b.post("/git-server/bind",{schema:{body:wt.object({name:wt.string().min(1),baseUrl:wt.string().url(),apiUrl:wt.string().url(),pat:wt.string().min(1),useAsProxy:wt.boolean().optional().default(!0)}),response:{200:wt.object({success:wt.literal(!0),gitServer:Nc,machineId:wt.string(),proxyRegistered:wt.boolean(),webhookEndpointPath:wt.string(),webhookUrl:wt.string().optional(),patConfigured:wt.literal(!0),patMeta:wt.object({username:wt.string(),email:wt.string(),lastValidatedAt:wt.string(),expiresAt:wt.string().nullable().optional()}),webhookSecret:wt.string()}),502:wt.object({error:wt.string()})}}},async(e,t)=>{try{const n=m?.();if(!n)throw new Error("Machine WebSocket is not connected");const s=await pc(n,l,{name:e.body.name,baseUrl:e.body.baseUrl,apiUrl:e.body.apiUrl,pat:e.body.pat,useAsProxy:e.body.useAsProxy});return t.send(s)}catch(n){const s=Uc(n);return Pe.warn(`[GIT SERVER] bind failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),b.post("/git-server/list",{schema:{response:{200:wt.object({gitServers:wt.array(Nc)}),502:wt.object({error:wt.string()})}}},async(e,t)=>{try{const e=await jc(m?.(),"POST","/v1/git-servers/machine-list",{machineId:l.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=Uc(e);return Pe.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),b.post("/git-server/delete",{schema:{body:wt.object({gitServerId:wt.string().min(1)}),response:{200:wt.object({success:wt.boolean(),machineId:wt.string()}),502:wt.object({error:wt.string()})}}},async(e,t)=>{try{const n=await jc(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=Uc(n);return Pe.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),b.post("/webhooks/gitlab/:gitServerId",{schema:{params:wt.object({gitServerId:wt.string()}),body:wt.record(wt.string(),wt.unknown()),response:{200:wt.object({status:wt.enum(["delivered","ignored","failed"]),deliveryId:wt.string(),providerEventName:wt.string(),events:wt.array(wt.unknown()),deliveries:wt.array(wt.object({target:wt.string(),eventId:wt.string(),status:wt.enum(["delivered","failed","ignored"]),reason:wt.string().optional(),output:wt.unknown().optional(),error:wt.object({message:wt.string(),detail:wt.string().optional(),upstreamStatus:wt.number().optional()}).optional()}))}),400:wt.object({error:wt.string()}),401:wt.object({error:wt.string()}),403:wt.object({error:wt.string()}),404:wt.object({error:wt.string()}),502:wt.object({error:wt.string()}),500:wt.object({error:wt.string()})}}},async(e,t)=>{const n=Ie(),s=Date.now(),a=(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.providerEventName??"-"),a=Array.isArray(t.deliveries)?t.deliveries:[],i=a.filter(e=>e&&"object"==typeof e&&"delivered"===e.status).length,o=a.filter(e=>e&&"object"==typeof e&&"failed"===e.status).length,r=a.filter(e=>e&&"object"==typeof e&&"ignored"===e.status).length,c=a.find(e=>e&&"object"==typeof e),l=c?.error&&"object"==typeof c.error?c.error:void 0,d=String(c?.reason??"-"),p=String(l?.upstreamStatus??"-"),u=String(l?.message??"-"),m=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)}`}(c?.output);return`status=${n}, providerEventName=${s}, deliveries=${a.length}, deliveredCount=${i}, failedCount=${o}, ignoredCount=${r}, reason=${d}, upstreamStatus=${p}, errorMessage=${u}, pipeline=${m}`}(i);return Pe[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};Pe.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body)}, remote=${e.ip||"-"}, userAgent=${"string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-"}`);const i=await zo();if(!i)return a(500,{error:"Git server encryption key not available"});const o=Vo(e.params.gitServerId,i),r=o?.webhookSecret;if(!r)return a(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});try{const t=Ko(e.params.gitServerId);return a(200,await async function({gitServerId:e,payload:t,config:n,pat:s}){const a=n.baseUrl??n.apiUrl,i={headers:{...n.headers??{},...n.deliveryId?{"x-gitlab-webhook-uuid":n.deliveryId}:{}},body:t},o=on(i,n.webhookSecret);if(0===o.events.length)return{status:"ignored",deliveryId:o.deliveryId,providerEventName:o.providerEventName,events:[],deliveries:[]};if(!a)throw{status:400,message:"GitLab base URL or API URL is required"};if(!s)throw{status:403,message:`No PAT configured for git server ${e}`};const r={baseUrl:a,token:s,webhookSecret:n.webhookSecret,...n.apiUrl?{apiUrl:n.apiUrl}:{}},c=n.store??(n.encryptionKey&&n.webhookSecret?function(e){const t=`gitlab:pipeline-trigger:${rn(e.gitlab)}:`,n=`gitlab-webhook:${e.gitServerId}:`;return{async get(s){if(s.startsWith(t)){const n=s.slice(t.length),a=Vo(e.gitServerId,e.encryptionKey);return a?.projectTriggerTokens?.[n]??null}return $r.get(`${n}${s}`)},async set(s,a,i){if(s.startsWith(t)){const n=s.slice(t.length),i=Vo(e.gitServerId,e.encryptionKey)??{webhookSecret:e.webhookSecret,projectTriggerTokens:{}};return void Xo(e.gitServerId,{webhookSecret:i.webhookSecret||e.webhookSecret,projectTriggerTokens:{...i.projectTriggerTokens??{},[n]:a}},e.encryptionKey)}await $r.set(`${n}${s}`,a,i)},async delete(s){if(s.startsWith(t)){const n=s.slice(t.length),a=Vo(e.gitServerId,e.encryptionKey);if(!a?.projectTriggerTokens?.[n])return;const i={...a.projectTriggerTokens};return delete i[n],void Xo(e.gitServerId,{webhookSecret:a.webhookSecret||e.webhookSecret,projectTriggerTokens:i},e.encryptionKey)}await($r.delete?.(`${n}${s}`))}}}({gitServerId:e,gitlab:r,webhookSecret:n.webhookSecret,encryptionKey:n.encryptionKey}):Er),l=function(e){return new cn({gitlab:e.gitlab,store:e.store,targets:[ln({variables:dn([pn(),un({AGENTRIX_GIT_SERVER_ID:e.gitServerId})]),...e.ref?{ref:()=>e.ref}:{},...e.triggerToken?{triggerToken:e.triggerToken}:{},...void 0!==e.createTriggerIfMissing?{createTriggerIfMissing:e.createTriggerIfMissing}:{}})]})}({gitServerId:e,gitlab:r,store:c,ref:n.ref,triggerToken:n.triggerToken,createTriggerIfMissing:n.createTriggerIfMissing});return l.handle(i)}({gitServerId:e.params.gitServerId,payload:e.body,pat:Yo(e.params.gitServerId,i)??void 0,config:{baseUrl:t?.baseUrl,apiUrl:t?.apiUrl,headers:e.headers,webhookSecret:r,encryptionKey:i}}))}catch(t){const s=t,i="number"==typeof s.status?s.status:s.statusCode,o="number"==typeof i&&i>=400&&i<600?i:500,r="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return Pe.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${o}, message=${r}`),a(o,{error:r})}}),b.post("/schedule",{schema:{body:wt.object({task:wt.string(),type:wt.enum(["once","recurring"]),due:wt.string().optional(),cron:wt.string().optional(),timezone:wt.string().optional(),timeType:wt.enum(["utc","local"]).optional()}),response:{200:wt.object({id:wt.string(),task:wt.string(),type:wt.enum(["once","recurring"]),due:wt.string().optional(),cron:wt.string().optional(),timezone:wt.string().optional(),timeType:wt.enum(["utc","local"]).optional(),createdAt:wt.string()}),400:wt.object({error:wt.string()}),503:wt.object({error:wt.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'})}),b.get("/schedule",{schema:{response:{200:wt.object({tasks:wt.array(wt.object({id:wt.string(),task:wt.string(),type:wt.enum(["once","recurring"]),due:wt.string().optional(),cron:wt.string().optional(),timezone:wt.string().optional(),timeType:wt.enum(["utc","local"]).optional(),createdAt:wt.string()}))}),503:wt.object({error:wt.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),b.delete("/schedule/:id",{schema:{params:wt.object({id:wt.string()}),response:{200:wt.object({success:wt.boolean()}),404:wt.object({error:wt.string()}),503:wt.object({error:wt.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 S=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);b.options("/channels",async(e,t)=>(I(t),t.send())),b.options("/channels/platforms",async(e,t)=>(I(t),t.send())),b.options("/channels/wechat/login/qrcode",async(e,t)=>(I(t),t.send())),b.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(I(t),t.send())),b.options("/channels/:id",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/connect",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/disconnect",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/contacts",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/bindings",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/bindings/:bindingId",async(e,t)=>(I(t),t.send())),b.options("/channels/task-message",async(e,t)=>(I(t),t.send())),b.options("/channels/group-history",async(e,t)=>(I(t),t.send())),b.get("/channels",{schema:{response:{200:wt.object({channels:wt.array(xr)}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return{channels:n.getChannels()}}),b.get("/channels/platforms",{schema:{response:{200:wt.object({platforms:wt.array(wt.enum(yr))})}}},async(e,t)=>(I(t),{platforms:[...yr]})),b.get("/channels/wechat/login/qrcode",{schema:{response:{200:wt.object({qrcode:wt.string(),qrcodeContent:wt.string(),qrcodeTerminal:wt.string(),baseUrl:wt.string()}),502:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);try{return await fr.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return Pe.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),b.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:wt.object({qrcode:wt.string()}),response:{200:wt.object({status:wt.string(),token:wt.string().optional(),baseUrl:wt.string().optional(),ilinkBotId:wt.string().optional(),ilinkUserId:wt.string().optional()}),502:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);try{return await fr.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return Pe.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),b.post("/channels",{schema:{body:Ir,response:{200:xr,503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return n.addChannel(e.body)}),b.delete("/channels/:id",{schema:{params:wt.object({id:wt.string()}),response:{200:wt.object({success:wt.boolean()}),404:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),b.post("/channels/:id/connect",{schema:{params:wt.object({id:wt.string()}),response:{200:xr,404:wt.object({error:wt.string()}),500:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/:id/disconnect",{schema:{params:wt.object({id:wt.string()}),response:{200:xr,404:wt.object({error:wt.string()}),500:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.get("/channels/:id/contacts",{schema:{params:wt.object({id:wt.string()}),response:{200:wt.object({contacts:wt.array(Tr)}),404:wt.object({error:wt.string()}),500:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.get("/channels/:id/bindings",{schema:{params:wt.object({id:wt.string()}),response:{200:wt.object({bindings:wt.array(Sr)}),404:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/task-message",{schema:{body:wt.object({taskId:wt.string(),content:wt.string().optional(),attachments:wt.array(wt.object({filePath:wt.string(),fileName:wt.string().optional(),mimeType:wt.string().optional(),kind:wt.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:wt.object({channelId:wt.string(),chatId:wt.string()}).optional()}),response:{200:wt.object({success:wt.boolean()}),404:wt.object({error:wt.string()}),503:wt.object({error:wt.string()}),500:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/group-history",{schema:{body:wt.object({taskId:wt.string(),limit:wt.number().int().positive().max(100).optional(),beforeSeq:wt.number().int().positive().optional(),afterSeq:wt.number().int().nonnegative().optional(),target:wt.object({channelId:wt.string(),chatId:wt.string(),platform:wt.string().optional(),chatType:wt.string().optional(),chatName:wt.string().optional()})}),response:{200:wt.object({historyXml:wt.string(),hasMoreBefore:wt.boolean(),hasMoreAfter:wt.boolean()}),400:wt.object({error:wt.string()}),503:wt.object({error:wt.string()}),500:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.delete("/channels/:id/bindings/:bindingId",{schema:{params:wt.object({id:wt.string(),bindingId:wt.string()}),response:{200:wt.object({success:wt.boolean()}),404:wt.object({error:wt.string()}),503:wt.object({error:wt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/list",{schema:{response:{200:wt.object({children:wt.array(wt.object({startedBy:wt.string(),taskId:wt.string(),pid:wt.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),b.post("/stop-session",{schema:{body:wt.object({sessionId:wt.string()}),response:{200:wt.object({success:wt.boolean()})}}},async e=>{const{sessionId:t}=e.body;return Pe.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),b.post("/stop",{schema:{response:{200:wt.object({status:wt.string()})}}},async()=>(Pe.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{Pe.debug("[CONTROL SERVER] Triggering daemon shutdown"),i()},50),{status:"stopping"})),"127.0.0.1"!==y&&Pe.warn(`[CONTROL SERVER] Listening on ${y}; ensure daemon control endpoints are protected by network policy`);const T=e=>new Promise((t,n)=>{w.listen({port:e,host:y},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{await function(e,t=300){return new Promise(n=>{const s=gn({host:"127.0.0.1",port:e});let a=!1;const i=e=>{a||(a=!0,s.destroy(),n(e))};s.once("connect",()=>i(!0)),s.once("error",()=>i(!1)),s.setTimeout(t,()=>i(!1))})}(30624)?(Pe.info("[CONTROL SERVER] Port 30624 already accepts loopback connections, falling back to dynamic port"),e=await T(0)):e=await T(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw Pe.info("[CONTROL SERVER] Failed to start:",t),t;Pe.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await T(0)}const t=parseInt(e.split(":").pop());Pe.info(`[CONTROL SERVER] Started on port ${t}`),f({port:t,host:y,webhookHost:v,stop:async()=>{await w.close(),Pe.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw Pe.info("[CONTROL SERVER] Failed to start:",e),e})})}function qc(e,t={}){const n=De(),s=E(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw Pe.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return mt(process.execPath,a,t)}function Hc(e,t){if(!e)return t;const n=Number.parseFloat(e);return!Number.isFinite(n)||n<=0?t:n}function Fc(e=process.env){return Boolean(e.CLOUD_AUTH_TOKEN?.trim())}function Bc(e=process.env){const t=e.AGENTRIX_EVENT_FORWARD_WS_URL?.trim();return t?{wsUrl:t,token:e.AGENTRIX_EVENT_FORWARD_TOKEN?.trim()||null,retentionHours:Hc(e.AGENTRIX_EVENT_FORWARD_RETENTION_HOURS,24),maxDbMb:Hc(e.AGENTRIX_EVENT_FORWARD_MAX_DB_MB,512)}:null}const Gc=Ne(import.meta.url);class Wc{constructor(e){this.options=e}worker=null;pending=new Map;nextRequestId=1;closed=!1;lastWorkerFailureAt=0;async append(e){const t={eventId:e.eventId,taskId:e.taskId,chatId:e.chatId??null,eventType:e.eventType,direction:e.direction,eventData:JSON.stringify(e.eventData??null),createdAt:e.createdAt??(new Date).toISOString()};try{await this.request("append",t)}catch(t){Gc.warn(`[FORWARD OUTBOX] Dropping event after append failure eventId=${e.eventId} error=${t instanceof Error?t.message:String(t)}`)}}pageAfter(e,t){return this.request("pageAfter",{cursor:e,limit:t})}getAckedCursor(){return this.request("getAckedCursor",{})}async setAckedCursor(e){await this.request("setAckedCursor",{cursor:e})}getDroppedBeforeCursor(){return this.request("getDroppedBeforeCursor",{})}cleanup(e){return this.request("cleanup",{cutoffIso:new Date(Date.now()-e.retentionMs).toISOString(),maxDbBytes:e.maxDbBytes,batchSize:1e3,sizeDropBatchSize:100})}async close(){if(this.closed)return;this.closed=!0;const e=this.worker;if(!e)return;const t=new Promise(t=>{const n=this.nextRequestId++;this.pending.set(n,{resolve:()=>t(),reject:()=>t()}),e.ref();try{e.postMessage({id:n,op:"close",args:{}})}catch{t()}}),n=new Promise(e=>{setTimeout(e,3e3).unref()});await Promise.race([t,n]),await e.terminate().catch(()=>{}),this.worker=null}request(e,t){if(this.closed)return Promise.reject(new Error("Forward outbox is closed"));let n;try{n=this.ensureWorker()}catch(e){return Promise.reject(e instanceof Error?e:new Error(String(e)))}const s=this.nextRequestId++;return new Promise((a,i)=>{this.pending.set(s,{resolve:a,reject:i}),1===this.pending.size&&n.ref();try{n.postMessage({id:s,op:e,args:t})}catch(e){this.pending.delete(s),i(e instanceof Error?e:new Error(String(e)))}})}ensureWorker(){if(this.worker)return this.worker;if(Date.now()-this.lastWorkerFailureAt<3e4)throw new Error("Forward outbox worker recently failed; backing off");const e=ut(import.meta.url),t=new fn("\n'use strict';\nconst { parentPort, workerData } = require('node:worker_threads');\nconst Database = require(workerData.betterSqlite3Path);\n\nconst SCHEMA_VERSION = 1;\n\nfunction log(level, message) {\n try {\n parentPort.postMessage({ kind: 'log', level: level, message: message });\n } catch (error) {\n // Nothing else we can do from the worker thread.\n }\n}\n\nfunction errorMessage(error) {\n return error && error.message ? String(error.message) : String(error);\n}\n\nconst db = new Database(workerData.dbPath);\ndb.pragma('busy_timeout = ' + workerData.busyTimeoutMs);\nconst initialVersion = db.pragma('user_version', { simple: true });\nif (initialVersion === 0) {\n // Must be set before the first table is created to apply without a full VACUUM.\n db.pragma('auto_vacuum = INCREMENTAL');\n}\ndb.pragma('journal_mode = WAL');\ndb.pragma('synchronous = NORMAL');\ndb.exec(\n 'CREATE TABLE IF NOT EXISTS forward_event (' +\n ' cursor INTEGER PRIMARY KEY AUTOINCREMENT,' +\n ' event_id TEXT UNIQUE NOT NULL,' +\n ' task_id TEXT NOT NULL,' +\n ' chat_id TEXT,' +\n ' event_type TEXT NOT NULL,' +\n ' direction TEXT NOT NULL,' +\n ' event_data TEXT NOT NULL,' +\n ' created_at TEXT NOT NULL' +\n '); ' +\n 'CREATE TABLE IF NOT EXISTS forward_state (' +\n ' key TEXT PRIMARY KEY,' +\n ' value TEXT NOT NULL' +\n ');'\n);\nif (initialVersion < SCHEMA_VERSION) {\n db.pragma('user_version = ' + SCHEMA_VERSION);\n}\n\nconst insertEvent = db.prepare(\n 'INSERT OR IGNORE INTO forward_event (event_id, task_id, chat_id, event_type, direction, event_data, created_at)' +\n ' VALUES (@eventId, @taskId, @chatId, @eventType, @direction, @eventData, @createdAt)'\n);\nconst selectAfter = db.prepare(\n 'SELECT cursor, event_id, task_id, chat_id, event_type, direction, event_data, created_at' +\n ' FROM forward_event WHERE cursor > ? ORDER BY cursor ASC LIMIT ?'\n);\nconst selectState = db.prepare('SELECT value FROM forward_state WHERE key = ?');\nconst upsertMaxState = db.prepare(\n 'INSERT INTO forward_state (key, value) VALUES (?, ?)' +\n ' ON CONFLICT(key) DO UPDATE SET value = CAST(MAX(CAST(value AS INTEGER), CAST(excluded.value AS INTEGER)) AS TEXT)'\n);\nconst deleteExpiredBatch = db.prepare(\n 'DELETE FROM forward_event WHERE cursor IN (' +\n ' SELECT cursor FROM forward_event WHERE cursor <= ? AND created_at < ? ORDER BY cursor ASC LIMIT ?' +\n ')'\n);\nconst selectOldestBatch = db.prepare(\n 'SELECT COUNT(*) AS n, MAX(cursor) AS maxCursor FROM (' +\n ' SELECT cursor FROM forward_event ORDER BY cursor ASC LIMIT ?' +\n ')'\n);\nconst deleteUpToCursor = db.prepare('DELETE FROM forward_event WHERE cursor <= ?');\n\nfunction readIntState(key) {\n const row = selectState.get(key);\n if (!row) {\n return null;\n }\n const value = Number.parseInt(row.value, 10);\n return Number.isFinite(value) ? value : null;\n}\n\nconst retryQueue = [];\nlet retryTimer = null;\nlet retryDelayMs = workerData.retryBaseDelayMs;\n\nfunction scheduleRetry() {\n if (retryTimer) {\n return;\n }\n retryTimer = setTimeout(runRetries, retryDelayMs);\n}\n\nfunction runRetries() {\n retryTimer = null;\n const entries = retryQueue.splice(0, retryQueue.length);\n for (const entry of entries) {\n try {\n insertEvent.run(entry.row);\n } catch (error) {\n entry.attempts += 1;\n if (entry.attempts >= workerData.retryMaxAttempts) {\n log('warn', 'retry attempts exhausted, dropping event eventId=' + entry.row.eventId + ' error=' + errorMessage(error));\n } else {\n retryQueue.push(entry);\n }\n }\n }\n if (retryQueue.length > 0) {\n retryDelayMs = Math.min(retryDelayMs * 2, workerData.retryMaxDelayMs);\n scheduleRetry();\n } else {\n retryDelayMs = workerData.retryBaseDelayMs;\n }\n}\n\nfunction appendRow(row) {\n try {\n insertEvent.run(row);\n if (retryQueue.length > 0) {\n scheduleRetry();\n }\n } catch (error) {\n if (retryQueue.length >= workerData.retryQueueLimit) {\n log('warn', 'retry queue overflow, dropping event eventId=' + row.eventId + ' error=' + errorMessage(error));\n } else {\n retryQueue.push({ row: row, attempts: 1 });\n scheduleRetry();\n }\n }\n return { queued: retryQueue.length };\n}\n\nfunction rowToEvent(row) {\n let eventData;\n try {\n eventData = JSON.parse(row.event_data);\n } catch (error) {\n eventData = { raw: row.event_data };\n }\n return {\n cursor: row.cursor,\n eventId: row.event_id,\n taskId: row.task_id,\n chatId: row.chat_id,\n eventType: row.event_type,\n direction: row.direction,\n eventData: eventData,\n createdAt: row.created_at,\n };\n}\n\nfunction dbSizeBytes() {\n const pageCount = db.pragma('page_count', { simple: true });\n const pageSize = db.pragma('page_size', { simple: true });\n const freelistCount = db.pragma('freelist_count', { simple: true });\n return (pageCount - freelistCount) * pageSize;\n}\n\nfunction cleanup(args) {\n const ackedCursor = readIntState('acked_cursor') || 0;\n let deletedExpired = 0;\n for (;;) {\n const result = deleteExpiredBatch.run(ackedCursor, args.cutoffIso, args.batchSize);\n deletedExpired += result.changes;\n if (result.changes < args.batchSize) {\n break;\n }\n }\n\n let deletedForSize = 0;\n let droppedUnackedCursor = null;\n while (dbSizeBytes() > args.maxDbBytes) {\n const oldest = selectOldestBatch.get(args.sizeDropBatchSize);\n if (!oldest || !oldest.n || oldest.maxCursor === null) {\n break;\n }\n const result = deleteUpToCursor.run(oldest.maxCursor);\n deletedForSize += result.changes;\n if (oldest.maxCursor > ackedCursor) {\n droppedUnackedCursor = oldest.maxCursor;\n }\n if (result.changes === 0) {\n break;\n }\n }\n if (droppedUnackedCursor !== null) {\n upsertMaxState.run('dropped_before_cursor', String(droppedUnackedCursor));\n }\n\n // Reclaim disk in small slices so cross-process writers never wait long.\n let vacuumGuard = 0;\n while (db.pragma('freelist_count', { simple: true }) > 64 && vacuumGuard < 1024) {\n db.pragma('incremental_vacuum(512)');\n vacuumGuard += 1;\n }\n try {\n db.pragma('wal_checkpoint(TRUNCATE)');\n } catch (error) {\n // Best effort: checkpoint can fail while other processes hold readers.\n }\n\n return {\n deletedExpired: deletedExpired,\n deletedForSize: deletedForSize,\n droppedUnackedCursor: droppedUnackedCursor,\n dbSizeBytes: dbSizeBytes(),\n };\n}\n\nfunction handleOp(op, args) {\n if (op === 'append') {\n return appendRow(args);\n }\n if (op === 'pageAfter') {\n return selectAfter.all(args.cursor, args.limit).map(rowToEvent);\n }\n if (op === 'getAckedCursor') {\n return readIntState('acked_cursor') || 0;\n }\n if (op === 'setAckedCursor') {\n upsertMaxState.run('acked_cursor', String(args.cursor));\n return null;\n }\n if (op === 'getDroppedBeforeCursor') {\n return readIntState('dropped_before_cursor');\n }\n if (op === 'cleanup') {\n return cleanup(args);\n }\n if (op === 'close') {\n if (retryTimer) {\n clearTimeout(retryTimer);\n retryTimer = null;\n }\n // Final best-effort flush of the retry queue before closing.\n for (const entry of retryQueue.splice(0, retryQueue.length)) {\n try {\n insertEvent.run(entry.row);\n } catch (error) {\n log('warn', 'dropping event on close eventId=' + entry.row.eventId + ' error=' + errorMessage(error));\n }\n }\n try {\n db.close();\n } catch (error) {\n // Ignore close errors.\n }\n return null;\n }\n throw new Error('Unknown forward outbox op: ' + op);\n}\n\nparentPort.on('message', (message) => {\n let reply;\n try {\n reply = { kind: 'result', id: message.id, ok: true, result: handleOp(message.op, message.args) };\n } catch (error) {\n reply = { kind: 'result', id: message.id, ok: false, error: errorMessage(error) };\n }\n parentPort.postMessage(reply);\n if (message.op === 'close') {\n process.exit(0);\n }\n});\n",{eval:!0,workerData:{dbPath:this.options.dbPath,betterSqlite3Path:e.resolve("better-sqlite3"),busyTimeoutMs:this.options.busyTimeoutMs,retryQueueLimit:this.options.retryQueueLimit,retryMaxAttempts:this.options.retryMaxAttempts,retryBaseDelayMs:this.options.retryBaseDelayMs,retryMaxDelayMs:this.options.retryMaxDelayMs}});return t.on("message",e=>this.handleWorkerMessage(e)),t.on("error",e=>{Gc.warn(`[FORWARD OUTBOX] Worker thread error: ${e instanceof Error?e.message:String(e)}`),this.handleWorkerExit(t,e instanceof Error?e:new Error(String(e)))}),t.on("exit",e=>{this.handleWorkerExit(t,0===e?null:new Error(`Forward outbox worker exited with code ${e}`))}),t.unref(),this.worker=t,t}handleWorkerMessage(e){if("log"===e.kind){const t=`[FORWARD OUTBOX] ${e.message}`;return void("warn"===e.level?Gc.warn(t):"info"===e.level?Gc.info(t):Gc.debug(t))}const t=this.pending.get(e.id);t&&(this.pending.delete(e.id),0===this.pending.size&&this.worker?.unref(),e.ok?t.resolve(e.result):t.reject(new Error(e.error)))}handleWorkerExit(e,t){this.worker===e&&(this.worker=null),t&&(this.lastWorkerFailureAt=Date.now());const n=[...this.pending.values()];this.pending.clear();for(const e of n)e.reject(t??new Error("Forward outbox worker exited"))}}let zc=null;function Kc(){return function(e=process.env){return Fc(e)&&null!==Bc(e)}()?(zc||(e={dbPath:E($e.resolveForwardDir(),"outbox.db")},zc=new Wc({dbPath:e.dbPath,busyTimeoutMs:e.busyTimeoutMs??5e3,retryQueueLimit:e.retryQueueLimit??1e3,retryMaxAttempts:e.retryMaxAttempts??10,retryBaseDelayMs:e.retryBaseDelayMs??500,retryMaxDelayMs:e.retryMaxDelayMs??3e4})),zc):null;var e}async function Vc(){const e=zc;zc=null,e&&await e.close()}const Xc={".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"},Jc={"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 Yc(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=M(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=M(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 Xc[t]||"application/octet-stream"}(a),r=a||function(e){return Jc[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=$(t);c=n&&M(n)?n:`${Ie()}${r||".dat"}`}catch{c=`${Ie()}${r||".dat"}`}else c=`${Ie()}${r||".dat"}`;const d=E(t,c),p=s.body,u=l(d);return await pt(p,u),{filePath:d,mimeType:o,filename:c}}catch(t){throw new Error(`Failed to download file from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const Qc=Ne(import.meta.url);async function Zc(e,t){const{attachmentsDir:n}=t;if(!Array.isArray(e.message.content))return e;const s=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t){try{const n=e.source.url;Qc.info(`image.download.started url=${n}`);const{filePath:s,mimeType:a}=await Yc(n,t,!0);return Qc.info(`image.download.completed filePath=${s}`),{type:"text",text:`Image file: ${s}\nType: ${a}`}}catch(t){return Qc.error(`image.download.failed error=${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t){try{const n=e.source.url;Qc.info(`document.download.started url=${n}`);const{filePath:s,mimeType:a,filename:i}=await Yc(n,t,!0);return Qc.info(`document.download.completed filePath=${s}`),{type:"text",text:`Document: ${s}\nTitle: ${e.title||i}\nType: ${a}`}}catch(t){return Qc.error(`document.download.failed error=${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n):e));return{...e,message:{...e.message,content:s}}}const el="Agentrix-DevOps",tl="main";function nl(e){return(e.supportedFeatures??[]).includes(ne)}function sl(e){return"zh-Hans"===e.preferredLanguage||`${process.env.AGENTRIX_LANG??""} ${process.env.LANG??""}`.toLowerCase().includes("zh")?"zh-Hans":"en"}function al(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 il(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 ol(e,t){return E($e.resolveDataDir(e,t),"devops-init")}function rl(e,t){return E(ol(e,t),"original-input.json")}function cl(e,t){return E(ol(e,t),"handoff.json")}function ll(e){const t=ol(e.userId,e.taskId);d(t,{recursive:!0}),u(rl(e.userId,e.taskId),JSON.stringify(e,null,2))}function dl(e,t){const n=rl(e,t);return r(n)?JSON.parse(c(n,"utf-8")):null}function pl(e,t){const n=cl(e,t);if(!r(n))return null;const s=JSON.parse(c(n,"utf-8"));return f(n),s}class ul{pidToTrackedSession;taskToStartPromise;sandboxPool;channelManager=null;socketClientProvider=null;acceptingNewWorkers=!0;workerStartGateCode=null;workerStartGateMessage=null;drainCallback=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}setWorkerStartGate(e,t,n){this.acceptingNewWorkers=e,this.workerStartGateCode=e?null:t??"daemon_control_busy",this.workerStartGateMessage=e?null:n??"Daemon is not accepting new workers"}isAcceptingNewWorkers(){return this.acceptingNewWorkers}setDrainCallback(e){this.drainCallback=e}createWorkerGateAck(e){return this.acceptingNewWorkers?null:{eventId:V(),status:"failed",opCode:e,message:this.workerStartGateMessage??"Daemon is not accepting new workers",data:{errorCode:this.workerStartGateCode??"daemon_control_busy"}}}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 Pe.warn(`[SESSION] Missing PID for task ${e}`);Pe.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 $e.getSecretKey();if(!t)return;const n=z(B(e.dataEncryptionKey),t);if(!n)return void Pe.warn("[SESSION] Failed to decrypt data encryption key");if(e.dataEncryptionKey=H(n),"task-message"!==e.event)return;const s=e.eventData;if(!s.encryptedMessage)return;const a=se(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:Pe.warn("[SESSION] Failed to decrypt task message")}appendForwardTaskStartEvent(e,t){const n=Kc();n&&n.append({eventId:t.eventId,taskId:e.taskId,chatId:e.chatId,eventType:e.event,direction:"inbound",eventData:t})}async persistCreateTaskStart(e){const t=$e.resolveDataDir(e.userId,e.taskId),n=$e.resolveAttachmentsDir(e.userId,e.taskId),s=jo({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}),this.appendForwardTaskStartEvent(e,t);let a=null;if(t.message){let e=t.message;ae(e)&&(e=await Zc(e,{attachmentsDir: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=$e.resolveDataDir(e.userId,e.taskId),n=$e.resolveAttachmentsDir(e.userId,e.taskId),s=jo({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}),this.appendForwardTaskStartEvent(e,t);let i=null;if(t.message){let e=t.message;ae(e)&&(e=await Zc(e,{attachmentsDir: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||!ae(t.message))return;const n=$e.resolveAttachmentsDir(e.userId,e.taskId),s=await Zc(t.message,{attachmentsDir: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=>{Pe.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after DevOps worker exit:`,t)}),0===this.pidToTrackedSession.size&&this.drainCallback?.()}),t.on("error",n=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId),0===this.pidToTrackedSession.size&&this.drainCallback?.()})}async maybeContinueAfterDevOpsInit(e){const t=pl(e.userId,e.taskId);t&&(Pe.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=dl(e,t);if(!n)return void Pe.warn(`[DEVOPS_INIT] Missing original task input for ${t}; cannot continue original worker`);if(Pe.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),$e.writeTaskInput(n);const a={eventId:V(),status:"success",opCode:n.eventId};await this.startWorkerInternal(n,"create-task",a)}restoreOriginalWorkerAfterSlashDevOpsInit(e){const t=jo({dataDir:$e.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const n=t.pageRecentMessages(1).data[0]?.localSequence??0;t.updateAgentLastSequence(e.agentId,n),Pe.info(`[DEVOPS_INIT] Restored original worker ${e.agentId} for task ${e.taskId} at sequence ${n}; waiting for the next user message`)}finally{t.close()}$e.writeTaskInput(e)}positionOriginalWorkerHistoryCursor(e,t){if(null===t)return void Pe.warn(`[DEVOPS_INIT] Original worker message for task ${e.taskId} has no local sequence; cannot isolate DevOps init history`);const n=jo({dataDir:$e.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),Pe.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:V(),taskId:e.taskId,agentSessionId:e.agentSessionId,cwd:e.cwd??e.userCwd}),void Pe.info(`[DEVOPS_INIT] Restored original agent session for task ${e.taskId}`);t.send("reset-task-session",{eventId:V(),taskId:e.taskId}),Pe.info(`[DEVOPS_INIT] Cleared DevOps init agent session for task ${e.taskId}`)}else Pe.warn(`[DEVOPS_INIT] No daemon socket client available to sync task session for ${e.taskId}`)}completeDevOpsInit(e){Pe.info(`[DEVOPS_INIT] Completion received for task ${e.taskId}, action=${e.action}`),function(e,t,n){const s=ol(e,t);d(s,{recursive:!0}),u(cl(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=>{Pe.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after completion signal:`,t)})},100)}startDevOpsInit(e){this.startDevOpsInitAsync(e).catch(t=>{Pe.error(`[DEVOPS_INIT] Failed to start slash-command DevOps init for task ${e.taskId}:`,t)})}async startDevOpsInitAsync(e){const t=$e.readTaskInput(e.userId,e.taskId);ll(t);const n=await this.buildDevOpsWorkerInput(t,!0);$e.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:V(),status:"success",opCode:e.eventId};return void await this.startWorkerInternal(e,t,n)}Pe.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 Pe.info(`[DEVOPS_INIT] Original worker for task ${t} is already running with PID ${s.pid}`);if(s)continue;const a=pl(e,t);if(!a)return void Pe.info(`[DEVOPS_INIT] Handoff for task ${t} was already consumed`);if(Pe.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)}Pe.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:V(),status:"success",opCode:e.eventId},s=this.createWorkerGateAck(e.eventId);if(s)return Pe.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;await this.decryptTaskMessage(e),await this.processTaskMessageAttachments(e),"create-task"===t?e=await this.resolveDevOpsInitCreateInput(e):"resume-task"===t&&(e=this.stripStaleDevOpsAgentSession(e)),$e.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const a=this.taskToStartPromise.get(e.taskId);if(a)return Pe.info(`[SESSION] Task ${e.taskId} is already starting, skip duplicate ${t}`),a;const i=this.startWorkerInternal(e,t,n).finally(()=>{this.taskToStartPromise.get(e.taskId)===i&&this.taskToStartPromise.delete(e.taskId)});return this.taskToStartPromise.set(e.taskId,i),i}stripStaleDevOpsAgentSession(e){if(e.agentId===el||!nl(e))return e;const t=dl(e.userId,e.taskId);if(!t||"agentSessionId"in t)return e;Pe.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(!nl(e)||e.agentId===el)return e;if(this.isLocalDirectoryDevOpsTarget(e)){if(!function(e,t={}){const n=t.checkLocalState??!0,s=E(e,".agentrix"),a=E(s,"env"),i=E(a,"init"),o=E(i,"state","local"),c=!r(s),l=!r(E(a,"README.md")),d=!r(E(i,"README.md")),p=!(!n||r(o)&&0!==function(e){try{return g(e)}catch{return[]}}(o).length);return{needsInit:c||l||d||p,missingAgentrixDir:c,missingEnvReadme:l,missingEnvModeDocs:d,missingLocalInitState:p}}($e.resolveProjectCWD(e.userCwd,e.userId,e.taskId),{checkLocalState:!0}).needsInit)return Pe.info(`[DEVOPS_INIT] Local project init state complete for task ${e.taskId}; starting original worker`),e}else{if(!this.isCodeRepositoryDevOpsTarget(e))return Pe.info(`[DEVOPS_INIT] No project directory or code repository selected for task ${e.taskId}; skipping Agentrix DevOps init`),e;Pe.info(`[DEVOPS_INIT] Code repository target selected for task ${e.taskId}; starting Agentrix-DevOps without local init-state precheck`)}ll(e);const t=await this.buildDevOpsWorkerInput(e,!1);return Pe.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=E($e.agentrixAgentsHomeDir,el),t=E($e.agentrixHomeDir,"tmp","agentrix-agent-devops-init"),n=`${e}.tmp-${Date.now()}`,s=`${e}.backup-${Date.now()}`;d(E($e.agentrixHomeDir,"tmp"),{recursive:!0}),r(E(t,".git"))?(At("git",["fetch","--depth=1","origin",`${tl}:refs/remotes/origin/${tl}`],{cwd:t,stdio:"pipe"}),At("git",["checkout",tl],{cwd:t,stdio:"pipe"}),At("git",["reset","--hard",`origin/${tl}`],{cwd:t,stdio:"pipe"})):(h(t,{recursive:!0,force:!0}),At("git",["clone","--depth=1","--branch",tl,"https://github.com/xmz-ai/agentrix-agent.git",t],{stdio:"pipe"}));const a=E(t,"agentrix-dev-init");if(!r(E(a,"agent.json")))throw new Error(`Agentrix DevOps agent definition not found at ${a}`);h(n,{recursive:!0,force:!0}),y(a,n,{recursive:!0}),qa(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"===sl(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?V():i.eventId,agentId:el,agentType:"claude",agentDir:n,eventData:{...a,eventId:V(),senderType:"system",senderId:"agentrix-devops-init",senderName:"Agentrix DevOps init",message:{uuid:yn(),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.createWorkerGateAck(e.eventId);if(s)return Pe.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;const a=this.getAliveSessionByTaskId(e.taskId);if(a)return Pe.info(`[SESSION] Task ${e.taskId} already has worker PID ${a.pid}, skip duplicate ${t}`),n.message=`Worker already running (PID ${a.pid})`,n;const i=$e.resolveProjectCWD(e.userCwd,e.userId,e.taskId),o=["worker","--type",e.agentType||"claude","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","120"],r=this.resolveChannelReplyTarget(e),c=this.buildWorkerEnv(r);let l;if(this.sandboxPool?.isEnabled())try{if(!await this.sandboxPool.createWorkerSandbox(e.taskId,e.userId,i))throw new Error("Failed to create sandbox instance");const{projectPath:t}=await import("./logger-C8KTAZ-P.mjs").then(function(e){return e.f}),{join:n}=await import("path"),s=["--no-warnings","--no-deprecation",n(t(),"dist","index.mjs"),...o],a=`"${process.execPath}" ${s.map(e=>`"${e}"`).join(" ")}`,r=await this.sandboxPool.wrapWorkerCommand(e.taskId,a);Pe.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${r}`),l=mt(r,{shell:!0,cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),Pe.info(`[SESSION] Worker started with sandbox, PID: ${l.pid}`)}catch(t){return Pe.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 l=qc(o,{cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),Pe.info(`[SESSION] Worker started without sandbox, PID: ${l.pid}`);return process.env.DEBUG&&(l.stdout?.on("data",e=>{Pe.debug(`[Daemon] worker stdout: ${e.toString()}`)}),l.stderr?.on("data",e=>{Pe.debug(`[Daemon] worker stderr: ${e.toString()}`)})),l.pid?(this.trackWorkerProcess(e,l),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"),Pe.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"),Pe.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){Pe.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){Pe.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return Pe.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(){Pe.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){Pe.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:V(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return Pe.warn(`[SESSION] Rejecting hive-publish for task ${e.taskId}: ${n.message}`),n;$e.writeTaskInput(e);try{const n=qc(["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=>{Pe.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{Pe.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;Pe.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:V(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return Pe.warn(`[SESSION] Rejecting hive-install for task ${e.taskId}: ${n.message}`),n;$e.writeTaskInput(e);try{const n=qc(["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=>{Pe.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{Pe.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;Pe.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:V(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return Pe.warn(`[SESSION] Rejecting deployment for task ${e.taskId}: ${n.message}`),n;$e.writeTaskInput(e);try{const n=qc(["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=>{Pe.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{Pe.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;Pe.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 ml{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=yt()}async initialize(e){if(this.settings=e,!e.enabled)return Pe.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!vn(this.platform))return Pe.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL($e.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new wn,await this.networkManager.initialize(t),Pe.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw Pe.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=$e.resolveUserWorkSpaceDir(t),a=$e.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=nt.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new bn(this.networkManager,c);return this.workerSandboxes.set(e,l),Pe.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return Pe.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 Pe.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),Pe.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){Pe.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),Pe.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,Pe.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class hl{constructor(e,t){this.client=e,this.machineId=t;const n=$e.agentrixAgentsHomeDir,s=E(n,"companion"),a=E(s,"claude");this.bootstrapPath=E(a,"BOOTSTRAP.md"),this.countPath=E(s,"BOOTSTRAP.count"),this.stateFilePath=E(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?Pe.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):(Pe.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):Pe.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 Pe.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void Pe.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return Pe.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),Pe.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:V(),machineId:t.machineId,agentId:t.agentId,chatId:t.chatId,chatTaskId:t.chatTaskId,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){Pe.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 gl(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function fl(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 yl(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 vl(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 wl(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 bl(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class kl{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:gl((t=e.credentials).appId,"appId"),appSecret:gl(t.appSecret,"appSecret")},this.client=new kn.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:kn.AppType.SelfBuild,domain:kn.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 kn.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:kn.Domain.Feishu,loggerLevel:kn.LoggerLevel.info,onReady:()=>{Pe.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{Pe.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{Pe.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{Pe.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new kn.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: ${wl(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:I(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.filePath),s=await this.client.im.file.create({data:{file_type:this.resolveLarkFileType(n,t.mimeType),file_name:n,file:I(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?(Pe.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return Pe.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 Pe.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 Pe.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${wl(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=us(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 Pe.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${wl(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 Pe.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){Pe.warn(`[CHANNEL][LARK] bot identity lookup failed: ${wl(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=M(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 Pe.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,d=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===d||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,d;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:vl(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:fl(n),fileKey:i?bl(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?bl(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:yl(t.create_time??e?.create_time??e?.ts),raw:e}}}const xl="https://api.telegram.org",Il=4e4,Sl=1e3;function Tl(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function Cl(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Al(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function _l(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function El(e){return e.photo?.[e.photo.length-1]?.file_id}class $l{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=Sl;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=Cl(e.token)??Cl(e.botToken)??Cl(e.bot_token);return{token:t||Tl(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:Il}),this.polling=!0,this.retryDelayMs=Sl,this.pollPromise=this.pollLoop(),this.setState("connected"),Pe.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:Il})}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.filePath),r=await Ht(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:Il})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:Il});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||$(n.file_path);return await gs(`${xl}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return Pe.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:Il});return t.title||Al(t)||t.username||e}catch(t){return Pe.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:Il});return Al(t)||t.username||e}catch(t){return Pe.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:Il,isPoll:!0});this.retryDelayMs=Sl,"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));Pe.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(`${xl}/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(`${xl}/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 Pe.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||Ie()),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?Al(t.from):void 0,type:_l(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:El(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 Ml(e){const t=Ul(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${Pl({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 Rl(e){const t=Ul(e);return t?`<msg ${Pl({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 Pl(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 Dl(e){const t=[];for(const n of e){const e=Rl(n);e&&t.push(e)}return t.join("\n")}function Nl(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 Ol(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 Ul(e){const{text:t,nonTextBlocks:n}=(s=e.message,ie(s)?{text:Nl(s),nonTextBlocks:[]}:oe(s)?{text:Ol(s),nonTextBlocks:[]}:re(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 jl{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=E($e.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=E($e.agentrixHomeDir,"channels","group-history"),this.loadState()}stateFilePath;groupHistoryFilePath;adapters=new Map;reconnectTimers=new Map;pendingMessages=new Map;store={version:1,channels:[],bindings:[]};taskDataKeyCache=new Map;stopping=!1;createTaskLocks=new Map;async start(){this.loadState();const e=this.store.channels.filter(e=>e.enabled);for(const t of e)try{await this.connectChannel(t.id)}catch(e){Pe.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}Pe.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=>{Pe.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),Pe.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:Ie(),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(),Pe.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(),Pe.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=>{Pe.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),Pe.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):(Pe.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(),Pe.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 kl({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new fr({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new $l({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){Pe.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 Pe.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);Pe.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=>{Pe.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),Pe.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=Pl({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){Pe.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)||d(t,{recursive:!0}),jo({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return E(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&&(Pe.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(Pe.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void Pe.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void Pe.warn(`[CHANNEL] Task ${t.taskId} is pending, skipping message forward`);const n=this.readCompanionState(),s=n?.chatId||t.taskId,a=await this.getTaskDataKeyForTask(t.taskId);if(!a)return void Pe.warn(`[CHANNEL] Missing task data key, skipping encrypted channel message forward: task=${t.taskId}`);const{plainMessage:i,encryptedMessage:o}=await this.buildEncryptedMessage(e,a);this.client.send("task-message",{eventId:V(),taskId:t.taskId,chatId:s,from:"machine",message:i,encryptedMessage:o,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}}),Pe.info(`[CHANNEL] Forwarded message to task ${t.taskId}`)}async buildEncryptedMessage(e,t){const n=e.attachmentPaths??[],s=n.length>0?`[User sent the following attachments: ${n.join(", ")}]`:void 0,a={type:"user",message:{role:"user",content:[s,e.text||(s?void 0:`[${e.type}]`)].filter(Boolean).join("\n\n")}};let i,o=a;if(t)try{i=pe(a,t),o=void 0}catch(e){Pe.warn("[CHANNEL] Failed to encrypt message, sending plaintext",e)}return{plainMessage:o,encryptedMessage:i}}async getOrCreateBindingForMessage(e){const t=this.store.bindings.find(t=>t.channelId===e.channelId&&t.chatId===e.chatId);if(t&&!this.isPendingTaskId(t.taskId))return{binding:t,isNew:!1};t&&(this.store.bindings=this.store.bindings.filter(e=>e.id!==t.id),this.saveState(),Pe.warn(`[CHANNEL] Removed pending binding before retry: channel=${t.channelId}, chat=${t.chatId}, task=${t.taskId}`));const n=await this.resolveChatName(e),s=await this.createTaskForChat(e,n),a=(new Date).toISOString(),i={id:Ie(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.isPendingTaskId(s)?(Pe.warn(`[CHANNEL] Task creation did not complete; not persisting pending binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0}):(this.store.bindings.push(i),this.saveState(),Pe.info(`[CHANNEL] Auto-created binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0})}isPendingTaskId(e){return e.startsWith("pending-")}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 Pe.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${Ie()}`;if(!this.client.connected)return Pe.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${Ie()}`;const s=await this.createChannelTaskEncryptionPayload();if(!s)return Pe.error("[CHANNEL] Cannot create encrypted channel task: missing local machine encryption credentials"),`pending-encryption-unavailable-${Ie()}`;const{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e,s.taskDataKey);try{const o=await this.client.sendWithAck("channel-task-create",{eventId:V(),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:s.dataEncryptionKey,ownerEncryptedDataKey:s.ownerEncryptedDataKey,message:a,encryptedMessage:i,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"===o?.status&&o.taskId?(this.taskDataKeyCache.set(o.taskId,s.taskDataKey),Pe.info(`[CHANNEL] Created task ${o.taskId} for chat ${e.chatId}`),o.taskId):(Pe.error(`[CHANNEL] API task creation failed: ${o?.message||"unknown"}`),`pending-api-error-${Ie()}`)}catch(e){return Pe.error("[CHANNEL] Failed to create task via API",e),`pending-error-${Ie()}`}}async resolveChatName(e){try{Pe.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(Pe.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if(Pe.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 Pe.warn(`[CHANNEL] Failed to resolve chat name for ${e.chatId}: ${t?.message||String(t)}`),e.senderName||e.senderId||e.chatId}}async createChannelTaskEncryptionPayload(){const e=await $e.readCredentials();if(!e?.secret)return Pe.warn("[CHANNEL] Missing machine secret; cannot create encrypted channel task key"),null;const t=await async function(e){if(!e.secret)return null;const t=function(e){if(!e.machineAesKey)return null;try{const t=B(e.machineAesKey);return 32===t.length?t:null}catch{return null}}(e);if(!t)return null;const n=await ce(e.secret),s=W();return{taskDataKey:s,dataEncryptionKey:H(de(s,n.publicKey)),ownerEncryptedDataKey:H(le(H(s),t))}}(e);return t||(Pe.warn("[CHANNEL] Missing machineAesKey in credentials; rebind this machine before creating encrypted channel tasks"),null)}async getTaskDataKeyForTask(e){const t=this.taskDataKeyCache.get(e);if(t)return t;if(!this.client.connected)return Pe.debug(`[CHANNEL] Socket not connected, cannot fetch encryption key for task ${e}`),null;try{const t=await this.client.sendWithAck("get-task-encryption-keys",{eventId:V(),taskId:e});if("success"===t?.status&&t.dataEncryptionKey){const n=await $e.getSecretKey();if(!n)return Pe.warn(`[CHANNEL] Missing machine secret key while decrypting task key: task=${e}`),null;const s=z(B(t.dataEncryptionKey),n);return s&&32===s.length?(this.taskDataKeyCache.set(e,s),s):(Pe.warn(`[CHANNEL] Failed to decrypt valid task data key: task=${e}`),null)}Pe.warn(`[CHANNEL] Failed to fetch encryption keys for task ${e}: ${t?.message||"unknown"}`)}catch(t){Pe.warn(`[CHANNEL] Error fetching encryption keys for task ${e}`,t)}return null}readCompanionState(){const e=E($e.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return Pe.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}:(Pe.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return Pe.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=>{Pe.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),Pe.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=_r.parse(e),(e.companionDataEncryptionKey||e.companionOwnerEncryptedDataKey||e.companionKeyMachineId||e.companionKeyChatId)&&this.saveState()}catch(e){Pe.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=D(this.stateFilePath);r(e)||d(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]))}}function Ll(){try{const e=st(De(),"package.json"),t=JSON.parse(Fe(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}async function ql(){const e=Ll();try{const t=ht("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}}}async function Hl(e,t={}){const n=function(){const e=st(at($e.getStatePaths().daemonStateFile),"upgrade.lock");if(Be(e))try{const t=Fe(e,"utf-8"),n=JSON.parse(t);"number"!=typeof n.pid||function(e){try{return process.kill(e,0),!0}catch{return!1}}(n.pid)||Ge(e)}catch{Ge(e)}try{const t=We(e,"wx");ze(t,JSON.stringify({pid:process.pid,createdAt:(new Date).toISOString()})),Ke(t)}catch{return null}return{release:()=>{try{const t=Fe(e,"utf-8");JSON.parse(t).pid===process.pid&&Ge(e)}catch{}}}}();if(!n)return{status:"busy",message:"CLI upgrade already in progress"};try{const n=e??await ql();if(!n.hasUpgrade)return{status:"already_latest",currentVersion:n.currentVersion,latestVersion:n.latestVersion};try{return await async function(e){await new Promise((t,n)=>{const s=mt("npm",["install","-g","@agentrix/cli@latest"],{stdio:e,env:process.env});s.on("error",n),s.on("exit",e=>{0!==e?n(new Error(`npm install exited with code ${e??"unknown"}`)):t()})})}(t.stdio??"inherit"),{status:"upgraded",fromVersion:n.currentVersion,toVersion:n.latestVersion??"latest"}}catch(e){return{status:"failed",currentVersion:n.currentVersion,latestVersion:n.latestVersion,error:e instanceof Error?e.message:String(e)}}}finally{n.release()}}const Fl=Yt(Ct),Bl=/^task-(.+)\.log(?:\.\d+)?(?:\.gz)?$/;function Gl(e,t){return N(e,t).split(P).join("/")}async function Wl(e){let t=0;const n=[e];for(;n.length>0;){const e=n.pop();let s,a;try{s=await zt(e)}catch{continue}if(t+=s.size,s.isDirectory()&&!s.isSymbolicLink())try{a=await Kt(e);for await(const t of a)n.push(E(e,t.name))}catch{continue}}return t}function zl(e,t){const n=E($e.agentrixWorkspaceHomeDir,"users",e,t,"data"),s=E(n,"workspace.json");if(r(s))try{return JSON.parse(c(s,"utf-8"))}catch{return null}const a=E(n,"cwd.txt");if(!r(a))return null;try{const e=c(a,"utf-8").trim();return e?{initialized:!0,initializedAt:new Date(p(a).mtimeMs).toISOString(),cwd:e}:null}catch{return null}}function Kl(){const e=$e.agentrixWorkspaceHomeDir,t=E(e,"users");if(!r(t))return[];const n=[];for(const e of g(t,{withFileTypes:!0})){if(!e.isDirectory())continue;const s=e.name,a=E(t,s);for(const e of g(a,{withFileTypes:!0})){if(!e.isDirectory())continue;const t=e.name,i=E(a,t);n.push({userId:s,taskId:t,taskDir:i,projectDir:E(i,"project"),dataDir:E(i,"data"),state:zl(s,t)})}}return n}function Vl(e){return"directory"===e?.repositorySourceType&&(!0===e.forceUserCwd||!1===e.useWorktree)}function Xl(e){const t=e.relativePath??Gl($e.agentrixHomeDir,e.absolutePath);return{id:e.id,kind:e.kind,label:e.label,relativePath:t,pathDisplay:t,bytes:e.bytes,reclaimable:e.reclaimable,defaultSelected:e.defaultSelected??e.reclaimable,deleteMode:e.deleteMode,reasonCode:e.reasonCode,reason:e.reason,childrenSummary:e.childrenSummary}}async function Jl(e){const t=await async function(e){try{const{stdout:t}=await Fl("git",["-C",e,"rev-parse","--path-format=absolute","--git-common-dir"],{windowsHide:!0}),n=t.trim();return n?n.endsWith(`${P}.git`)?D(n):n:null}catch{return null}}(e);if(!t)return null;try{const n=await zi(t),s=S(e);return n.some(e=>{try{return S(e.path)===s&&!e.isMain}catch{return!1}})?t:null}catch{return null}}async function Yl(e,t){const n=await async function(e,t){const n=function(e){const t=e.trim().replace(/\\/g,"/");if(!t||t.includes("\0")||t.startsWith("/"))return null;const n=t.split("/").filter(Boolean);return 0===n.length||n.some(e=>"."===e||".."===e)?null:n.join("/")}(t);if(!n)return null;const s=await Vt(e),a=R(s,...n.split("/"));if(a!==s&&!a.startsWith(s+P))return null;if(!r(a))return{relativePath:n,absolutePath:a};const i=await Vt(a);return i===s||i.startsWith(s+P)?{relativePath:n,absolutePath:a}:null}($e.agentrixHomeDir,e);if(!n)return{relativePath:e,releasable:!1,reasonCode:"invalid_path",message:"Path must stay inside the Agentrix home directory"};const{relativePath:s,absolutePath:a}=n;if(!r(a))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"missing",message:"Path no longer exists"};const i=s.split("/")[0];if("logs"===i){const e=function(e){const t=e.split("/");return"logs"!==t[0]?null:Bl.exec(t[t.length-1])?.[1]??null}(s);return e&&t.has(e)?{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"active_task",message:"Task is currently running"}:{relativePath:s,absolutePath:a,kind:"logs",method:"rm",releasable:!0}}if("tmp"===i)return{relativePath:s,absolutePath:a,kind:"tmp",method:"rm",releasable:!0};if("repos"===i)return 4===s.split("/").length?{relativePath:s,absolutePath:a,kind:"repos",method:"rm",releasable:!0}:{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_repo_path",message:"Only repository-level paths are cleanable"};if("workspaces"!==i)return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"protected_area",message:"This Agentrix area is not cleanable"};const o=function(e){const t=e.split("/");if(t.length<4||"workspaces"!==t[0]||"users"!==t[1])return null;const[,,n,s]=t,a=E($e.agentrixWorkspaceHomeDir,"users",n,s);return{userId:n,taskId:s,taskDir:a,projectDir:E(a,"project"),dataDir:E(a,"data"),state:zl(n,s)}}(s);if(!o)return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_workspace_path",message:"Only task project and task data paths are cleanable"};if(t.has(o.taskId))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"active_task",message:"Task is currently running"};if(Vl(o.state))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"user_directory",message:"This task uses a user-owned directory"};const c=s.split("/").slice(4).join("/");if("project"===c){const e=await Jl(a);return e?{relativePath:s,absolutePath:a,kind:"workspaces",method:"remove-worktree",releasable:!0,workspace:o,mainRepoDir:e}:{relativePath:s,absolutePath:a,kind:"workspaces",method:"rm-stale-directory",releasable:!0,workspace:o}}return"data"===c?{relativePath:s,absolutePath:a,kind:"workspaces",method:"rm",releasable:!0,workspace:o}:{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_workspace_path",message:"Only task project and task data paths are cleanable"}}async function Ql(e){const t=await Wl(e.absolutePath);if("remove-worktree"===e.method){if(!e.mainRepoDir)throw new Error("Missing main repository for worktree removal");await Vi(e.mainRepoDir,e.absolutePath,!0)}else{const t=v(e.absolutePath);t.isDirectory()&&!t.isSymbolicLink()?await Gt(e.absolutePath,{recursive:!0,force:!1}):await Wt(e.absolutePath)}return t}function Zl(e){try{if(!Xe(e).isDirectory())return{ok:!1,status:"missing",error:"Path is not a directory"};try{Je(e,Ye.R_OK|Ye.W_OK)}catch{return{ok:!1,status:"permission_lost",error:"Directory is not readable and writable"}}return{ok:!0,status:"active"}}catch(e){return{ok:!1,status:"missing",error:e instanceof Error?e.message:"Directory is unavailable"}}}function ed(e,t,n){const s=Xe(e);return{name:t,path:e,type:n,size:s.size,modifiedAt:s.mtime.toISOString()}}function td(e){const t=it(e?.trim()||In()),n=Zl(t);if("active"!==n.status)return{ok:!1,status:n.status,path:t,parentPath:null,entries:[],error:n.error};const s=ot(t).root,a=t===s?null:at(t),i=Qe(t,{withFileTypes:!0}).map(e=>{const n=st(t,e.name);try{if(e.isDirectory())return ed(n,e.name,"directory");if(e.isFile())return ed(n,e.name,"file")}catch{return null}return null}).filter(e=>Boolean(e)).sort((e,t)=>e.type!==t.type?"directory"===e.type?-1:1:e.name.localeCompare(t.name));return{ok:!0,status:"active",path:t,parentPath:a,entries:i}}class nd{state="ready";machineId;workerManager;getSocketClient;requestRestartCallback;restartRequested=!1;pendingRestartReport=null;activeStorageOperations={};activeStorageChildren=new Map;cancelledStorageOperations=new Set;constructor(e){this.machineId=e.machineId,this.workerManager=e.workerManager,this.getSocketClient=e.getSocketClient,this.requestRestartCallback=e.requestRestart,this.workerManager.setDrainCallback(()=>this.handleSessionDrain())}getState(){return this.state}isAcceptingNewWorkers(){return this.workerManager.isAcceptingNewWorkers()}clearGracefulRestartGate(){"pending_restart"===this.state&&(this.state="ready"),this.restartRequested=!1,this.pendingRestartReport=null,this.workerManager.setWorkerStartGate(!0)}rollbackGracefulRestart(){"pending_restart"!==this.state&&"restarting"!==this.state||(this.state="ready"),this.restartRequested=!1,this.pendingRestartReport=null,this.workerManager.setWorkerStartGate(!0)}prepareGracefulRestart(e,t,n){this.workerManager.setWorkerStartGate(!1,"daemon_pending_restart",t??"Daemon restart is pending"),this.workerManager.pruneStaleSessions();const s=this.workerManager.getCurrentSessions().length;if(0===s){this.state="restarting";const a=n??this.pendingRestartReport??void 0;return this.pendingRestartReport=null,this.requestRestart(e,t,a),{state:"restarting",activeSessions:s}}return this.state="pending_restart",this.pendingRestartReport=n??this.pendingRestartReport,{state:"pending_restart",activeSessions:s}}buildPingResult(){this.workerManager.pruneStaleSessions();const e="pending_restart"===this.state||"restarting"===this.state;return{machineId:this.machineId,runningCliVersion:Oe.version,installedCliVersion:Ll(),restartRequired:e,restartPending:e,platform:process.platform,uptimeMs:Math.max(0,Math.floor(1e3*process.uptime())),activeSessions:this.workerManager.getCurrentSessions().length,capabilities:["ping","upgrade-cli","storage-scan","storage-clean","pick-directory","validate-directory","list-directory","create-directory"]}}handleCommand(e,t){if(this.matchesTarget(e))if("ping"!==e.action){if("validate-directory"===e.action){const n="string"==typeof e.params?.path?e.params.path:"";return n.trim()?void t({eventId:V(),status:"success",opCode:e.eventId,data:{result:Zl(n)}}):void t(this.failedAck(e.eventId,"operation_failed","Directory path is required"))}if("pick-directory"!==e.action){if("list-directory"===e.action){const n="string"==typeof e.params?.path?e.params.path:void 0;return void t({eventId:V(),status:"success",opCode:e.eventId,data:{result:td(n)}})}if("create-directory"!==e.action)"upgrade-cli"!==e.action?"storage-scan"!==e.action&&"storage-clean"!==e.action?t(this.failedAck(e.eventId,"unsupported_operation","Unsupported machine control operation")):this.handleStorageManagement(e,t):this.handleUpgradeCli(e,t);else try{const n=function(e,t){const n=t.trim();if(!n||"."===n||".."===n||n.includes("/")||n.includes("\\"))throw new Error("Directory name is invalid");const s=it(e),a=Zl(s);if("active"!==a.status)throw new Error(a.error||"Parent directory is unavailable");const i=it(s,n);if(i!==s&&!i.startsWith(s.endsWith(rt)?s:s+rt))throw new Error("Directory path is invalid");return Ze(i),{path:i,validation:Zl(i)}}("string"==typeof e.params?.parentPath?e.params.parentPath:"","string"==typeof e.params?.name?e.params.name:"");t({eventId:V(),status:"success",opCode:e.eventId,data:{result:n}})}catch(n){const s=n instanceof Error?n.message:"Failed to create directory";t(this.failedAck(e.eventId,"operation_failed",s))}}else try{const n=wa("string"==typeof e.params?.defaultPath?e.params.defaultPath:void 0);t({eventId:V(),status:"success",opCode:e.eventId,data:{result:{path:n??null,...n?{validation:Zl(n)}:{}}}})}catch(n){const s=n instanceof Error?n.message:"Failed to pick directory";t(this.failedAck(e.eventId,"operation_failed",s))}}else t({eventId:V(),status:"success",opCode:e.eventId,data:{result:this.buildPingResult()}});else t(this.failedAck(e.eventId,"machine_not_found","Machine control target does not match this daemon"))}handleUpgradeCli(e,t){"ready"===this.state?(this.state="upgrading",t({eventId:V(),status:"success",opCode:e.eventId}),this.runUpgrade(e).catch(t=>{Pe.error("[MACHINE CONTROL] upgrade-cli failed unexpectedly:",t),this.state="ready",this.sendProgress({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t instanceof Error?t.message:"CLI upgrade failed"})})):t(this.failedAck(e.eventId,"pending_restart"===this.state?"daemon_pending_restart":"daemon_control_busy","Daemon is not ready for CLI upgrade"))}async runUpgrade(e){this.sendProgress({eventId:V(),opCode:e.eventId,status:"running",message:"Checking and installing CLI upgrade"});const t=await Hl(void 0,{stdio:"ignore"});if("busy"===t.status)return this.state="ready",void this.sendProgress({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_busy",errorMessage:t.message});if("already_latest"===t.status)return this.state="ready",void this.sendProgress({eventId:V(),opCode:e.eventId,status:"succeeded",message:"CLI is already up to date",result:{alreadyLatest:!0,currentVersion:t.currentVersion,latestVersion:t.latestVersion,restartRequired:!1,restartDeferred:!1,activeSessions:this.workerManager.getCurrentSessions().length}});if("failed"===t.status)return this.state="ready",void this.sendProgress({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t.error});const n={opCode:e.eventId,target:e.target,fromVersion:t.fromVersion,toVersion:t.toVersion},s=this.prepareGracefulRestart("machine-control","CLI upgrade installed",n);this.sendProgress({eventId:V(),opCode:e.eventId,status:"running",message:"pending_restart"===s.state?"CLI upgrade installed; restart deferred until active sessions finish":"CLI upgrade installed; restarting daemon",result:{fromVersion:t.fromVersion,toVersion:t.toVersion,restartRequired:!0,restartDeferred:"pending_restart"===s.state,activeSessions:s.activeSessions}})}handleStorageManagement(e,t){t(this.startStorageManagement(e,e=>this.sendProgress(e)))}startStorageManagement(e,t){if(!this.matchesTarget(e))return this.failedAck(e.eventId,"machine_not_found","Machine control target does not match this daemon");if("ready"!==this.state)return this.failedAck(e.eventId,"daemon_control_busy","Daemon is not ready for storage management");const n="storage-scan"===e.action||"storage-clean"===e.action?e.action:null;if(!n)return this.failedAck(e.eventId,"unsupported_operation","Unsupported storage operation");if(this.activeStorageOperations[n])return this.failedAck(e.eventId,"operation_busy",`Another ${n} operation is already running`);const s=this.buildStorageWorkerRequest(e);return"storage-clean"!==e.action||s.items&&0!==s.items.length?(this.activeStorageOperations[n]=e.eventId,this.runStorageManagementWorker(e,s,t).catch(n=>{Pe.error("[MACHINE CONTROL] storage management failed unexpectedly:",n),t({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:n instanceof Error?n.message:"Storage operation failed"})}).finally(()=>{this.activeStorageChildren.delete(e.eventId),this.cancelledStorageOperations.delete(e.eventId),this.activeStorageOperations[n]===e.eventId&&delete this.activeStorageOperations[n]}),{eventId:V(),status:"success",opCode:e.eventId}):this.failedAck(e.eventId,"operation_failed","No storage items selected")}cancelStorageManagement(e,t){const n=Object.entries(this.activeStorageOperations).find(([,t])=>t===e);return n?(this.cancelledStorageOperations.add(e),this.activeStorageChildren.get(e)?.kill?.("SIGTERM"),delete this.activeStorageOperations[n[0]],t({eventId:V(),opCode:e,status:"failed",errorCode:"operation_cancelled",errorMessage:"Storage operation cancelled"}),{eventId:V(),status:"success",opCode:e}):this.failedAck(e,"operation_failed","Storage operation is not running")}buildStorageWorkerRequest(e){const t={activeTaskIds:this.workerManager.getCurrentSessions().map(e=>e.taskId)};if("storage-clean"===e.action){t.dryRun=!0===e.params?.dryRun;const n=Array.isArray(e.params?.items)?e.params.items:[];t.items=n.map(e=>e&&"object"==typeof e&&"string"==typeof e.relativePath?{relativePath:e.relativePath}:null).filter(e=>Boolean(e))}return t}async runStorageManagementWorker(e,t,n){let s=null;try{s=Ve(st(xn(),`agentrix-${e.action}-`));const a=st(s,"request.json");ze(a,JSON.stringify(t));const i=e.action,o=qc([i,"--op-code",e.eventId,"--request-file",a],{stdio:["ignore","pipe","pipe"],env:process.env});this.activeStorageChildren.set(e.eventId,o),n({eventId:V(),opCode:e.eventId,status:"running",message:"storage-scan"===e.action?"Scanning Agentrix storage":"Cleaning Agentrix storage"}),await new Promise(t=>{let s="",a=!1;const r=t=>{"completed"!==t.type&&"failed"!==t.type||(a=!0),n(this.mapStorageWorkerEventToProgress(e,t))};o.stdout?.setEncoding("utf8"),o.stdout?.on("data",e=>{s+=e;const t=s.split(/\r?\n/);s=t.pop()??"";for(const e of t){const t=e.trim();if(t)try{r(JSON.parse(t))}catch(e){Pe.warn(`[MACHINE CONTROL] Ignoring malformed storage worker event: ${t}`,e)}}}),o.stderr?.setEncoding("utf8"),o.stderr?.on("data",e=>{Pe.warn(`[MACHINE CONTROL] ${i} stderr: ${e.trim()}`)}),o.on("error",t=>{a||(a=!0,n({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t.message}))}),o.on("close",i=>{if(s.trim())try{r(JSON.parse(s.trim()))}catch(e){Pe.warn(`[MACHINE CONTROL] Ignoring malformed trailing storage worker event: ${s.trim()}`,e)}if(!a){if(this.cancelledStorageOperations.has(e.eventId))return a=!0,void t();n({eventId:V(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:0===i?"Storage operation ended before reporting completion; please retry":`Storage worker exited with code ${i}`})}t()})})}finally{s&&function(e){try{p(e).isDirectory()?h(e,{recursive:!0,force:!0}):f(e)}catch{}}(s)}}mapStorageWorkerEventToProgress(e,t){return"failed"===t.type?{eventId:V(),opCode:e.eventId,status:"failed",message:t.message,errorCode:"operation_failed",errorMessage:t.message,result:{phase:t.type,...t}}:"completed"===t.type?{eventId:V(),opCode:e.eventId,status:"succeeded",message:"storage-scan"===e.action?"Storage scan completed":"Storage clean completed",result:t.result??{summary:t.summary}}:{eventId:V(),opCode:e.eventId,status:"running",message:this.describeStorageWorkerEvent(e.action,t),result:{phase:t.type,...t}}}describeStorageWorkerEvent(e,t){return"category-started"===t.type?`Scanning ${t.label}`:"item"===t.type?`Scanned ${t.item.pathDisplay??t.item.relativePath}`:"item-validating"===t.type?`Validating ${t.relativePath}`:"item-cleaning"===t.type?`Cleaning ${t.relativePath}`:"item-completed"===t.type?`Cleaned ${t.relativePath}`:"item-skipped"===t.type?`Skipped ${t.relativePath}`:"item-failed"===t.type?`Failed ${t.relativePath}`:"storage-scan"===e?"Scanning Agentrix storage":"Cleaning Agentrix storage"}handleSessionDrain(){if("pending_restart"!==this.state)return;const e=this.pendingRestartReport??void 0,t=this.prepareGracefulRestart("machine-control","Active sessions drained after CLI upgrade",e);e&&this.sendProgress({eventId:V(),opCode:e.opCode,status:"running",message:"Active sessions drained; restarting daemon",result:{fromVersion:e.fromVersion,toVersion:e.toVersion,restartRequired:!0,restartDeferred:!1,activeSessions:t.activeSessions}})}requestRestart(e,t,n){this.restartRequested||(this.restartRequested=!0,this.requestRestartCallback(e,t,n))}sendProgress(e){const t=this.getSocketClient();t?.connected?t.send("machine-control-progress",e):Pe.warn(`[MACHINE CONTROL] Dropping progress ${e.opCode}; socket not connected`)}matchesTarget(e){return e.target.machineId===this.machineId}failedAck(e,t,n){return{eventId:V(),status:"failed",opCode:e,message:n,data:{errorCode:t}}}}function sd(){return E(D($e.getStatePaths().daemonStateFile),"daemon-restart-report.json")}function ad(e){return new Promise(t=>setTimeout(t,e))}function id(e){try{return process.kill(e,0),!0}catch{return!1}}function od(e){return Zl(e).status}class rd{constructor(e,t={}){this.credentials=e,this.intervalMs=t.intervalMs??3e5,this.stateFilePath=t.stateFilePath??E($e.agentrixHomeDir,"workspace-mode.state.json")}timer=null;running=!1;intervalMs;stateFilePath;start(){this.timer||(this.syncOnce(),this.timer=setInterval(()=>{this.syncOnce()},this.intervalMs),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}async syncOnce(){if(!this.running){this.running=!0;try{const e=await this.loadState(),t=this.buildStatusReports(e);if(0===t.length)return;const n=this.markStatusesObserved(e,t);await this.saveState(n);const s={statuses:t};await async function(e,t){const n=await fetch(e,t);if(!n.ok){const e=await n.text().catch(()=>"");throw new Error(`HTTP ${n.status}${e?`: ${e}`:""}`)}return n.json()}(`${$e.serverUrl}/v1/workspaces/machine/path-statuses`,{method:"POST",headers:{Authorization:`Bearer ${this.credentials.token}`,"Content-Type":"application/json"},body:JSON.stringify(s)}),await this.saveState(this.markStatusesSynced(n,t))}catch(e){Pe.warn("[WORKSPACE SYNC] Failed to sync workspace path statuses",e)}finally{this.running=!1}}}async applyCacheUpdate(e){if(e.machineId!==this.credentials.machineId)return;const t=await this.loadState(),n=(new Date).toISOString(),s={...t.workspaces};if("replace"===e.action){const t={};for(const s of e.workspaces??[])t[s.id]=this.entryFromWorkspace(s,n);return void await this.saveState({version:1,machineId:this.credentials.machineId,workspaces:t})}if("upsert"===e.action&&e.workspace)return s[e.workspace.id]=this.entryFromWorkspace(e.workspace,n),void await this.saveState({...t,workspaces:s});"remove"===e.action&&e.workspaceId&&(delete s[e.workspaceId],await this.saveState({...t,workspaces:s}))}async loadState(){const e={version:1,machineId:this.credentials.machineId,workspaces:{}};if(!r(this.stateFilePath))return e;try{const t=JSON.parse(await Ht(this.stateFilePath,"utf-8"));return 1===t.version&&t.machineId===this.credentials.machineId&&t.workspaces&&"object"==typeof t.workspaces?t:e}catch(t){return Pe.warn("[WORKSPACE SYNC] Failed to read workspace sync state; rebuilding cache",t),e}}async saveState(e){await qt(D(this.stateFilePath),{recursive:!0}),await Ft(this.stateFilePath,JSON.stringify(e,null,2),"utf-8")}buildStatusReports(e){const t=[];for(const n of Object.values(e.workspaces)){const e=od(n.path);e!==n.lastSyncedStatus&&t.push({workspaceId:n.workspaceId,pathStatus:e})}return t}markStatusesSynced(e,t){const n={...e.workspaces};for(const e of t){const t=n[e.workspaceId];t&&(n[e.workspaceId]={...t,lastKnownStatus:e.pathStatus,lastSyncedStatus:e.pathStatus,updatedAt:(new Date).toISOString()})}return{...e,workspaces:n}}markStatusesObserved(e,t){const n={...e.workspaces};for(const e of t){const t=n[e.workspaceId];t&&(n[e.workspaceId]={...t,lastKnownStatus:e.pathStatus,updatedAt:(new Date).toISOString()})}return{...e,workspaces:n}}entryFromWorkspace(e,t){return{workspaceId:e.id,path:e.path,lastKnownStatus:e.pathStatus,lastSyncedStatus:e.pathStatus,updatedAt:t}}}const cd=wt.enum(["outbound","inbound"]),ld=wt.object({cursor:wt.number().int().positive(),eventId:wt.string(),taskId:wt.string(),chatId:wt.string().nullish(),eventType:wt.string(),direction:cd,eventData:wt.record(wt.string(),wt.unknown()),createdAt:wt.string()});wt.object({type:wt.literal("hello"),protocolVersion:wt.number().int(),machineId:wt.string(),cloudId:wt.string().optional(),hostname:wt.string(),cliVersion:wt.string().optional()});const dd=wt.object({type:wt.literal("hello-ack"),resumeFromCursor:wt.number().int().nonnegative().optional()});wt.object({type:wt.literal("events"),events:wt.array(ld),droppedBeforeCursor:wt.number().int().positive().optional()});const pd=wt.object({type:wt.literal("ack"),cursor:wt.number().int().nonnegative()}),ud=wt.discriminatedUnion("type",[dd,pd]),md=Ne(import.meta.url),hd=(e,t)=>new Sn(e,t);class gd{machineId;cloudId;settings;outbox;pollIntervalMs;batchSize;maxUnackedEvents;reconnectBaseDelayMs;reconnectMaxDelayMs;cleanupIntervalMs;heartbeatIntervalMs;createWebSocket;ws=null;started=!1;stopped=!1;helloAcked=!1;pumping=!1;cleaning=!1;sendCursor=0;flowAckedCursor=0;pendingDroppedBeforeCursor=null;reconnectDelayMs;reconnectTimer=null;pollTimer=null;cleanupTimer=null;heartbeatTimer=null;lastPongAt=0;constructor(e){this.machineId=e.machineId,this.cloudId=e.cloudId,this.settings=e.settings,this.outbox=e.outbox,this.pollIntervalMs=e.pollIntervalMs??300,this.batchSize=e.batchSize??200,this.maxUnackedEvents=e.maxUnackedEvents??1e3,this.reconnectBaseDelayMs=e.reconnectBaseDelayMs??1e3,this.reconnectMaxDelayMs=e.reconnectMaxDelayMs??6e4,this.cleanupIntervalMs=e.cleanupIntervalMs??3e5,this.heartbeatIntervalMs=e.heartbeatIntervalMs??3e4,this.createWebSocket=e.createWebSocket??hd,this.reconnectDelayMs=this.reconnectBaseDelayMs}start(){this.started||(this.started=!0,md.info(`[FORWARD] Task event forwarding enabled url=${this.settings.wsUrl} retentionHours=${this.settings.retentionHours} maxDbMb=${this.settings.maxDbMb}`),this.connect(),this.pollTimer=setInterval(()=>{this.pump()},this.pollIntervalMs),this.pollTimer.unref(),this.cleanupTimer=setInterval(()=>{this.runCleanup()},this.cleanupIntervalMs),this.cleanupTimer.unref(),this.heartbeatTimer=setInterval(()=>{this.heartbeat()},this.heartbeatIntervalMs),this.heartbeatTimer.unref(),this.runCleanup())}async stop(){this.stopped=!0;for(const e of[this.pollTimer,this.cleanupTimer,this.heartbeatTimer,this.reconnectTimer])e&&clearInterval(e);this.pollTimer=null,this.cleanupTimer=null,this.heartbeatTimer=null,this.reconnectTimer=null;const e=this.ws;if(this.ws=null,this.helloAcked=!1,e){try{e.close(1e3)}catch{}setTimeout(()=>e.terminate(),500).unref()}md.info("[FORWARD] Task event forwarding stopped")}connect(){if(this.stopped)return;let e;try{e=this.createWebSocket(this.settings.wsUrl,{handshakeTimeout:1e4,...this.settings.token?{headers:{Authorization:`Bearer ${this.settings.token}`}}:{}})}catch(e){return md.warn(`[FORWARD] Failed to create WebSocket: ${e instanceof Error?e.message:String(e)}`),void this.scheduleReconnect()}this.ws=e,this.helloAcked=!1,e.on("open",()=>{if(this.ws!==e)return;this.lastPongAt=Date.now();const t={type:"hello",protocolVersion:1,machineId:this.machineId,...this.cloudId?{cloudId:this.cloudId}:{},hostname:n.hostname(),cliVersion:Oe.version};e.send(JSON.stringify(t))}),e.on("message",t=>{this.ws===e&&this.handleFrame(String(t))}),e.on("pong",()=>{this.lastPongAt=Date.now()}),e.on("error",e=>{md.warn(`[FORWARD] WebSocket error: ${e.message}`)}),e.on("close",t=>{this.ws===e&&(this.ws=null,this.helloAcked=!1,this.stopped||(md.info(`[FORWARD] Connection closed (code=${t}), reconnecting in ${this.reconnectDelayMs}ms`),this.scheduleReconnect()))})}scheduleReconnect(){this.stopped||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.reconnectDelayMs),this.reconnectTimer.unref(),this.reconnectDelayMs=Math.min(2*this.reconnectDelayMs,this.reconnectMaxDelayMs))}async handleFrame(e){let t;try{t=JSON.parse(e)}catch{return void md.warn("[FORWARD] Ignoring non-JSON frame from receiver")}const n=ud.safeParse(t);if(n.success){if("hello-ack"===n.data.type){try{const e=await this.outbox.getAckedCursor();this.sendCursor=n.data.resumeFromCursor??e,this.flowAckedCursor=this.sendCursor;const t=await this.outbox.getDroppedBeforeCursor();this.pendingDroppedBeforeCursor=null!==t&&t>this.sendCursor?t:null}catch(e){return void md.warn(`[FORWARD] Failed to resolve resume cursor: ${e instanceof Error?e.message:String(e)}`)}return this.helloAcked=!0,this.reconnectDelayMs=this.reconnectBaseDelayMs,md.info(`[FORWARD] Handshake complete, resuming after cursor ${this.sendCursor}`),void this.pump()}if("ack"===n.data.type){const e=n.data.cursor;e>this.flowAckedCursor&&(this.flowAckedCursor=e),this.outbox.setAckedCursor(e).catch(t=>{md.warn(`[FORWARD] Failed to persist acked cursor ${e}: ${t instanceof Error?t.message:String(t)}`)}),this.pump()}}else md.warn("[FORWARD] Ignoring unknown frame from receiver")}async pump(){if(this.pumping||this.stopped)return;const e=this.ws;if(e&&e.readyState===Sn.OPEN&&this.helloAcked){this.pumping=!0;try{for(;;){if(this.stopped||this.ws!==e||e.readyState!==Sn.OPEN||!this.helloAcked)return;const t=this.maxUnackedEvents-(this.sendCursor-this.flowAckedCursor);if(t<=0)return;const n=Math.min(this.batchSize,t),s=await this.outbox.pageAfter(this.sendCursor,n);if(0===s.length)return;const a={type:"events",events:s,...null!==this.pendingDroppedBeforeCursor?{droppedBeforeCursor:this.pendingDroppedBeforeCursor}:{}};if(e.send(JSON.stringify(a)),this.pendingDroppedBeforeCursor=null,this.sendCursor=s[s.length-1].cursor,s.length<n)return}}catch(e){md.warn(`[FORWARD] Push failed: ${e instanceof Error?e.message:String(e)}`)}finally{this.pumping=!1}}}async runCleanup(){if(!this.cleaning&&!this.stopped){this.cleaning=!0;try{const e=await this.outbox.cleanup({retentionMs:36e5*this.settings.retentionHours,maxDbBytes:1024*this.settings.maxDbMb*1024});e.deletedForSize>0?md.warn(`[FORWARD] Outbox exceeded ${this.settings.maxDbMb}MB, dropped ${e.deletedForSize} oldest events`+(null!==e.droppedUnackedCursor?` (gap up to cursor ${e.droppedUnackedCursor})`:"")):e.deletedExpired>0&&md.debug(`[FORWARD] Outbox cleanup removed ${e.deletedExpired} expired events (size=${e.dbSizeBytes} bytes)`)}catch(e){md.warn(`[FORWARD] Outbox cleanup failed: ${e instanceof Error?e.message:String(e)}`)}finally{this.cleaning=!1}}}heartbeat(){const e=this.ws;if(e&&e.readyState===Sn.OPEN){if(Date.now()-this.lastPongAt>2*this.heartbeatIntervalMs+5e3)return md.warn("[FORWARD] Heartbeat timeout, terminating connection"),void e.terminate();try{e.ping()}catch{}}}}function fd(e){const t=ss(e);return"machine_binding_revoked"===t.code||t.message.includes("Machine binding revoked")}function yd(e){const t=ss(e);return t.code||t.action?t:null}function vd(e,t){$e.writeDaemonState({status:"starting",pid:process.pid,...void 0!==t.port?{port:t.port}:{},...t.host?{host:t.host}:{},...t.webhookHost?{webhookHost:t.webhookHost}:{},phase:e,startTime:t.startTime,updatedAt:(new Date).toISOString(),cliVersion:Oe.version,logPath:t.logPath})}async function wd(){Ue({type:"daemon"});const e=je(),t=(new Date).toLocaleString();let n="boot";const{requestShutdown:s,shutdownPromise:a}=function(){const{processType:e,onShutdownRequest:t,forceExitTimeoutMs:n=3e4}={processType:"daemon"},s=`[${e.toUpperCase()}]`;let a,i=!1;const o=new Promise(e=>{a=(a,o)=>{i?Pe.debug(`${s} Shutdown already requested; ignoring duplicate request from ${a}`):(i=!0,Pe.info(`${s} Requesting shutdown (source: ${a}, errorMessage: ${o})`),t&&t(a,o),setTimeout(()=>process.exit(1),n).unref?.(),e({source:a,errorMessage:o}))}}),r=e=>{process.on(e,()=>{a("os-signal")})};return r("SIGINT"),r("SIGTERM"),process.on("uncaughtException",e=>{Pe.info(`${s} FATAL: Uncaught exception`,e),Pe.info(`${s} Stack trace: ${e.stack}`),a("exception",e.message)}),process.on("unhandledRejection",e=>{Pe.info(`${s} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);Pe.info(`${s} Stack trace: ${t.stack}`),a("exception",t.message)}),process.on("exit",e=>{Pe.info(`${s} Process exiting with code: ${e}`)}),{requestShutdown:a,shutdownPromise:o}}();console.log("[DAEMON RUN] Starting daemon process..."),Pe.debug("[DAEMON RUN] Environment",ga()),await Wn()&&(console.log("Daemon already running..."),process.exit(0));let i=await $e.acquireDaemonLock(5,200);for(;!i;)await Kn(),i=await $e.acquireDaemonLock(5,200),i||(Pe.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{n="machine_auth",vd(n,{startTime:t,logPath:e}),function(){if($e.disableCaffeinate)return Pe.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return Pe.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(oa&&!oa.killed)return Pe.debug("[caffeinate] Caffeinate already running"),!0;try{return oa=mt("caffeinate",["-im"],{stdio:"ignore",detached:!1}),oa.on("error",e=>{Pe.debug("[caffeinate] Error starting caffeinate:",e),oa=null}),oa.on("exit",(e,t)=>{Pe.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),oa=null}),Pe.info(`[caffeinate] Started with PID ${oa.pid}`),function(){if(la)return;la=!0;const e=()=>{ca()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{Pe.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{Pe.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return Pe.info("[caffeinate] Failed to start caffeinate:",e),!1}}()&&Pe.debug("[DAEMON RUN] Sleep prevention enabled");const o=await Zn();Pe.debug("[DAEMON RUN] Auth and machine setup complete");const l=new ml;await l.initialize($e.getSandboxSettings());const d=new ul(l);let p,u,m,h,g=!1;d.setSocketClientProvider(()=>p?.client),h=new nd({machineId:o.machineId,workerManager:d,getSocketClient:()=>p?.client,requestRestart:(e,t,n)=>{!function(e){try{const t=qc(function(e){const t=["restart-daemon"];return void 0!==e.oldPid&&t.push("--old-pid",String(e.oldPid)),e.expectedCliVersion&&t.push("--expected-version",e.expectedCliVersion),e.reason&&t.push("--reason",e.reason),e.report&&t.push("--report-json",JSON.stringify(e.report)),t}(e),{detached:!0,stdio:"ignore",env:process.env});return t.unref(),t}catch(e){return Pe.error("[DAEMON RESTART] Failed to launch restart command",e),null}}({oldPid:process.pid,expectedCliVersion:n?.toVersion??Ll(),reason:t,report:n})?h.rollbackGracefulRestart():(g=!0,s("agentrix-cli",t))}});const{port:y,host:v,webhookHost:w,stop:b}=await Lc({getChildren:()=>d.getCurrentSessions(),stopSession:e=>d.stopSession(e),startDevOpsInit:e=>d.startDevOpsInit(e),completeDevOpsInit:e=>d.completeDevOpsInit(e),requestShutdown:()=>s("agentrix-cli"),registerSession:(e,t)=>d.registerTaskWorker(e,t),prepareGracefulRestart:e=>h.prepareGracefulRestart(e.source,e.reason),clearGracefulRestartGate:()=>h.clearGracefulRestartGate(),getSocketClient:()=>p?.client,credentials:o,get companionScheduler(){return u},get channelManager(){return m}});n="machine_socket",vd(n,{port:y,host:v,webhookHost:w,startTime:t,logPath:e});try{await va(),Pe.debug("[DAEMON RUN] Openers detected")}catch(e){Pe.warn("[DAEMON RUN] Failed to detect openers",e)}const k=new rd(o),x=new ia({machineId:o.machineId,serverUrl:$e.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:ue(o.token,o.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:V(),machineId:o.machineId,timestamp:Date.now().toString(),controlPort:y})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:Ne(import.meta.url,void 0,{filter:e=>!function(e){return e.includes("daemon-gitlab-request")||e.includes("daemon-gitlab-response")}(e)})},d,{requestShutdown:s,machineControl:h,workspaceStatusSync:k}),I=new jl(x.client,o.machineId);m=I,d.setChannelManager(I),await x.connect(),p=x;const S={status:"ready",pid:process.pid,port:y,host:v,webhookHost:w,machineId:o.machineId,startTime:t,cliVersion:Oe.version,logPath:e};$e.writeDaemonState(S),Pe.debug("[DAEMON RUN] Daemon ready state written"),Pe.info("[DAEMON RUN] Machine client connected to server"),await async function(e){const t=function(){const e=sd();if(!r(e))return null;try{const t=JSON.parse(c(e,"utf-8"));return t.opCode&&t.target?.machineId?t:null}catch{return null}}();if(!t)return!1;const n=Oe.version,s={eventId:V(),opCode:t.opCode,status:"succeeded",message:"CLI upgrade installed; daemon restarted",result:{fromVersion:t.fromVersion,toVersion:t.toVersion??t.expectedCliVersion,currentVersion:n,runningCliVersion:n,installedCliVersion:n,restartRequired:!1,restartDeferred:!1,activeSessions:0}};return e.send("machine-control-progress",s),await e.flush(3e3).catch(e=>{Pe.warn("[DAEMON RESTART] Could not confirm restart report flush",e)}),function(){try{const e=sd();r(e)&&f(e)}catch{}}(),Pe.info(`[DAEMON RESTART] Flushed pending restart report for ${t.opCode}`),!0}(x.client).catch(e=>{Pe.warn("[DAEMON RUN] Failed to flush pending restart report",e)}),await uc(x.client,o),k.start();const T=new Go(x.client,o.machineId);u=T,T.start();const C=function(e){const t=Bc();if(!t)return md.debug("[FORWARD] AGENTRIX_EVENT_FORWARD_WS_URL not set, task event forwarding disabled"),null;if(!Fc())return md.warn("[FORWARD] AGENTRIX_EVENT_FORWARD_WS_URL is set but task event forwarding only supports cloud mode (CLOUD_AUTH_TOKEN); forwarding disabled"),null;const n=Kc();return n?new gd({machineId:e.machineId,cloudId:e.cloudId,settings:t,outbox:n}):null}({machineId:o.machineId,cloudId:o.cloudId});C?.start(),await I.start(),x.setCompanionInteractionCallback(e=>{T.recordInteraction(e)});const A=new hl(x.client,o.machineId);A.start(),x.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&T.setHeartbeatTaskId(e.taskId)}),x.client.onEvent("companion-memory-organization-response",e=>{e?.taskId&&T.setMemoryOrganizationTaskId(e.taskId)});const _=async(e,t)=>{await I.stop(),k.stop(),T.stop(),A.stop(),await(C?.stop()),await x.disconnect(),await b(),await Vc(),await l.shutdown(),await zn(),await ca(),await $e.releaseDaemonLock(i),g&&Pe.info("[DAEMON RUN] Restart command owns replacement daemon startup"),Pe.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};Pe.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const E=await a;await _(E.source,E.errorMessage)}catch(t){!function(e,t,n){const s=yd(t),a=fd(t),i=s?.message||(a?"Machine binding is no longer valid.":t instanceof Error?t.message:String(t)),o=s?.action||(a?"Run `agentrix logout` and bind this machine again.":void 0);$e.writeDaemonState({status:"failed",phase:e,...s?.code?{code:s.code}:{},message:i,...o?{action:o}:{},failedAt:(new Date).toISOString(),cliVersion:Oe.version,logPath:n,pid:process.pid})}(n,t,e);const s=yd(t);s?(console.error(s.message),s.action&&console.error(s.action),Pe.error(`[DAEMON RUN][FATAL] ${s.code??"socket_auth_failed"}: ${s.message}`+(s.action?`\n${s.action}`:""))):fd(t)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again."),Pe.error("[DAEMON RUN][FATAL] Machine binding revoked.\nRun `agentrix logout` and bind this machine again.")),Pe.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",t),process.exit(1)}}const bd="\n\n[Tool result truncated to 1024 bytes]";function kd(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(bd,"utf8");return n>t?Id(bd,t):`${Id(e,t-n)}${bd}`}function xd(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Id(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}function Sd(e,t){return[`eventId=${e.eventId}`,void 0!==e.sequence?`sequence=${e.sequence}`:void 0,e.opCode?`opCode=${e.opCode}`:void 0,`senderType=${e.senderType}`,`messageType=${t?.type??e.messageType??"unknown"}`,`encrypted=${Boolean(e.encryptedMessage)}`].filter(Boolean).join(" ")}function Td(e,t,n={}){const s=function(e){return ae(e)?ii(e):oe(e)?{answers:e.answers,...e.details?{details:e.details}:{},...e.status?{status:e.status}:{},...e.reason?{reason:e.reason}:{}}:null}(t);if(null===s)return null;const a="string"==typeof s?s:JSON.stringify(s);return["message.user_content",n.source?`source=${n.source}`:void 0,Sd(e,t),`chars=${a.length}`,`content=${JSON.stringify(s)}`].filter(Boolean).join(" ")}const Cd=Ne(import.meta.url),Ad={senderType:"system",senderId:"system",senderName:"system"};class _d{client;context;historyDb;getPermissionMode;outbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;forwardOutbox;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new cs(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onReconnect:t.onReconnect,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.forwardOutbox=void 0!==t.forwardOutbox?t.forwardOutbox:Kc(),this.initHandlers()}appendForwardEvent(e,t,n="outbound"){this.forwardOutbox&&this.forwardOutbox.append({eventId:t.eventId,taskId:this.context.taskId,chatId:t.chatId??this.context.chatId,eventType:e,direction:n,eventData:t})}sendForwarded(e,t){this.appendForwardEvent(e,t),this.client.send(e,t)}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=V();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:V(),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.sendForwarded("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:V(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.sendForwarded("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:V(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.sendForwarded("worker-ready",n),Cd.info([`worker.ready taskId=${this.context.taskId}`,void 0!==e?`activeMs=${e}`:void 0,null!==t?`permissionMode=${t}`:void 0].filter(Boolean).join(" "))}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:V(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.sendForwarded("worker-running",n)}sendPermissionMode(e){const t={eventId:V(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.sendForwarded("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:V(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.sendForwarded("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(Ad,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(Ad,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(Ad,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(Ad,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 kd(e,t);const n=xd(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?kd(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:xd(e);var t}).join("\n"),t):kd(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??V(),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 d=this.buildTaskUsageReport(s,c);if(this.appendForwardEvent("task-message",l),this.context.dataEncryptionKey){const e=pe(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,{payload:l,usageReport:d??void 0,sentAt:Date.now(),messageType:l.messageType,isResult:"result"===s.type}),d&&(this.appendForwardEvent("task-usage-report",d),this.client.send("task-usage-report",d)),this.client.send("task-message",l),"result"===s.type&&Cd.info([`outbound.result.sent eventId=${c}`,d?.eventId?`usageEventId=${d.eventId}`:"usageEventId=none",`encrypted=${Boolean(l.encryptedMessage)}`,`artifacts=${Boolean(o)}`,`outboxSize=${this.outbox.size}`].join(" ")),c}waitForEventAcks(e,t){const n=new Set(e.filter(e=>this.outbox.has(e)));return 0===n.size?Promise.resolve():new Promise(e=>{const s=t=>{this.ackWaiters.delete(t),n.delete(t),0===n.size&&(clearTimeout(a),e())},a=setTimeout(()=>{for(const e of n){const n=this.outbox.get(e),s=n?Date.now()-n.sentAt:t;Cd.warn(`${n?.isResult?"outbound.result.ack_timeout":"outbound.event.ack_timeout"} eventId=${e} pendingMs=${s} outboxSize=${this.outbox.size}`),this.ackWaiters.delete(e)}e()},t);for(const e of n)this.ackWaiters.set(e,()=>s(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:V(),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:V(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.sendForwarded("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:V(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.sendForwarded("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:V(),taskId:this.context.taskId,title:e};this.sendForwarded("change-task-title",t),Cd.info(`task.title_changed title=${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:V(),taskId:this.context.taskId,agentId:e,...t};this.sendForwarded("update-agent-info",n),Cd.info(`agent.info_updated updates=${JSON.stringify(t)}`)}async sendVisionPlanCard(e){const t={eventId:V(),taskId:this.context.taskId,issueId:e.issueId,repoRoot:e.repoRoot,createdAt:(new Date).toISOString()};this.appendForwardEvent("vision-plan-card",t);const n=await this.client.sendWithAck("vision-plan-card",t);if("success"!==n.status)throw new Error(n.message||"Failed to send Vision Plan card");return Cd.info(`vision_plan_card.sent issueId=${e.issueId}`),n}sendResetTaskSession(){const e={eventId:V(),taskId:this.context.taskId};this.sendForwarded("reset-task-session",e),Cd.info(`session.reset_requested taskId=${this.context.taskId}`)}async sendMergeRequest(e,t,n){const s={eventId:V(),taskId:this.context.taskId,summary:e,description:t,sourceBranch:n};Cd.info(`merge_request.sent taskId=${this.context.taskId}`),this.appendForwardEvent("merge-request",s);const a=await this.client.sendWithAck("merge-request",s);if(!a.success)throw new Error(`Failed to create pull request: ${a.error||"Unknown error"}`);return Cd.info(`merge_request.created pullRequestNumber=${a.data.pullRequestNumber}`),{pullRequestNumber:a.data.pullRequestNumber,pullRequestUrl:a.data.pullRequestUrl}}async sendMergePr(){const e={eventId:V(),taskId:this.context.taskId,mergeMethod:"squash"};return Cd.info(`merge_pr.sent taskId=${this.context.taskId}`),this.appendForwardEvent("merge-pr",e),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:V(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};Cd.info(`repo.association.sent repository=${e}/${t}/${n}`),this.sendForwarded("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:V(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},a=this.forwardOutbox?(e,t)=>this.appendForwardEvent(e,t,"inbound"):null,{"cancel-task":async e=>{e.taskId===t.taskId&&(Cd.info(`worker.cancelled taskId=${t.taskId}`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&(Cd.info(`worker.stopped taskId=${t.taskId} reason=${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;Cd.debug(`message.received ${Sd(e)}`);let i=e.message??null;if(!i&&e.encryptedMessage&&t.dataEncryptionKey&&(i=se(e.encryptedMessage,t.dataEncryptionKey)??null),!i&&e.encryptedMessage&&!t.dataEncryptionKey)return void Cd.warn(`message.decrypt_failed ${Sd(e)} reason=missing_data_encryption_key`);if(!i&&e.encryptedMessage)return void Cd.warn(`message.decrypt_failed ${Sd(e)} reason=invalid_encrypted_payload`);if(!i)return void Cd.warn(`message.empty ${Sd(e)} reason=missing_message_payload`);e.channelReplyTarget&&"object"==typeof i&&(i.__channelReplyTarget=e.channelReplyTarget);const o={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&ae(i)&&(i=await Zc(i,{attachmentsDir:t.attachmentsDir})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(i,o))return void Cd.debug(`message.dropped ${Sd(e,i)} reason=should_not_persist`);if(!n.saveMessage({eventId:e.eventId,message:i,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return s(e.eventId),void Cd.debug(`message.duplicate ${Sd(e,i)} acked=true`);const r=Td(e,i,{source:"runtime"});r&&Cd.info(r);const c={...e,message:i,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:c,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),a?.("task-message",c),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(i,o),Cd.info(`message.accepted ${Sd(e,i)} persisted=true duplicate=false acked=true dispatched=${Boolean(t.onTaskMessage)}`)},"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,a;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;if(void 0!==e.opCode){const n=this.outbox.get(e.opCode),s=n?Date.now()-n.sentAt:void 0;this.outbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.(),n?.isResult?Cd.info([`outbound.result.acked eventId=${e.opCode}`,"number"==typeof t?`sequence=${t}`:"sequence=unknown",void 0!==s?`ackMs=${s}`:void 0].filter(Boolean).join(" ")):Cd.debug([`outbound.event.acked eventId=${e.opCode}`,n?.messageType?`messageType=${n.messageType}`:void 0,"number"==typeof t?`sequence=${t}`:void 0,void 0!==s?`ackMs=${s}`:void 0].filter(Boolean).join(" "))}void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(Promise.resolve(this.context.onReconnect?.()).catch(e=>{Cd.warn(`reconnect.handler_failed error=${e instanceof Error?e.message:String(e)}`)}),this.outbox.size>0){Cd.info(`reconnect.outbox_flush count=${this.outbox.size}`);for(const[e,t]of this.outbox.entries())t.usageReport&&this.client.send("task-usage-report",t.usageReport),this.outbox.set(e,{...t,sentAt:Date.now()}),this.client.send("task-message",t.payload)}}else this.hasConnectedOnce=!0})}}const Ed=Yt(Ct),$d="xmz-ai",Md="agentrix-hive",Rd="https://github.com/xmz-ai/agentrix-hive.git",Pd="github";class Dd{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=V();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,initPolicies:e.initPolicies};return this.taskDataKey?t.encryptedMessage=pe(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=pe(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,initPolicies:e.initPolicies};return this.taskDataKey?t.encryptedMessage=pe(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=$e.resolveRepoStoreCheckoutDir(Pd,$d,Md),t=$e.resolveRepoStoreLockPath(Pd,$d,Md),n=await $e.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await Wi(e)){if(!no(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await Yi(Rd,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await mo(e,"origin",uo(Rd));try{return await Ed("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 $e.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 He.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||xs.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 He.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 Nd(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=se(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 Od(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=se(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 Ud(){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()}}}const jd=Ne(import.meta.url);function Ld(e){return $t("agentrix_computer_use","Execute a concrete operation on the user's local computer through Agentrix Computer Use.\n\nUse this tool when the user asks you to operate local desktop apps, windows, documents, menus, dialogs, browsers, Finder, or other GUI surfaces on this machine. Provide the requested operation as a natural-language instruction. Do not decompose the task into low-level click coordinates; Agentrix Computer Use will operate the GUI through its configured desktop-control tools.\n\nThis tool can control the local computer. Call it only for explicit user-requested computer operation.",{instruction:wt.string().describe("Concrete natural-language desktop operation to perform, including the app/document/target and desired outcome."),expectedResult:wt.string().optional().describe("Optional concise success condition the computer-use sub-task should verify before returning."),title:wt.string().optional().describe('Optional title for the computer-use sub-task. Defaults to "Computer use".')},async t=>{try{const n=await async function(e,t){if(!e.instruction.trim())throw new Error("instruction is required.");const n=t.status??cc();if(!n.enabled||n.missing.length>0)throw new Error(function(e){const t=["Agentrix Computer Use execution bridge is not ready.","","Enablement: "+(e.enabled?`enabled by ${e.enabledBy}`:"disabled"),`Codex home checked: ${e.codexHome}`,""];return e.enabled||t.push("Enable it with one of:","- set AGENTRIX_COMPUTER_USE_ENABLED=true for the worker/daemon environment;","- set settings.json field agentrixComputerUse.enabled=true;",`- create marker file ${e.markerPath}.`,""),e.missing.length>0&&t.push("Missing configuration:",...e.missing.map(e=>`- ${e}`),""),t.push("Agentrix tries to configure Codex automatically after this bridge is enabled:","1. cua-driver mcp-config --client codex","2. link the Cua Driver SKILL.md pack into Codex when a valid local skill source can be discovered","If automatic configuration fails, run the official Cua Driver installer/update flow or set AGENTRIX_CUA_DRIVER_PATH / AGENTRIX_CUA_DRIVER_SKILL_SOURCE.","Grant macOS Accessibility and Screen Recording permissions to Cua Driver when prompted."),t.join("\n")}(n));const s=function(e){const t=e.expectedResult?.trim();return["You are the Agentrix Computer Use execution worker for the current Agentrix task.","","Use the configured Cua Driver skill and MCP tools in this Codex environment to operate the local computer. Do not implement or modify Agentrix code unless the desktop operation explicitly requires editing a file. Prefer Cua Driver app-control tools over shell commands for GUI work. If the request needs a permission grant or user login that you cannot complete, stop and explain exactly what the user must do.","","Desktop operation instruction:",e.instruction.trim(),"",t?`Expected result:\n${t}`:void 0,"","Return a concise report of what you did, what result you observed, and any blocker or follow-up required."].filter(e=>Boolean(e)).join("\n")}(e),a=e.title?.trim()||"Computer use",i=t.historyDb.getAgentSessions().get(Kr);if(i)return zr.info(`Emitting computer-use instruction to existing sub-task ${i} for task ${t.taskId}`),await t.sendMessage({taskId:i,target:"agent",message:{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}),{taskId:i,title:a,action:"emitted"};zr.info(`Starting computer-use sub-task for task ${t.taskId}`);const o=await t.startSubTask({agentId:"codex",message:{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:"new"},title:a,cwd:t.cwd,forceUserCwd:!0,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}});return t.historyDb.upsertAgentSession(Kr,o.taskId),{taskId:o.taskId,title:a,action:"created"}}({instruction:t.instruction,expectedResult:t.expectedResult,title:t.title},{taskId:e.taskId,cwd:e.workingDirectory,historyDb:e.historyDb,startSubTask:t=>e.agentContext.startSubTask(t),sendMessage:t=>e.agentContext.sendMessage(t)});return{content:[{type:"text",text:"created"===n.action?[`computer-use sub-task created: ${n.taskId}`,`Title: ${n.title}`,"","The computer operation is now running asynchronously in that sub-task. Use this same agentrix_computer_use tool again for follow-up instructions or corrections; it will route them to the same computer-use sub-task."].join("\n"):[`computer-use instruction sent to existing sub-task: ${n.taskId}`,"","The computer-use sub-task will continue from its existing context."].join("\n")}]}}catch(e){return{content:[{type:"text",text:e instanceof Error?e.message:String(e)}],isError:!0}}})}function qd({workClient:e}){return $t("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:wt.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function Hd(e){return $t("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:wt.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=te.parse({previewUrl:t}),s=await fetch(`${$e.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 Fd(e){return $t("send_vision_artifact","Send the issue vision artifacts (visual plan and test report) to the Agentrix platform so the user can review them.\n\nUse this after generating or materially updating the visual plan, and again after generating the visual test report. Pass only the repository root and issue id; Agentrix derives the current task routing from platform context.",{repoRoot:Dr.shape.repoRoot,issueId:Dr.shape.issueId},async t=>{const n=await Nr(t);if(!e.workClient.sendVisionPlanCard)throw new Error("Vision artifact publishing is not available in this worker");return await e.workClient.sendVisionPlanCard({issueId:n.issueId,repoRoot:t.repoRoot}),{content:[{type:"text",text:`Agentrix vision artifacts sent for issue ${n.issueId}.`}]}})}function Bd({agentContext:e}){return $t("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:wt.string().describe("Sub-task ID to send the message to"),instructions:wt.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:wt.array(wt.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async t=>{try{let n;return n=t.answers&&t.answers.length>0?{type:"ask_user_response",answers:t.answers}:{type:"user",message:{role:"user",content:t.instructions??""}},await e.sendMessage({taskId:t.taskId,message:n,target:"agent"}),{content:[{type:"text",text:`${t.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${t.taskId}.`}]}}catch(e){return jd.error(`Failed to send message to sub-task ${t.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Gd({historyDb:e}){return $t("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:wt.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:wt.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=Dl(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 Wd({agentContext:e}){return $t("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 zd({agentContext:e}){return $t("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 jd.error("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 Kd({agentContext:e,agentId:t,setPendingNavigateTaskId:n}){return $t("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:wt.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:wt.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:wt.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:wt.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:wt.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:wt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:wt.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:wt.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async s=>{try{if(s.autoNavigate&&!s.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const a=s.agentId||t;let i;return s.independent?(i=await e.startIndependentTask({agentId:a,message:{type:"user",message:{role:"user",content:s.instructions}},title:s.title,cwd:s.cwd,forceUserCwd:!s.useWorktree,autoNavigate:s.autoNavigate}),s.autoNavigate&&n(i.taskId),jd.info(`Created independent task ${i.taskId} for agent ${a} (autoNavigate: ${s.autoNavigate??!1})`)):(i=await e.startSubTask({agentId:a,message:{type:"user",message:{role:"user",content:s.instructions}},title:s.title,cwd:s.cwd,forceUserCwd:!s.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}}),jd.info(`Created sub-task ${i.taskId} for agent ${a}`)),{content:[{type:"text",text:`🚀 Task created: ${i.taskId}\n${s.agentId?`Agent: ${a}\n`:""}${s.independent?"Mode: Independent\n":""}Summary: ${s.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return jd.error("Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Vd({agentContext:e}){return $t("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:wt.string().min(1).max(200).describe("Task title"),instructions:wt.string().describe("Instructions for the owner agent"),briefSummary:wt.string().optional().describe("One-line summary shown to user immediately"),agentId:wt.string().describe("Target agent ID"),cwd:wt.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:wt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async t=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:t.agentId,message:{type:"user",message:{role:"user",content:t.instructions}},title:t.title,cwd:t.cwd,forceUserCwd:!t.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}})).taskId}\n${t.briefSummary?`Summary: ${t.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return jd.error("Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Xd({agentContext:e}){return $t("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:wt.string().min(1).max(200).describe("Task title"),requirement:wt.string().describe("Overall requirement"),briefSummary:wt.string().optional().describe("One-line summary shown to user immediately"),todos:wt.array(wt.object({agentId:wt.string().describe("Agent ID responsible for the todo"),title:wt.string().min(1).max(200).describe("Todo title"),instructions:wt.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async t=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:t.title,todos:t.todos,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"},message:{type:"user",message:{role:"user",content:t.requirement}}})).taskId}\n${t.briefSummary?`Summary: ${t.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return jd.error("Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Jd({askUser:e}){return $t("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:wt.array(wt.object({question:wt.string().describe("The complete question to ask the user"),header:wt.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:wt.boolean().describe("Set to true to allow multiple option selections"),options:wt.array(wt.object({label:wt.string().describe("Option label (1-5 words)"),description:wt.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 t=>{try{const n=t.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(n);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 jd.error("Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function Yd({invokeAgent:e}){return $t("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:wt.string().describe("Target agent ID"),hint:wt.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 Qd({workClient:e,agentId:t,uploadFile:n}){return $t("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:wt.string().optional().describe("Your display name"),avatarPath:wt.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:wt.string().optional().describe("Short status line or tagline shown under your name")},async s=>{let a;if(s.avatarPath)try{a=(await n({name:"avatar.png",path:s.avatarPath,visibility:"public"})).fileId}catch(e){return jd.error("Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:s.displayName,avatar:a,signature:s.signature});const i=[];return s.displayName&&i.push(`name → ${s.displayName}`),a&&i.push("avatar → uploaded"),s.signature&&i.push(`signature → ${s.signature}`),{content:[{type:"text",text:`Profile updated: ${i.join(", ")}`}]}})}function Zd({assign:e}){return $t("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:wt.string().describe("Target agent ID"),instruction:wt.string().describe("Task instruction for the agent"),acknowledgment:wt.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 ep({agentContext:e}){return $t("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:wt.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:wt.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async t=>{try{const n=await e.listTasks({limit:t.limit??10,status:t.status??"all"});return n.length?{content:[{type:"text",text:JSON.stringify(n,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return jd.error("Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function tp({chatHistoryDb:e}){return $t("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:wt.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:wt.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=Dl(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 np({agentContext:e}){return $t("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:wt.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:wt.string().optional().describe("Path to detailed analysis file in workspace, if any")},async t=>{try{const n=e.getChatId();return await e.sendMessage({taskId:n,message:{type:"companion_reminder",content:t.content,filePath:t.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return jd.error("Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}const sp=wt.enum(["created","updated","deleted"]);function ap({taskId:e}){return $t("record_memory_change","Append a structured JSONL record for an actual Companion memory change.\nUse this from Companion chat, heartbeat shadow, or memory-organization shadow after memory files were really created, updated, deleted, merged, compressed, or cleaned.\nDo not call this tool when the memory review found nothing to change.\nAfter recording an actual change, use send_reminder separately if the main Companion should be awakened.",{title:wt.string().optional().describe("Deprecated compatibility field; each change.summary is used for the JSONL record and semantic git commit title."),trigger:wt.enum(["scheduled","user_request"]).describe("What triggered this memory change."),source:wt.string().optional().describe("Where the changed memory fact came from, such as user correction, recent conversation, task history, reminder, existing memory consolidation, or verified project evidence. This is the memory evidence source, not the Companion execution path."),notifiedCompanion:wt.boolean().describe("Whether a reminder has already been sent or will be sent immediately after this record."),changes:wt.array(wt.object({file:wt.string().describe("Current primary self-evolution file path, relative to Companion claude home, such as memory/agentrix-companion-memory/memory.md or MEMORY.md. Legacy memory/-relative paths are accepted and normalized."),action:sp,summary:wt.string().describe("One-sentence summary of what changed."),reasons:wt.array(wt.string()).min(1).describe("Short reasons for this change."),deletedFiles:wt.array(wt.string()).optional().describe("Optional old allowlisted files removed while consolidating into file.")})).min(1).describe("One or more concrete file-bound memory changes for this topic.")},async t=>{try{const n=process.env.AGENTRIX_COMPANION_HOME;if(!n)throw new Error("AGENTRIX_COMPANION_HOME is not set; memory changes can only be recorded by Companion workers.");const s=new Date,a=s.toISOString().slice(0,10),i=E(n,"memory-changes"),o=E(i,`${a}.jsonl`),r=t.changes.map(e=>({file:Ii(n,e.file).relativePath,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles?.map(e=>Ii(n,e).relativePath)??[]}));await Si({companionHome:n});const c=new Map;for(const e of r){const t=c.get(e.file);t?t.push(e):c.set(e.file,[e])}const l=[];for(const a of c.values()){const i=a[0],o=Array.from(new Set(a.flatMap(e=>e.deletedFiles))),r=await Ai({companionHome:n,title:i.summary,body:Ci({trigger:t.trigger,source:t.source,action:i.action,file:i.file,reasons:a.flatMap(e=>e.reasons),deletedFiles:o,notifiedCompanion:t.notifiedCompanion,taskId:e}),paths:[i.file,...o]});if(r)for(const n of a)l.push(JSON.stringify({time:s.toISOString(),trigger:t.trigger,source:t.source,taskId:e,file:n.file,action:n.action,summary:n.summary,reasons:n.reasons,deletedFiles:n.deletedFiles,notifiedCompanion:t.notifiedCompanion,commit:r}));else jd.warn(`Skipping memory change JSONL record because no semantic git commit was created: file=${i.file}`)}return l.length>0&&(await Cn(i,{recursive:!0}),await An(o,`${l.join("\n")}\n`,"utf-8")),jd.info(`Memory changes recorded: path=${o}, source=${t.source??"unspecified"}, trigger=${t.trigger}, records=${l.length}, requestedChanges=${r.length}, taskId=${e}`),{content:[{type:"text",text:l.length>0?`Memory changes recorded: ${l.length} JSONL record(s) at ${o}`:"No memory change JSONL records were written because no semantic git commit was created."}]}}catch(e){return jd.error("Failed to record memory change:",e),{content:[{type:"text",text:`Failed to record memory change: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ip({uploadFile:e}){return $t("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:wt.string().describe("Absolute path to the local file to upload"),name:wt.string().optional().describe("Display name for the file (defaults to filename)")},async n=>{try{const s=t("path"),a=n.name||s.basename(n.filePath);return{content:[{type:"text",text:(await e({name:a,path:n.filePath,visibility:"public"})).url}]}}catch(e){return jd.error("File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const op=2147483648,rp=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function cp({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a}){return $t("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:wt.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:wt.array(wt.object({filePath:wt.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:wt.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:wt.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 i=>{const o=s?.()??null;if(!o)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=i.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await dp(n));return t}(i.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const r=await Bn(e,{content:s||void 0,attachments:a.length>0?a:void 0},o);return r?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:o.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:r.error}}),{content:[{type:"text",text:`Failed to send channel message: ${r.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:o.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 jd.warn("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 lp({taskId:e,getChannelReplyTarget:t}){return $t("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:wt.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:wt.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:wt.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 Ln("/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 dp(e){if(!O(e.filePath))throw new Error("filePath must be absolute");const t=await _n(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>op)throw new Error(`file is too large for channel delivery (${t.size} bytes; max 2147483648 bytes)`);const n=e.fileName||$(e.filePath),s=$(e.filePath);if(rp.test(s)||rp.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=xs.lookup(n)||xs.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 pp({agentContext:e}){return $t("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 jd.error("Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*up(e){yield e}function mp({visionModel:e}){return $t("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:wt.string().describe("Absolute path to the image file to analyze"),prompt:wt.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async t=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const n=(await Tn(t.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[t.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=t.prompt||"Describe this image in detail.",i=Et({prompt:up({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:n}},{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 jd.error("Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function hp({agentContext:e}){return $t("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 jd.error("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 gp({agentContext:e}){return $t("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:wt.enum(["agent","skill"]),draftAgentId:wt.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:wt.string().optional().describe("Absolute local skill directory for skill publishing"),name:wt.string().optional().describe("Listing name, lowercase kebab-case"),displayName:wt.string().optional().describe("Human-readable listing name"),description:wt.string().optional(),readme:wt.string().optional(),category:wt.string().optional(),tags:wt.array(wt.string()).optional(),authorType:wt.enum(["user","agent"]).default("user"),authorId:wt.string(),machineId:wt.string().optional(),cloudId:wt.string().optional()},async t=>{try{const n=await e.publishToHive(t);return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return jd.error("Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function fp({agentContext:e}){return $t("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:wt.string().describe("Owned HiveListing ID to update"),version:wt.string().optional().describe("Optional new version; defaults to next patch version"),changelog:wt.string().optional(),sourceDir:wt.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:wt.string().optional(),cloudId:wt.string().optional()},async t=>{try{const{listingId:n,...s}=t,a=await e.updateHiveListingVersion(n,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return jd.error("Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function yp({agentContext:e}){return $t("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:wt.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:wt.string().describe("Absolute local directory where the agent or skill was installed"),name:wt.string().optional().describe("Optional local name for installed agent"),machineId:wt.string().optional(),cloudId:wt.string().optional(),installedVersion:wt.string().optional()},async t=>{try{const{listingId:n,...s}=t,a=await e.recordHiveInstall(n,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return jd.error("Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function vp({agentContext:e}){return $t("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:wt.string().describe("HiveListing ID"),rating:wt.number().int().min(1).max(5),comment:wt.string().optional().describe("Markdown review text")},async t=>{try{const n=await e.createHiveReview(t.listingId,{rating:t.rating,comment:t.comment??null});return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return jd.error("Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function wp({agentContext:e}){return $t("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:wt.string().describe("HiveListing ID"),content:wt.string().min(1).describe("Markdown comment content"),parentId:wt.string().optional().describe("Parent comment ID for replies")},async t=>{try{const n=await e.createHiveComment(t.listingId,{content:t.content,parentId:t.parentId});return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return jd.error("Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function bp(e){if(e)return e.replace(/\/+$/g,"")||"/"}function kp(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,headRef:e.headRef,headSha:e.headSha,checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,branchName:e.branchName,branchBinding:e.branchBinding,cwd:bp(e.cwd)||"",userCwd:bp(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,initPolicies:e.initPolicies,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,workspaceId:e.workspaceId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function xp(e){return!!e.branchName&&"none"!==e.branchBinding&&"external-observed"!==e.branchBinding}function Ip(e,t,n){return t||(n?.trim()?`agentrix/${function(e){return e.replace(/^[a-z]+(?:\([^)]+\))?!?:\s*/i,"").normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/['’]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48).replace(/-+$/g,"")||"task"}(n)}-${function(e){return e.replace(/^task-/,"").replace(/[^a-zA-Z0-9]/g,"").toLowerCase().slice(0,8)||"task"}(e)}`:`agentrix/${e}`)}async function Sp(e,t){const n=Qt(e);await n.raw(["checkout","-B",t,"HEAD"])}function Tp(e){return`HEAD:refs/heads/${e}`}function Cp(e,t){return`Cannot create PR: current branch is ${e}, but this task is bound to ${t}. Switch to ${t} or choose Keep during branch mismatch handling before creating the PR.`}async function Ap(e){if(!e)return null;const t=await zo();return t?Yo(e,t):null}async function _p(e,t){const n=Jo(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 Bi("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await Bi("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 Ep(e,t,n){const s=await Ap(n);s?await async function(e,t){const n=bo();try{await Bi("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:ko(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await Bi("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,env:xo(),windowsHide:!0})}(t,e)}function $p(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.")}function Mp(...e){return e.find(e=>"string"==typeof e&&e.trim().length>0)?.trim()}function Rp(e,t){const n=Mp(e.checkoutSha,e.headSha);if(n)return n;const s=Mp(e.checkoutRef,e.headRef,e.baseBranch);if(!s)throw new Error("Cannot create worktree: no checkout ref, checkout SHA, or base branch was provided.");const a=function(e){return e.trim().replace(/^refs\/heads\//,"").replace(/^origin\//,"")}(s);return t.includes(a)?`origin/${a}`:s}async function Pp(e,t,n){const s=Qt(e);try{await s.raw(["rev-parse","--verify","--quiet",`${t}^{commit}`])}catch{const e=[n.checkoutSha?`checkoutSha=${n.checkoutSha}`:void 0,n.headSha?`headSha=${n.headSha}`:void 0,n.checkoutRef?`checkoutRef=${n.checkoutRef}`:void 0,n.headRef?`headRef=${n.headRef}`:void 0,n.baseBranch?`baseBranch=${n.baseBranch}`:void 0].filter(Boolean).join(", ");throw new Error(`Cannot create worktree: checkout start point ${t} does not exist after fetch${e?` (${e})`:""}.`)}}async function Dp(e,t,n,s,a,i,o={}){const c=uo(t),l=await Wi(e);if(!no(e)&&!l)throw new Error(`Directory ${e} exists but is not a git repository`);const p=await Ap(a);if(no(e)){p?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=D(n);r(s)||d(s,{recursive:!0});const a=bo();try{await Bi("git",["-c","credential.helper=","clone",t,n],{env:ko(a,e),windowsHide:!0})}finally{f(a)}}(p,c,e),a&&await _p(e,a)):await Yi(t,e),await po(e,"origin",c),await Ep(e,t,a),a&&await _p(e,a);const n=await ho(e),l=$p(n,s),u=Rp({...o,baseBranch:l},n);return await Pp(e,u,{...o,baseBranch:l}),i?await Qi(e,i,u):await Qt(e).raw(["checkout","--detach",u]),await eo(e)}if(await mo(e,"origin",c),await Ep(e,t,a),a&&await _p(e,a),i){const t=await ho(e),n=$p(t,s),a=Rp({...o,baseBranch:n},t);await Pp(e,a,{...o,baseBranch:n}),await Qi(e,i,a)}return await eo(e)}async function Np(e,t,n,s={}){const a=await Ap(s.gitServerId);a?await async function(e,t,n,s=!1){const a=bo();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await Bi("git",i,{cwd:t,env:ko(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 Bi("git",a,{cwd:t,env:xo(),windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=Gi(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function Op(e,t,n){const s=n.trim();if(!s)return;const a=$e.resolveDataDir(e,t),i=E(a,"patch.diff");return await qt(a,{recursive:!0}),await Ft(i,`${s}\n`),i}async function Up(e,t,n){await $e.writeLastSentArtifactVersion(e,t,n)}function jp(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 Lp(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:yn()}}function qp(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:yn()}}function Hp(e){const t="```sh\n",n="\n```";return`${t}${kd(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function Fp(e,t,n,s=6e4){return new Promise(a=>{const i=mt("/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,d;if(o&&clearTimeout(o),r){i=124,d=!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,d=0!==i,l=c;const p=Hp(l);n.onOutput(qp(p)),n.onOutput(Lp(p,i,d)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=Hp(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(qp(t)),n.onOutput(Lp(t,1,!0)),n.onComplete(1),a(1)})})}const Bp=Ne(import.meta.url);class Gp{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="idle";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 Bp.warn("Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void Bp.warn("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),Bp.debug(`message.enqueued id=${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();Bp.debug(`message.processing id=${e.id} type=${e.type}`),await this.processMessage(e),Bp.debug(`message.dispatched id=${e.id} type=${e.type}`)}catch(e){Bp.error(`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:Bp.warn(`Unknown message type: ${e.type}`)}}async processNormalMessage(e){Bp.debug("message.dispatching_to_agent_queue type=normal");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){Bp.info(`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){Bp.info("Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){Bp.info("Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){Bp.info("Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processAgentrixDevInit(e){Bp.info("Processing agentrix-dev-init command"),await this.processCommand(async()=>{await(this.config.handlers.onAgentrixDevInit?.(e.originalMessage))},e)}async processPlanMode(e){Bp.info("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");Bp.debug("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.workerState=e,Bp.info(`worker.state.changed from=${t} to=${e} activeAgents=${this.agentRunningMap.size} backgroundTasks=${this.backgroundTaskMap.size+this.anonymousBackgroundTaskCount}`),"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,Bp.debug(`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,Bp.debug(`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,Bp.debug(`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)Bp.warn("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||(Bp.info(`worker.idle_timer.started timeoutMs=${this.idleTimeoutMs}`),this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(Bp.info(`worker.stop.requested reason=idle_timeout source=coordinator timeoutMs=${this.idleTimeoutMs}`),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.isStopped?Bp.debug("coordinator.stop.ignored alreadyStopped=true"):(Bp.info("coordinator.stop requested=true"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait())}}function Wp(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(Ad,n)}async function zp(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 lo(t),s=await Zi(t),d=await async function(e,t){const n=Gi(e);try{return(await n.log([`origin/${t}..HEAD`])).total>0}catch{return!0}}(t,e);if(s||d){if(!r)throw new Error("merge-pr requires user input to resolve git state, which is not supported in oneshot execution mode");const p=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,d,c,o);if("Pause"===p)return void Wp(n,"Operation paused. Please handle git state and run merge again.");if(("Push"===p||"PushAndMerge"===p)&&(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 Np(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===p))return void Wp(n,"✅ All changes pushed to remote. You can now review and run merge again if everything looks good.")}const p=await n.sendMergePr();if(p.success)Wp(n,`✅ PR merged successfully! Branch ${e} has been merged into the target branch.`);else{let e;switch(p.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: ${p.error||"Unknown error"}`;break;default:e=`Failed to merge PR: ${p.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.")}async function Kp(e,t,n){let s=!1;const a=e.updates??{};if(Object.prototype.hasOwnProperty.call(a,"model")){const e=a.model,n="string"==typeof e&&e.trim().length>0?e.trim():null===e?void 0:t.model;t.model!==n&&(n?t.model=n:delete t.model,s=!0)}const i={},o=a.repositoryId;"string"==typeof o&&o.length>0&&t.repositoryId!==o&&(t.repositoryId=o,i.taskRepositoryId=o,s=!0);const r=a.branchName;"string"==typeof r&&r.length>0&&t.branchName!==r&&(t.branchName=r,i.branchName=r,s=!0);const c=a.branchBinding;return"none"!==c&&"explicit"!==c&&"platform-managed"!==c&&"external-observed"!==c||t.branchBinding===c||(t.branchBinding=c,i.branchBinding=c,s=!0),Object.keys(i).length>0&&n&&await n.updateTaskMetadata(i),s}function Vp(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 Xp(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:Ie(),session_id:e.sessionId}}function Jp(e,t){const n=Ie();return t.set(e,n),n}function Yp(e,t){return t.get(e)||e}function Qp(e,t,n={}){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"error"===e.type?Zp(e.message):"event_msg"===e.type?function(e){const t=e.payload??e.msg;if(!t)return null;switch(t.type){case"thread_goal_updated":return function(e){if(!e)return null;const t=[`Codex goal update: ${e.status??"unknown"}`];if(e.objective?.trim()&&t.push(`Objective: ${e.objective.trim()}`),"number"==typeof e.tokensUsed){const n="number"==typeof e.tokenBudget?` / ${e.tokenBudget}`:"";t.push(`Tokens used: ${e.tokensUsed}${n}`)}return"number"==typeof e.timeUsedSeconds&&t.push(`Time used: ${e.timeUsedSeconds}s`),Zp(t.join("\n"))}(t.goal);case"thread_goal_cleared":return Zp("Codex goal cleared");default:return null}}(e):"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:Jp(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:Jp(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:Jp(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:Jp(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"collab_tool_call":return function(e,t){return eu(e,Jp(e.id,t))}(e,t);default:return null}}(e.item,t):"item.updated"===e.type?function(e){switch(e.type){case"collab_tool_call":return function(e){return{type:"system",subtype:"temporary",content:nu(e,"Subagent update")}}(e);case"todo_list":return ou(e);default:return null}}(e.item):"item.completed"===e.type?function(e,t,n){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:Ie().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:Yp(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??Jp(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,n){const s=Yp(e.id,t),a="failed"===e.status&&e.error,i=a?e.error.message:function(e,t){const n=e.result?.content||"";if(!t.taskDataDir||"get_window_state"!==(s=e.tool)&&"screenshot"!==s&&!s.endsWith("__get_window_state")&&!s.endsWith("__screenshot"))return n;var s;if(!Array.isArray(n)){const s=su(n,t.taskDataDir);if(s!==n)return[s];const a=au(e,t.taskDataDir);return a?[n,a]:n}const a=n.map(e=>su(e,t.taskDataDir)),i=au(e,t.taskDataDir);return i?[...a,i]:a}(e,n);return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:s,is_error:a,content:i}]},parent_tool_use_id:null,session_id:""}}(e,t,n);case"web_search":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:Yp(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"collab_tool_call":return function(e,t){const n=t.get(e.id),s=n??Jp(e.id,t),a=!n,i={type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:s,is_error:"failed"===e.status,content:nu(e,"Subagent action completed")}]},parent_tool_use_id:null,session_id:""};return a?[eu(e,s),i]:i}(e,t);case"todo_list":return ou(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,n):null}function Zp(e){return{type:"system",subtype:"temporary",content:e}}function eu(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:t,name:"Subagent",input:{action:e.tool,sender_thread_id:e.sender_thread_id,receiver_thread_ids:e.receiver_thread_ids,prompt:e.prompt??void 0,agents:tu(e)}}]},parent_tool_use_id:null,session_id:""}}function tu(e){const t=e.agents_states;return t&&Object.keys(t).length>0?t:void 0}function nu(e,t){const n=[`${t}: ${e.tool} (${e.status})`,`Sender: ${e.sender_thread_id}`];e.receiver_thread_ids.length>0&&n.push(`Receivers: ${e.receiver_thread_ids.join(", ")}`),e.prompt?.trim()&&n.push(`Prompt: ${e.prompt.trim()}`);const s=Object.entries(e.agents_states??{}).map(([e,t])=>{const n=t.message?.trim();return n?`- ${e}: ${t.status} - ${n}`:`- ${e}: ${t.status}`});return s.length>0&&n.push("Agents:",...s),n.join("\n")}function su(e,t){const n=function(e){if("object"!=typeof e||null===e)return null;const t=e,n=t.data,s=n&&"object"==typeof n?n:void 0,a="string"==typeof t.mimeType?t.mimeType:"string"==typeof t.mime_type?t.mime_type:"string"==typeof s?.mimeType?s.mimeType:"string"==typeof s?.mime_type?s.mime_type:"image/png";if(!a.startsWith("image/"))return null;const i="string"==typeof t.base64String?t.base64String:"string"==typeof t.base64_string?t.base64_string:"string"==typeof s?.base64String?s.base64String:"string"==typeof s?.base64_string?s.base64_string:"string"==typeof n?n:void 0;return i?{base64:iu(i),mimeType:a}:null}(e);if(!n)return e;try{const e=E(t,"attachments");d(e,{recursive:!0});const s=function(e){switch(e.toLowerCase()){case"image/jpeg":case"image/jpg":return".jpg";case"image/webp":return".webp";case"image/gif":return".gif";default:return".png"}}(n.mimeType),a=E(e,`${Ie()}${s}`);return u(a,Buffer.from(n.base64,"base64")),{type:"text",text:`Image file: ${a}\nType: ${n.mimeType}`}}catch(e){return{type:"text",text:`[Image unavailable: failed to save tool result image: ${e instanceof Error?e.message:String(e)}]`}}}function au(e,t){const n=function(e){const t=e.arguments,n=t?.screenshot_out_file;return"string"==typeof n&&n.trim()?n.trim():null}(e);if(!n||!r(n))return null;try{const e=E(t,"attachments");d(e,{recursive:!0});const s=function(e){const t=M(e).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(t)?".jpeg"===t?".jpg":t:".png"}(n),a=function(e){switch(e.toLowerCase()){case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";default:return"image/png"}}(s),i=E(e,`${Ie()}${s}`);return T(n,i),{type:"text",text:`Image file: ${i}\nType: ${a}`}}catch(e){return{type:"text",text:`[Image unavailable: failed to copy screenshot_out_file: ${e instanceof Error?e.message:String(e)}]`}}}function iu(e){const t=e.match(/^data:[^;]+;base64,(.*)$/s);return t?t[1]:e}function ou(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:""}}let ru,cu,lu;function du(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 pu(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 uu(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||E(n.homedir(),".codex");return E(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(cu===e&&void 0!==ru)return ru;if(cu=e,ru=null,!r(e))return ru;let t;try{t=c(e,"utf8")}catch{return ru}for(const e of t.split(/\r?\n/)){const t=du(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=pu(n[1])?.trim();return ru=s||null,ru}return ru}()}class mu{createCodex(e){const t={},n=function(){if(void 0!==lu)return lu??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return lu=e,e;lu=null}();n&&(t.codexPathOverride=n),e.env&&(t.env=ni(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(Ha(`\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 Ha(`\n ## Task Preview URL Protocol:\n - Important: when a browser-viewable frontend preview URL is available, publishing it is required, not optional.\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})),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.sendVisionArtifactToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(function(e){return Ha(`\n ## Agentrix Vision Artifact Protocol:\n - After you create or materially update the visual plan (\`plan/index.html\`), and again after you create or update the visual test report (\`test/index.html\`), send the issue vision artifacts to the platform for review using the Agentrix event broker MCP tool: server "${e.serverName}", tool "${e.toolName}".\n - Pass only the repository root and issue id. The platform presents the available plan and test artifacts together.\n - Do not start the local Vision engine just to use this tool.\n - If this tool is unavailable, share the local artifact paths with the user and ask them to review.\n `)}({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.sendVisionArtifactToolName}));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 En(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=uu(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=Date.now(),c=await o.run("string"==typeof e?e:ii(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0}),l=Date.now()-r;return oi({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:c.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:c.finalResponse??"",structuredOutput:ri(c.finalResponse??"",Boolean(t.structuredOutputSchema)),durationMs:l})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=uu(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=Date.now(),{events:c}=await o.runStreamed("string"==typeof e?e:ii(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let l=t.agentSessionId||"",d="",p={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const u=new Map,m={get:e=>u.get(e),set:(e,t)=>{u.set(e,t)}};for await(const e of c){if("thread.started"===e.type&&(l=e.thread_id,yield Xp({sessionId:l,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);"item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(d=e.item.text);const n=e,s=n.type;if("error"===s||"event_msg"===s||"item.started"===s||"item.updated"===s||"item.completed"===s){const e=Qp(n,m,{taskDataDir:t.taskDataDir});if(!e)continue;const s=Array.isArray(e)?e:[e];for(const e of s)yield e}}const h=oi({sessionId:l,model:a??"unknown",numTurns:1,usage:p,result:d,structuredOutput:ri(d,Boolean(t.structuredOutputSchema)),durationMs:Date.now()-r});yield h}loop(e){const t=e.abortController,n=this.createCodex(e),s={workingDirectory:e.cwd,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let a=e.model;const i=()=>uu(e.getModel?e.getModel():a)??void 0;let o=i(),r=e.agentSessionId?n.resumeThread(e.agentSessionId,{...s,model:o??void 0}):n.startThread({...s,model:o??void 0}),c=!1;const l=[];let d=null,p=e.agentSessionId??null,u=0;const m=()=>{if(!c&&(c=!0,d)){const e=d;d=null,e(null)}},h=e=>"string"==typeof e?e:ii(e),g=async function*(){try{for(;!c&&!t.signal.aborted;){const a=l.length>0?l.shift():await new Promise(e=>{d=e});if(!a)break;let m="";const g=i();g!==o&&(o=g),p&&(r=n.resumeThread(p,{...s,model:o??void 0}));const f=new Map,y={get:e=>f.get(e),set:(e,t)=>{f.set(e,t)}},v=Date.now(),{events:w}=await r.runStreamed(h(a),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of w){if(c)break;if("thread.started"===t.type){p=t.thread_id,yield Xp({sessionId:p,cwd:e.cwd,model:o??void 0});continue}if("turn.completed"===t.type){p&&(yield oi({sessionId:p,model:o??"unknown",numTurns:u+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:m,structuredOutput:ri(m,Boolean(e.structuredOutputSchema)),durationMs:Date.now()-v}));break}if("turn.failed"===t.type)throw new Error(t.error.message);const n=t,s=n.type;if("error"===s||"event_msg"===s||"item.started"===s||"item.updated"===s||"item.completed"===s){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(m=t.item.text);const s=Qp(n,y,{taskDataDir:e.taskDataDir});if(!s)continue;const a=Array.isArray(s)?s:[s];for(const e of a)yield e}}u+=1}}finally{m()}}();return t.signal.addEventListener("abort",m,{once:!0}),{push:e=>{if(!c){if(d){const t=d;return d=null,void t(e)}l.push(e)}},events:g,stop:m,setModel:async e=>{a=e,o=uu(e)??void 0}}}}const hu=new Function("specifier","return import(specifier)");function gu(e){return hu(e)}const fu=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification"];function yu(e){const t={};for(const n of fu){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}const vu=Ne(import.meta.url);class wu{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}=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{ji.info(`Loading agent: ${t}`);const e=await Pt({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return ji.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 s=e.claude,a=s.plugins.map(e=>({type:"local",path:e})),i=n||Dt().resolveAgentDir(t),o=s.config.sdkMcpTools?.map(e=>E(i,"claude",e)),r={customSystemPrompt:s.systemPrompt,customModel:s.config.model,customFallbackModel:s.config.fallbackModel,customMaxTurns:s.config.maxTurns,customExtraArgs:s.config.extraArgs,customPermissionMode:s.config.settings?.permissionMode,customPlugins:a,systemPromptMode:s.config.systemPrompt?.mode??"append",customPRPromptTemplate:s.prPromptTemplate,prPromptMode:s.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:o};return ji.info(`Agent ${t} loaded successfully (${a.length} plugins)`),r}catch{return ji.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});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=me(),a=t||s.resolveAgentDir(e),i=E(a,"claude");return await async function(e,t){const n=st(e,"hooks");if(!Be(n))return{};const s=[st(n,"dist","index.mjs"),st(n,"dist","index.js"),st(n,"index.mjs"),st(n,"index.js")];let a=null;for(const e of s)if(Be(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] ${st(n,"index.js")} or ${st(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${nn(a).href}?t=${Date.now()}`,n=await gu(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),yu(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return yu(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){const n={};for(const s of e)try{vu.info(`Loading SDK MCP tools from: ${s}`);const e=await gu(s),a=e.default||e;if(!a){vu.warn(`No default export found in ${s}`);continue}const i="function"==typeof a?a(t):a,o=i.name;n[o]=i,vu.info(`Loaded MCP server: ${o}`)}catch(e){const t=e instanceof Error?e.message:String(e);vu.error(`Failed to load SDK MCP tools from ${s}: ${t}`)}return n}(s.customSdkMcpTools,n.context)),a=new Ui(t,e,s,i,o)}else a=new mu;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class bu{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=tt.join(this.workingDirectory,e);return He.existsSync(t)?He.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=tt.join(this.workingDirectory,e);return He.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=He.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?ge.includes(o.name)||this.listFilesRecursively(tt.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class ku{constructor(e){this.params=e}state=null;persistedState=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=$e.getWorkspaceState(n,s),o=e.repositorySourceType,r="string"==typeof e.branchName&&e.branchName.length>0,c="string"==typeof i?.branchName&&i.branchName.length>0,l={...e,repositorySourceType:o,taskRepositoryId:e.taskRepositoryId??i?.taskRepositoryId,headRef:e.headRef??i?.headRef,headSha:e.headSha??i?.headSha,checkoutRef:e.checkoutRef??i?.checkoutRef,checkoutSha:e.checkoutSha??i?.checkoutSha,branchName:r?e.branchName:c?i.branchName:e.branchName,branchBinding:r?e.branchBinding:c?i.branchBinding:e.branchBinding},{initialCommitHash:d,isGitRepository:p,setupAction:u,useWorktree:m,initPolicyUpdates:h}=await this.ensureWorkspace(l,t,i),g={initialized:!0,initializedAt:(new Date).toISOString(),cwd:a,repositorySourceType:l.repositorySourceType,useWorktree:m,userCwd:e.userCwd,forceUserCwd:e.forceUserCwd,gitUrl:e.gitUrl,baseBranch:e.baseBranch,headRef:e.headRef??i?.headRef,headSha:e.headSha??i?.headSha,checkoutRef:e.checkoutRef??i?.checkoutRef,checkoutSha:e.checkoutSha??i?.checkoutSha,branchName:l.branchName,branchBinding:l.branchBinding,taskRepositoryId:l.taskRepositoryId,initialCommitHash:d,initPolicies:{...i?.initPolicies,...e.initPolicies,...h}};await $e.writeWorkspaceState(n,s,g),this.persistedState=g;const f=await async function(e,t,n,s){return async function(e,t,n,s){if(!await Wi(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await Zi(e),i=await eo(e),o=s||$e.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await co(e,o),c=r?await Op(t,n,r.patch):void 0,l=await $e.readLastSentArtifactVersion(t,n),d=!!r&&r.artifactVersion!==l;return{currentCommitHash:i,currentArtifactVersion:r?.artifactVersion,hadUncommittedChanges:a,hasNewArtifacts:d,lastSentArtifactVersion:l??void 0,patchPath:c,diffStats:r?.stats}}(e,t,n,s)}(a,n,s,d);return this.state={cwd:a,initialCommitHash:d,isGitRepository:p,setupAction:u,gitStateResult:f,taskRepositoryId:g.taskRepositoryId,branchName:g.branchName,branchBinding:g.branchBinding},p&&!e.taskRepositoryId&&await async function(e,t){try{const n=await fo(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 updateBranchBinding(e,t){await this.updateTaskMetadata({branchName:e,branchBinding:t})}async updateTaskMetadata(e){if(!this.state||!this.persistedState)throw new Error("[WORKSPACE] Workspace not initialized");const{userId:t,taskId:n}=this.params.options,s={...this.persistedState};"taskRepositoryId"in e&&(s.taskRepositoryId=e.taskRepositoryId),"branchName"in e&&(s.branchName=e.branchName),"branchBinding"in e&&(s.branchBinding=e.branchBinding),this.persistedState=s,await $e.writeWorkspaceState(t,n,s);const a={...this.state};"taskRepositoryId"in e&&(a.taskRepositoryId=e.taskRepositoryId),"branchName"in e&&(a.branchName=e.branchName),"branchBinding"in e&&(a.branchBinding=e.branchBinding),this.state=a}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 co(t,n);if(!o)return{};try{await Op(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new bu(e);return he(t)}(t),c=await $e.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,gitServerId:c}=e;if(!a)throw new Error("[WORKSPACE] gitUrl is required for git-server mode");const l=xp(e)?e.branchName:void 0,d=e.forceUserCwd||!1===e.useWorktree,p="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await Wi(s),m=no(s);if(d)return this.ensureDirectGitServerWorkspace(e,t,n,u,m);if(Boolean(e.taskRepositoryId&&c)&&(!u||p)){const i=await async function(e,t,n,s,a,i,o={}){const c=bp(e)||e,l=uo(n),d=go(l);if(!d)throw new Error(`Unable to resolve repository owner/name from git URL: ${l}`);const p=$e.resolveRepoStoreCheckoutDir(s,d.owner,d.repo),u=$e.resolveRepoStoreLockPath(s,d.owner,d.repo),m=await $e.acquireFileLock(u);if(!m)throw new Error(`Timed out waiting for repo store lock at ${u}`);try{const e=await async function(e,t,n,s){const a=uo(t);if(!await Wi(e)){if(!no(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await Xi(e)}await mo(e,"origin",a),await Ep(e,t,n);const i=await ho(e),o=$p(i,s);return await async function(e,t,n){await Bi("git",["checkout","--force","-B",t,n],{cwd:e,windowsHide:!0}),await Bi("git",["reset","--hard",n],{cwd:e,windowsHide:!0}),await Bi("git",["clean","-fd"],{cwd:e,windowsHide:!0})}(e,o,`origin/${o}`),{baseBranch:o,remoteBranches:i}}(p,n,s,a),t={...o,baseBranch:e.baseBranch},l=Rp(t,e.remoteBranches);await Pp(p,l,t);const d=i,u=await zi(p);if(u.find(e=>bp(e.path)===c))return s&&await _p(c,s),{initialCommitHash:await eo(c)};const m=d?u.find(e=>e.branch===d&&bp(e.path)!==c):void 0;if(d&&m)throw new Error(`Branch ${d} is already attached to worktree ${m.path}. Remove it before retrying.`);const h=Qt(p),g=await h.branchLocal(),f=!!d&&g.all.includes(d);if(r(c)&&!no(c))throw new Error(`Worktree directory already exists at ${c}. This may be from a previous task. To clean up: git worktree remove ${c} OR rm -rf ${c}`);try{d?f?await h.raw(["worktree","add",c,d]):await Ki(p,c,d,l):await h.raw(["worktree","add","--detach",c,l])}catch(e){try{await Vi(p,c,!0)}catch{}throw e}return await _p(c,s),{initialCommitHash:await eo(c)}}finally{await $e.releaseFileLock(u,m)}}(s,0,a,c,o,l,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha});return u?{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}:{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,i.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 t=await Dp(s,a,0,o,c,l,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha})||await eo(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await po(s,"origin",uo(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,gitServerId:l}=e;if(!o)throw new Error("[WORKSPACE] gitUrl is required for git-server direct directory mode");const d=xp(e)?e.branchName:void 0;if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const t=await Dp(i,o,0,c,l,d,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha})||await eo(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"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=go(uo(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${uo(t)}`);const s=await fo(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 Wi(s))return this.tryResolveDirtyRepo(e,t,n);if(!no(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(no(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await Wi(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await to(t)||await Ji(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=bp(t)||t;if(!await Wi(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await to(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=s;if((await zi(i)).find(e=>bp(e.path)===o))return{initialCommitHash:await eo(o)};const l=Qt(i),d=await l.branchLocal(),p=!!c&&d.all.includes(c);if(r(o)&&!no(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{c?p?await l.raw(["worktree","add",o,c]):await Ki(i,o,c,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await Vi(i,o,!0)}catch{}throw e}return{initialCommitHash:await eo(o)}}(t,s,0,xp(e)?e.branchName:void 0)}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}}async ensureTemporaryWorkspace(e,t,n){const{cwd:s}=e;if(!await Wi(s)){await async function(e){return{initialCommitHash:await async function(e){return await Xi(e),await Ji(e),await eo(e)}(e)}}(s),xp(e)&&e.branchName&&await Qi(s,e.branchName,e.baseBranch);const t=await eo(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"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 Wi(e)&&await Zi(e)}(e.cwd)){const s=this.getPersistedInitPolicy(n,e,"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}:$e.shouldPromptOnUncommittedChanges()&&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=Gi(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;await to(e.cwd)||await Ji(e.cwd),r=xp(e)?"Ignore"===a?await lo(e.cwd)===e.branchName?"none":"kept":await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch"):"none";const c=await eo(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,s){const a=e?.initPolicies?.[n]??t.initPolicies?.[n];return a&&s.includes(a)?a:null}resolveInitialCommitHash(e,t,n){return e?"kept"===n?t:e:t}async tryResolveBranchMismatch(e,t,n,s,a){if(!xp(e)||!e.branchName)return"none";const i=e.branchName,o=await lo(e.cwd);if(o===i)return"none";const r=this.getPersistedInitPolicy(n,e,"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 Qi(e.cwd,i,e.baseBranch),"switched")}}const xu=wt.object({title:wt.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:wt.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:wt.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),Iu=bt(xu,{target:"draft-07"}),Su=bt(xu);function Tu(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?xu.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=Cu(e),n=JSON.parse(t);return xu.parse(n)}(t.result??"")}function Cu(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class Au{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const _u=[{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 Eu(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function $u(e=[]){const t=[],n=new Set;for(const e of _u.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(Eu).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 Mu=wt.object({message:wt.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),Ru=bt(Mu,{target:"draft-07"}),Pu=bt(Mu);async function Du(e){if(!await Zi(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await eo(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,env:e.env,disableClaudePlanModeTools:e.disableClaudePlanModeTools,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?Ru:Pu}});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?Mu.parse(t.structured_output):Mu.parse(JSON.parse(Cu(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=Gi(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 eo(e)}(e.workingDirectory,n);if(await Zi(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 Nu(e){if(e)return{type:"json_schema",schema:e}}async function Ou(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=_.join(e,s.name),a=_.join(t,s.name);s.isDirectory()?await Ou(n,a):await o.promises.copyFile(n,a)}}function Uu(e){return"oneshot"===function(e){return e.workerExecutionMode??fe}(e)}async function ju(e){const t=E(e,".agentrix"),n=E(t,"prompt.md"),s=E(t,"plugins"),[a,i]=await Promise.all([Lu(n),qu(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function Lu(e){try{if(!(await C.stat(e)).isFile())return;const t=(await C.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(Hu(e))return;throw e}}async function qu(e){let t;try{t=await C.readdir(e,{withFileTypes:!0})}catch(e){if(Hu(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=E(e,s.name),a=E(t,".claude-plugin","plugin.json");try{(await C.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(Hu(e))continue;throw e}}return n}function Hu(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}function Fu(e){const t=e,n=ye({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}function Bu(e){if(!e)return!1;const t=E(e,".agentrix","vision");try{return r(t)&&p(t).isDirectory()}catch{return!1}}function Gu(e){const t=e?.trim();if(t)return t.replace(/\/+$/,"")}async function Wu(e){const t=await async function(e){const t=function(e){if(!e)return null;try{const t=new URL(e),n=decodeURIComponent(t.username),s=decodeURIComponent(t.password);if(t.host.toLowerCase(),"x-access-token"===n&&s)return s}catch{return null}return null}(e.gitUrl);if(t)return{GITHUB_TOKEN:t,GH_TOKEN:t};if(!e.gitServerId)return{};const n=await zo();if(!n)return{};const s=Yo(e.gitServerId,n);if(!s)return{};const a=Ko(e.gitServerId);return function(e,t,n){return{GITLAB_TOKEN:e,...t?{GITLAB_BASE_URL:t,CI_SERVER_URL:t}:{},...n?{GITLAB_API_URL:n}:{}}}(s,Gu(a?.baseUrl),Gu(a?.apiUrl))}(e);for(const[e,n]of Object.entries(t))process.env[e]=n;return t}function zu(e,t,n){if(null==n)return;const s=String(n);0!==s.length&&(e[t]=s)}function Ku(e,t){const n={},s=e.machineId??t.machineId;return zu(n,"AGENTRIX_TASK_ID",e.taskId),zu(n,"AGENTRIX_USER_ID",e.userId),zu(n,"AGENTRIX_AGENT_ID",e.agentId),zu(n,"AGENTRIX_AGENT_TYPE",e.agentType),zu(n,"AGENTRIX_CHAT_ID",e.chatId),zu(n,"AGENTRIX_MACHINE_ID",s),zu(n,"AGENTRIX_CLOUD_ID",e.cloudId),zu(n,"AGENTRIX_ROOT_TASK_ID",e.rootTaskId),zu(n,"AGENTRIX_PARENT_TASK_ID",e.parentTaskId),zu(n,"AGENTRIX_TASK_TYPE",e.taskType),zu(n,"AGENTRIX_WORKSPACE_ID",e.workspaceId),zu(n,"AGENTRIX_WORKING_DIR",t.workingDirectory),zu(n,"AGENTRIX_BASE_REF",e.baseBranch),zu(n,"AGENTRIX_HEAD_REF",e.headRef),zu(n,"AGENTRIX_HEAD_SHA",e.headSha),zu(n,"AGENTRIX_CHECKOUT_REF",e.checkoutRef),zu(n,"AGENTRIX_CHECKOUT_SHA",e.checkoutSha),zu(n,"AGENTRIX_TASK_BRANCH",e.branchName),zu(n,"AGENTRIX_TASK_BRANCH_BINDING",e.branchBinding),zu(n,"AGENTRIX_WORKING_USER",e.userId),zu(n,"AGENTRIX_WORKING_TASK",e.taskId),n}function Vu(e,t){if(e.environmentVariables)for(const[t,n]of Object.entries(e.environmentVariables))null!=n&&(process.env[t]=String(n));Object.assign(process.env,Ku(e,t))}function Xu(e,t){const n={};if(t.baseEnv)for(const[e,s]of Object.entries(t.baseEnv))"string"==typeof s&&(n[e]=s);return{...n,...Ku(e,t)}}const Ju=Ne(import.meta.url),Yu=Symbol("companionHeartbeatContext"),Qu=Symbol("companionMemoryOrganizationContext");class Zu{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=Le(),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=$e.resolveDataDir(i,a);this.historyDb=jo({dataDir:l,taskId:a}),this.workClient=new _d(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new Dd({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:$e.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:$e.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const d={...kp(this.options.input),cwd:this.workingDirectory};this.workspace=new ku({options:d,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=Ud();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;loopModelSetter=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 Uu(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=oe(t);return!!ve(t)||!!we(t)||!!be(t)||!(!re(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)){Ju.info("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!(!re(t)||"user"!==t.type)&&"![plan]"===ii(t).trim()}deduplicateHeartbeats(e){let t=-1;for(let n=e.length-1;n>=0;n--)ve(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(!re(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=Ml(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)}clearRuntimeInputMetadata(e){delete e.__localSequence,delete e.__isChannelInput,delete e.__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(ve(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionHeartbeatPrompt(e)},parent_tool_use_id:null,session_id:""};return n[Yu]=e,n}if(be(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:""}}if(we(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionMemoryOrganizationPrompt(e)},parent_tool_use_id:null,session_id:""};return n[Qu]=e,n}return re(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")}buildCompanionMemoryOrganizationPrompt(e){const t=this.options.input,n=[`trigger: ${e.trigger}`,`timestamp: ${e.timestamp}`,e.triggerTime?`local trigger time: ${e.triggerTime}`:void 0,"number"==typeof e.intervalHours?`configured interval hours: ${e.intervalHours}`:void 0,`current worker taskId: ${t.taskId}`,t.chatId?`companion chatId: ${t.chatId}`:void 0].filter(e=>Boolean(e));return Ju.info(`Memory organization input received: trigger=${e.trigger}, timestamp=${e.timestamp}, intervalHours=${e.intervalHours??"unset"}, taskId=${t.taskId}`),["[memory organization] You are being awakened for Companion memory organization.",...n.map(e=>`- ${e}`),"","Use the available conversation, task, and history tools to gather the current signals needed for this memory organization run. Follow the memory organization mode instructions from your system prompt and MEMORY_ORGANIZATION.md."].join("\n")}extractCompanionPromptPlaceholders(e){const t=e[Qu];return t?(delete e[Qu],{COMPANION_SHADOW_TASK:"memory_organization",COMPANION_MEMORY_ORGANIZATION_TRIGGER:t.trigger,COMPANION_MEMORY_ORGANIZATION_TIMESTAMP:t.timestamp,COMPANION_MEMORY_ORGANIZATION_INTERVAL_HOURS:"number"==typeof t.intervalHours?String(t.intervalHours):""}):e[Yu]?(delete e[Yu],{COMPANION_SHADOW_TASK:"heartbeat"}):void 0}async prepareMessageForRunner(e){return Zc(e,{attachmentsDir:$e.resolveAttachmentsDir(this.options.input.userId,this.taskId)})}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",Ju.warn("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{Ju.info(`Auto-installing agent ${e} from git`),await La({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){Ju.warn(`Auto-install failed for agent ${e}: ${t}`)}else Ju.warn(`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=$e.agentrixAgentsHomeDir,a=E(s,`${e}.new`),i=E(s,`${e}-bak`);try{Ju.info(`Applying upgrade for ${e}`),qa(n),m(n,a),await Ou(t,i),h(t,{recursive:!0,force:!0}),m(a,t),Be(i)&&h(i,{recursive:!0,force:!0}),Ju.info(`Upgrade applied for ${e}`)}catch(n){Ju.warn(`Upgrade failed for ${e}: ${n}`),!Be(t)&&Be(i)&&m(i,t),Be(a)&&h(a,{recursive:!0,force:!0})}}async initialize(){const e=this.options.input,t="filesystem"===e.agentSource;let n=null;const s=e.agentDir??$e.resolveAgentDir(e.agentId,this.workingDirectory);Boolean(t&&"git-server"===e.repositorySourceType&&!e.agentDir&&!Be(E(s,"agent.json")))&&(n=await this.workspace.setup());const a=e.agentDir??$e.resolveAgentDir(e.agentId,this.workingDirectory),i=E(a,"upgrade"),o=Boolean(a)&&Boolean(e.agentGitUrl)&&!t,r=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&o&&!Be(a)),c=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!t&&!r&&Be(i));if(await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:r,upgradingAgent:c}),r&&await this.autoInstallAgent(e.agentId),t&&"default"!==e.agentId&&!Be(E(a,"agent.json")))throw new Error(`Filesystem agent not found: ${e.agentId} (${a})`);c&&await this.applyAgentUpgrade(e.agentId,a,i),Ju.info(`Resolved agent ${e.agentId}: ${a}`);const l=await wu.create(e.agentType,e.agentId,{agentDir:a,context:this.agentContext});this.runner=l,this.initializePermissionModeState(),n??=await this.workspace.setup(),this.projectAgentrixGuidance=await ju(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),Ju.info(`Prepared ${this.options.input.repositorySourceType} workspace via ${n.setupAction} at ${this.workingDirectory} (${n.initialCommitHash||"none"})`),await this.setEnvironmentVariables(),this.lastProcessedSequence=this.historyDb.getAgentLastSequences().get(this.primaryAgentId)??0,Ju.info(`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($u())}createWorkspaceHandlers(e){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: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)},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 qn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?Ju.warn(`Failed to report session ${t}:`,n.error):Ju.info(`Session ${t} registered`)}async setEnvironmentVariables(){Vu(this.options.input,{workingDirectory:this.workingDirectory,machineId:this.credentials.machineId}),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),await Wu(this.options.input)}buildClaudeRunEnvironment(){return Xu(this.options.input,{workingDirectory:this.workingDirectory,machineId:this.credentials.machineId,baseEnv:process.env})}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new Gp({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 Fn(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)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}sendCurrentWorkerStatus(){const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning(this.coordinator.getActiveAgents()):"idle"===e&&this.workClient.sendWorkerReady()}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=Nd(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=Od(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}if("task-message"===e){const e=t;if(e.message){const t=Td(e,e.message,{source:"startup"});t&&Ju.info(t)}}if(this.isOneShotExecution())await this.processPendingMessages(),this.coordinator.hasAgentMessages()||this.isStopping||this.stopTask("oneshot_complete");else{if("task-message"===e){const n=t,s=n.message;s&&we(s)&&this.historyDb.saveMessage({eventId:n.eventId,message:s,senderType:n.senderType,senderId:n.senderId,senderName:n.senderName}).inserted&&this.historyDb.saveTaskEvent({eventType:e,eventId:n.eventId,eventData:n,taskId:this.taskId,chatId:n.chatId??this.options.input.chatId,sequence:n.sequence??null})}this.triggerMessageProcessing()}"task-message"===e&&t?.eventId&&this.workClient.sendEventAck(t.eventId)}async executeMergeRequest(){Ju.info("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 Ju.warn("No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await Zi(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await eo(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return Ju.error(e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await ao(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=this.workspace.getState(),o=i.branchName?{branchName:i.branchName,branchBinding:i.branchBinding}:this.options.input,r=xp(o),c=r?Ip(this.options.input.taskId,o.branchName):void 0;if(r&&c){const e=await lo(this.workingDirectory);if(e!==c){const t=Cp(e,c);return Ju.warn(t),void this.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}const l=this.runner?.getAgentConfiguration(),d=jp(a,(l?.customPRPromptTemplate?(n=l.customPRPromptTemplate,s={initialCommitHash:a,currentCommitHash:e,branchName:c??"to-be-generated-from-pr-title"},n.replace(/\{\{initialCommitHash\}\}/g,s.initialCommitHash).replace(/\{\{currentCommitHash\}\}/g,s.currentCommitHash).replace(/\{\{branchName\}\}/g,s.branchName)):void 0)??void 0);Ju.debug(`PR prompt: ${d.substring(0,200)}...`);const p=this.runner;let u=null;const m=p.runStreamed(d,{cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:Iu}});for await(const e of m){if(this.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){u=e;break}const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}if(!u)throw new Error("Merge-request did not return a result message");if("success"!==u.subtype)throw new Error("Merge-request did not return a successful result message");const h=Tu(u),g=Ip(this.options.input.taskId,c,h.title);r||await Sp(this.workingDirectory,g);const f=Tp(g);Ju.info(`Pushing HEAD to remote branch ${g}`),await Np(this.workingDirectory,f,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),Ju.info("Successfully pushed branch to remote");const y=await this.workClient.sendMergeRequest(h.title,h.description,g);"explicit"!==o.branchBinding&&await this.workspace.updateBranchBinding(g,"platform-managed");const v=`${h.userMessage}\n\n✅ Pull request created successfully!\nNumber: #${y.pullRequestNumber}\nURL: ${y.pullRequestUrl}`,w={input_tokens:u.usage.input_tokens??0,cached_input_tokens:u.usage.cache_read_input_tokens??0,output_tokens:u.usage.output_tokens??0,reasoning_output_tokens:0};this.workClient.sendTaskMessage(this.getChatSenderMeta(),oi({sessionId:u.session_id,model:this.options.input.model??"unknown",numTurns:u.num_turns,usage:w,result:v}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);Ju.error("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(!$e.isDirectBashAllowed())return Ju.warn("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});Ju.info(`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await Fp(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{Ju.info(`Command completed with exit code: ${e}`)}});Ju.info(`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await zp({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(){Ju.info("Generating commit message with agent"),await Du({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),env:this.buildClaudeRunEnvironment(),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})}}),Ju.info("Committed changes with agent-generated message")}async executeNewSession(){Ju.info("Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),Ju.info("Session reset sent, stopping task for clean restart"),this.stopTask("event")}isAgentrixDevOpsInitWorker(){return this.options.input.agentId===el}async maybeConfirmAgentrixDevOpsInit(){if(!this.isAgentrixDevOpsInitWorker())return!0;const e=sl(this.options.input),t=(await this.askUser([al(e)],{onTimeout:"abort_task"})).answers[0]??"";return("zh-Hans"===e?"先初始化"===t:"Initialize first"===t)||(await Hn(this.taskId,this.options.input.userId,"continue"),!1)}getAgentrixExtraTools(){if(this.isAgentrixDevOpsInitWorker())return[$t("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:wt.string().describe("Short user-visible summary of what initialization completed")},async e=>{const t=sl(this.options.input),n=await this.askUser([il(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(Ju.info(`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 Hn(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(Ju.info(`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void Ju.info(`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=>{Ju.debug(e)},modeConfig:n,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.workingDirectory),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.loopModelSetter=o.setModel??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);const t=e.__localSequence;if(void 0!==t&&this.markPrimaryMessageProcessed(t),Boolean(e.__isChannelInput)){const t=e.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(t)?t:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}this.clearRuntimeInputMetadata(e),o.push(await this.prepareMessageForRunner(e)),delete e.__isChannelInput,delete e.__channelReplyTarget}}catch(e){Ju.error("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(),Ju.info(`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.loopModelSetter=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 Ju.info(`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&this.markPrimaryMessageProcessed(o),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.extractCompanionPromptPlaceholders(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=>{Ju.debug(e)},modeConfig:t,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.workingDirectory),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(),Ju.info(`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($u(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.loopModelSetter=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",Ju.info("One-shot execution completed, stopping task")),"idle"===e?Ju.info("Idle timeout reached, stopping task"):"ask_user_timeout"===e&&Ju.info("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 Ju.warn("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 Ju.warn(`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 Ju.info(`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return Ju.info(`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;Ju.info(`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 et.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 Ju.warn(`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 Vp(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:")?(Ju.info(`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 Ju.warn(`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:")?(Ju.info(`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 Ju.warn(`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 Nu(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=$e.resolveDataDir(t,e);this.chatHistoryDb=jo({dataDir:n,taskId:e})}return{createTask:Kd(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),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,workingDirectory:this.workingDirectory}),createSoloTask:Vd(t),createGroupTask:Xd(t),replyToSubTask:Bd(t),changeTaskTitle:qd(t),publishTaskPreviewUrl:Hd(t),sendVisionArtifact:Fd(t),askUser:Jd(t),getTaskHistory:Gd(t),getTaskAgents:Wd(t),listSubTask:zd(t),invoke:Yd(t),assign:Zd(t),updateAgentInfo:Qd(t),sendReminder:np(t),recordMemoryChange:ap(t),listTasks:ep(t),readConversation:tp(t),uploadFile:ip(t),sendChannelMessage:cp(t),getChannelGroupHistory:lp(t),listAgents:pp(t),analyzeImage:mp(t),scheduleTask:$t("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:wt.enum(["create","list","delete"]).describe("Operation to perform"),task:wt.string().optional().describe("Task description (required for create)"),type:wt.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:wt.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:wt.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:wt.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:wt.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:wt.string().optional().describe("Task ID (required for delete)")},async e=>{try{const t=await $e.readDaemonState();if(!t?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${t.port}`;if("list"===e.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"===e.action){if(!e.task||!e.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const t=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:e.task,type:e.type,due:e.due,cron:e.cron,timezone:e.timezone,timeType:e.timeType})}),s=await t.json();if(!t.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"===e.action){if(!e.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const t=await fetch(`${n}/schedule/${e.id}`,{method:"DELETE"}),s=await t.json();return t.ok?{content:[{type:"text",text:`Deleted: ${e.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${e.action}`}],isError:!0}}catch(e){return jd.error("Schedule task failed:",e),{content:[{type:"text",text:`Failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}}),prepareHiveRepository:hp(t),publishToHive:gp(t),updateHiveListingVersion:fp(t),recordHiveInstall:yp(t),createHiveReview:vp(t),createHiveComment:wp(t),computerUse:Ld(t)};var t}isComputerUseEnabled(){try{return cc().enabled}catch(e){return Ju.warn(`Failed to evaluate Agentrix Computer Use enablement: ${e instanceof Error?e.message:String(e)}`),!1}}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 Au,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 wu.create(a,e,{context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),d=this.buildSystemHooks({trackBackgroundTasks:!1}),p=Ud(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.workingDirectory),allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:l,hooks:d,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});let m=n.message;if("codex"===a&&!n.sessionId){const t=[ti(e,i),"=== CONVERSATION STREAM START FROM HERE ===",ii(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:p.filter(n);s&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},s,{groupId:t})}}catch(t){Ju.error(`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 Au,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 wu.create(a,e,{context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),d=Ud(),p=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.workingDirectory),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()});p.push(t);let u=!1;for await(const t of p.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:d.filter(t);n&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},n,{groupId:s})}}catch(t){Ju.error(`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 Ju.warn("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=Rl(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 Ju.debug("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 Ju.debug(`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),Ju.info(`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),Ju.info(`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&&Ju.warn(`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:$e.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:ke(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:V(),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}},handlers:{attachmentsDir:$e.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!ve(e)||!this.shouldDropHeartbeatWhileBusy()||(Ju.debug("Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(oe(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{const t=this.options.input.model;await Kp(e,this.options.input,this.workspace),t!==this.options.input.model&&Object.prototype.hasOwnProperty.call(e.updates??{},"model")&&(Ju.info(`Task model updated from ${t??"default"} to ${this.options.input.model??"default"}; applying to subsequent Claude responses`),await(this.loopModelSetter?.(this.options.input.model)))},onReconnect:async()=>{this.sendCurrentWorkerStatus()},onWorkerStatusRequest:async()=>{this.sendCurrentWorkerStatus()},onSubTaskResultUpdated:async e=>{const t=Nd(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=Od(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){Ju.info(`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})}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{Ju.warn("Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){Ju.warn("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 Up(this.options.input.userId,this.taskId,n)}catch(e){Ju.warn("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 Bn(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&&Ju.debug(`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){Ju.debug("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 em{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>bp(e)||e;if(n)return l(n);const d=$e.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return await this.assertUsableUserCwd(e),e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.assertUsableUserCwd(e),await this.shouldUseWorktree(e)?l(d):e}return l(d)}static async shouldUseWorktree(e){try{return!no(e)&&await Wi(e)}catch{return!1}}static async assertUsableUserCwd(e){let t;try{t=await Xt(e)}catch{throw new Error(`Workspace directory is unavailable: ${e}. Restore or relink the workspace before starting a filesystem task.`)}if(!t.isDirectory())throw new Error(`Workspace path is not a directory: ${e}`);try{await Jt(e,x.R_OK|x.W_OK)}catch{throw new Error(`Workspace directory is not readable and writable: ${e}. Restore permissions before starting a filesystem task.`)}}}const tm=Ne(import.meta.url);class nm{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;currentTurnComplete=null;workerStartedAt=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return Uu(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${Ie()}`}beginCurrentTurn(){return this.finishCurrentTurn(),new Promise(e=>{this.currentTurnComplete=()=>{this.currentTurnComplete=null,e()}})}finishCurrentTurn(){const e=this.currentTurnComplete;e&&e()}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(),tm.warn("Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}tm.info(`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,n=Date.now();this.workerStartedAt=n,this.logger=Le(),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const s=kp(this.options.input),a=await em.calculateFinalCwd(s),i={...s,cwd:a};tm.debug(`Phase 1: Working directory: ${a}`);const o=1e3*Math.max(0,this.options.idleTimeoutSecond??0);tm.info([`worker.start taskId=${e}`,"workerType=codex",`agentId=${this.options.input.agentId??"unknown"}`,`cwd=${a}`,`repositorySourceType=${this.options.input.repositorySourceType??"unknown"}`,"sandboxMode=danger-full-access",`idleTimeoutMs=${o}`].join(" "));const r=this.createWorkerClientConfig(t,e,a),c=$e.resolveDataDir(t,e);this.historyDb=jo({dataDir:c,taskId:e});const l=new _d(r.config,{...r.handlers,historyDb:this.historyDb});this.workClient=l,tm.debug("Phase 2: WorkerClient created"),this.coordinator=this.createMessageCoordinator(l,o),tm.debug("Phase 3: Coordinator created");const d=Date.now();await l.connect();const p=Date.now()-d;l.sendWorkerInitializing(),tm.debug("Phase 4: Connected to server"),tm.debug("Phase 5: Skipped (no AgentContext for Codex)"),tm.debug("Phase 6: Skipped (no custom resources for Codex)");const u=new ku({options:i,handlers:this.createWorkspaceHandlers(l,a)}),m=Date.now(),{initialCommitHash:h,gitStateResult:g,setupAction:f,branchName:y}=await u.setup(),v=Date.now()-m;this.workspace=u,this.projectAgentrixGuidance=await ju(a),tm.debug("Phase 7: Workspace setup complete"),tm.info([`workspace.ready action=${f}`,`cwd=${a}`,`branch=${y??"unknown"}`,`commit=${h||"none"}`,`repositorySourceType=${this.options.input.repositorySourceType??"unknown"}`,`workspaceMs=${v}`,`hadUncommittedChanges=${Boolean(g?.hadUncommittedChanges)}`].join(" ")),l.sendWorkerInitialized(),l.sendTaskSlashCommandsUpdate($u()),tm.debug("Phase 8: Initialization finalized");const w=Date.now();await this.registerWithDaemon(a);const b=Date.now()-w;tm.debug("Phase 9: Registered with daemon"),tm.debug(`Prepared ${this.options.input.repositorySourceType} workspace via ${f} at ${a} (${h||"none"})`),tm.info(["worker.init.completed totalMs="+(Date.now()-n),`connectMs=${p}`,`workspaceMs=${v}`,`daemonRegisterMs=${b}`,`cwd=${a}`,"workerType=codex",`model=${this.options.input.model??"auto"}`].join(" ")),this.context={credentials:this.credentials,options:this.options,workClient:l,workingDirectory:a,dataDir:c,initialCommitHash:h,logger:this.logger},Vu(this.options.input,{workingDirectory:a,machineId:this.credentials.machineId}),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),await Wu(this.options.input),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,tm.info(`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 qn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?tm.warn(`Failed to report session ${t}:`,n.error):tm.info(`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new Gp({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 Fn(this.taskId,this.options.input.userId),this.stopTask("event")}},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}sendCurrentWorkerStatus(){const e=this.workClient;if(!e||!this.coordinator)return;const{state:t}=this.coordinator.getStatus();"running"===t?e.sendWorkRunning(this.coordinator.getActiveAgents()):"idle"===t&&e.sendWorkerReady()}async handleEvent(){if("task-message"===this.options.input.event){const e=this.options.input.eventData,t=e.message;if(t){const n=Td(e,t,{source:"startup"});n&&tm.info(n)}t&&re(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e.eventId&&this.workClient?.sendEventAck(e.eventId))}}async executeMergeRequest(){this.refreshGroupId(),tm.info("Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return tm.warn("No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await Zi(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await eo(this.context.workingDirectory),t=this.context.initialCommitHash,n=this.workspace.getState(),s=n.branchName?{branchName:n.branchName,branchBinding:n.branchBinding}:this.options.input,a=xp(s),i=a?Ip(this.options.input.taskId,s.branchName):void 0;if(a&&i){const e=await lo(this.context.workingDirectory);if(e!==i){const t=Cp(e,i);return tm.warn(t),void this.context.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}if(!t){const e="Cannot create PR: initial commit hash is missing.";return tm.error(e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await ao(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 o=jp(t);tm.debug(`PR prompt: ${o.substring(0,200)}...`);const r=this.options.input.agentId??"default",c=await wu.create("codex",r),l={mode:"work",supportChangeTitle:!1},d=c.runStreamed(o,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,abortController:this.abortController,modeConfig:l,env:this.buildCodexRunEnvironment(),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:Su}});let p=null;for await(const e of d){if(this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){p=e;break}const t=this.filterMessages(e);null!==t&&this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}if(!p)throw new Error("Merge-request did not return a result message");const u=Tu(p),m=Ip(this.options.input.taskId,i,u.title);a||await Sp(this.context.workingDirectory,m);const h=Tp(m);tm.info(`Pushing HEAD to remote branch ${m}`),await Np(this.context.workingDirectory,h,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),tm.info("Successfully pushed branch to remote"),await this.createPullRequest(u.title,u.description,m),"explicit"!==s.branchBinding&&await this.workspace.updateBranchBinding(m,"platform-managed"),this.sendMessage(u.userMessage)}catch(e){const t=e instanceof Error?e.message:String(e);tm.error("Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){tm.info(`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!$e.isDirectBashAllowed())return tm.warn("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});tm.info(`Executing command: ${e}`);const t=await Fp(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{tm.info(`Command completed with exit code: ${e}`)}});tm.info(`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await zp({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 wu.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");tm.info("Generating commit message with agent"),await Du({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},env:this.buildCodexRunEnvironment(),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})}}),tm.info("Committed changes with agent-generated message")}async executeNewSession(){tm.info("Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),tm.info("Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return Nu(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 $e.readDaemonState();if(!Me(e))return tm.debug("Agentrix event MCP broker unavailable: daemon state not found"),null;const t=Fu(this.options.input),n=Bu(this.context?.workingDirectory),s=function(e,t){const n={taskId:t.taskId,userId:t.userId,machineId:t.machineId??e.machineId,nonce:xe(16).toString("base64url"),taskPreviewEnabled:t.taskPreviewEnabled,visionPlanEnabled:t.visionPlanEnabled},s=(a=JSON.stringify(n),Buffer.from(a,"utf8").toString("base64url"));var a;return`${s}.${Rr(s,Mr(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId,taskPreviewEnabled:t,visionPlanEnabled:n});return{serverName:Or,url:jn(e,Ur),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:jr,previewToolName:t?Lr:void 0,sendVisionArtifactToolName:n?qr:void 0,token:s}}buildCodexRunEnvironment(){const e=Xu(this.options.input,{workingDirectory:this.context.workingDirectory,machineId:this.credentials.machineId,baseEnv:process.env});return this.codexAgentrixEventMcp&&(e[this.codexAgentrixEventMcp.tokenEnvVar]=this.codexAgentrixEventMcp.token),e}async runCodex(){tm.info(`Starting Codex agent for task ${this.taskId}`),this.currentModel=uu(this.options.input.model),this.currentModel?tm.info(`Using model: ${this.currentModel}`):tm.info("Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await wu.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void tm.info(`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,getModel:()=>this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(!e){if(this.isStopping)break;continue}const t=this.beginCurrentTurn();this.refreshGroupId(),this.startAgentTurn(e),this.updateAgentRunning(!0),s.push(e),await t}}catch(e){tm.error("Message pump failed:",e),this.stopTask("event")}})();try{for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e)}catch(e){throw this.logAgentTurnFailed(e),e}finally{this.finishCurrentTurn()}tm.info(`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 tm.info(`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId(),this.startAgentTurn(n);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,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:Fu(this.options.input),enableVisionPlan:Bu(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});try{for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e)}catch(e){throw this.logAgentTurnFailed(e),e}this.isStopping||this.stopTask("oneshot_complete")}finally{tm.info(`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($u(e.slash_commands??[]),e.session_id),tm.debug(`Thread started: ${e.session_id}`),tm.info(`agent.thread.started sessionId=${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);if(null!==t&&("result"===e.type?(this.logAgentTurnCompleted(e),await this.handleSdkResultMessage(t)):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"===e.type)return this.updateAgentRunning(!1),void this.finishCurrentTurn();this.updateAgentRunning(!0)}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!==Or?!("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:Ie().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:Ie().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 Vp(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}startAgentTurn(e){tm.info([`agent.turn.started groupId=${this.currentGroupId??"none"}`,`model=${this.currentModel??this.options.input.model??"auto"}`,"session="+(this.threadId?"resume":"new"),`inputChars=${e.length}`].join(" "))}logAgentTurnCompleted(e){const t=e.usage;tm.info([`agent.turn.completed sessionId=${e.session_id||this.threadId||"unknown"}`,`subtype=${e.subtype}`,`isError=${e.is_error}`,`durationMs=${e.duration_ms}`,`turns=${e.num_turns}`,`inputTokens=${t?.input_tokens??0}`,`outputTokens=${t?.output_tokens??0}`,`cacheRead=${t?.cache_read_input_tokens??0}`,`resultChars=${"success"===e.subtype?(e.result??"").length:0}`].join(" "))}logAgentTurnFailed(e){const t=e instanceof Error?e.message:String(e);tm.warn([`agent.turn.failed sessionId=${this.threadId??"unknown"}`,`error=${JSON.stringify(t)}`].filter(Boolean).join(" "))}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:")?(tm.info(`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 tm.warn(`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:")?(tm.info(`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 tm.warn(`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t,n){tm.info(`Creating PR: ${e}`);const s=await this.context.workClient.sendMergeRequest(e,t,n);this.sendMessage(`✅ Pull request created successfully!\nNumber: #${s.pullRequestNumber}\nURL: ${s.pullRequestUrl}`)}async convertSDKMessageToCodexInput(e){const t=e.message.content;if("string"==typeof t)return t;if(Array.isArray(t)){const e=[],n=$e.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 Yc(t,n,!1);tm.info(`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){tm.error(`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 Yc(t,n,!0);tm.info(`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){tm.error(`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",tm.info("One-shot execution completed, stopping task")),"idle"===e?(this.exitReason="idle_timeout",tm.info("worker.stop.requested reason=idle_timeout source=codex_worker")):"ask_user_timeout"===e&&(this.exitReason="ask_user_timeout",tm.info("ask_user timed out, stopping task")),this.askUserAwaiter.clear(),this.coordinator?.stop(),this.finishCurrentTurn(),"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:$e.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:ke(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:V(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3}},handlers:{attachmentsDir:$e.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(oe(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}re(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{const t=this.options.input.model;await Kp(e,this.options.input,this.workspace),t!==this.options.input.model&&Object.prototype.hasOwnProperty.call(e.updates??{},"model")&&(this.currentModel=uu(this.options.input.model),tm.info(`Task model updated from ${t??"default"} to ${this.options.input.model??"default"}; applying to subsequent Codex turns`))},onReconnect:async()=>{this.sendCurrentWorkerStatus()},onWorkerStatusRequest:async()=>{this.sendCurrentWorkerStatus()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),tm.info(`worker.exit reason=${e} taskId=${this.taskId} totalMs=${this.workerStartedAt?Date.now()-this.workerStartedAt:"unknown"}`);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())}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=>{tm.warn("Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){tm.warn("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 Up(this.options.input.userId,this.taskId,n)}catch(e){tm.warn("Failed to mark artifact version as sent:",e)}}}function sm(){const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(!e)return;if(e.includes("/")||e.includes("\\")||e.startsWith(".")){const t=_.isAbsolute(e)?e:_.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 am(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 im(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(...im(_.join(e,a.name),n)):s.push(n))}return s}async function om(e,t,n){const s=im(e).map(e=>` - ${e}`).join("\n");return new Promise((a,i)=>{let o=!1,r=null;const c=e=>{o||(o=!0,clearTimeout(d),a(e))},l=e=>{o||(o=!0,clearTimeout(d),i(e))},d=setTimeout(()=>{c({approved:!1,reasons:["Review timed out after 10 minutes"],tags:[]})},6e5),p=(u=e=>{r=e,c(e)},$t("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:wt.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:wt.array(wt.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:wt.array(wt.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:am(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=_t({name:"hive_review",version:"1.0.0",tools:[p]}),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=Et({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:sm(),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 rm=Yt(Ct);function cm(e,t,n){const s=$e.serverUrl.replace(/^http/,"ws");return lt(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function lm(e,...t){const{stdout:n}=await rm("git",t,{cwd:e});return n.trim()}function dm(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const pm=Yt(Ct);function um(e,t,n){const s=$e.serverUrl.replace(/^http/,"ws");return lt(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const mm=["claude","codex","deployment","companion","hive-publish","hive-install"],hm={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=$e.readTaskInput(n,s),o=i.dataEncryptionKey?B(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=kp(t.input),s=await em.calculateFinalCwd(n),a=new Zu(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=$e.readTaskInput(n,s),o=i.dataEncryptionKey?B(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 nm(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:$e.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:d,supportLocal:p}=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=_.join($e.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await Ou(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=$e.serverUrl.replace(/^http/,"ws");return lt(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:V(),taskId:s,targetAgentId:i,success:!0,name:c,avatar:l,isSystemAgent:d,supportLocal:p}),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:V(),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:$e.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 d,p,{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(_.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=_.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:dm(r),displayName:r,description:c,readme:n,repoDirName:dm(r)}}(r);m=e.name,h=e.displayName,g=e.description,f=e.readme,u=_.posix.join(u,e.repoDirName),console.log(`[HivePublish] Parsed skill metadata name=${m}, displayName=${h}`)}v=_.join($e.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(v,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await lm(v,"clone","--depth","1",c,".");const t=_.join(v,u);if(o.mkdirSync(_.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 Ou(r,t),o.writeFileSync(_.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await lm(v,"add",".");const i=await async function(e){try{return await rm("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 om(r,m,n.type);if(d=e.reasons,p=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 lm(v,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await lm(v,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const w=await lm(v,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${w}`),y=cm(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:V(),taskId:s,listingId:a,success:!0,gitCommitHash:w,hasChanges:i,tags:p,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??cm(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{y.emit("hive-publish-complete",{eventId:V(),taskId:s,listingId:a,success:!1,error:t instanceof Error?t.message:String(t),reviewReasons:d}),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:$e.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,d=n.installDir??n.draftAgentDir;let p=null,u=null;try{console.log(`[HiveInstall] Starting for task ${s}, name=${c}`),u=_.join($e.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 pm("git",t,{cwd:e});return n.trim()}(u,"clone","--depth","1",r,".");const t=_.join(u,i);if(!o.existsSync(t))throw new Error(`Source directory not found in hive repo: ${i}`);if("skill"===l&&!o.existsSync(_.join(t,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${i}`);const n=(m=d).startsWith("~/")?_.join(process.env.HOME||"",m.slice(2)):_.isAbsolute(m)?m:_.join($e.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 Ou(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),qa(n)}catch(e){try{o.rmSync(n,{recursive:!0,force:!0})}catch{}throw e}const a=_.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"),p=um(e,0,s),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);p.on("connect",()=>{clearTimeout(a),p.emit("hive-install-complete",{eventId:V(),taskId:s,success:!0,agentDir:n}),console.log("[HiveInstall] Sent hive-install-complete (success)"),setTimeout(e,1e3)}),p.on("connect_error",e=>{clearTimeout(a),t(e)})})}catch(t){console.error("[HiveInstall] Failed:",t);try{p=p??um(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{p.emit("hive-install-complete",{eventId:V(),taskId:s,success:!1,error:t instanceof Error?t.message:String(t)}),clearTimeout(n),setTimeout(e,1e3)};p.connected?a():(p.on("connect",a),p.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HiveInstall] Failed to send error event")}throw t}finally{if(p&&p.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=$e.readTaskInput(n,s),o=i.dataEncryptionKey?B(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 Oo();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=kp(t.input),i=await em.calculateFinalCwd(a),o=new Zu(e,t,i);await o.start()}(e,r)}}};async function gm(e,t){const n=`${$e.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function fm(e){try{const t=c(E(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function ym(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}function vm(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 wm(e,t){if(!$n.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=Rn({input:$n,output:Mn});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}function bm(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function km(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function xm(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||$e.serverUrl}function Im(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return k(E(t,e),x.X_OK),!0}catch{return!1}})}function Sm(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 Tm(e){try{return await Jt(e),!0}catch{return!1}}function Cm(e){return e.filter(e=>e.required&&!e.installed)}async function Am(e,t){Im(e)?console.log(q.green(`✓ ${e} is installed`)):Im("npm")?(console.log(q.blue(`Installing ${e} with npm...`)),await Sm("npm",["install","-g",t])):console.log(q.yellow(`npm is not available. Install ${t} manually.`))}async function _m(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function Em(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 $m(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(q.yellow("Invalid selection"))}}function Mm(e){return JSON.stringify(e)}async function Rm(e,t){const n=await async function(e){try{return(await Ee.get(`${$e.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||xm()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(q.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),xm()}}(t),s=Rn({input:$n,output:Mn});try{await async function(e,t,n){const s=E($e.claudeConfigDir,"settings.json");if(!t&&await Tm(s)&&!await Em(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(q.gray("Skipped Claude config"));const a=await $m(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(q.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await _m(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await _m(e,"Agentrix API key for Claude");else{const t=await _m(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await _m(e,"Anthropic auth token")}const o=await _m(e,"Claude primary model","claude-sonnet-4-6"),r=await _m(e,"Claude fast model","claude-haiku-4-5"),c=await _m(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 qt($e.claudeConfigDir,{recursive:!0}),await Ft(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(q.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=E($e.codexHomeDir,"config.toml");if(!t&&await Tm(s)&&!await Em(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(q.gray("Skipped Codex config"));const a=await $m(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(q.gray("Skipped Codex config"));const i=await _m(e,"Codex model","gpt-5.5"),o=await $m(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 _m(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await _m(e,"OpenAI API key")):(c=await _m(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await _m(e,"Custom API key")),await qt($e.codexHomeDir,{recursive:!0}),await Ft(s,function(e){const t=e.provider,n=[`model = ${Mm(e.model)}`,`model_provider = ${Mm(t)}`,"",`[model_providers.${t}]`,`name = ${Mm("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${Mm(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${Mm(s)}`)}return e.envKey&&n.push(`env_key = ${Mm(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=$e.readOrInitSettings({sandbox:$e.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0,promptOnUncommittedChanges:!1}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};$e.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(q.green(`✓ Wrote Codex config: ${s}`)),console.log(q.green(`✓ Wrote Codex env vars to ${$e.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function Pm(e={}){console.log(q.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=ma(),t=[...Cm(e.cli.filter(e=>"claude"!==e.name)),...Cm(e.sandbox)];"linux"!==process.platform||Im("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(q.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(q.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(q.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=>Im(e.name))||null;if(!t){console.log(q.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(q.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(q.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await Sm(s.join(" "),[],{shell:!0}):await Sm(s[0],s.slice(1))}(t),await Am("claude","@anthropic-ai/claude-code@latest"),await Am("codex","@openai/codex@latest");const n=ha();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await Zn();await Rm(Boolean(e.force),t),e.skipDaemon||await async function(){if(await Wn())console.log(q.green("✓ Daemon is already running"));else{console.log(q.blue("Starting Agentrix daemon...")),qc(["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 Gn())return void console.log(q.green("✓ Daemon started successfully"));console.log(q.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(q.green("\n✓ Agentrix CLI initialization complete"))}function Dm(e,t){const n=e[t]?.trim();return n||void 0}function Nm(e,t){return e.replace(/^~(?=\/|$)/,t)}function Om(e){const t=e.trim().replace(/\/+$/,"");try{const e=new URL(t);if("http:"!==e.protocol&&"https:"!==e.protocol)throw new Error("unsupported protocol")}catch{throw new Error("AGENTRIX_BASE_URL must be a valid http(s) URL")}return t}async function Um(e,t){const n=Dm(e,"AGENTRIX_API_KEY");if(n)return n;const s=Dm(e,"AGENTRIX_API_KEY_FILE");if(!s)return;const a=(await async function(e,t){try{return(await Ht(Nm(e,t),"utf-8")).replace(/[\r\n]/g,"")}catch{throw new Error(`AGENTRIX_API_KEY_FILE is set but is not readable: ${e}`)}}(s,t)).trim();return a||void 0}function jm(e){return JSON.stringify(e)}function Lm(e,t){return`${JSON.stringify({env:{ANTHROPIC_BASE_URL:e.baseUrl,ANTHROPIC_AUTH_TOKEN:t,ANTHROPIC_MODEL:e.claudeModel,CLAUDE_CODE_SUBAGENT_MODEL:e.claudeSubagentModel,ANTHROPIC_SMALL_FAST_MODEL:e.claudeFastModel,ANTHROPIC_DEFAULT_OPUS_MODEL:"claude-opus-4-6",ANTHROPIC_DEFAULT_SONNET_MODEL:"claude-sonnet-4-6",ANTHROPIC_DEFAULT_HAIKU_MODEL:"claude-haiku-4-5"},model:e.claudeModel},null,2)}\n`}function qm(e){var t;return`${[`model = ${jm(e.codexModel)}`,'model_provider = "agentrix"',`approval_policy = ${jm("never")}`,`model_reasoning_effort = ${jm("high")}`,"","[model_providers.agentrix]",'name = "Agentrix"','wire_api = "responses"',`base_url = ${jm((t=e.baseUrl,`${t.replace(/\/+$/,"")}/v1`))}`,'env_key = "AGENTRIX_API_KEY"'].join("\n")}\n`}function Hm(e,t){return`${JSON.stringify({connectionMode:"gemini-compatible",baseUrl:e.baseUrl,apiKey:t,imageModel:e.geminiImageModel},null,2)}\n`}async function Fm(e={}){const t=e.env||process.env,s=!0===e.force,a=!0===e.dryRun,i=await async function(e){const t=function(e){return Dm(e,"HOME")||n.homedir()}(e),s=Nm(Dm(e,"AGENTRIX_HOME_DIR")||Dm(e,"AGENTRIX_DIR")||E(t,".agentrix"),t),a=Nm(Dm(e,"AGENTRIX_CLAUDE_HOME")||E(t,".claude"),t),i=Nm(Dm(e,"AGENTRIX_CODEX_HOME")||E(t,".codex"),t),o=Nm(Dm(e,"AGENTRIX_GEMINI_HOME")||E(s,"config","gemini"),t),r=Dm(e,"AGENTRIX_CLAUDE_MODEL")||"claude-sonnet-4-6";return{agentrixHomeDir:s,claudeConfigDir:a,codexHomeDir:i,geminiConfigDir:o,baseUrl:Om(Dm(e,"AGENTRIX_BASE_URL")||"https://api.xmz.ai"),apiKey:await Um(e,t),codexModel:Dm(e,"AGENTRIX_CODEX_MODEL")||"gpt-5.5",claudeModel:r,claudeFastModel:Dm(e,"AGENTRIX_CLAUDE_FAST_MODEL")||"claude-haiku-4-5",claudeSubagentModel:Dm(e,"AGENTRIX_CLAUDE_SUBAGENT_MODEL")||r,geminiImageModel:Dm(e,"AGENTRIX_GEMINI_IMAGE_MODEL")||"gemini-2.5-flash-image"}}(t);if(function(e,t){return!(!t&&r(E(e.claudeConfigDir,"settings.json"))&&r(E(e.codexHomeDir,"config.toml"))&&r(E(e.geminiConfigDir,"settings.json")))}(i,s)&&!i.apiKey)throw new Error("AGENTRIX_API_KEY or AGENTRIX_API_KEY_FILE is required to generate missing LLM config files");i.apiKey&&(t.AGENTRIX_API_KEY=i.apiKey);const o=function(e,t){return[{kind:"claude",path:E(e.claudeConfigDir,"settings.json"),content:Lm(e,t)},{kind:"codex",path:E(e.codexHomeDir,"config.toml"),content:qm(e)},{kind:"gemini",path:E(e.geminiConfigDir,"settings.json"),content:Hm(e,t)}]}(i,i.apiKey||""),c=[];for(const e of o)s||!r(e.path)?(c.push({kind:e.kind,path:e.path,action:"write"}),a||(await qt(D(e.path),{recursive:!0}),await Ft(e.path,e.content,"utf-8"))):c.push({kind:e.kind,path:e.path,action:"skip"});return{dryRun:a,files:c,env:i.apiKey?{AGENTRIX_API_KEY:i.apiKey}:{}}}function Bm(e,t){return"skip"===e?"skip":t?"would write":"write"}const Gm={workspaces:"Task workspaces",logs:"Logs",tmp:"Temporary files",repos:"Repository store",runtime:"Runtime assets",monitor:"Monitor data",config:"Configuration",other:"Other"},Wm=864e5,zm=/^task-(.+)\.log(?:\.\d+)?(?:\.gz)?$/;function Km(e){return{kind:e,label:Gm[e],bytes:0,reclaimableBytes:0,itemCount:0}}function Vm(e){const t=e.state?.initializedAt?Date.parse(e.state.initializedAt):Number.NaN;return Number.isFinite(t)?t:p(e.taskDir).mtimeMs}function Xm(e){return zm.exec(e)?.[1]??null}function Jm(e){return{kind:e.kind,label:e.label,bytes:e.bytes,reclaimableBytes:e.reclaimableBytes,itemCount:e.itemCount}}async function Ym(e,t,n,s,a){n.bytes+=a.bytes,n.itemCount+=1,a.reclaimable&&(n.reclaimableBytes+=a.bytes),s.push(a),t({type:"item",opCode:e,item:a})}async function Qm(e,t,n,s,a,i){const o=Km(s);t({type:"category-started",opCode:e,kind:o.kind,label:o.label});const c=E($e.agentrixHomeDir,a);if(!r(c)){const n=Jm(o);return t({type:"category-completed",opCode:e,category:n}),n}for(const a of g(c,{withFileTypes:!0})){const r=E(c,a.name);try{const c=await Wl(r);await Ym(e,t,o,n,Xl({id:`${s}:${Gl($e.agentrixHomeDir,r)}`,kind:s,label:a.name,absolutePath:r,bytes:c,reclaimable:i,deleteMode:i?"rm":"protected",reasonCode:i?void 0:`${s}_protected`,reason:i?void 0:"This area is shown for visibility only"}))}catch(n){t({type:"item-error",opCode:e,kind:s,pathDisplay:Gl($e.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}const l=Jm(o);return t({type:"category-completed",opCode:e,category:l}),l}async function Zm(e){if(!e)return{};const t=await Ht(e,"utf8");return JSON.parse(t)}function eh(e){process.stdout.write(`${JSON.stringify(e)}\n`)}const th=["local_machine_limit_reached","Online local machine limit reached","Current subscription does not allow online local machines","Disconnect another local machine or upgrade your subscription","machine_limited","Local machine is unavailable under current subscription","Machine binding revoked","Run `agentrix logout` and bind"];async function nh(){const e=await $e.readDaemonState();if("failed"===e?.status)return console.log(q.red("✗ Daemon failed to start")),console.log(q.yellow(e.message)),void(e.action&&console.log(q.yellow(e.action)));const t=await async function(){const e=E($e.getStatePaths().logsDir,"daemon.log");try{return(await Ht(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(q.red("✗ Daemon exited shortly after startup")),!t)return;const n=function(e){const t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&th.some(t=>e.includes(t)));return 0===t.length?null:[...new Set(t.slice(-3))].join("\n")}(t);n?console.log(q.yellow(n)):(console.log(q.gray("Recent daemon log:")),console.log(t))}const sh=j(L(process.argv)).scriptName("agentrix").version(Oe.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");function ah(e){try{return process.kill(e,0),!0}catch{return!1}}async function ih(e){let t;if("string"==typeof e["report-json"])try{t=JSON.parse(e["report-json"])}catch{console.error(q.red("Error:"),"Invalid restart report JSON"),process.exit(1)}const n="number"==typeof e["old-pid"]?e["old-pid"]:void 0,s="string"==typeof e["expected-version"]?e["expected-version"]:void 0,a=await async function(e){const t=void 0===e.oldPid?await $e.readDaemonState():null,n=e.oldPid??(t&&Me(t)&&id(t.pid)?t.pid:void 0),s=e.expectedCliVersion??Ll();var a;if(e.report&&(a={...e.report,oldPid:n,expectedCliVersion:s,reason:e.reason,createdAt:(new Date).toISOString()},u(sd(),JSON.stringify(a,null,2),"utf-8")),e.stopExistingDaemon&&void 0!==n&&id(n)&&await Kn(),void 0!==n){const t=await async function(e,t){const n=Date.now()+t;for(;Date.now()<n;){if(!id(e))return!0;await ad(100)}return!id(e)}(n,e.oldDaemonExitTimeoutMs??12e4);if(!t)return{success:!1,error:`Old daemon PID ${n} did not exit before timeout`}}try{qc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}const i=await async function(e,t,n){const s=Date.now()+n;for(;Date.now()<s;){const n=await $e.readDaemonState();if(n&&Me(n)&&n.pid!==e&&n.cliVersion===t&&id(n.pid))return n;await ad(100)}return null}(n,s,e.newDaemonStartTimeoutMs??3e4);return i?{success:!0}:{success:!1,error:`Replacement daemon did not report version ${s} before timeout`}}({oldPid:n,expectedCliVersion:s,reason:"string"==typeof e.reason?e.reason:void 0,report:t,stopExistingDaemon:void 0===n});a.success||(console.error(q.red("Error:"),a.error??"Daemon restart failed"),process.exit(1))}$e.getStatePaths,sh.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(q.dim(`Current version: ${Oe.version}`));const t=await Gn(),n=t?await $e.readDaemonState():null;await async function(e){try{if(console.log(""),e||(console.log(q.blue("🔄 Checking for upgrades...")),e=await ql()),!e.hasUpgrade)return console.log(q.green("✓ Already on latest version")),console.log(""),!0;console.log(q.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`));const t=await Hl(e,{stdio:"inherit"});if("busy"===t.status)return console.log(q.yellow(`⚠️ ${t.message}`)),!1;if("failed"===t.status)throw new Error(t.error);return console.log(q.green("✓ Upgrade complete")),console.log(""),!0}catch(e){return console.log(""),console.log(q.yellow("⚠️ CLI upgrade failed")),console.log(q.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}()||process.exit(1);try{const e=await $e.readCredentials();e&&(console.log(q.dim("Checking agent updates...")),await async function(e){const t=$e.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>p(E(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=E(t,s),a=E(n,"upgrade");if(r(a))continue;const i=fm(n);Pe.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await gm(s,e);if(!t||!t.gitUrl){Pe.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];Tt(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?E(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=fm(o);if(!c||i&&!ym(c,i)){Pe.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}Pe.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),Pe.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){Pe.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}(e))}catch{}if(t){console.log(q.blue("Preparing daemon restart..."));const e=await async function(){return await Ln("/prepare-graceful-restart",{source:"agentrix-cli",reason:"CLI upgrade installed"})}();let t=!0;const s=Ll();e.error?(console.log(q.yellow(`⚠️ Could not prepare graceful restart: ${e.error}`)),console.log(q.blue("Restarting daemon directly...")),await Kn(),qc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()):"pending_restart"===e.state&&(console.log(q.yellow(`Daemon restart deferred until ${e.activeSessions??0} active session(s) finish.`)),t=!1);let a=!1;t&&(a=await async function(e,t,n=15e3){const s=Date.now()+n;let a=!e;for(;Date.now()<s;){if(e?.pid&&!a){if(ah(e.pid)){await new Promise(e=>setTimeout(e,100));continue}a=!0}const n=await $e.readDaemonState();if(n&&Me(n)&&n.pid!==e?.pid&&n.cliVersion===t&&ah(n.pid))return!0;await new Promise(e=>setTimeout(e,100))}return!1}(n,s),a?console.log(q.green("✓ Daemon restarted successfully")):console.log(q.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check.")))}const s=Ll();"0.0.0"!==s?console.log(q.green(`\n✓ Now running version: ${s}`)):console.log(q.dim("\nRun 'agentrix --version' to see the new version")),process.exit(0)}),sh.command("doctor","System diagnostics & troubleshooting",{},async e=>{await fa(),process.exit(0)}),sh.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await $e.readCredentials())return void console.log(q.yellow("Not currently authenticated"));console.log(q.blue("This will log you out of Agentrix")),console.log(q.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=qe({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(q.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await Kn(),console.log(q.gray("Stopped daemon"))}catch{}await $e.clearCredentials(),console.log(q.gray("Removed credentials")),console.log(q.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(q.blue("Logout cancelled"))}()}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),sh.command("stop","Stop the daemon",{},async e=>{await Kn(),process.exit(0)}),sh.command("restart","Restart the daemon",e=>e.option("old-pid",{type:"number",describe:"PID of the daemon that must exit before replacement starts"}).option("expected-version",{type:"string",describe:"CLI version expected from the replacement daemon"}).option("reason",{type:"string",describe:"Restart reason"}),async e=>{await ih(e),console.log(q.green("✓ Daemon restarted successfully")),process.exit(0)}),sh.command("status","Show daemon and authentication status",{},async e=>{await fa("daemon"),console.log(""),await async function(){const e=await $e.readCredentials();if(console.log(q.bold("\nAuthentication Status\n")),!e)return void console.log(q.red("✗ Not authenticated"));console.log(q.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(q.gray(` Token: ${t}`)),e.machineId?(console.log(q.green("✓ Machine registered")),console.log(q.gray(` Machine ID: ${e.machineId}`)),console.log(q.gray(` Host: ${n.hostname()}`))):console.log(q.yellow("⚠️ Machine not registered")),console.log(q.gray(`\n Data directory: ${$e.agentrixHomeDir}`));try{await Gn()?console.log(q.green("✓ Daemon running")):console.log(q.gray("✗ Daemon not running"))}catch{console.log(q.gray("✗ Daemon not running"))}}(),process.exit(0)}),sh.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await Ln("/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)}),sh.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await pa()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===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=ft.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 gt()).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("name",{type:"string",describe:"Git server display name, defaults to the GitLab hostname"}).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"}).option("proxy",{type:"boolean",describe:"Register this machine as a Git proxy node (use --no-proxy to save PAT locally only)"}),async e=>{try{await async function(e){const t=vm(bm(e["base-url"])??await wm("GitLab base URL"),"baseUrl"),n=vm(bm(e["api-url"])??await wm("GitLab API URL",function(e){return`${vm(e,"baseUrl")}/api/v4`}(t)),"apiUrl"),s=new URL(t).hostname,a=bm(e.name)??await wm("Git server name",s),i=(bm(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()}(bm(e["pat-file"])):void 0)??await async function(e){return $n.isTTY&&Mn.isTTY&&"function"==typeof $n.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{$n.setRawMode(!1),$n.pause(),$n.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Mn.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Mn.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Mn.write(`${e}: `),$n.setRawMode(!0),$n.resume(),$n.on("data",i)}):wm(e)}("GitLab PAT");if(!i)throw new Error("GitLab PAT is required");const o=("boolean"==typeof(l=e.proxy)?l:void 0)??await async function(e,t){if(!$n.isTTY)return t;const n=(await wm("Use this machine as a Git proxy node (Y/n)")).toLowerCase();return n?["y","yes"].includes(n):t}(0,!0);var l;const d=await async function(e){return await Ln("/git-server/bind",e)}({name:a,baseUrl:t,apiUrl:n,pat:i,useAsProxy:o});if(d.error||!d.success||!d.gitServer)throw new Error(`Git server add failed: ${d.error||"Daemon did not return a bound Git server"}`);const p=d.gitServer;console.log(JSON.stringify({id:p.id,type:"gitlab",baseUrl:p.baseUrl,apiUrl:p.apiUrl,webhookEndpointPath:d.webhookEndpointPath??Lt(p.id),webhookUrl:d.webhookUrl??jt(p.id,await $e.readDaemonState()),backendRegistered:!0,proxyRegistered:d.proxyRegistered??o,patConfigured:!0,patMeta:d.patMeta??Jo(p.id),webhookSecret:d.webhookSecret},null,2))}(e),process.exit(0)}catch(e){km(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await async function(){const e=await zo();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}(),t=await $e.readDaemonState(),n=await async function(){return await Ln("/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=Ko(e.id)??{},a=Vo(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:Lt(e.id),webhookUrl:jt(e.id,n),patConfigured:(i=e.id,Wo.hasPat(i)),patMeta:Jo(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){km(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(sh),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 Pm({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(sh),function(e){e.command("llm-config apply","Generate Claude, Codex, and Gemini config from Agentrix environment variables",e=>e.option("source",{type:"string",choices:["env"],default:"env",describe:"Configuration source"}).option("force",{type:"boolean",default:!1,describe:"Overwrite existing LLM config files"}).option("dry-run",{type:"boolean",default:!1,describe:"Show planned writes without changing files"}).option("verbose",{type:"boolean",default:!1,describe:"Show detailed file actions"}),async e=>{try{const t=await Fm({force:!0===e.force,dryRun:!0===e.dryRun,env:process.env}),n=t.files.filter(e=>"write"===e.action).length,s=t.files.filter(e=>"skip"===e.action).length,a=t.dryRun?"LLM config dry run":"LLM config applied";if(console.log(q.green(`✓ ${a}: ${n} write(s), ${s} skipped`)),!0===e.verbose||t.dryRun)for(const e of t.files)console.log(`${Bm(e.action,t.dryRun)} ${e.kind}: ${e.path}`);t.env.AGENTRIX_API_KEY&&console.log(q.gray("AGENTRIX_API_KEY prepared for this process.")),process.exit(0)}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(sh),function(e){e.command("storage-scan",!1,e=>e.option("op-code",{type:"string",demandOption:!0}).option("request-file",{type:"string"}),async e=>{const t=e["op-code"];try{const n=await Zm(e["request-file"]);await async function(e){const{opCode:t,emit:n}=e,s=new Set(e.activeTaskIds??[]),a=$e.getStorageManagementSettings(),i=[],o=[];n({type:"started",opCode:t,root:$e.agentrixHomeDir,startedAt:(new Date).toISOString()}),o.push(await async function(e,t,n,s,a){const i=Km("workspaces");t({type:"category-started",opCode:e,kind:i.kind,label:i.label});const o=Date.now()-a*Wm;for(const a of Kl()){const c=n.has(a.taskId),l=Vl(a.state),d=!c&&!l&&Vm(a)<o,p=c?{reasonCode:"active_task",reason:"Task is currently running"}:l?{reasonCode:"user_directory",reason:"Task uses a user-owned directory"}:{},u=r(a.projectDir),m=r(a.dataDir),h=u?await Wl(a.projectDir):0,g=m?await Wl(a.dataDir):0;if(u){const n=c||l?null:await Jl(a.projectDir);await Ym(e,t,i,s,Xl({id:`workspace:${a.userId}:${a.taskId}:project`,kind:"workspace-project",label:a.taskId,absolutePath:a.projectDir,bytes:h,reclaimable:!c&&!l,defaultSelected:d,deleteMode:c||l?"protected":n?"remove-worktree":"rm-stale-directory",childrenSummary:[{label:"project",bytes:h},...m?[{label:"data",bytes:g}]:[]],...p}))}m&&await Ym(e,t,i,s,Xl({id:`workspace:${a.userId}:${a.taskId}:data`,kind:"workspace-data",label:`${a.taskId} data`,absolutePath:a.dataDir,bytes:g,reclaimable:!c&&!l,defaultSelected:d,deleteMode:c||l?"protected":"rm",childrenSummary:[{label:"data",bytes:g}],...p}))}const c=Jm(i);return t({type:"category-completed",opCode:e,category:c}),c}(t,n,s,i,a.autoSelectTaskOlderThanDays)),o.push(await async function(e,t,n,s,a){const i=Km("logs");t({type:"category-started",opCode:e,kind:i.kind,label:i.label});const o=E($e.agentrixHomeDir,"logs");if(!r(o)){const n=Jm(i);return t({type:"category-completed",opCode:e,category:n}),n}const c=new Map(Kl().map(e=>[e.taskId,e])),l=Date.now()-a*Wm;for(const a of g(o,{withFileTypes:!0})){const r=E(o,a.name);try{const o=await Wl(r),d=Xm(a.name),u=d?c.get(d):void 0,m=!!d&&n.has(d),h=u?Vm(u):p(r).mtimeMs,g=Boolean(d)&&h<l;await Ym(e,t,i,s,Xl({id:`logs:${Gl($e.agentrixHomeDir,r)}`,kind:"logs",label:a.name,absolutePath:r,bytes:o,reclaimable:!m,defaultSelected:!m&&g,deleteMode:m?"protected":"rm",reasonCode:m?"active_task":void 0,reason:m?"Task is currently running":void 0}))}catch(n){t({type:"item-error",opCode:e,kind:"logs",pathDisplay:Gl($e.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}const d=Jm(i);return t({type:"category-completed",opCode:e,category:d}),d}(t,n,s,i,a.autoSelectTaskOlderThanDays)),o.push(await Qm(t,n,i,"tmp","tmp",!0)),o.push(await async function(e,t,n){const s=Km("repos");t({type:"category-started",opCode:e,kind:s.kind,label:s.label});const a=E($e.agentrixHomeDir,"repos");if(!r(a)){const n=Jm(s);return t({type:"category-completed",opCode:e,category:n}),n}for(const i of g(a,{withFileTypes:!0})){if(!i.isDirectory())continue;const o=E(a,i.name);for(const a of g(o,{withFileTypes:!0})){if(!a.isDirectory())continue;const i=E(o,a.name);for(const o of g(i,{withFileTypes:!0})){if(!o.isDirectory())continue;const r=E(i,o.name);try{const i=await Wl(r);await Ym(e,t,s,n,Xl({id:`repos:${Gl($e.agentrixHomeDir,r)}`,kind:"repos",label:`${a.name}/${o.name}`,absolutePath:r,bytes:i,reclaimable:!0,defaultSelected:!1,deleteMode:"rm"}))}catch(n){t({type:"item-error",opCode:e,kind:"repos",pathDisplay:Gl($e.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}}}const i=Jm(s);return t({type:"category-completed",opCode:e,category:i}),i}(t,n,i)),o.push(await Qm(t,n,i,"runtime","node-runtime",!1)),o.push(await Qm(t,n,i,"monitor","monitor",!1));const c=o.reduce((e,t)=>e+t.bytes,0),l=o.reduce((e,t)=>e+t.reclaimableBytes,0),d={scanId:`scan-${t}`,root:$e.agentrixHomeDir,generatedAt:(new Date).toISOString(),totalBytes:c,reclaimableBytes:l,categories:o,items:i.sort((e,t)=>Number(t.reclaimable)-Number(e.reclaimable)||t.bytes-e.bytes)};return n({type:"completed",opCode:t,result:d,summary:{totalBytes:c,reclaimableBytes:l,itemCount:i.length,skippedCount:i.filter(e=>!e.reclaimable).length},completedAt:d.generatedAt}),d}({opCode:t,activeTaskIds:n.activeTaskIds,emit:eh}),process.exitCode=0}catch(e){eh({type:"failed",opCode:t,errorCode:"operation_failed",message:e instanceof Error?e.message:"Storage scan failed"}),process.exitCode=1}}),e.command("storage-clean",!1,e=>e.option("op-code",{type:"string",demandOption:!0}).option("request-file",{type:"string",demandOption:!0}),async e=>{const t=e["op-code"];try{const n=await Zm(e["request-file"]);await async function(e){const{opCode:t,emit:n}=e,s=new Set(e.activeTaskIds??[]),a={releasedBytes:0,deletedCount:0,skippedCount:0,failedCount:0,dryRunCount:0};n({type:"started",opCode:t,itemCount:e.items.length,startedAt:(new Date).toISOString()});for(const i of e.items){n({type:"item-validating",opCode:t,relativePath:i.relativePath});const o=await Yl(i.relativePath,s);if(o.releasable)if(n({type:"item-cleaning",opCode:t,relativePath:o.relativePath,method:o.method}),e.dryRun)a.dryRunCount+=1,n({type:"item-completed",opCode:t,relativePath:o.relativePath,releasedBytes:0,method:o.method});else try{const e=await Ql(o);a.releasedBytes+=e,a.deletedCount+=1,n({type:"item-completed",opCode:t,relativePath:o.relativePath,releasedBytes:e,method:o.method})}catch(e){a.failedCount+=1,n({type:"item-failed",opCode:t,relativePath:o.relativePath,errorCode:"delete_failed",message:e instanceof Error?e.message:"Failed to clean item"})}else a.skippedCount+=1,n({type:"item-skipped",opCode:t,relativePath:o.relativePath,reasonCode:o.reasonCode,message:o.message})}return n({type:"completed",opCode:t,summary:{...a},result:{summary:{...a}},completedAt:(new Date).toISOString()}),a}({opCode:t,activeTaskIds:n.activeTaskIds,items:n.items??[],dryRun:!0===n.dryRun,emit:eh}),process.exitCode=0}catch(e){eh({type:"failed",opCode:t,errorCode:"operation_failed",message:e instanceof Error?e.message:"Storage clean failed"}),process.exitCode=1}})}(sh),sh.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 Ln("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?q.green("✓ Session stopped"):q.red("Failed to stop session"))}catch(e){console.log(q.red("No daemon running"))}process.exit(0)}),sh.command("daemon",!1,{},async e=>{try{await Zn()}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await wd(),process.exit(0)}),sh.command("worker",!1,e=>e.option("type",{type:"string",choices:mm,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=hm[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=e["user-id"],i=e["task-id"],o=e["idle-timeout"];Ue({type:"worker",taskId:i});const r=await Zn();await n.run({credentials:r,startedBy:s,userId:a,taskId:i,idleTimeoutSecond:o}),await Vc()}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),sh.command("restart-daemon",!1,e=>e.option("old-pid",{type:"number",describe:"PID of the daemon that must exit before replacement starts"}).option("expected-version",{type:"string",describe:"CLI version expected from the replacement daemon"}).option("reason",{type:"string",describe:"Restart reason"}).option("report-json",{type:"string",describe:"Machine-control restart report context"}),async e=>{await ih(e),process.exit(0)}),sh.command("start","Start daemon (if not running) and show status",{},async e=>{try{await Zn()}catch(e){console.error(q.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=ha();if(t.ok||(console.log(q.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(q.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(q.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await Wn()){console.log("Starting Agentrix background service..."),qc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1,t=!1;const n=Date.now()+12e4;for(;Date.now()<n;){await new Promise(e=>setTimeout(e,100));const n=await $e.readDaemonState();if("failed"===n?.status){t=!0;break}if(await Gn()){e=!0;break}}t&&(await nh(),process.exit(1)),e?(await new Promise(e=>setTimeout(e,1200)),await Gn()?console.log(q.green("✓ Daemon started successfully")):(await nh(),process.exit(1))):console.log(q.yellow("⚠️ Daemon may still be starting..."))}await fa("daemon"),process.exit(0)}),sh.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 d,statSync as p,writeFileSync as u,renameSync as m,rmSync as h,readdirSync as g,unlinkSync as f,cpSync as y,lstatSync as v,symlinkSync as w,readlinkSync as b,accessSync as k,constants as x,createReadStream as I,realpathSync as S,copyFileSync as T,promises as C}from"node:fs";import*as _ from"node:path";import A,{join as E,basename as $,extname as M,resolve as P,sep as R,dirname as D,relative as N,isAbsolute as O,normalize as U,delimiter as j}from"node:path";import L from"yargs";import{hideBin as q}from"yargs/helpers";import H from"chalk";import{encodeBase64 as F,encryptMachineEncryptionKey as B,decodeBase64 as G,createKeyPairWithUit8Array as W,generateAESKey as z,decryptWithEphemeralKey as K,SocketAuthErrorDataSchema as V,createEventId as X,encryptFileContent as J,VisionPlanReviewWriteEventSchema as Y,splitRtcChunkFrame as Q,RtcChunkFlags as Z,buildRtcChunkFrame as ee,decodeGitPath as te,UpdateTaskPreviewUrlRequestSchema as ne,AGENTRIX_DEV_INIT_FEATURE as se,decryptSdkMessage as ae,isSDKUserMessage as ie,isAskUserMessage as oe,isAskUserResponseMessage as re,isSDKMessage as ce,createKeyPair as le,encryptAES as de,encryptWithEphemeralKey as pe,encryptSdkMessage as ue,machineAuth as me,getAgentContext as he,detectPreview as ge,IGNORED_DIRECTORIES as fe,DEFAULT_WORKER_EXECUTION_MODE as ye,getTaskExecutionMode as ve,isCompanionHeartbeatMessage as we,isCompanionMemoryOrganizationMessage as be,isCompanionReminderMessage as ke,workerAuth as xe}from"@agentrix/shared";import{randomBytes as Ie,randomUUID as Se,createHash as Te,createDecipheriv as Ce,createCipheriv as _e,createHmac as Ae,timingSafeEqual as Ee}from"node:crypto";import $e from"axios";import{m as Me,i as Pe,a as Re,l as De,p as Ne,c as Oe,b as Ue,d as je,g as Le,e as qe}from"./logger-CVvo37Gw.mjs";import He,{createInterface as Fe}from"node:readline";import*as Be from"fs";import{readFileSync as Ge,existsSync as We,unlinkSync as ze,openSync as Ke,writeFileSync as Ve,closeSync as Xe,mkdtempSync as Je,statSync as Ye,accessSync as Qe,constants as Ze,readdirSync as et,mkdirSync as tt,promises as nt}from"fs";import*as st from"path";import at,{join as it,dirname as ot,resolve as rt,parse as ct,sep as lt}from"path";import dt from"open";import{io as pt}from"socket.io-client";import{EventEmitter as ut}from"node:events";import{pipeline as mt}from"node:stream/promises";import{createRequire as ht}from"node:module";import{spawn as gt,execSync as ft}from"child_process";import yt from"ps-list";import vt from"cross-spawn";import{getPlatform as wt}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import bt from"fastify";import{z as kt,toJSONSchema as xt}from"zod";import{validatorCompiler as It,serializerCompiler as St}from"fastify-type-provider-zod";import{spawnSync as Tt,spawn as Ct,execSync as _t,execFile as At,execFileSync as Et}from"node:child_process";import{createSdkMcpServer as $t,query as Mt,tool as Pt,AbortError as Rt}from"@anthropic-ai/claude-agent-sdk";import{replacePromptPlaceholders as Dt,loadAgentConfig as Nt,getAgentContext as Ot,GitServerLocalStore as Ut,deriveLocalGitServerEncryptionKey as jt,validateGitLabPatToken as Lt,buildGitLabWebhookUrl as qt,buildGitLabWebhookEndpointPath as Ht}from"@agentrix/shared/node";import{mkdir as Ft,readFile as Bt,writeFile as Gt,readdir as Wt,rm as zt,unlink as Kt,lstat as Vt,opendir as Xt,realpath as Jt,stat as Yt,access as Qt}from"node:fs/promises";import{promisify as Zt}from"node:util";import en from"simple-git";import{EventEmitter as tn}from"events";import nn from"better-sqlite3";import{fileURLToPath as sn,pathToFileURL as an}from"url";import{Cron as on}from"croner";import{memoryStore as rn,normalizeGitLabWebhook as cn,resolveGitLabApiUrl as ln,GitLabWebhookBridge as dn,gitlabPipelineTarget as pn,composeVariables as un,defaultVariables as mn,staticVariables as hn}from"@xmz-ai/gitlab-webhook-bridge";import{McpServer as gn}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as fn}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{createConnection as yn}from"node:net";import{Worker as vn}from"node:worker_threads";import{randomUUID as wn}from"crypto";import{isSupportedPlatform as bn,NetworkManager as kn,SandboxManager as xn}from"@xmz-ai/sandbox-runtime";import*as In from"@larksuiteoapi/node-sdk";import{tmpdir as Sn,homedir as Tn}from"os";import Cn from"ws";import{readFile as _n,mkdir as An,appendFile as En,stat as $n}from"fs/promises";import{Codex as Mn}from"@openai/codex-sdk";import{stdin as Pn,stdout as Rn}from"node:process";import{createInterface as Dn}from"node:readline/promises";import"winston";import"node:url";const Nn=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_GEMINI_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function On(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Un(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 jn(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=On(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=On(s)))}async function Ln(e){return new Promise(t=>setTimeout(t,e))}function qn(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function Hn(e,t){const n=await Me.readDaemonState();if(!Pe(n)){const e="No daemon running, no state file found";return De.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=qn(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 De.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${qn(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 De.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function Fn(e,t){return await Hn("/session-started",{sessionId:e,metadata:t})}async function Bn(e,t,n){return await Hn("/devops-init-complete",{taskId:e,userId:t,action:n})}async function Gn(e,t){return await Hn("/devops-init-start",{taskId:e,userId:t})}async function Wn(e,t,n){const s="string"==typeof t?{content:t}:t;return await Hn("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function zn(){const e=await Me.readDaemonState();if(!e||"failed"===e.status)return!1;try{return process.kill(e.pid,0),Pe(e)}catch{return Re(e)?(De.debug("[DAEMON RUN] Starting daemon PID not running, cleaning up state"),await Vn()):(De.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await Vn()),!1}}async function Kn(){if(De.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await zn())return De.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await Me.readDaemonState();if(!Pe(e))return De.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=it(Ne(),"package.json"),n=JSON.parse(Ge(t,"utf-8")).version;return De.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return De.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function Vn(){try{await Me.clearDaemonState(),De.debug("[DAEMON RUN] Daemon state file removed")}catch(e){De.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function Xn(){try{const e=await Me.readDaemonState();if(!Pe(e)&&!Re(e))return void De.debug("No daemon state found");De.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await Hn("/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){De.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){De.debug("Error stopping daemon",e)}}function Jn(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function Yn(e,t){if($e.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?Jn(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?Jn(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?Jn(e.message):e instanceof Error?`${t}: ${e.message}`:t}function Qn(){return F(new Uint8Array(Ie(32)))}async function Zn(e,t,n,s){try{const a={id:e.machineId,metadata:JSON.stringify(t)};if(s&&n){const t=function(e){const t=function(e){if(!e.machineAesKey)return null;try{const t=G(e.machineAesKey);return 32===t.length?t:null}catch{return null}}(e);if(t)return t;const n=z();return e.machineAesKey=F(n),n}(e);a.dataEncryptionKey=B(s.publicKey,t,G(n))}await $e.post(`${Me.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(Yn(e,"Failed to sync machine data"))}}async function es(e){try{return(await $e.get(`${Me.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})).data}catch(e){throw new Error(Yn(e,"Stored machine credentials are no longer valid"))}}async function ts(){const e=await Me.readCredentials();if(e){const t=await es(e);let n=e;e.secret||(n={...e,secret:Qn()},await Me.writeCredentials(n),De.info("[AUTH] Generated missing local auth secret"));try{await Zn(n,Me.metadata()),De.info("[AUTH] Machine metadata synced")}catch(e){De.warn("[AUTH] Failed to sync machine metadata",e)}return De.info("[AUTH] Using existing credentials"),{...n,cloudId:t.cloudId}}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=Me.generateMachineId();n={token:t,secret:Qn(),machineId:e},De.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=Me.generateMachineId(),t=new Uint8Array(Ie(32)),n=await W(t);try{console.log(`[AUTH] Sending auth request to: ${Me.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${F(n.publicKey).substring(0,20)}...`);const t={machineId:e};await $e.post(`${Me.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(Yn(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:F(e,"base64"),machineId:t},s=JSON.stringify(n),a=F((new TextEncoder).encode(s),"base64url");return`${Me.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?(De.debug("[browser] Headless environment detected, skipping browser open"),!1):(De.debug(`[browser] Attempting to open URL: ${e}`),await dt(e),De.debug("[browser] Browser opened successfully"),!0)}catch(e){return De.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 $e.get(`${Me.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=K(G(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${Yn(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 Ln(1e3)}}finally{process.off("SIGINT",a)}return{token:null,userPublicKey:null}}(e,t)}(n,e);return s.token?{credentials:{token:s.token,secret:F(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}if(await Zn(n,Me.metadata(),a,s),await Me.writeCredentials(n),De.info("[AUTH] Machine setup completed"),t)try{const e=await es(n);return{...n,cloudId:e.cloudId}}catch(e){De.warn("[AUTH] Failed to resolve cloud id after setup",e)}return 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=Nn.has(t);(n||o)&&(e[t]=i,Un(e,t,i),jn(e,t,i))}}(e,function(e=process.env){const t=E(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?On(t):E(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))}();const ns=Oe(import.meta.url),ss=new Set(["authorization","apikey","accesstoken","refreshtoken","machineaeskey","key","password","pat","secret","token"]);class as{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 is(e){if(!e||"object"!=typeof e)return{message:String(e??"unknown error")};const t=e,n=function(e){const t=V.safeParse(e);return t.success?t.data:null}(t.data);return n?{message:n.message||t.message||"Socket connection failed",...n.code?{code:n.code}:{},...n.action?{action:n.action}:{}}:{message:t.message||"unknown socket error"}}function os(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=is(e);if(n.code||n.action)return[n.code?`[${n.code}]`:void 0,n.message,n.action].filter(Boolean).join(" ");const s=[];return t.message&&s.push(t.message),t.type&&s.push(`type=${t.type}`),void 0!==t.description&&s.push(`description=${cs(t.description)}`),void 0!==t.data&&s.push(`data=${cs(t.data)}`),void 0!==t.context&&s.push(`context=${cs(t.context)}`),s.filter(Boolean).join(" ")||"unknown socket error"}function rs(e,t=0){if(t>8)return"[MaxDepth]";if(Array.isArray(e))return e.map(e=>rs(e,t+1));if(!e||"object"!=typeof e)return e;const n={};for(const[s,a]of Object.entries(e)){const e=s.replace(/[-_]/g,"").toLowerCase();n[s]=ss.has(e)?"[REDACTED]":rs(a,t+1)}return n}function cs(e){try{return JSON.stringify(rs(e))}catch{return"[Unserializable]"}}function ls(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};const t=e,n=t.data&&"object"==typeof t.data&&!Array.isArray(t.data)?t.data:void 0,s={},a=["eventId","taskId","chatId","from","senderType","messageType","opCode","sequence","status"];for(const e of a)void 0!==t[e]&&(s[e]=t[e]);void 0!==n?.sequence&&(s.ackSequence=n.sequence),void 0!==t.message&&(s.hasMessage=!0),"string"==typeof t.encryptedMessage&&(s.encrypted=!0,s.encryptedMessageChars=t.encryptedMessage.length);const i=new Set(a),o=Object.keys(t).filter(e=>!i.has(e)&&"message"!==e&&"encryptedMessage"!==e);return o.length>0&&(s.extraKeys=o.sort()),s}class ds{socket=null;config;eventHandlers=new Map;eventEmitter=new ut;KeepAliveManager=null;healthCheckInterval=null;connectStartedAt=null;reconnectTimer=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new as(e.keepAliveConfig))}connect(){if(this.socket)return void this.targetLogger.debug("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.connectStartedAt=Date.now(),this.socket=pt(e,a),this.setupSocketHandlers(),this.targetLogger.debug(`Connecting to ${e}`)}disconnect(){this.socket&&(this.targetLogger.info("Disconnecting"),this.clearReconnectTimer(),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.targetLogger.debug(`received event ${e}, summary: ${cs(ls(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.targetLogger.debug(`received event with ack ${e}, summary: ${cs(ls(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.targetLogger.debug(`send event ${e}, summary: ${cs(ls(t))}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.targetLogger.warn("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.targetLogger.debug(`send event ${e}, summary: ${cs(ls(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",()=>{const e=this.connectStartedAt?Date.now()-this.connectStartedAt:void 0;this.connectStartedAt=null,this.targetLogger.info(`socket.connected host=${this.config.serverUrl}${void 0!==e?` connectMs=${e}`:""}`),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.targetLogger.info(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck(),"io server disconnect"===e&&this.scheduleReconnect("server disconnect")}),this.socket.on("connect_error",e=>{this.targetLogger.warn(`Connection error: ${os(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.targetLogger.warn(`Socket error: ${os(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}scheduleReconnect(e){this.socket&&!this.reconnectTimer&&(this.targetLogger.info(`Scheduling reconnect after ${e}`),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.socket?.connect()},1e3),this.reconnectTimer.unref?.())}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}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.targetLogger.warn("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)}get targetLogger(){return this.config.logger??ns}}const ps="attachment",us={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function ms(){const e=E(Me.agentrixHomeDir,"tmp","channel-files");return r(e)||d(e,{recursive:!0}),e}function hs(e){const t=function(e){if(!e)return;return $(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||ps;return E(ms(),`${Se()}-${t}`)}function gs(e){const t=P(ms()),n=P(e);if(n!==t&&!n.startsWith(`${t}${R}`))throw new Error("Access denied: channel attachment path is outside channel files directory");return n}async function fs(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=vs(t);return e?`${ps}${e}`:void 0}if(M(e))return e;const n=vs(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=hs(n),a=l(s);return await mt(e.body,a),s}async function ys(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=$(new URL(e).pathname);return M(t)?t:void 0}catch{return}}(e);return fs(s,t||a)}function vs(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?us[t]:void 0}var ws,bs,ks,xs={},Is={"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}},Ss=(ks||(ks=1,function(e){var t,n,s,a=bs?ws:(bs=1,ws=Is),i=at.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),d=s.indexOf(i.source);if("application/octet-stream"!==n[c]&&(l>d||l===d&&"application/"===n[c].substr(0,12)))continue}n[c]=e}}})}(xs)),xs);function Ts(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return gs(decodeURIComponent(e))}return Me.resolveWorkspaceFilePath(e,t,n)}function Cs(e,t){e?e.send("workspace-file-response",t):De.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function _s(e,t){e?e.send("workspace-file-mutation-response",t):De.error("[WORKSPACE] Cannot send workspace-file-mutation-response: client not available")}function As(e,t,n,s){return{eventId:X(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function Es(e,t,n,s){return{eventId:X(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function $s(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,operation:r,content:c,createOnly:l}=t;De.debug(`[WORKSPACE] File mutation request: taskId=${n}, userId=${s}, relativePath=${a}, operation=${r}, createOnly=${!!l}`);try{if(a.startsWith("channel-attachment/"))return void _s(e.client,Es(o,n,"permission_denied","Channel attachments are read-only"));const t=Ts(s,n,a);if(!function(e,t,n,s){const a=n.replace(/^\/+/,""),i="project"===a||a.startsWith("project/")?"project":"data"===a||a.startsWith("data/")?"data":"",o=_.normalize(Me.resolveWorkspaceFilePath(e,t,i)),r=_.normalize(s);return r===o||r.startsWith(o+_.sep)}(s,n,a,t))return void _s(e.client,Es(o,n,"permission_denied","Path escapes workspace"));if("delete"===r)return await i.promises.rm(t,{force:!1}),void _s(e.client,{eventId:X(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r}});if(void 0===c)return void _s(e.client,Es(o,n,"bad_request","File content is required"));await i.promises.mkdir(_.dirname(t),{recursive:!0});try{await i.promises.writeFile(t,c,l?{flag:"wx"}:void 0)}catch(t){if("EEXIST"===t.code)return void _s(e.client,Es(o,n,"file_exists","File already exists"));throw t}const d=await i.promises.stat(t);_s(e.client,{eventId:X(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r,modifiedAt:d.mtime.toISOString()}})}catch(t){De.error(`[WORKSPACE] Failed to handle workspace-file-mutation-request: ${t.message}`,t);const s="ENOENT"===t.code?"file_not_found":"EACCES"===t.code?"permission_denied":"unknown_error";_s(e.client,Es(o,n,s,t.message))}}}function Ms(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;De.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,d=Ts(s,n,a);if(!i.existsSync(d))return De.warn(`[WORKSPACE] File not found: ${d}`),void Cs(e.client,As(o,n,"file_not_found","File or directory not found"));const p=await i.promises.stat(d),u=p.mtime.toISOString();if(c&&u===c)return void function(e,t,n,s){De.debug(`[WORKSPACE] File not modified: ${s}`),Cs(e,{eventId:X(),requestId:t,taskId:n,success:!0,notModified:!0})}(e.client,o,n,d);if(p.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=_.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}}));Cs(e,{eventId:X(),requestId:t,taskId:n,success:!0,data:{type:"directory",entries:c,metadata:{size:0,modifiedAt:a.mtime.toISOString()}}})}(e.client,o,n,d,p,t);{const s=Ss.lookup(d)||"application/octet-stream";return p.size>t?void function(e,t,n,s,a,i,o){De.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),Cs(e,{eventId:X(),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,d,p,s,t):void await async function(e,t,n,s,a,o){const r=Ss.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 Me.getSecretKey();if(!t)return De.warn("[WORKSPACE] Machine secret key not available"),null;const n=G(e);return K(n,t)||(De.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return De.warn("[WORKSPACE] Error decrypting dataEncryptionKey:",e),null}}(o));const d={type:"file",metadata:{size:a.size,mimeType:r,modifiedAt:a.mtime.toISOString()}};l?d.encryptedContent=J(c,l):d.content=c,Cs(e,{eventId:X(),requestId:t,taskId:n,success:!0,data:d})}(e.client,o,n,d,p,l)}}catch(t){De.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";Cs(e.client,As(o,n,s,t.message))}}}function Ps(e,t){return{eventId:X(),status:"failed",opCode:e,message:t}}function Rs(e,t){const n=_.relative(t,e);if(n.startsWith("..")||_.isAbsolute(n))throw new Error("Vision Plan review path is outside the bound issue directory")}const Ds=100,Ns=[{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 Os{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}withMetadata(e,t={}){return{data:e,metadata: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();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 De.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{data:await o.json(),headers:o.headers,status:o.status}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw De.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();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 De.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 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 De.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:Ds,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:Ds,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===Ds){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:Ds,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<Ds)break;t+=1}}return s}async executeOperation(e,t,n={}){return(await this.executeOperationWithMetadata(e,t,n)).data}async executeOperationWithMetadata(e,t,n={}){n.silent||De.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let s;switch(e){case"listRepos":s=this.withMetadata(await this.listRepos());break;case"listBranches":s=this.withMetadata(await this.listBranches(t.owner,t.name));break;case"createMergeRequest":s=this.withMetadata(await this.createMergeRequest(t));break;case"getMergeRequest":s=this.withMetadata(await this.getMergeRequest(t.owner,t.name,t.iid));break;case"listMergeRequests":s=this.withMetadata(await this.listMergeRequests(t.owner,t.name));break;case"triggerPipeline":s=this.withMetadata(await this.triggerPipeline(t));break;case"ensurePipelineTriggerToken":s=this.withMetadata(await this.ensurePipelineTriggerToken(t));break;case"requestGitlabApi":s=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":s=this.withMetadata({authMode:"local_pat",hasPat:!0});break;default:throw{status:400,message:`Unknown operation: ${e}`}}return n.silent||De.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,s.data)}`),s}catch(t){const s=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw n.silent||De.error(`${this.logPrefix()} operation failed: op=${e}, message=${s}`),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 Ns.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}`};if("GET"===t){const e=await this.requestWithResponse(a,t);return this.withMetadata(e.data,{status:e.status})}const i=await this.requestWithResponse(a,t,e.body);return this.withMetadata(i.data,{status:i.status})}}function Us(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function js(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function Ls(e){return $e.isAxiosError(e)?{message:e.message,status:e.response?.status,code:e.code}:{message:e instanceof Error?e.message:String(e)}}async function qs(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 $e.get(Us(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 Hs(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){De.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${js(Us(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await qs(e,a);return De.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=Ls(t);De.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 Fs(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 Bs(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}}(E(Me.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:Fs(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=E(Me.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)}De.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${js(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 Hs(e))n.add(t)}catch(t){const n=Ls(t);s.push({source:e.source,baseUrl:js(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?De.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):De.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function Gs(e,t){return{eventId:X(),status:"failed",opCode:e,message:t}}function Ws(e,t){De.info(`[GITLAB PROXY] reqId=${e.requestId}, gitServer=${e.gitServerId}, method=${t.method}, path=${t.path}, status=${t.status}, elapsedMs=${t.elapsedMs}`)}function zs(e){return async(t,n)=>{if(De.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 De.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(Gs(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&De.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){De.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function Ks(e){return async(t,n)=>{De.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&&De.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){De.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function Vs(e){return async(t,n)=>{if(De.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return De.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(Gs(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await Bs(t.agentType);if(0===e.length&&!s)return De.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(Gs(t.eventId,"No models available from configured endpoints"));De.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:X(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){De.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function Xs(e){return async t=>{De.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function Js(e){return async(t,n)=>{De.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&&De.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){De.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function Ys(e){return async(t,n)=>{De.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&&De.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){De.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function Qs(e){return async(t,n)=>{De.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&&De.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){De.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(Gs(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function Zs(e){return async t=>{De.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||De.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function ea(e){return async t=>{const n=Date.now(),s=("string"==typeof(a=t.payload).method&&a.method.trim().length>0?a.method.trim():"GET").toUpperCase();var a;const i=function(e){return"string"==typeof e.path&&e.path.length>0?e.path:"-"}(t.payload),o=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?e.client.send("daemon-gitlab-response",s):De.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=t.accessToken?.trim();if(!e){const e=Date.now()-n;return De.warn(`[GITLAB PROXY] access token missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),Ws(t,{method:s,path:i,status:0,elapsedMs:e}),void o({success:!1,errorCode:"PAT_MISSING",errorMessage:`No access token provided for git server ${t.gitServerId}`,executionTimeMs:e})}const a=t.payload.apiUrl;if(!a){const e=Date.now()-n;return De.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),Ws(t,{method:s,path:i,status:0,elapsedMs:e}),void o({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:e})}const r=new Os(a,e,{requestId:t.requestId,gitServerId:t.gitServerId}),c=await r.executeOperationWithMetadata(t.operation,t.payload,{silent:!0}),l=Date.now()-n;Ws(t,{method:s,path:i,status:c.metadata.status??200,elapsedMs:l}),o({success:!0,data:c.data,executionTimeMs:l})}catch(e){const a=e;let r="GITLAB_CONNECTIVITY_FAILED";401===a.status?r="PAT_INVALID":403===a.status?r="PAT_SCOPE_INSUFFICIENT":404===a.status&&(r="RESOURCE_NOT_FOUND");const c="string"==typeof a.message?a.message:"Unknown error",l="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,d=function(e){return"number"==typeof e.status?e.status:0}(a),p=Date.now()-n;Ws(t,{method:s,path:i,status:d,elapsedMs:p}),De.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${r}, status=${d}, message=${c}${l?`, detail=${l}`:""}`),o({success:!1,errorCode:r,errorMessage:c,executionTimeMs:p})}}}function ta(e){return async(t,n)=>{e.machineControl?e.machineControl.handleCommand(t,n):n(Gs(t.eventId,"Machine control is not available"))}}function na(e){return async(t,n)=>{if(e.workspaceStatusSync)try{await e.workspaceStatusSync.applyCacheUpdate(t),n({eventId:X(),status:"success",opCode:t.eventId})}catch(e){De.warn("[WORKSPACE SYNC] Failed to apply workspace cache update",e),n(Gs(t.eventId,e instanceof Error?e.message:"Failed to apply workspace cache update"))}else n(Gs(t.eventId,"Workspace sync is not available"))}}function sa(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)}const aa=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function ia(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return gs(decodeURIComponent(e))}return Me.resolveWorkspaceFilePath(e,t,n)}class oa{client;machineId;machineControl;iceServers=[];sessions=new Map;rtcModule={};peerConstructor;constructor(e,t,n){this.client=e,this.machineId=t,this.machineControl=n;const s=ht(import.meta.url);try{this.rtcModule=s("node-datachannel"),this.peerConstructor=(a=this.rtcModule).RTCPeerConnection||a.PeerConnection||a.RTCConnection||a.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}catch(e){const t=e instanceof Error?e.message:String(e);De.warn(`[RTC] node-datachannel unavailable; RTC support disabled: ${t}`)}var a}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))):De.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:X()})}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),De.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void De.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId)){const n=this.sessions.get(e.sessionId);return De.info(`[RTC] Reusing session: session=${e.sessionId}, requested=${e.requestedChannels?.join(",")||"default"}, allowed=${n?.allowedChannels.join(",")||"none"}, task=${s??"none"}`),void this.sendMachineRtcResponse(e.sessionId,t,!0,void 0,n?.allowedChannels)}const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,allowedChannels:this.normalizeAllowedChannels(e),peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),De.info(`[RTC] Accepted session request: session=${e.sessionId}, requested=${e.requestedChannels?.join(",")||"default"}, allowed=${i.allowedChannels.join(",")||"none"}, rejected=${e.rejectedChannels?.join(",")||"none"}, task=${s??"none"}`),this.sendMachineRtcResponse(e.sessionId,t,!0,void 0,i.allowedChannels)}sendMachineRtcResponse(e,t,n,s,a=["file"]){De.info(`[RTC] Sending session response: session=${e}, accepted=${n}, allowed=${a.join(",")||"none"}, reason=${s??"none"}`),this.client.send("machine-rtc-response",{eventId:X(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0,allowedChannels:a}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void De.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,allowedChannels:["file"],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){De.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{De.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{De.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:X(),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:X(),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?.(()=>{De.info(`[RTC] Data channel open: session=${e.sessionId}, allowed=${e.allowedChannels.join(",")||"none"}, task=${e.allowedTaskId??"none"}`),e.lastActivity=Date.now(),sa(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?.(()=>{De.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{De.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{Q(new Uint8Array(t))}catch(e){De.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 De.warn("[RTC] Non-JSON message",n)}if(s&&"string"==typeof s.type){if(!this.isChannelAllowed(e,s.channel))return De.warn(`[RTC] Unauthorized channel message: session=${e.sessionId}, type=${s.type}, channel=${s.channel}, allowed=${e.allowedChannels.join(",")||"none"}`),void this.sendControl(e,{v:1,type:`${s.channel}.error`,channel:s.channel,requestId:s.requestId,streamId:s.streamId,timestamp:(new Date).toISOString(),error:{code:"forbidden",message:`RTC channel ${s.channel} is not authorized`}});if("file.request"!==s.type){if("file.mutate"!==s.type)return"storage.start"===s.type?(De.info(`[RTC][storage] Received start message: session=${e.sessionId}, request=${s.requestId}, stream=${s.streamId}`),void this.handleStorageStart(e,s)):"storage.cancel"===s.type?(De.info(`[RTC][storage] Received cancel message: session=${e.sessionId}, request=${s.requestId}, stream=${s.streamId}`),void this.handleStorageCancel(e,s)):void 0;this.handleFileMutation(e,s).catch(e=>{De.error("[RTC] Failed to handle file mutation",e)})}else this.handleFileRequest(e,s).catch(e=>{De.error("[RTC] Failed to handle file request",e)})}}normalizeAllowedChannels(e){const t=e.allowedChannels?.length?e.allowedChannels:["file"];return Array.from(new Set(t))}isChannelAllowed(e,t){return"control"===t||e.allowedChannels.includes(t)}handleStorageStart(e,t){if(!this.machineControl)return De.warn(`[RTC][storage] Rejecting start; machine control unavailable: session=${e.sessionId}`),void this.sendStorageError(e,t,"capability_missing","Machine control is not available");const n=t.payload;if(!n)return De.warn(`[RTC][storage] Rejecting start; missing payload: session=${e.sessionId}, request=${t.requestId}`),void this.sendStorageError(e,t,"operation_failed","Storage start payload is required");De.info(`[RTC][storage] Starting operation: session=${e.sessionId}, op=${n.opCode}, action=${n.action}, target=${n.target.cloudId?`${n.target.cloudId}:`:""}${n.target.machineId}, expiresAt=${n.expiresAt??"none"}`);const s={eventId:n.opCode,target:n.target,action:n.action,params:n.params,requestedAt:n.requestedAt,expiresAt:n.expiresAt},a=this.machineControl.startStorageManagement(s,n=>{this.sendStorageProgress(e,t,n)});if("success"!==a.status){const s=a.data;return De.warn(`[RTC][storage] Operation rejected: session=${e.sessionId}, op=${n.opCode}, code=${s?.errorCode??"operation_failed"}, message=${a.message??"none"}`),void this.sendStorageError(e,t,s?.errorCode??"operation_failed",a.message||"Storage operation failed")}De.info(`[RTC][storage] Operation accepted: session=${e.sessionId}, op=${n.opCode}, action=${n.action}`),this.sendControl(e,{v:1,type:"storage.accepted",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{opCode:n.opCode}})}handleStorageCancel(e,t){if(!this.machineControl||!t.payload?.opCode)return void De.warn(`[RTC][storage] Ignoring cancel; machine control or op missing: session=${e.sessionId}`);De.info(`[RTC][storage] Cancelling operation: session=${e.sessionId}, op=${t.payload.opCode}`);const n=this.machineControl.cancelStorageManagement(t.payload.opCode,n=>{this.sendStorageProgress(e,t,n)});if("success"!==n.status){const s=n.data;De.warn(`[RTC][storage] Cancel rejected: session=${e.sessionId}, op=${t.payload.opCode}, code=${s?.errorCode??"operation_failed"}, message=${n.message??"none"}`),this.sendStorageError(e,t,s?.errorCode??"operation_failed",n.message||"Storage cancel failed")}}sendStorageProgress(e,t,n){const s=n.result&&"object"==typeof n.result?n.result.phase:void 0,a=`[RTC][storage] Sending progress: session=${e.sessionId}, op=${n.opCode}, status=${n.status}, phase=${"string"==typeof s?s:"none"}, message=${n.message??n.errorMessage??"none"}`;"running"===n.status?De.debug(a):De.info(a),this.sendControl(e,{v:1,type:"storage.progress",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:{progress:n}})}sendStorageError(e,t,n,s){De.warn(`[RTC][storage] Sending error: session=${e.sessionId}, request=${t.requestId}, code=${n}, message=${s}`),this.sendControl(e,{v:1,type:"storage.error",channel:"storage",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:n,message:s}})}validateFilePayload(e,t){const n=t.payload;return n?n.userId!==e.workspaceUserId?(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"}}),null):e.allowedTaskId&&n.taskId!==e.allowedTaskId?(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"}}),null):n:null}assertWorkspacePath(e,t,n){if(n.startsWith("channel-attachment/"))throw Object.assign(new Error("Channel attachments are read-only"),{code:"permission_denied"});const s=ia(e,t,n);if(!function(e,t,n,s){const a=n.replace(/^\/+/,""),i="project"===a||a.startsWith("project/")?"project":"data"===a||a.startsWith("data/")?"data":"",o=_.normalize(Me.resolveWorkspaceFilePath(e,t,i)),r=_.normalize(s);return r===o||r.startsWith(o+_.sep)}(e,t,n,s))throw Object.assign(new Error("Path escapes workspace"),{code:"permission_denied"});return s}async handleFileRequest(e,t){const n=this.validateFilePayload(e,t);if(!n)return;const s=ia(n.userId,n.taskId,n.relativePath);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 a=await i.promises.stat(s);if(!function(e,t){return!t||e.mtime.toISOString()!==t}(a,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(a.isDirectory()||"directory"===n.entryType){const n=await i.promises.readdir(s,{withFileTypes:!0}),o={entries:await Promise.all(n.map(async e=>{const t=_.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:a.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:o})}const o=1024*(n.maxFileSizeMB??aa)*1024;if(a.size>o)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 r=Ss.lookup(s)||"application/octet-stream",c={size:a.size,mimeType:"string"==typeof r?r:"application/octet-stream",modifiedAt:a.mtime.toISOString()};this.sendControl(e,{v:1,type:"file.meta",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:c}),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:a.size}})}async handleFileMutation(e,t){const n=this.validateFilePayload(e,t);if(n)try{const s=this.assertWorkspacePath(n.userId,n.taskId,n.relativePath);if("delete"===n.operation)return await i.promises.rm(s,{force:!1}),void this.sendMutationAck(e,t,{relativePath:n.relativePath,operation:n.operation});if(void 0===n.content)throw Object.assign(new Error("File content is required"),{code:"bad_request"});await i.promises.mkdir(_.dirname(s),{recursive:!0});try{await i.promises.writeFile(s,n.content,n.createOnly?{flag:"wx"}:void 0)}catch(e){if("EEXIST"===e.code)throw Object.assign(new Error("File already exists"),{code:"file_exists"});throw e}const a=await i.promises.stat(s);this.sendMutationAck(e,t,{relativePath:n.relativePath,operation:n.operation,modifiedAt:a.mtime.toISOString()})}catch(n){this.sendControl(e,{v:1,type:"file.error",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),error:{code:n.code||"unknown_error",message:n.message||"File mutation failed"}})}}sendMutationAck(e,t,n){this.sendControl(e,{v:1,type:"file.mutation_ack",channel:"file",requestId:t.requestId,streamId:t.streamId,timestamp:(new Date).toISOString(),payload:n})}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=Z.Binary|(0===o?Z.Start:0),a=Buffer.isBuffer(e)?e:Buffer.from(e),i=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),r=ee({streamId:t,seq:o,flags:n,payloadLength:i.length},i);sa(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=ee({streamId:t,seq:o,flags:Z.End|Z.Binary,payloadLength:0},new Uint8Array);sa(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&sa(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){De.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 ra{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new ds(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client,machineControl:n.machineControl,workspaceStatusSync:n.workspaceStatusSync},this.rtcManager=new oa(this.client,s,n.machineControl),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 120 seconds"))},12e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{(function(e){return is(e).message.includes("Machine route already has an active daemon socket")})(e)||(clearTimeout(n),t(e))}),this.client.connect()})}async disconnect(){this.client.connected&&(await this.client.flush(5e3).catch(()=>{}),await this.prepareServerDisconnect().catch(()=>{})),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":zs(t=this.context),"resume-task":Ks(t),"list-models":Vs(t),"stop-task":Zs(t),"deploy-agent":Js(t),"hive-publish":Ys(t),"hive-install":Qs(t),"shutdown-machine":Xs(t),"workspace-file-request":Ms({client:t.client}),"workspace-file-mutation-request":$s({client:t.client}),"vision-plan-review-write":async(e,t)=>{const n="string"==typeof e?.eventId?e.eventId:"vision-plan-review-write";try{const s=Y.parse(e);!function(e){if(!/^[A-Za-z0-9._-]+$/.test(e)||e.includes(".."))throw new Error("Invalid Vision Plan issue id")}(s.issueId);const a=`project/.agentrix/issues/${s.issueId}/review/user`;if(s.reviewDirRelativePath!==a)return void t(Ps(n,"Vision Plan review write path does not match the bound issue"));const o=Me.resolveWorkspaceFilePath(s.userId,s.taskId,a);Rs(o,Me.resolveWorkspaceFilePath(s.userId,s.taskId,`project/.agentrix/issues/${s.issueId}`));const r=await async function(e){await i.promises.mkdir(e,{recursive:!0});let t=(await i.promises.readdir(e).catch(()=>[])).reduce((e,t)=>{const n=/^(\d{3})(?:-|\.md$)/.exec(t);return n?Math.max(e,Number(n[1])):e},0)+1;for(;;){const n=`${String(t).padStart(3,"0")}-vision-plan-review.md`,s=_.join(e,n);try{const e=await i.promises.open(s,"wx");return await e.close(),s}catch(e){if("EEXIST"!==e.code)throw e;t+=1}}}(o);Rs(r,o),await i.promises.writeFile(r,s.content.endsWith("\n")?s.content:`${s.content}\n`,"utf8");const c=_.posix.join(a,_.basename(r)).replace(/^project\//,"");t({eventId:X(),status:"success",opCode:s.eventId,data:{relativePath:c}})}catch(e){De.error("[VisionPlanReviewWrite] Failed to write review:",e),t(Ps(n,e instanceof Error?e.message:"Failed to write Vision Plan review"))}},"daemon-gitlab-request":ea(t),"machine-control-command":ta(t),"workspace-cache-update":na(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.onEventWithAck("machine-control-command",e["machine-control-command"]),this.client.onEventWithAck("workspace-cache-update",e["workspace-cache-update"]),this.client.onEvent("shutdown-machine",e["shutdown-machine"]),this.client.onEvent("workspace-file-request",e["workspace-file-request"]),this.client.onEvent("workspace-file-mutation-request",e["workspace-file-mutation-request"]),this.client.onEventWithAck("vision-plan-review-write",e["vision-plan-review-write"]),this.client.onEvent("daemon-gitlab-request",e["daemon-gitlab-request"])}async prepareServerDisconnect(){const e={eventId:X(),machineId:this.context.machineId,timestamp:(new Date).toISOString()},t=await(n=this.client.sendWithAck("machine-disconnect-prepare",e),new Promise((e,t)=>{const s=setTimeout(()=>{t(new Error("Timed out after 5000ms"))},5e3);n.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})}));var n;if("success"!==t.status)throw new Error(t.message||"Machine disconnect prepare failed")}}let ca=null;let la=!1;async function da(){if(la)De.info("[caffeinate] Already stopping, skipping");else if(ca&&!ca.killed){la=!0,De.info(`[caffeinate] Stopping caffeinate process PID ${ca.pid}`);try{ca.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),ca&&!ca.killed&&ca.kill("SIGKILL"),ca=null,la=!1}catch(e){De.info("[caffeinate] Error stopping caffeinate:",e),la=!1}}}let pa=!1;function ua(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(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function ma(){try{let e;e="win32"===process.platform?await async function(){try{const e=ft("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 yt()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=ua(n);e&&t.push(e)}return t}catch(e){return[]}}function ha(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:ft(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function ga(){const e=wt(),t=function(){const e=ha("git"),t=ha("claude"),n=ha("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=ha("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=ha("bwrap"),t=ha("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 fa(){const e=ga(),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 ya(){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:Me.agentrixHomeDir,serverUrl:Me.serverUrl,logsDir:Me.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 va(e){if(e||(e="all"),console.log(H.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(H.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${H.green(Ue.version)}`),console.log(`Platform: ${H.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${H.green(process.version)}`),console.log(""),console.log(H.bold("🔧 Daemon Spawn Diagnostics"));const e=Ne(),t=E(e,"bin","agentrix.mjs"),n=E(e,"dist","index.mjs");console.log(`Project Root: ${H.blue(e)}`),console.log(`Wrapper Script: ${H.blue(t)}`),console.log(`CLI Entrypoint: ${H.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?H.green("✓ Yes"):H.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?H.green("✓ Yes"):H.red("❌ No")}`),console.log(""),console.log(H.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${H.blue(Me.agentrixHomeDir)}`),console.log(`Server URL: ${H.blue(Me.serverUrl)}`),console.log(`Logs Dir: ${H.blue(Me.getStatePaths().logsDir)}`),console.log(H.bold("\n🌍 Environment Variables"));const s=ya();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?H.green(s.AGENTRIX_HOME_DIR):H.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?H.green(s.AGENTRIX_SERVER_URL):H.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?H.yellow("ENABLED"):H.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?H.green(s.DEBUG):H.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?H.green(s.NODE_ENV):H.gray("not set")}`),console.log(H.bold("\n🔐 Authentication"));try{await Me.readCredentials()?console.log(H.green("✓ Authenticated (credentials found)")):console.log(H.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(H.red("❌ Error reading credentials"))}!function(e=!1){const t=ga(),n=wt();console.log(H.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(H.green(`✓ ${n.name}`),H.gray(`- ${n.description}`)),e&&n.path&&console.log(H.gray(` Location: ${n.path}`));else{const e=n.required?H.red("❌"):H.yellow("⚠️");console.log(`${e} ${n.name}`,H.gray(`- ${n.description}`)),n.installCommand&&console.log(H.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(H.bold("\n🔒 Sandbox Dependencies")),console.log(H.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(H.green(`✓ ${n.name}`),H.gray(`- ${n.description}`)),e&&n.path&&console.log(H.gray(` Location: ${n.path}`))):(console.log(H.red(`❌ ${n.name}`),H.gray(`- ${n.description}`)),n.installCommand&&console.log(H.blue(` Install: ${n.installCommand}`)))}else console.log(H.bold("\n🔒 Sandbox Dependencies")),console.log(H.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(H.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(H.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(H.red(` • ${t.name}`));console.log(H.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(H.bold("\n🤖 Daemon Status"));try{const t=await zn(),n=await Me.readDaemonState();if(t&&Pe(n)?(console.log(H.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(H.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(H.red("❌ Daemon is not running")),n){console.log(H.bold("\n📄 Daemon State:"));const e=Me.getStatePaths();console.log(H.blue(`Location: ${e.daemonStateFile}`)),console.log(H.gray(JSON.stringify(n,null,2)))}const s=await ma();if(s.length>0){console.log(H.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(H.blue(`\n${{daemon:"🤖 Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?H.cyan:e.includes("daemon")?H.blue:H.gray;console.log(` ${s(`PID ${t}`)}: ${H.gray(n)}`)})})}else console.log(H.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(H.bold("\n💡 Process Management")),console.log(H.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(H.red("❌ Error checking daemon status"))}}let wa=null;async function ba(){const e=Ca(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(wa&&wa.expiresAt>Date.now()&&wa.overridesSignature===t)return wa.openers;const n=xa(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 wa={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function ka(e){const t=process.platform;if("darwin"===t)return function(e){const t=Ia(e),n=[];if(t){const e=Ra(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"),Sa($a("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=Ea("powershell")?"powershell":Ea("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=Ia(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${Pa(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return Sa($a(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=Ia(e);if(Ea("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return Sa($a("zenity",e,{captureOutput:!0}))}if(Ea("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),Sa($a("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 xa(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:()=>_a("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>_a("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>_a("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>_a("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>_a("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?Ea("osascript")&&Aa("Terminal"):"win32"===e?Ea("wt")||Ea("powershell")||Ea("pwsh")||Ea("cmd"):"linux"===e&&Boolean(Ta())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(Ea("wt"))return void Ma("wt",["-d",e]);const t=Ea("powershell")?"powershell":Ea("pwsh")?"pwsh":null;return t?void Ma(t,["-NoExit","-Command",`Set-Location -LiteralPath '${Pa(e)}'`]):void Ma("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=Ta();if(!t)throw new Error("No supported terminal is available");return void Ma(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!$a("osascript",["-e",'tell application "Terminal"',"-e",`do script "${Ra(`cd ${Da(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?Ea("open"):"win32"===e||"linux"===e&&(Ea("xdg-open")||Ea("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return Ea("xdg-open")?void $a("xdg-open",[e]):void $a("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}$a("explorer",[e])}else $a("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?Ea("osascript"):"win32"===e?Ea("powershell")||Ea("pwsh"):"linux"===e&&Ea("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");$a("gio",["open","--ask",e])}else $a(Ea("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${Pa(e)}'`]);else if(null===$a("osascript",["-e",`set targetPath to POSIX file "${Ra(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??Ca();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=>Aa(e)):A.isAbsolute(e)||e.includes(A.sep)?r(e):Ea(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!$a(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 Ia(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!p(t).isDirectory())return}catch{return}return t}}function Sa(e){if(!e)return null;return e.trim()||null}function Ta(){const e=Da(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&Ea(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${Da(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 ${Da(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${Da(t)} && exec ${e}`]}].find(e=>Ea(e.command))??null}function Ca(){try{const e=Me.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return De.warn("[OPENERS] Failed to read opener overrides",e),{}}}function _a(e,t,s){return"darwin"===t?function(e,t){if(Ea("mdfind")){const t=$a("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(Ea("plutil")){const t=[A.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=$a("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){De.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>Aa(e))}(e,s):"win32"===t?function(e){return Ea("reg")&&(Boolean($a("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean($a("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(Ea("xdg-settings")){const t=$a("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(Ea("gio")){const t=$a("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function Aa(e){return"darwin"===process.platform&&Boolean($a("open",["-Ra",e]))}function Ea(e){return"win32"===process.platform?Boolean($a("where",[e])):Boolean($a("sh",["-c",`command -v ${e}`]))}function $a(e,t,n){const s=Tt(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&&De.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function Ma(e,t){Ct(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function Pa(e){return e.replace(/'/g,"''")}function Ra(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Da(e){return`'${e.replace(/'/g,"'\\''")}'`}function Na(e,t){if(t){const n=N(t,e),s=!n||n.startsWith("..")||O(n)?$(e):n;return E(t,"versions",s)}let n=D(e),s=0;for(;s<10;){if(r(E(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return E(n,"versions",t)}const t=D(n);if(t===n)break;n=t,s++}const a=D(e),i=$(e);return E(a,`.${i}.version`)}function Oa(e,t){const n=Na(e,t);if(!r(n))return"0.0.0";try{return c(n,"utf-8").trim()}catch(e){return"0.0.0"}}function Ua(e,t,n){try{const s=Na(e,n),a=D(s);r(a)||d(a,{recursive:!0}),u(s,t,"utf-8")}catch(e){}}function ja(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 La(e,t,n){const s=Oa(e,n),a=ja(t.metadata.version,s);if(!r(e)){const s=D(e);return r(s)||d(s,{recursive:!0}),u(e,t.content,"utf-8"),Ua(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"),Ua(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 qa(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 Ha(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=E(Me.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),_t(e.join(" "),{stdio:"pipe"}),a){const e=E(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 Fa(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function Fa(e){const t=[],n=E(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=E(n,e);p(s).isDirectory()&&r(E(s,"package.json"))&&t.push(s)}const s=E(e,"claude","hooks");r(s)&&r(E(s,"package.json"))&&t.push(s);for(const e of t)_t("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),_t("yarn build",{cwd:e,stdio:"pipe"})}function Ba(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 Ga=Ba("\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");function Wa(e){return Ba(`\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 "${e.serverName}", tool "${e.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 `)}function za(e){return Ba(`\n ## Task Preview URL Protocol:\n - Important: when a browser-viewable frontend preview URL is available, publishing it is required, not optional.\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 `)}function Ka(e){return Ba(`\n ## Task Preview URL Protocol:\n - Important: when a browser-viewable frontend preview URL is available, publishing it is required, not optional.\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 \`${e}\` 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 `)}function Va(e){return Ba(`\n ## Agentrix Vision Artifact Protocol:\n - After you create or materially update the visual plan (\`plan/index.html\`), and again after you create or update the visual test report (\`test/index.html\`), use \`${e}\` to send the issue vision artifacts to the platform so the user can review them.\n - Pass only the repository root and issue id. The platform presents the available plan and test artifacts together.\n - Do not start the local Vision engine just to use this tool.\n - If this tool is unavailable, share the local artifact paths with the user and ask them to review.\n `)}function Xa(e){return Ba(`\n ## Agentrix Vision Artifact Protocol:\n - After you create or materially update the visual plan (\`plan/index.html\`), and again after you create or update the visual test report (\`test/index.html\`), send the issue vision artifacts to the platform for review using the Agentrix event broker MCP tool: server "${e.serverName}", tool "${e.toolName}".\n - Pass only the repository root and issue id. The platform presents the available plan and test artifacts together.\n - Do not start the local Vision engine just to use this tool.\n - If this tool is unavailable, share the local artifact paths with the user and ask them to review.\n `)}function Ja(e){return Ba(`\n ## Agentrix Computer Use Protocol:\n - When the user explicitly asks you to operate this local computer, use \`${e}\`.\n - Use it for desktop apps, Finder, documents, windows, menus, dialogs, and other GUI operations.\n - Pass a concrete natural-language operation instruction. Do not invent low-level click coordinates or try to perform the GUI operation yourself.\n - When the operation references a file, directory, document, download, or save location, include the absolute path in the instruction.\n - Only use this tool for user-requested local computer control.\n `)}const Ya=Ba("\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 Qa(e){const t="group"===e?.chatType?.toLowerCase();return Ba(`\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 Ba(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?Ba("\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`)}Qa();const Za=Ba('\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'),ei=Ba('\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'),ti=Ba('\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'),ni=Ba("\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"),si=Ba(`\n ${ti}\n\n ${Za}\n\n ${ei}\n`),ai=Ba('\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 ii(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 oi(e,t){const n=t.find(t=>t.id===e);if(!n)return ii(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(ai),a.join("\n")}function ri(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function ci(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function li(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function di(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(ci).map(e=>e.text).join("\n").trim():""}function pi(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n=Math.max(0,Math.trunc(e.durationMs??0)),s={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:n,duration_api_ms:n,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:s,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 ui(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 mi="agentrix",hi="1.0.0",gi=Zt(At),fi=Oe(import.meta.url),yi=["*","","!.gitignore","","!MEMORY.md","!USER.md","!SOUL.md","!IDENTITY.md","!SKILLS.md","!system_prompt.md","","!HEARTBEAT.md","!MEMORY_ORGANIZATION.md","!UPGRADES.md","!*.upgrade","","!memory/","!memory/**","!memory-changes/","!memory-changes/**","","!plugins/","!plugins/**","!versions/","!versions/**",""].join("\n"),vi=new Set(["MEMORY.md","USER.md","SOUL.md","IDENTITY.md","SKILLS.md","system_prompt.md","HEARTBEAT.md","MEMORY_ORGANIZATION.md","UPGRADES.md"]),wi=["memory","memory-changes","plugins","versions"],bi={GIT_AUTHOR_NAME:"Agentrix Companion",GIT_AUTHOR_EMAIL:"companion@agentrix.local",GIT_COMMITTER_NAME:"Agentrix Companion",GIT_COMMITTER_EMAIL:"companion@agentrix.local"};function ki(e){return function(e){return e.split(R).join("/")}(U(e)).replace(/^\.\//,"")}function xi(e,t){fi.warn(e,t)}async function Ii(e,t){const{stdout:n}=await gi("git",t,{cwd:e,encoding:"utf-8",windowsHide:!0,env:{...process.env,...bi}});return n}async function Si(e){try{return await Ii(e,["diff","--cached","--quiet","--exit-code"]),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}async function Ti(e,t,n){const s=["commit","-m",t];return n?.trim()&&s.push("-m",n.trim()),await Ii(e,s),(await Ii(e,["rev-parse","HEAD"])).trim()}async function Ci(e){return(await Ii(e,["ls-files"])).split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).filter(_i)}function _i(e){const t=ki(e);return!(!t||"."===t||t.startsWith("../")||t.includes("/../"))&&(!!vi.has(t)||!(t.includes("/")||!t.endsWith(".upgrade"))||wi.some(e=>t===e||t.startsWith(`${e}/`)))}function Ai(e,t){const n=U(e),s=U(t),a=O(s)?s:U(E(n,s)),i=ki(N(n,a));if(!i.startsWith("../")&&!O(i)&&_i(i))return{absolutePath:a,relativePath:i};if(!O(s)){const e=U(E(n,"memory",s)),t=ki(N(n,e));if(!t.startsWith("../")&&!O(t)&&_i(t))return{absolutePath:e,relativePath:t}}throw new Error(`Companion self-evolution path is not allowlisted: ${t}`)}async function Ei(e){const{companionHome:t}=e;if(!t)return fi.warn("Skipping self-evolution git repo ensure: companion home is not set"),!1;if(!r(t))return fi.warn(`Skipping self-evolution git repo ensure: companion home does not exist (${t})`),!1;try{await Ft(t,{recursive:!0});const e=r(E(t,".git"));return e||await Ii(t,["init"]),await async function(e){const t=E(e,".gitignore");await Bt(t,"utf-8").catch(()=>{})!==yi&&await Gt(t,yi,"utf-8")}(t),e||(await $i(t),await Si(t)&&await Ti(t,"Initialize Companion self-evolution history","Initial snapshot before automatic Companion run checkpoints.")),!0}catch(e){return xi("Failed to ensure Companion self-evolution git repo",e),!1}}async function $i(e){const t=await async function(e){const t=new Set;r(E(e,".gitignore"))&&t.add(".gitignore");for(const n of vi)r(E(e,n))&&t.add(n);const n=await Wt(e).catch(()=>[]);for(const s of n)!s.includes("/")&&s.endsWith(".upgrade")&&r(E(e,s))&&t.add(s);for(const n of wi)r(E(e,n))&&t.add(n);for(const n of await Ci(e))t.add(n);return Array.from(t)}(e);0!==t.length&&await Ii(e,["add","-A","--",...t])}function Mi(e){const t=["reasons:"];for(const n of e.reasons)t.push(`- ${n}`);return t.push("",`trigger: ${e.trigger}`,`source: ${e.source??"unspecified"}`),e.taskId&&t.push(`taskId: ${e.taskId}`),t.push(`action: ${e.action}`,`file: ${e.file}`),e.deletedFiles?.length&&t.push(`deletedFiles: ${e.deletedFiles.join(", ")}`),t.push(`notifiedCompanion: ${e.notifiedCompanion}`),t.join("\n")}async function Pi(e){const{companionHome:t,title:n,body:s,paths:a}=e;try{const e=await async function(e,t){const n=new Set(await Ci(e)),s=Array.from(new Set(t.map(ki))).filter(_i).filter(t=>r(E(e,t))||n.has(t));return 0===s.length?[]:(await Ii(e,["add","-A","--",...s]),s)}(t,a);return 0===e.length?(fi.warn("Skipping Companion memory change commit: no allowlisted paths to stage"),null):await Si(t)?await Ti(t,n,s):null}catch(e){return xi("Failed to create Companion memory change semantic commit",e),null}}async function*Ri(e){yield e}let Di;const Ni=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],Oi=["EnterPlanMode","ExitPlanMode"],Ui=new Set(Oi),ji=["Glob","Grep","Read","Skill"],Li=["Read","Glob","Grep"],qi=["Read","Glob","Grep","TodoWrite"];function Hi(e,t,n,s,a,i,o,l){const d=function(e){const{agentId:t,modeConfig:n,cwd:s,agentConfig:a,channelBound:i,channelContext:o,projectGuidance:l,promptPlaceholders:d,enableTaskPreviewUrl:p,enableVisionPlan:u,enableAgentrixComputerUse:m}=e,{mode:h,groupAgents:g}=n,f=a.customSystemPrompt,y=a.systemPromptMode??"append",v=function(e,t){const{mode:n,supportChangeTitle:s}=e,a=t?.enableTaskPreviewUrl??!0,i=[Ya];switch(n){case"work":s&&i.unshift(Ga),a&&i.push(Ka("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(Va("mcp__agentrix__send_vision_artifact")),t?.enableAgentrixComputerUse&&i.push(Ja("mcp__agentrix__agentrix_computer_use"));break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":i.unshift(ni),t?.enableAgentrixComputerUse&&i.push(Ja("mcp__agentrix__agentrix_computer_use"));break;case"group_work":s&&i.unshift(Ga),a&&i.push(Ka("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(Va("mcp__agentrix__send_vision_artifact"))}return i.join("\n\n")}(n,{enableTaskPreviewUrl:p,enableVisionPlan:u,enableAgentrixComputerUse:m});if("group_chat"===h||"group_work"===h){const e=[si];return g&&g.length>0&&e.push(ii(g)),v&&e.push(v),i&&e.push(Qa(o)),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const w="reply"===h&&g&&g.length>0?oi(t,g):void 0,b={},k=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE,x="companion_shadow"===h?function(e){return"memory_organization"===e?.COMPANION_SHADOW_TASK?"memory_organization":"heartbeat"}(d):void 0;k&&(b.COMPANION_HOME=k,b.COMPANION_MODE="companion_shadow"===h?"shadow":"chat","companion_shadow"===h&&(b.AGENTRIX_MONITOR=function(){const e=Me.readSettings();if(!e||"object"!=typeof e)return"disable";const t=e["agentrix-monitor"];return t&&"object"==typeof t&&!0===t.enable?"enable":"disable"}(),b.COMPANION_SHADOW_TASK=x??"heartbeat")),Object.assign(b,d);const I=Object.keys(b).length>0?b:void 0,S=f?Dt(f,s,I):void 0,T="companion_shadow"===h?function(e,t){if(!e||!t)return;const n=E(e,"memory_organization"===t?"MEMORY_ORGANIZATION.md":"HEARTBEAT.md");if(!r(n))return;const s=c(n,"utf-8").trim();return s?[`## Injected Companion ${"memory_organization"===t?"Memory Organization":"Heartbeat"} Routine`,"",s].join("\n"):void 0}(k,x):void 0;if("replace"===y&&S){const e=[S];return w&&e.push(w),v&&e.push(v),i&&e.push(Qa(o)),T&&e.push(T),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const C=[];return w&&C.push(w),v&&C.push(v),i&&C.push(Qa(o)),S&&C.push(S),T&&C.push(T),l?.systemPromptAppend&&C.push(l.systemPromptAppend),{type:"preset",preset:"claude_code",append:C.length>0?C.join("\n\n"):void 0}}({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,enableVisionPlan:n.enableVisionPlan,enableAgentrixComputerUse:n.enableAgentrixComputerUse}),p=(u=function(e){switch(e){case"work":case"companion_shadow":return;case"chat":case"companion_chat":return[...Ni];case"reply":return[...ji];case"group_chat":return[...Li];case"group_work":return[...qi]}}(n.modeConfig.mode),Boolean(n.disableClaudePlanModeTools)&&u?u.filter(e=>!Ui.has(e)):u);var u;const m=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),h=function(){if(void 0!==Di)return Di??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=O(t)?t:P(t);return r(e)?e:void 0}return function(e){const t="win32"===process.platform?"where":"which",n=Tt(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 Di=t,t}Di=null}(),g=o?function(e){const{modeConfig:t,tools:n,agentType:s,allowAskUser:a=!0,supportedFeatures:i,channelBound:o,channelGroupBound:r,visionModel:c,enableTaskPreviewUrl:l=!0,enableVisionPlan:d=!1,enableComputerUse:p=!1,extraTools:u=[],serverName:m=mi,serverVersion:h=hi}=e,{mode:g,supportChangeTitle:f}=t,y=[];switch(g){case"work":p&&y.push(n.computerUse),i?.includes("sub-task")&&(y.push(n.createTask),y.push(n.replyToSubTask),y.push(n.listSubTask)),f&&y.push(n.changeTaskTitle),a&&y.push(n.askUser),l&&y.push(n.publishTaskPreviewUrl),d&&y.push(n.sendVisionArtifact),y.push(n.getTaskHistory);break;case"chat":p&&y.push(n.computerUse),y.push(n.createTask),y.push(n.replyToSubTask),a&&y.push(n.askUser),y.push(n.getTaskHistory),y.push(n.listSubTask);break;case"group_chat":y.push(n.invoke),y.push(n.createSoloTask),y.push(n.createGroupTask),y.push(n.replyToSubTask),y.push(n.getTaskAgents),y.push(n.getTaskHistory);break;case"group_work":y.push(n.invoke),y.push(n.assign),f&&y.push(n.changeTaskTitle),l&&y.push(n.publishTaskPreviewUrl),d&&y.push(n.sendVisionArtifact),y.push(n.getTaskAgents),y.push(n.getTaskHistory);break;case"reply":y.push(n.getTaskHistory),a&&y.push(n.askUser);break;case"companion_chat":y.push(n.createTask),y.push(n.replyToSubTask),a&&y.push(n.askUser),y.push(n.getTaskHistory),y.push(n.uploadFile),y.push(n.listAgents),y.push(n.scheduleTask);break;case"companion_shadow":y.push(n.getTaskHistory),y.push(n.readConversation),y.push(n.listAgents),y.push(n.scheduleTask)}("companion_chat"===g||"companion_shadow"===g)&&(y.push(n.listTasks),y.push(n.sendReminder),y.push(n.recordMemoryChange),y.push(n.prepareHiveRepository),y.push(n.publishToHive),y.push(n.updateHiveListingVersion),y.push(n.recordHiveInstall),y.push(n.createHiveReview),y.push(n.createHiveComment)),"companion"===s&&y.push(n.updateAgentInfo),o&&"companion_shadow"!==g&&y.push(n.sendChannelMessage),r&&"companion_shadow"!==g&&y.push(n.getChannelGroupHistory),c&&"companion_shadow"!==g&&"reply"!==g&&y.push(n.analyzeImage),y.push(...u);const v=$t({name:m,version:h,tools:y}),w=y.map(e=>((e,t)=>`mcp__${e}__${t}`)(m,e.name));return{server:v,toolNames:w}}({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,enableVisionPlan:n.enableVisionPlan,enableComputerUse:n.enableAgentrixComputerUse,extraTools:n.agentrixExtraTools}):void 0,f={...g?.server?{agentrix:g.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:d,tools:p,...n.disableClaudePlanModeTools?{disallowedTools:[...Oi]}:{},mcpServers:f,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?ri(n.env):void 0,pathToClaudeCodeExecutable:h,maxTurns:s.customMaxTurns??n.maxTurns??l,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:m,outputFormat:n.structuredOutputSchema}}class Fi{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?li(e):e;let a=null;await this.checkpointCompanionRun(t,"before_run");try{const e=Mt({prompt:Ri(s),options:Hi(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if("result"===t.type){a=t;break}if(!a)throw new Error("ClaudeRunner.run: missing result message");return a}finally{await this.checkpointCompanionRun(t,"after_run")}}async*runStreamed(e,t){const n=this.agentConfig,s="string"==typeof e?li(e):e;await this.checkpointCompanionRun(t,"before_run");try{const e=Mt({prompt:Ri(s),options:Hi(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if(yield t,"result"===t.type)break}finally{await this.checkpointCompanionRun(t,"after_run")}}loop(e){const t=this,n=e.abortController,s=this.agentConfig,a=Hi(this.agentId,this.agentType,e,s,this.agentHooks,this.agentMcpServers,e.agentrixTools);let i=!1;const o=[];let r=null,c=null;const l=()=>{if(!i&&(i=!0,r)){const e=r;r=null,e(null)}},d=async function*(){for(;!i&&!n.signal.aborted;){if(o.length>0){yield o.shift();continue}const e=await new Promise(e=>{r=e});if(!e)break;yield e}},p=async function*(){try{await t.checkpointCompanionRun(e,"before_run");const n=Mt({prompt:d(),options:a});c=n;for await(const e of n)yield e}finally{c=null,await t.checkpointCompanionRun(e,"after_run"),l()}}();return n.signal.addEventListener("abort",l,{once:!0}),{push:e=>{if(i)return;const t="string"==typeof e?li(e):e;if(r){const e=r;return r=null,void e(t)}o.push(t)},events:p,stop:l,setPermissionMode:async e=>{c&&await c.setPermissionMode(e)},setModel:async e=>{c&&await c.setModel(e)}}}async checkpointCompanionRun(e,t){const n=e.modeConfig.mode;if("companion_chat"!==n&&"companion_shadow"!==n)return;const s=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE;var a;await async function(e){const{companionHome:t,mode:n,phase:s}=e;if("companion_chat"!==n&&"companion_shadow"!==n)return{committed:!1};try{if(!await Ei({companionHome:t})||!t)return{committed:!1};if(await $i(t),!await Si(t))return{committed:!1};const a="companion_shadow"===n?e.shadowTask??"unknown":"unknown",i=await Ti(t,function(e,t,n){const s="before_run"===n?"before":"after";return"companion_shadow"===e?"unknown"===t?`checkpoint: ${s} companion_shadow run`:`checkpoint: ${s} companion_shadow ${t} run`:`checkpoint: ${s} companion_chat run`}(n,a,s),function(e,t,n){return[`mode: ${e}`,`shadow_task: ${"companion_shadow"===e?t:"unknown"}`,`phase: ${n}`].join("\n")}(n,a,s));return fi.info(`Created Companion self-evolution ${s} checkpoint ${i}`),{committed:!0,commit:i}}catch(e){return xi(`Failed to create Companion self-evolution ${s} checkpoint`,e),{committed:!1}}}({companionHome:s,mode:n,shadowTask:"companion_shadow"===n?(a=e.promptPlaceholders,"heartbeat"===a?.COMPANION_SHADOW_TASK?"heartbeat":"memory_organization"===a?.COMPANION_SHADOW_TASK?"memory_organization":"unknown"):void 0,phase:t})}}const Bi=Oe(import.meta.url);function Gi(){return`Companion probe timed out after ${Math.round(45)}s`}function Wi(e){return e instanceof Error&&e.message?e.message:String(e)}function zi(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 Ki(){const e=E(Me.agentrixHomeDir,"tmp","companion-probe");d(e,{recursive:!0});const t=new Fi("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?Gi():zi(a)}:{success:!0}}catch(e){return{success:!1,error:s?Gi():Wi(e)}}finally{clearTimeout(a)}}const Vi=Zt(At);function Xi(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),en(t)}async function Ji(e){try{const t=Xi(e);return await t.checkIsRepo()}catch{return!1}}async function Yi(e){const t=Xi(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 Qi(e,t,n,s="HEAD"){const a=D(t);if(r(a)||d(a,{recursive:!0}),r(t)&&!ro(t))throw new Error(`Worktree directory already exists at ${t}`);const i=Xi(e);await i.raw(["worktree","add","-b",n,t,s])}async function Zi(e,t,n=!1){const s=Xi(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function eo(e){const t=Xi(e);await t.init()}async function to(e){const t=Xi(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function no(e,t){const n=D(t);r(n)||d(n,{recursive:!0});const s=Xi();await s.clone(e,t)}async function so(e,t,n){const s=Xi(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(await wo(e).catch(()=>[])).includes(t)?await Vi("git",["checkout","-B",t,`origin/${t}`],{cwd:e,windowsHide:!0}):n?await Vi("git",["checkout","-b",t,n],{cwd:e,windowsHide:!0}):await s.checkoutLocalBranch(t)}async function ao(e){const t=Xi(e);return!(await t.status()).isClean()}async function io(e){const t=Xi(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function oo(e){try{const t=Xi(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function ro(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function co(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function lo(e,t,n){const s=Xi(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:co(te(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function po(e,t){try{const{stdout:n}=await Vi("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 uo(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:co(te(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function mo(e,t){return Te("sha256").update(`${e}\n${t}`).digest("hex")}async function ho(e,t){const n=await po(e,["diff","--binary","--find-renames",t,"--"]),s=uo(await po(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await Vi("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=>po(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=uo((await Promise.all(a.map(t=>po(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:mo(t,r)}:null;var c}async function go(e){const t=Xi(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function fo(e,t,n){const s=Xi(e);await s.remote(["set-url",t,n])}function yo(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function vo(e,t,n){const s=Xi(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await fo(e,t,n):await s.addRemote(t,n)}async function wo(e,t="origin"){const{stdout:n}=await Vi("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)}function bo(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 ko(e){try{const t=Xi(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?bo(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const xo="oauth2",Io="AGENTRIX_GIT_USERNAME",So="AGENTRIX_GIT_PASSWORD";function To(){const e=E(s(),`git-askpass-${Se()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${Io}:-${xo}}" ;;\n *) printf '%s\\n' "\${${So}:-}" ;;\nesac\n`,{mode:448}),e}function Co(e,t,n=xo){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[Io]:n,[So]:t}}function _o(){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 Ao=Zt(At),Eo="github",$o="xmz-ai",Mo="agentrix-agent",Po="https://github.com/xmz-ai/agentrix-agent.git",Ro="main";async function Do(e,t,n){await Ao("git",["clone","--depth=1","--branch",t,e,n]),await vo(n,"origin",yo(e))}async function No(e){const t=Me.resolveRepoStoreCheckoutDir(Eo,$o,Mo),n=E(t,"companion"),s=Me.resolveRepoStoreLockPath(Eo,$o,Mo),a=await Me.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=`${Me.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||Ro}}return{gitUrl:Po,branch:Ro}}(e);if(!await Ji(t)){if(!ro(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await Do(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 Ao("git",["fetch","--depth=1",e,t],{cwd:n}),await Ao("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await vo(n,"origin",yo(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=E(D(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await Do(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 Me.releaseFileLock(s,a)}}function Oo(e){r(e)||d(e,{recursive:!0})}function Uo(e){return e.split("\\").join("/")}function jo(e,t){const n=E(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 Lo(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 qo(e){return E(e,"versions/.companion-template-language.json")}async function Ho(e){const t=Me.agentrixAgentsHomeDir,n=E(t,"companion"),s=E(n,"claude"),a=!r(E(n,"agent.json")),i=await No(e?.credentials);let o=r(E(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 Ki();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(E(o,"agent.json")))y(o,n,{recursive:!0}),Fa(n),console.log("[Companion] Installed from template repository");else try{await Ha({agentId:"companion",gitUrl:Po,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(E(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await Ha({agentId:"companion",gitUrl:Po,branch:"main",subDir:"companion"})),o=r(E(i.companionDir,"agent.json"))?i.companionDir:n}Oo(E(s,"memory"));const l=Lo(e?.preferredLanguage),d=function(e,t,n){if(n)return{language:t,source:"initial-install",verified:!0};const s=function(e){const t=qo(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=E(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"===d.source&&d.language!==l&&console.log(`[Companion] Using installed template language ${d.language}; requested language ${l} ignored for safe upgrades`),d.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=Lo(e),a=jo("common",t),i=jo(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=E(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n,language:"common",sourcePath:s})}const d=E(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=E(s,i);if(p(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=Uo(N(e,a));t[o]=c(a,"utf-8")}};return n(e),t}(d);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:E(d,e)})}if(0===o.length)throw new Error(`Companion template files are missing in ${t}`);return{language:s,templates:o}}(d.language,o,a);!function(e,t,n){if("unverified"===n)return;const s=qo(e);Oo(D(s)),u(s,JSON.stringify({language:t,source:n,updatedAt:(new Date).toISOString()},null,2),"utf-8")}(n,m,d.source);const f=[];for(const e of h){const t=La(E(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/")))&&(Fa(n),console.log("[Companion] Rebuilt plugins after template updates"));const{pendingUpgrades:v,blockedUpgrades:w}=function(e,t,n={}){const s=[],a=[];for(const i of e){if("notify-user"!==i.metadata.updateStrategy)continue;const e=E(t,i.relativePath);if(!r(e))continue;const o=Oa(e,t);if(ja(i.metadata.version,o)>0){const r={template:i,targetPath:e,upgradePath:`${e}.upgrade`,versionPath:Na(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:d.verified});if(v.length>0||w.length>0)try{const e=E(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:v,blockedUpgrades:w,agentDir:n,language:m,languageSource:d.source});u(e,t,"utf-8");for(const e of v)u(e.upgradePath,qa(e),"utf-8");console.log(`[Companion] Created UPGRADES.md with ${v.length} pending upgrade(s) and ${w.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 Fo=[{version:1,fileName:"001_init.sql"},{version:2,fileName:"002_app_server_state.sql"}];function Bo(e){var t;return function(e,t){const n=new nn(e),s=new tn;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=ot(sn(import.meta.url)),t=[it(e,"migrations"),it(process.cwd(),"dist","migrations"),it(process.cwd(),"src","worker","history","migrations")];for(const e of t)if(We(e))return e;throw new Error(`Task history migrations directory not found at ${t[0]}`)}(),n=e.pragma("user_version",{simple:!0});for(const s of Fo){const a=Go(t,s.fileName);(0===n||n<s.version)&&(e.exec(a),e.pragma(`user_version = ${s.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 * FROM task_event\n WHERE event_type = 'task-message'\n ORDER BY COALESCE(sequence, 0) DESC, rowid DESC\n LIMIT ?\n "),d=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 "),u=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence ASC\n LIMIT ?\n "),m=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence < ?\n ORDER BY local_sequence DESC\n LIMIT ?\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 1 as has_row\n FROM task_message\n WHERE local_sequence > ?\n LIMIT 1\n "),f=n.prepare("\n SELECT * FROM task_message\n WHERE local_sequence > ?\n ORDER BY local_sequence DESC\n LIMIT ?\n "),y=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 "),w=n.prepare("\n INSERT INTO task_agent_session (\n agent_id,\n task_id,\n session_id,\n last_sequence,\n active_turn_status,\n goal_status,\n token_usage,\n updated_at\n ) VALUES (\n @agentId,\n @taskId,\n @sessionId,\n NULL,\n @activeTurn,\n @goal,\n @tokenUsage,\n @updatedAt\n )\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n session_id = excluded.session_id,\n active_turn_status = CASE\n WHEN @hasActiveTurn THEN excluded.active_turn_status\n ELSE task_agent_session.active_turn_status\n END,\n goal_status = CASE\n WHEN @hasGoal THEN excluded.goal_status\n ELSE task_agent_session.goal_status\n END,\n token_usage = CASE\n WHEN @hasTokenUsage THEN excluded.token_usage\n ELSE task_agent_session.token_usage\n END,\n updated_at = excluded.updated_at\n "),b=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??X(),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??X(),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(zo),s=n.at(-1)?.sequence??null;return{data:n,hasMore:null!==s&&Boolean(d.get(s))}},pageRecentTaskEvents:e=>{const t=l.all(e);return{data:t.map(zo).reverse(),hasMore:t.length>=e}},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?zo(s):null},pageRecentMessages:e=>{const t=p.all(e).map(Wo).reverse(),n=t[0]?.localSequence??null;return{data:t,hasMore:!!n&&Boolean(h.get(n))}},pageMessagesAfter:(e,t)=>{const n=u.all(e,t).map(Wo),s=n.at(-1)?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(g.get(s))}},pageMessagesBefore:(e,t)=>{const n=m.all(e,t).map(Wo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},pageRecentMessagesAfter:(e,t)=>{const n=f.all(e,t).map(Wo).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},getAgentSessions:()=>{const e=y.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.session_id);return t},getAgentLastSequences:()=>{const e=y.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())},updateAgentAppServerState:(e,n,s)=>{const a=Object.prototype.hasOwnProperty.call(s,"activeTurn"),i=Object.prototype.hasOwnProperty.call(s,"goal"),o=Object.prototype.hasOwnProperty.call(s,"tokenUsage");(a||i||o)&&w.run({agentId:e,taskId:t,sessionId:n,activeTurn:a?JSON.stringify(s.activeTurn??null):null,goal:i?JSON.stringify(s.goal??null):null,tokenUsage:o?JSON.stringify(s.tokenUsage??null):null,hasActiveTurn:a?1:0,hasGoal:i?1:0,hasTokenUsage:o?1:0,updatedAt:(new Date).toISOString()})},updateAgentLastSequence:(e,n)=>{b.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,it(t,"data.bin")),e.taskId)}function Go(e,t){const n=it(e,t);return Ge(n,"utf8")}function Wo(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 zo(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 Ko=[1,2,4,6,8,12,24];function Vo(e){return"number"==typeof e&&Ko.includes(e)}function Xo(e){return Vo(e)?e:4}class Jo{constructor(e,t,n={}){this.client=e,this.machineId=t;const s=Me.agentrixAgentsHomeDir,a=E(s,"companion","claude");this.stateFilePath=n.stateFilePath??E(a,"state.json"),this.initialDelayMs=n.initialDelayMs??6e4,this.monitorCandidateChecker=n.monitorCandidateChecker}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;memoryOrganizationEnabled=!1;memoryOrganizationIntervalHours=4;memoryOrganizationTaskId=null;companionState=null;stateFilePath;initialDelayMs;monitorCandidateChecker;started=!1;cronJobs=new Map;start(){this.started?this.reloadStateAndReschedule():(this.started=!0,this.loadState(),this.companionState?(De.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):De.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),De.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(),De.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),De.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(),De.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),De.info("[COMPANION SCHEDULER] Cleared heartbeat task ID")}setMemoryOrganizationTaskId(e){this.memoryOrganizationTaskId=e,this.saveStateField("memoryOrganizationTaskId",e)}clearMemoryOrganizationTaskId(){this.memoryOrganizationTaskId=null,this.saveStateField("memoryOrganizationTaskId",void 0),De.info("[COMPANION SCHEDULER] Cleared memory organization task ID")}recordInteraction(e){if(!this.companionState?.chatId||e!==this.companionState.chatId)return;const t=(new Date).toISOString();this.saveStateField("lastInteractionTimestamp",t),De.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&&(De.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,this.memoryOrganizationEnabled=this.companionState?.memoryOrganizationEnabled??!1,this.memoryOrganizationIntervalHours=Xo(this.companionState?.memoryOrganizationIntervalHours),this.memoryOrganizationTaskId=this.companionState?.memoryOrganizationTaskId??null,De.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"}, memoryOrganizationEnabled=${this.memoryOrganizationEnabled}, memoryOrganizationIntervalHours=${this.memoryOrganizationIntervalHours}, memoryOrganizationTaskId=${this.memoryOrganizationTaskId??"none"}`)}}catch(e){De.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=D(this.stateFilePath);r(s)||d(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),De.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){De.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")}`}isMemoryOrganizationDue(e,t){if(!this.memoryOrganizationEnabled)return!1;if(!(e.agentId&&e.machineId&&e.userId&&e.chatId))return!1;if(!e.lastMemoryOrganizationTimestamp)return!0;const n=new Date(e.lastMemoryOrganizationTimestamp).getTime();if(Number.isNaN(n))return!0;const s=60*this.memoryOrganizationIntervalHours*60*1e3;return t.getTime()-n>=s}triggerMemoryOrganization(e,t){const n=t.toISOString();this.saveStateField("lastMemoryOrganizationTimestamp",n);const s=t.toLocaleString(),a={type:"companion_memory_organization",timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours};if(this.memoryOrganizationTaskId)return De.debug(`[COMPANION SCHEDULER] Sending memory organization to existing task ${this.memoryOrganizationTaskId}`),void this.client.send("task-message",{eventId:X(),taskId:this.memoryOrganizationTaskId,chatId:e.chatId,from:"machine",message:a,senderType:"system",senderId:"system",senderName:"system"});De.debug("[COMPANION SCHEDULER] Requesting initial memory organization task"),this.client.send("request-companion-memory-organization",{eventId:X(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours})}isMonitorEnabled(){try{const e=Me.readSettings();if(!e||"object"!=typeof e)return!1;const t=e["agentrix-monitor"];return Boolean(t&&"object"==typeof t&&!0===t.enable)}catch(e){return De.debug("[COMPANION SCHEDULER] Failed to read Agentrix Monitor settings",e),!1}}readMonitorControl(){try{const e=E(Me.agentrixHomeDir,"monitor","control.json"),t=JSON.parse(c(e,"utf-8"));return t.base_url&&t.token?{baseUrl:t.base_url.replace(/\/+$/,""),token:t.token}:(De.debug("[COMPANION SCHEDULER] Agentrix Monitor control file is missing base_url or token"),null)}catch(e){return De.debug("[COMPANION SCHEDULER] Agentrix Monitor control file unavailable",e),null}}async listMonitorCandidates(e,t,n){n.set("agent_id",t.agentId),n.set("limit","5");const s=await fetch(`${e.baseUrl}/candidates?${n.toString()}`,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},signal:AbortSignal.timeout(5e3)});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`Monitor candidate query failed: ${s.status} ${e}`.trim())}const a=await s.json();return Array.isArray(a.candidates)?a.candidates:[]}async hasPendingMonitorCandidates(e){if(!this.isMonitorEnabled())return!1;if(!e.agentId)return!1;if(this.monitorCandidateChecker)return await this.monitorCandidateChecker(e);const t=this.readMonitorControl();if(!t)return!1;try{const n=[new URLSearchParams({status:"init",kind:"handoff"}),new URLSearchParams({status:"pending",kind:"memory"}),new URLSearchParams({status:"pending",kind:"knowledge"}),new URLSearchParams({status:"pending",kind:"automation"})];for(const s of n)if((await this.listMonitorCandidates(t,e,s)).length>0)return!0}catch(e){De.debug("[COMPANION SCHEDULER] Agentrix Monitor candidate check failed",e)}return!1}addScheduledTask(e){const t={id:Se(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),De.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)),De.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 De.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 De.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 on(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),De.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){De.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){De.info(`[COMPANION SCHEDULER] Scheduled task fired: id=${e.id}, task="${e.task}"`),this.loadState();const t=this.companionState;if(!t?.chatId)return;const n=t.chatTaskId??t.chatId;this.client.send("task-message",{eventId:X(),taskId:n,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()?De.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);De.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}async tick(){if(this.loadState(),!this.companionState)return void De.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");const e=this.companionState,t=[],n=new Date;if(this.isMemoryOrganizationDue(e,n)&&(De.info("[COMPANION SCHEDULER] Memory organization triggered"),this.triggerMemoryOrganization(e,n)),!this.enabled)return void De.debug("[COMPANION SCHEDULER] Heartbeat disabled, skipping");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){if(!await this.hasPendingMonitorCandidates(e))return void De.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");t.push("monitor_candidates")}De.info(`[COMPANION SCHEDULER] Heartbeat triggered: ${t.join(", ")}`);const a=("number"==typeof e.heartbeatTriggerCount?e.heartbeatTriggerCount:0)+1;this.saveStateField("lastHeartbeatTimestamp",n.toISOString()),this.saveStateField("lastHeartbeatDate",s),this.saveStateField("heartbeatTriggerCount",a);const i=n.toLocaleString(),o={type:"companion_heartbeat",timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a};this.heartbeatTaskId?(De.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:X(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:o,senderType:"system",senderId:"system",senderName:"system"})):(De.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:X(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a}))}}const Yo=new Ut({credentialsDir:E(Me.agentrixHomeDir,"credentials")});async function Qo(){const e=await Me.readCredentials();return e?.secret?jt(e.secret):null}function Zo(e){return Yo.loadGitServerConfig(e)}function er(e,t){return Yo.loadGitLabWebhookBridgeSecrets(e,t)}function tr(e,t,n){Yo.saveGitLabWebhookBridgeSecrets(e,t,n)}function nr(e){return Yo.loadPatMeta(e)}function sr(e,t){return Yo.loadPat(e,t)}const ar="https://ilinkai.weixin.qq.com",ir="https://novac2c.cdn.weixin.qq.com/c2c",or=1e3,rr=ht(import.meta.url)("qrcode-terminal");function cr(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function lr(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function dr(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 pr(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 ur(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function mr(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 hr(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 gr(e){if(e.image_item?.media?.full_url)return fr(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 fr(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 fr(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 yr(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 vr(e){return e.retcode??e.ret??e.errcode}function wr(e,t){const n=vr(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function br(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function kr(e){let t="";return rr.generate(e,{small:!0},e=>{t=e}),t}class xr{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=or;contextTokens=new Map;clientId=Ie(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=lr(e.token)??lr(e.botToken)??lr(e.bot_token)??lr(e.apiKey)??lr(e.api_key);return{baseUrl:lr(e.baseUrl)??lr(e.base_url)??ar,token:t||cr(t,"token"),routeTag:lr(e.routeTag)??lr(e.route_tag),getUpdatesBuf:lr(e.getUpdatesBuf)??lr(e.get_updates_buf)??"",channelVersion:lr(e.channelVersion)??lr(e.channel_version)??"1.0.0",pollTimeoutMs:dr(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:dr(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:lr(e.fileDownloadEndpoint)??lr(e.file_download_endpoint)??lr(e.downloadEndpoint)??lr(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||ar,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${br(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=vr(a);if(i&&0!==i)throw new Error(wr(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:kr(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||ar,s=await fetch(`${br(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=vr(a);if(i&&0!==i)throw new Error(wr(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=or,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),De.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()}-${Ie(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=vr(s);if(a&&0!==a)throw new Error(wr(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.filePath),a=await Bt(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},d="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)}},p=await this.request("sendmessage",{msg:{from_user_id:"",to_user_id:e,client_id:`agentrix-wechat:${Date.now()}-${Ie(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[d]}},{timeoutMs:this.credentials.requestTimeoutMs}),u=vr(p);if(u&&0!==u)throw new Error(wr(p,"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=Ie(16).toString("hex"),i=Ie(16).toString("hex"),o=this.encryptWechatMedia(t,i),r=Te("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=vr(c);if(l&&0!==l)throw new Error(wr(c,"WeChat getuploadurl failed"));const d=this.extractUploadParam(c),p=await fetch(`${ir}/upload?encrypted_query_param=${encodeURIComponent(d)}&filekey=${encodeURIComponent(a)}`,{method:"POST",headers:{"Content-Type":"application/octet-stream","Content-Length":String(o.length)},body:o});if(!p.ok){const e=await p.text().catch(()=>"");throw new Error(`WeChat CDN upload failed: HTTP ${p.status}: ${e||p.statusText}`)}const u=p.headers.get("x-encrypted-param");if(!u)throw new Error("WeChat CDN upload response missing x-encrypted-param");return{fullUrl:`${ir}/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 ys(e,t.fileName);const s=await this.requestDownloadFile(e);return await fs(s,t.fileName||e)}catch(t){return De.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=vr(e);if(t&&0!==t)throw new Error(wr(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=or,"connected"!==this.connectionState&&this.setState("connected");for(const e of yr(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));De.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=hs(t||e.fileName||"attachment");return await Gt(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=Ce("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=Ce("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=_e("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 br(this.credentials.baseUrl,e)}generateWechatUin(){const e=Ie(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 De.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?fr(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?fr(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??Se()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:ur(n,["sender_name","nickname","user_name"]),type:hr(e),text:mr(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:gr(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:pr(e.timestamp??e.create_time),raw:e}}}const Ir=["telegram","wechat","lark"],Sr=kt.enum(Ir),Tr=kt.enum(["connecting","connected","disconnected","error"]),Cr=kt.enum(["text","image","file","voice"]),_r=kt.record(kt.string(),kt.unknown()),Ar=kt.object({id:kt.string(),platform:Sr,name:kt.string().optional(),credentials:_r,enabled:kt.boolean(),connectionState:Tr,lastConnectedAt:kt.string().optional(),lastDisconnectedAt:kt.string().optional(),lastError:kt.string().optional(),createdAt:kt.string(),updatedAt:kt.string()}),Er=kt.object({platform:Sr,name:kt.string().optional(),credentials:_r,enabled:kt.boolean().optional()}),$r=kt.object({id:kt.string(),channelId:kt.string(),chatId:kt.string(),taskId:kt.string(),chatName:kt.string().optional(),createdAt:kt.string(),updatedAt:kt.string()});kt.object({id:kt.string(),channelId:kt.string(),platform:Sr,chatId:kt.string(),chatType:kt.string().optional(),senderId:kt.string().optional(),senderType:kt.string().optional(),senderName:kt.string().optional(),type:Cr,text:kt.string().optional(),fileKey:kt.string().optional(),fileName:kt.string().optional(),imageKey:kt.string().optional(),attachmentPaths:kt.array(kt.string()).optional(),mentionedBot:kt.boolean().optional(),replyToBot:kt.boolean().optional(),triggered:kt.boolean().optional(),rawContent:kt.unknown().optional(),timestamp:kt.string(),raw:kt.unknown().optional()});const Mr=kt.object({id:kt.string(),name:kt.string(),avatar:kt.string().optional(),description:kt.string().optional(),chatStatus:kt.string().optional(),external:kt.boolean().optional()}),Pr=kt.enum(["auto","image","file","audio","video"]),Rr=kt.object({filePath:kt.string(),fileName:kt.string().optional(),mimeType:kt.string().optional(),kind:Pr.optional()});kt.object({content:kt.string().optional(),attachments:kt.array(Rr).optional()});const Dr=kt.object({version:kt.literal(1),channels:kt.array(Ar),bindings:kt.array($r)});let Nr=rn();const Or=rn();function Ur(e){return e.secret||e.token}function jr(e,t){return Ae("sha256",t).update(e).digest("base64url")}function Lr(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&&Ee(n,s)}(s,jr(n,Ur(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 qr=kt.object({repoRoot:kt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:kt.string().min(1).max(160).regex(/^[A-Za-z0-9._-]+$/).describe("Agentrix issue directory id, for example 478-vision-plan-agentrix-platform-bridge")});async function Hr(e,t){return{issueId:qr.parse(e).issueId}}const Fr="agentrix_event_broker",Br="/mcp/agentrix-event-broker",Gr="change_title",Wr="publish_task_preview_url",zr="send_vision_artifact";function Kr(e,t){return{changeTitle:(e,n)=>async function(e,t,n){const s=e?.();if(!s?.connected)throw new Error("Agentrix daemon machine socket is not connected");const a={eventId:X(),taskId:t.taskId,title:n},i=await s.sendWithAck("change-task-title",a);if("success"!==i.status)throw new Error(i.message||"Failed to change task title")}(t,e,n),publishTaskPreviewUrl:(t,n)=>async function(e,t,n){const s=await fetch(`${Me.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),sendVisionArtifact:async(e,n)=>{const s=await Hr(n,e.taskId),a=t?.();if(!a?.connected)throw new Error("Agentrix daemon machine socket is not connected");const i=await a.sendWithAck("vision-plan-card",{eventId:X(),taskId:e.taskId,issueId:s.issueId,repoRoot:n.repoRoot,createdAt:(new Date).toISOString()});if("success"!==i.status)throw new Error(i.message||"Failed to send Vision Plan card");return{issueId:s.issueId}}}}async function Vr(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 gn({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(Gr,{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:kt.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(Wr,{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:kt.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=ne.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}]}}),!0===e.context.visionPlanEnabled&&t.registerTool(zr,{title:"Send Agentrix vision artifacts",description:["Send the issue vision artifacts (visual plan and test report) to the Agentrix platform so the user can review them.","Use this after generating or materially updating the visual plan, and again after generating the visual test report.","Pass only the repository root and issue id."].join(" "),inputSchema:{repoRoot:kt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:kt.string().min(1).max(160).describe("Agentrix issue directory id")}},async({repoRoot:t,issueId:n})=>({content:[{type:"text",text:await async function(e,t,n){const s=qr.parse(n);return`Agentrix vision artifacts sent for issue ${(await e.sendVisionArtifact(t,s)).issueId}.`}(e.dispatcher,e.context,{repoRoot:t,issueId:n})}]})),t}({context:Lr(n.credentials,s),dispatcher:n.dispatcher}),i=new fn({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){De.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(()=>{})}}class Xr extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="MachineAesKeyUpdateError"}}function Jr(e){if(!e)return null;try{const t=G(e);return 32===t.length?t:null}catch{return null}}function Yr(e){return!!Jr(e.machineAesKey)}const Qr=Oe(import.meta.url),Zr="agentrix-computer-use";function ec(){const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return r(e)?{available:!0,path:e}:{available:!1,path:e};const t=Tt("win32"===process.platform?"where":"which",["codex"],{encoding:"utf8"}).stdout.split(/\r?\n/).map(e=>e.trim()).find(Boolean);return t?{available:!0,path:t}:{available:!1}}function tc(e,t){const s=t?.trim();if(s)return r(s)?{available:!0,path:s}:{available:!1,path:s};const a=Tt("win32"===process.platform?"where":"which",[e],{encoding:"utf8"}).stdout.split(/\r?\n/).map(e=>e.trim()).find(Boolean);if(a)return{available:!0,path:a};for(const e of[E(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver","/Applications/CuaDriver.app/Contents/MacOS/cua-driver"])if(r(e))return{available:!0,path:e};return{available:!1}}function nc(e){try{return p(e).isDirectory()}catch{return!1}}function sc(e){return"boolean"==typeof e?e:void 0}function ac(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function ic(e){return[E(e,"skills","cua-driver"),E(n.homedir(),".agents","skills","cua-driver")]}function oc(){const e=process.env.AGENTRIX_CUA_DRIVER_SKILL_SOURCE?.trim();if(e){const t=ac(e);return r(E(t,"SKILL.md"))?t:null}const t=[E(n.homedir(),".agents","skills","cua-driver"),E(n.homedir(),".claude","skills","cua-driver"),E(n.homedir(),".openclaw","skills","cua-driver")].filter(e=>Boolean(e));for(const e of t){const t=P(ac(e));if(r(E(t,"SKILL.md")))return t}return null}function rc(e=Me.readSettings()){const t=function(){const e=process.env.AGENTRIX_COMPUTER_USE_CODEX_HOME||process.env.AGENTRIX_CODEX_HOME_FOR_COMPUTER_USE;return e?.trim()?e.trim().replace(/^~(?=\/|$)/,n.homedir()):E(n.homedir(),".codex")}(),s=E(Me.agentrixHomeDir,"computer-use","enabled"),a=function(e,t){if(n=process.env.AGENTRIX_COMPUTER_USE_ENABLED,["1","true","yes","on"].includes((n??"").trim().toLowerCase()))return"env";var n;const s=e;return!1===s?.agentrixComputerUse?.enabled?null:!0===s?.agentrixComputerUse?.enabled?"settings":r(t)?"marker":null}(e,s),i=ec(),o=tc("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH),l=E(t,"config.toml"),d=function(e){try{return c(e,"utf8")}catch{return""}}(l),p=d.length>0,u=/\[mcp_servers\.(["']?cua-driver["']?|cua_driver)\]/.test(d)||/cua-driver/.test(d);E(t,"skills","cua-driver");const m=null!==function(e){for(const t of ic(e))if(nc(t)&&r(E(t,"SKILL.md")))return t;return null}(t),h=oc()??void 0,g=function(e){if(!e||"darwin"!==process.platform)return{};const t=Tt(e,["doctor","--json"],{encoding:"utf8",timeout:1e4});try{const e=JSON.parse(t.stdout);return{accessibilityGranted:sc(e.ax_granted),screenRecordingGranted:sc(e.screen_recording_granted)}}catch(e){return 0!==t.status?{error:[t.stderr,t.stdout].map(e=>e?.trim()).filter(Boolean).join("\n")||"Failed to check Cua Driver permission status."}:{error:`Failed to parse Cua Driver permission status: ${e instanceof Error?e.message:String(e)}`}}}(o.path),f=[];return i.available||f.push("Codex CLI is not available. Install Codex or set AGENTRIX_CODEX_PATH to the codex executable."),o.available||f.push("Cua Driver CLI is not available. Install Cua Driver or set AGENTRIX_CUA_DRIVER_PATH to the cua-driver executable."),g.error&&f.push(`Cua Driver permission status could not be checked: ${g.error}`),!1===g.accessibilityGranted&&f.push("Cua Driver Accessibility permission is not granted. Install Agentrix Computer Use to open the macOS permission prompt, then grant Accessibility access."),!1===g.screenRecordingGranted&&f.push("Cua Driver Screen Recording permission is not granted. Install Agentrix Computer Use to open the macOS permission prompt, then grant Screen Recording access."),p&&u||f.push(`Cua Driver MCP is not configured in ${l}. Run: cua-driver mcp-config --client codex`),m||f.push(`Cua Driver Codex skill is missing. Checked ${ic(t).join(" and ")}.`),{platform:process.platform,enabled:null!==a,enabledBy:a,codexHome:t,codexAvailable:i.available,codexPath:i.path,codexConfigPresent:p,cuaDriverAvailable:o.available,cuaDriverPath:o.path,cuaDriverAccessibilityGranted:g.accessibilityGranted,cuaDriverScreenRecordingGranted:g.screenRecordingGranted,cuaDriverMcpConfigured:u,cuaDriverSkillPresent:m,cuaDriverSkillSource:h,markerPath:s,missing:f}}function cc(e){const t=tc("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH);if(!t.available||!t.path)return"cua-driver command is not available. Install Cua Driver CLI or set AGENTRIX_CUA_DRIVER_PATH.";const n=ec();if(!n.available||!n.path)return"Codex CLI is not available. Install Codex or set AGENTRIX_CODEX_PATH to the codex executable.";d(e,{recursive:!0});const s=Tt(t.path,["mcp-config","--client","codex"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e,AGENTRIX_CODEX_HOME:e}});if(0!==s.status){const e=[s.stderr,s.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return"Failed to run `cua-driver mcp-config --client codex`"+(e?`:\n${e}`:".")}const a=Tt(n.path,["mcp","add","cua-driver","--",t.path,"mcp"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e}});if(0===a.status)return null;const i=[a.stderr,a.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return`Failed to run \`codex mcp add cua-driver -- ${t.path} mcp\`${i?`:\n${i}`:"."}`}function lc(e){const t=oc(),n=E(e,"skills","cua-driver");if(!t)return["Cua Driver skill source was not found.","Install or update Cua Driver so its installer auto-wires agent skills, or set AGENTRIX_CUA_DRIVER_SKILL_SOURCE to a directory containing SKILL.md."].join(" ");if(r(n)){if(r(E(n,"SKILL.md")))return null;try{return v(n).isSymbolicLink()?`Existing Cua Driver skill symlink at ${n} does not resolve to a valid skill.`:`Existing path ${n} is not a valid Cua Driver skill directory.`}catch(e){return`Failed to inspect existing Cua Driver skill path ${n}: ${e instanceof Error?e.message:String(e)}`}}try{return d(D(n),{recursive:!0}),w(t,n,"dir"),null}catch(e){return`Failed to create Cua Driver skill symlink ${n} -> ${t}: ${e instanceof Error?e.message:String(e)}`}}function dc(e){try{return(r(e)||v(e).isSymbolicLink())&&h(e,{recursive:!0,force:!0}),null}catch(t){return"ENOENT"===t.code?null:`Failed to remove ${e}: ${t instanceof Error?t.message:String(t)}`}}function pc(e){try{return v(e).isSymbolicLink()?(f(e),null):null}catch(t){return"ENOENT"===t.code?null:`Failed to remove symlink ${e}: ${t instanceof Error?t.message:String(t)}`}}function uc(e){try{if(!v(e).isSymbolicLink())return null;const t=b(e);return t.includes("CuaDriver.app")||t.includes("cua-driver")?(f(e),null):null}catch(t){return"ENOENT"===t.code?null:`Failed to remove Cua Driver skill symlink ${e}: ${t instanceof Error?t.message:String(t)}`}}function mc(){const e=rc(),t=[],s=[],a=function(e){try{return r(e)&&f(e),null}catch(t){return`Failed to remove Agentrix Computer Use marker at ${e}: ${t instanceof Error?t.message:String(t)}`}}(e.markerPath);a?s.push(a):"marker"===e.enabledBy?t.push("Removed Agentrix Computer Use enablement marker."):t.push("Agentrix Computer Use enablement marker is already absent or not the active source.");const i=function(){try{const e=Me.readSettings()??{};return Me.writeSettings({...e,agentrixComputerUse:{...e.agentrixComputerUse??{},enabled:!1}}),null}catch(e){return`Failed to disable Agentrix Computer Use in settings: ${e instanceof Error?e.message:String(e)}`}}();i?s.push(i):t.push("Disabled Agentrix Computer Use in settings.");const o=function(e){const t=[],s=[],a=e.cuaDriverPath;a&&(Tt(a,["stop"],{encoding:"utf8",timeout:1e4}),t.push("Stopped Cua Driver daemon if it was running."));const i=["/Applications/CuaDriver.app","/Applications/CuaDriverRs.app",E(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_updater.plist"),E(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_daemon.plist"),E(n.homedir(),"Library","LaunchAgents","com.trycua.cua-driver-rs.plist"),E(n.homedir(),"Library","Application Support","Cua Driver"),E(n.homedir(),"Library","Caches","cua-driver"),E(n.homedir(),".cua-driver-rs")];for(const e of i){const n=dc(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const e of[E(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver"]){const n=pc(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const a of[E(e.codexHome,"skills","cua-driver"),E(n.homedir(),".agents","skills","cua-driver")]){const e=uc(a);e?s.push(e):t.push(`Removed ${a}.`)}const o=function(e){const t=E(e,"config.toml");try{const n=ec();if(n.available&&n.path&&Tt(n.path,["mcp","remove","cua-driver"],{encoding:"utf8",env:{...process.env,CODEX_HOME:e}}),!r(t))return null;const s=c(t,"utf8"),a=s.replace(/\n?\[mcp_servers\.(?:"cua-driver"|'cua-driver'|cua-driver|cua_driver)\][\s\S]*?(?=\n\[[^\]]+\]|\s*$)/g,"").replace(/\n{3,}/g,"\n\n").trimEnd()+"\n";return a!==s&&u(t,a,"utf8"),null}catch(e){return`Failed to remove Cua Driver MCP config from ${t}: ${e instanceof Error?e.message:String(e)}`}}(e.codexHome);return o?s.push(o):t.push("Removed Cua Driver MCP config from Codex when present."),{actions:t,errors:s}}(e);t.push(...o.actions),s.push(...o.errors);const l=rc();"env"===l.enabledBy&&s.push("Agentrix Computer Use is still enabled by AGENTRIX_COMPUTER_USE_ENABLED. Remove that environment variable and restart the daemon to complete uninstall.");const d=0===s.length&&!l.enabled;return{success:d,status:l,actions:t,error:d?void 0:s.join("\n")||"Agentrix Computer Use is still enabled."}}function hc(e=Me.readSettings()){const t=rc(e);if(!t.enabled)return t;const n=[];if(!t.cuaDriverMcpConfigured){Qr.info("computer_use.configure_mcp");const e=cc(t.codexHome);e&&n.push(e)}if(!t.cuaDriverSkillPresent){Qr.info("computer_use.configure_skill");const e=lc(t.codexHome);e&&n.push(e)}const s=rc(e);return 0===n.length?s:{...s,missing:[...s.missing,...n.map(e=>`Automatic Cua Driver configuration failed: ${e}`)]}}function gc(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(/\/+$/,"")}function fc(e,t){if(void 0===e||""===e.trim())return t;const n=e.trim().toLowerCase();if(["true","1","yes"].includes(n))return!0;if(["false","0","no"].includes(n))return!1;throw new Error(`Invalid boolean value: ${e}`)}async function yc(e,t,n){const s=await Lt(n.apiUrl,n.pat,{log:{warn:(e,t)=>De.warn(e,t),error:(e,t)=>De.warn(e,t)}});if(!s.result.valid||!s.user)throw new Error(function(e,t){if(e.valid)return"";switch(e.status){case"insufficient_scope":{const t=e.missingScopes?.filter(Boolean).join(", ");return t?`GitLab PAT is missing required scopes: ${t}. Update or recreate the PAT with these scopes, then run the command again.`:"GitLab PAT is missing required scopes. Update or recreate the PAT with the required GitLab scopes, then run the command again."}case"expired":return"GitLab rejected this PAT because it is expired, revoked, or no longer accepted. Create a new GitLab PAT and run the command again.";case"network_error":return`Cannot reach the GitLab API at ${t}. Check the GitLab URL, network, VPN, or intranet access, then run the command again.`;case"invalid":return"Token is empty"===e.error?"GitLab PAT is required. Provide a token with --pat-file, stdin, or the interactive prompt.":"GitLab rejected this PAT. Check that you copied the full token, or create a new GitLab PAT and run the command again.";default:return e.error||`GitLab PAT validation failed for ${t}/user`}}(s.result,n.apiUrl));const a=await Qo();if(!a)throw new Error("No Agentrix auth secret found for GitLab configuration");const i=await async function(e,t,n,s,a=15e3){if(!e.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:X(),method:t,path:n,body:s},o=await function(e,t,n){let s;const a=new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)});return Promise.race([e,a]).finally(()=>{s&&clearTimeout(s)})}(e.sendWithAck("machine-rpc-call",i),a,`Timed out waiting for machine RPC ${t} ${n}`);if(!o.success)throw new Error(o.error?.message||`Machine RPC failed: ${t} ${n}`);return o.data}(e,"POST","/v1/git-servers/machine-bind",{name:n.name,baseUrl:n.baseUrl,apiUrl:n.apiUrl,machineId:t.machineId,pat:n.pat,useAsProxy:n.useAsProxy});if(!i.success||!i.gitServer)throw new Error("Backend Git server bind failed");const o=i.gitServer,r={username:s.user.username,email:s.user.email||"",lastValidatedAt:(new Date).toISOString(),expiresAt:s.result.expiresAt};var c,l;!function(e,t){Yo.saveGitServerConfig(e,t)}(o.id,{baseUrl:o.baseUrl,apiUrl:o.apiUrl}),function(e,t,n){Yo.savePat(e,t,n)}(o.id,n.pat,a),c=o.id,l=r,Yo.savePatMeta(c,l);const d=function(e,t){return Yo.ensureGitLabWebhookSecret(e,t)}(o.id,a);return{success:!0,gitServer:o,machineId:i.machineId,proxyRegistered:i.proxyRegistered,webhookEndpointPath:Ht(o.id),webhookUrl:qt(o.id,await Me.readDaemonState()),patConfigured:!0,patMeta:r,webhookSecret:d}}async function vc(e,t){try{return await async function(e,t){const n=function(e=process.env){if(!fc(e.AGENTRIX_GITLAB_AUTO_CONFIG,!0))return null;const t=e.GITLAB_BASE_URL?.trim(),n=function(e){const t=e.GITLAB_TOKEN?.trim();if(t)return t;const n=e.GITLAB_TOKEN_FILE?.trim();if(!n)return null;if(!r(n))throw new Error(`GITLAB_TOKEN_FILE is not readable: ${n}`);return c(n,"utf8").trim()}(e);if(!t&&!n)return null;if(!t)throw new Error("GITLAB_BASE_URL is required when GITLAB_TOKEN is configured");if(!n)throw new Error("GITLAB_TOKEN or GITLAB_TOKEN_FILE is required when GITLAB_BASE_URL is configured");const s=gc(t,"GITLAB_BASE_URL"),a=gc(e.GITLAB_API_URL?.trim()||`${s}/api/v4`,"GITLAB_API_URL");return{name:e.AGENTRIX_GITLAB_NAME?.trim()||new URL(s).hostname,baseUrl:s,apiUrl:a,pat:n,useAsProxy:fc(e.AGENTRIX_GITLAB_USE_AS_PROXY,!0)}}();if(!n)return null;const s=await yc(e,t,n),a=s.gitServer,i={gitServerId:a.id,baseUrl:a.baseUrl,apiUrl:a.apiUrl,webhookEndpointPath:s.webhookEndpointPath,webhookUrl:s.webhookUrl,proxyRegistered:s.proxyRegistered};return De.info(`[GIT SERVER] auto-configured from environment: gitServer=${i.gitServerId}, proxyRegistered=${i.proxyRegistered}`),i}(e,t)}catch(e){return De.warn("[GIT SERVER] environment auto-config failed; daemon startup will continue",e),null}}function wc(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=E(e,a.name),i=p(s),o=N(t,s);n.push({name:a.name,path:o,size:i.size,modifiedAt:i.mtimeMs,isDirectory:a.isDirectory()}),a.isDirectory()&&n.push(...wc(s,t))}return n}function bc(){return E(Me.agentrixAgentsHomeDir,"companion","claude")}function kc(e,t){const n=U(E(e,t));return n.startsWith(e)?{absolutePath:n,relativePath:N(e,n)}:null}function xc(e,t,n){const s=E(e,"memory-changes"),a=E(s,`${t.key}.jsonl`),i=`${t.key}T00:00:00.000Z`,o=r(a)?c(a,"utf-8").split("\n").map((e,n)=>{const s=e.trim();if(!s)return null;try{return function(e,t,n){const s=Array.isArray(e?.changes)?e.changes:[e],a=s.map(e=>e?.summary).filter(Boolean),i=s.flatMap(e=>Array.isArray(e?.reasons)?e.reasons:[]).filter(Boolean),o=s.map(e=>e?.file).filter(Boolean),r=s.map(e=>e?.action).filter(Boolean);return{id:n,createdAt:e?.time||e?.timestamp||e?.createdAt||t,title:e?.title||a[0]||"记忆已更新",summary:i.length?i.join("\n"):"",files:o,actions:r,source:e?.source,trigger:e?.trigger,commit:e?.commit}}(JSON.parse(s),i,`${t.key}-${n}`)}catch{return null}}).filter(Boolean):[],l=r(s)&&g(s).some(e=>/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(e)&&e.slice(0,10)<t.key);return{...n,nextAfter:t.nextAfter,events:o.sort((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime()),hasMore:l}}function Ic(e,t){if(t.date){const n=function(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;const t=new Date(`${e}T00:00:00.000Z`);return Number.isNaN(t.getTime())?null:{key:e,nextAfter:t.toISOString()}}(t.date);return n?xc(e,n,{date:t.date}):null}if(t.after){const n=function(e){const t=function(e){const t=new Date(e);return Number.isNaN(t.getTime())?null:t}(e);if(!t)return null;const n=new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()));n.setUTCDate(n.getUTCDate()-1);const s=n.toISOString();return{key:n.toISOString().slice(0,10),nextAfter:s}}(t.after);return n?xc(e,n,{after:t.after}):null}return null}function Sc(e,t){if(!r(E(e,".git")))return"";try{return Et("git",["-C",e,...t],{encoding:"utf8",timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return""}}function Tc(e,t,n){const s=n.replace(/[^0-9a-f]/gi,"");return s?Sc(e,["show","--format=","--no-ext-diff",s,"--",t]):""}function Cc(e){if(!e||"object"!=typeof e)return"";const t=e,n=(Array.isArray(t.changes)?t.changes:[]).map(e=>e&&"object"==typeof e?e.summary:null).filter(e=>"string"==typeof e&&e.trim().length>0);if(n.length)return n.join(";");const s=t.input;if(s&&"object"==typeof s){const e=Cc(s);if(e)return e}for(const e of["result","summary","title","content","text","message"]){const n=t[e];if("string"==typeof n&&n.trim())return n;if(n&&"object"==typeof n){const e=Cc(n);if(e)return e}}return""}function _c(e){if("string"==typeof e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{const e=Cc(JSON.parse(t));if(e)return e}catch{}return e}if(!e||"object"!=typeof e)return"";const t=Cc(e);if(t)return t;const n=e.content;return"string"==typeof n?_c(n):Array.isArray(n)?n.map(e=>_c(e)).filter(Boolean).join("\n"):""}function Ac(e,t){return _c(e).trim()||t}function Ec(e){return!/(no\s+(memory\s+)?changes?\s+(needed|required|found|detected)|no\s+updates?\s+(needed|required|found|detected)|无需.*(更新|变更|修改|创建|新增|删除)|不需要.*(更新|变更|修改|创建|新增|删除)|没有.*(更新|变更|修改|创建|新增|删除)|无.*(更新|变更|修改|创建|新增|删除)|未.*(发现|检测到).*(更新|变更|修改|创建|新增|删除))/i.test(e)&&/更新|updated|created|deleted|修改|创建|新增|删除|memory change|memory changes/i.test(e)}function $c(e){return!!e&&"object"==typeof e&&"companion_memory_organization"===e.type}function Mc(e){if(!e)return!1;if(Array.isArray(e))return e.some(Mc);if("object"!=typeof e)return!1;const t=e;return"tool_use"===t.type&&("mcp__agentrix__record_memory_change"===t.name||"record_memory_change"===t.name)||Object.values(t).some(Mc)}function Pc(e){if(!e||"object"!=typeof e)return"";const t=e;return"result"===t.type&&"string"==typeof t.result?t.result:""}function Rc(e,t,n=1){if(!e||!t)return[];try{const s=Bo({dataDir:Me.resolveDataDir(e,t),taskId:t});try{return[...s.pageRecentMessages(50).data].reverse().filter(e=>"system"!==e.senderType&&_c(e.message).trim()).slice(0,n).map(e=>({summary:Ac(_c(e.message),""),time:e.createdAt}))}finally{s.close()}}catch{return[]}}function Dc(e,t=1){return Rc("string"==typeof e.userId?e.userId:null,"string"==typeof e.chatTaskId?e.chatTaskId:null,t).map(e=>({type:"chat",title:"Companion Chat",summary:e.summary,time:e.time}))}async function Nc(e,t,n=1){const s="string"==typeof e.chatId?e.chatId:null;if(!s)return[];try{const a=new URLSearchParams({chatId:s,limit:String(Math.min(Math.max(3*n,10),50))}),i=await Gc(t,"GET",`/v1/tasks/recent?${a.toString()}`,void 0,1e4);return Array.isArray(i.tasks)?i.tasks.filter(e=>!["completed","cancelled","error"].includes(String(e.state))).slice(0,n).map(t=>{const n="string"==typeof t.taskId?t.taskId:"",s="string"==typeof t.title&&t.title.trim()?t.title.trim():"Task",a=Rc("string"==typeof e.userId?e.userId:null,n,1)[0];return{type:"task",title:s,summary:a?.summary||"",time:a?.time||t.updatedAt||t.createdAt||(new Date).toISOString()}}):[]}catch{return[]}}function Oc(e,t=1){const n=E(e,"memory-changes");if(!r(n))return[];const s=g(n).filter(e=>/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(e)).sort().reverse(),a=[];for(const n of s){const s=n.slice(0,10),i=xc(e,{key:s,nextAfter:`${s}T00:00:00.000Z`},{date:s});for(const e of i.events){const n=Ac(e.summary||e.files.join(", ")||e.title,"记忆已更新");if(a.push({type:"memory",title:e.title||"记忆已更新",summary:n,time:String(e.createdAt)}),a.length>=t)return a}}return a}function Uc(e,t){const n=[],s=Bo({dataDir:Me.resolveDataDir(e,t),taskId:t});try{let e=!1,t=!1;for(const a of s.pageRecentTaskEvents(1e3).data){const s=a.eventData,i=s.message;if($c(i)){e=!0,t=!1;continue}if(!e)continue;Mc(i)&&(t=!0);const o="agent"===s.senderType?Pc(i):"";o&&(n.push({time:a.createdAt,summary:Ac(o,"记忆整理已运行"),updated:t}),e=!1,t=!1)}}finally{s.close()}return n}function jc(e,t,n=1){const s="string"==typeof e.userId?e.userId:null,a="string"==typeof e.chatTaskId?e.chatTaskId:null;if(!s||!a)return[];const i=("heartbeat"===t?[e.heartbeatTaskId,e.heartbeatShadowTaskId]:[e.memoryOrganizationTaskId,e.memoryOrganizationShadowTaskId]).filter(e=>"string"==typeof e&&e.length>0),o=[a,...i],r="heartbeat"===t?["heartbeat","心跳","reminder","待处理事项"]:["memory organization","memory-organization","记忆整理","companion_memory_organization","memory review","memory changes","记忆更新"],c=[];if("memory-organization"===t){for(const e of[...new Set(i)])try{c.push(...Uc(s,e))}catch{}if(c.length>0)return Lc(c,n)}for(const e of[...new Set(o)]){const n=i.includes(e);try{const a=Bo({dataDir:Me.resolveDataDir(s,e),taskId:e});try{for(const e of a.pageRecentMessages(160).data){if("agent"!==e.senderType)continue;const s=_c(e.message);if(!s.trim())continue;if(!n&&!r.some(e=>s.toLowerCase().includes(e.toLowerCase())))continue;const a=Ac(s,"heartbeat"===t?"Heartbeat 已运行":"记忆整理已运行");c.push({time:e.createdAt,summary:a,updated:Ec(s)})}}finally{a.close()}}catch{}}return Lc(c,n)}function Lc(e,t=1){const n=new Set;return e.sort((e,t)=>new Date(t.time).getTime()-new Date(e.time).getTime()).filter(e=>{const t=`${e.time}:${e.summary}`;return!n.has(t)&&(n.add(t),!0)}).slice(0,t)}function qc(e){return"127.0.0.1"===e||"::1"===e||"::ffff:127.0.0.1"===e}const Hc=kt.object({id:kt.string(),type:kt.string(),name:kt.string(),baseUrl:kt.string(),apiUrl:kt.string(),oauthServerId:kt.string().nullable().optional(),ownerId:kt.string().nullable().optional(),authModeDefault:kt.string().optional(),executionMode:kt.string().optional(),syncMode:kt.string().optional(),networkMode:kt.string().optional(),githubAppName:kt.string().nullable().optional(),enabled:kt.boolean().optional(),createdAt:kt.string().optional(),updatedAt:kt.string().optional()}).passthrough(),Fc=kt.object({platform:kt.string(),enabled:kt.boolean(),enabledBy:kt.enum(["env","settings","marker"]).nullable(),codexHome:kt.string(),codexAvailable:kt.boolean(),codexPath:kt.string().optional(),codexConfigPresent:kt.boolean(),cuaDriverAvailable:kt.boolean(),cuaDriverPath:kt.string().optional(),cuaDriverAccessibilityGranted:kt.boolean().optional(),cuaDriverScreenRecordingGranted:kt.boolean().optional(),cuaDriverMcpConfigured:kt.boolean(),cuaDriverSkillPresent:kt.boolean(),cuaDriverSkillSource:kt.string().optional(),markerPath:kt.string(),missing:kt.array(kt.string())});function Bc(e){return e instanceof Error?e.message:"Unknown error"}async function Gc(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:X(),method:t,path:n,body:s},o=await async function(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)}}(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 Wc(e){const{getChildren:t,stopSession:n,startDevOpsInit:s,completeDevOpsInit:a,requestShutdown:i,registerSession:o,credentials:l,getSocketClient:m,prepareGracefulRestart:h,clearGracefulRestartGate:g}=e;return new Promise(f=>{const y=Me.getDaemonControlHost(),v=Me.getDaemonWebhookHost(),w=bt({logger:!1});w.removeContentTypeParser("application/json"),w.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,{})}),w.setValidatorCompiler(It),w.setSerializerCompiler(St);const b=w.withTypeProvider();!function(e,t){const n=t.getSocketClient??(()=>{}),s={credentials:t.credentials,getSocketClient:n,dispatcher:t.dispatcher??Kr(t.credentials,n)};e.post(Br,async(e,t)=>{try{await Vr(e,t,s)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return De.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(Br,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(Br,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(w,{credentials:l,getSocketClient:m});const I=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")};b.post("/session-started",{schema:{body:kt.object({sessionId:kt.string(),metadata:kt.any()}),response:{200:kt.object({status:kt.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return De.debug(`[CONTROL SERVER] Session started: ${t}`),o(t,n),{status:"ok"}}),b.post("/devops-init-complete",{schema:{body:kt.object({taskId:kt.string(),userId:kt.string(),action:kt.enum(["continue","stop"])}),response:{200:kt.object({status:kt.literal("ok")})}}},async e=>{const{taskId:t,userId:n,action:s}=e.body;return De.info(`[CONTROL SERVER] Agentrix DevOps init complete for task ${t}, action=${s}`),a?.({taskId:t,userId:n,action:s}),{status:"ok"}}),b.post("/devops-init-start",{schema:{body:kt.object({taskId:kt.string(),userId:kt.string()}),response:{200:kt.object({status:kt.literal("ok")})}}},async e=>{const{taskId:t,userId:n}=e.body;return De.info(`[CONTROL SERVER] Starting Agentrix DevOps init for existing task ${t}`),s?.({taskId:t,userId:n}),{status:"ok"}}),b.post("/prepare-graceful-restart",{schema:{body:kt.object({source:kt.string().optional(),reason:kt.string().optional()}).optional(),response:{200:kt.object({state:kt.enum(["pending_restart","restarting"]),activeSessions:kt.number()}),503:kt.object({error:kt.string()}),403:kt.object({error:kt.string()})}}},async(e,t)=>qc(e.ip)?h?h({source:e.body?.source??"control-server",reason:e.body?.reason}):t.code(503).send({error:"Graceful restart gate is not available"}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),b.post("/clear-graceful-restart-gate",{schema:{response:{200:kt.object({success:kt.literal(!0)}),403:kt.object({error:kt.string()})}}},async(e,t)=>qc(e.ip)?(g?.(),{success:!0}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),b.options("/ping",async(e,t)=>(I(t),t.send())),b.get("/ping",{schema:{response:{200:kt.object({status:kt.literal("ok"),machineId:kt.string(),timestamp:kt.string(),controlHost:kt.string(),webhookHost:kt.string(),hasMachineAesKey:kt.boolean()})}}},async(e,t)=>(I(t),{status:"ok",machineId:l.machineId,timestamp:(new Date).toISOString(),controlHost:y,webhookHost:v,hasMachineAesKey:Yr(l)})),b.get("/computer-use/status",{schema:{response:{200:kt.object({status:Fc}),403:kt.object({error:kt.string()})}}},async(e,t)=>qc(e.ip)?{status:rc()}:t.code(403).send({error:"Computer Use status is only allowed from loopback"})),b.post("/computer-use/install",{schema:{response:{200:kt.object({success:kt.boolean(),status:Fc,actions:kt.array(kt.string()),error:kt.string().optional()}),403:kt.object({error:kt.string()})}}},async(e,t)=>{if(!qc(e.ip))return t.code(403).send({error:"Computer Use installation is only allowed from loopback"});try{return function(){let e=rc();const t=[],n=[];if("darwin"!==process.platform)return{success:!1,status:e,actions:t,error:"Agentrix Computer Use currently requires macOS because Cua Driver is macOS-only."};if(!e.cuaDriverAvailable)return{success:!1,status:e,actions:t,error:"Cua Driver is not installed or not available. Install Cua Driver from Desktop first, or set AGENTRIX_CUA_DRIVER_PATH."};if(e.cuaDriverAvailable&&t.push(`Detected Cua Driver at ${e.cuaDriverPath??"PATH"}`),e.cuaDriverPath){const s=function(e){const t=Tt(e,["call","check_permissions",'{"prompt":true}',"--raw","--compact"],{encoding:"utf8",timeout:3e4});if(0===t.status)return null;const n=[t.stderr,t.stdout].map(e=>e?.trim()).filter(Boolean).join("\n");return"Failed to open Cua Driver permission prompt"+(n?`:\n${n}`:".")}(e.cuaDriverPath);s?n.push(s):t.push("Checked Cua Driver permissions and opened macOS permission prompts for any missing grants.")}if(e.cuaDriverMcpConfigured)t.push("Cua Driver MCP is already configured for Agentrix Computer Use.");else{const s=cc(e.codexHome);s?n.push(s):t.push("Configured Cua Driver MCP for Agentrix Computer Use.")}if(e=rc(),e.cuaDriverSkillPresent)t.push("Cua Driver skill is already available to Agentrix Computer Use.");else{const s=lc(e.codexHome);s?n.push(s):t.push("Linked Cua Driver skill for Agentrix Computer Use.")}const s=function(e){try{return d(D(e),{recursive:!0}),u(e,`${(new Date).toISOString()}\n`,"utf8"),null}catch(t){return`Failed to enable Agentrix Computer Use at ${e}: ${t instanceof Error?t.message:String(t)}`}}(e.markerPath);s?n.push(s):e.enabled?t.push("Agentrix Computer Use was already enabled."):t.push("Enabled Agentrix Computer Use.");const a=function(){try{const e=Me.readSettings()??{};return Me.writeSettings({...e,agentrixComputerUse:{...e.agentrixComputerUse??{},enabled:!0}}),null}catch(e){return`Failed to enable Agentrix Computer Use in settings: ${e instanceof Error?e.message:String(e)}`}}();a&&n.push(a);const i=rc(),o=0===n.length&&i.enabled&&0===i.missing.length;return{success:o,status:0===n.length?i:{...i,missing:[...i.missing,...n.map(e=>`Agentrix Computer Use install failed: ${e}`)]},actions:t,error:o?void 0:[...n,...i.missing].join("\n")||"Agentrix Computer Use is not ready."}}()}catch(e){return{success:!1,status:rc(),actions:[],error:Bc(e)}}}),b.post("/computer-use/uninstall",{schema:{response:{200:kt.object({success:kt.boolean(),status:Fc,actions:kt.array(kt.string()),error:kt.string().optional()}),403:kt.object({error:kt.string()})}}},async(e,t)=>{if(!qc(e.ip))return t.code(403).send({error:"Computer Use uninstall is only allowed from loopback"});try{return mc()}catch(e){return{success:!1,status:rc(),actions:[],error:Bc(e)}}}),b.post("/machine/aes-key",{schema:{body:kt.object({machineId:kt.string(),machineAesKey:kt.string()}),response:{200:kt.object({success:kt.literal(!0),updated:kt.boolean(),hasMachineAesKey:kt.literal(!0)}),400:kt.object({error:kt.string()}),403:kt.object({error:kt.string()}),409:kt.object({error:kt.string()}),500:kt.object({error:kt.string()})}}},async(e,t)=>{if(!qc(e.ip))return t.code(403).send({error:"machine AES key recovery is only allowed from loopback"});try{const t=await async function(e,t,n=Me){if(t.machineId!==e.machineId)throw new Xr("machineId does not match daemon credentials",409);if(!Jr(t.machineAesKey))throw new Xr("machineAesKey must decode to a 32-byte key",400);const s=await n.readCredentials()??e;if(s.machineId!==e.machineId)throw new Xr("stored credentials machineId does not match daemon credentials",409);if(Yr(s))return e.machineAesKey=s.machineAesKey,{success:!0,updated:!1,hasMachineAesKey:!0};const a={...s,machineAesKey:t.machineAesKey};return await n.writeCredentials(a),e.machineAesKey=t.machineAesKey,{success:!0,updated:!0,hasMachineAesKey:!0}}(l,e.body);return De.info(t.updated?`[CONTROL SERVER] Recovered machine AES key stored for ${l.machineId}`:`[CONTROL SERVER] Machine AES key already present for ${l.machineId}`),t}catch(e){const n=e instanceof Xr?e.statusCode:500,s=400===n||409===n?n:500,a=e instanceof Error?e.message:"Failed to store machine AES key";return De.warn(`[CONTROL SERVER] Failed to store recovered machine AES key: ${a}`),t.code(s).send({error:a})}}),b.options("/openers",async(e,t)=>(I(t),t.send())),b.get("/openers",{schema:{response:{200:kt.object({openers:kt.array(kt.object({id:kt.string(),label:kt.string(),kind:kt.enum(["system","file-manager","terminal","editor","ide"]),method:kt.enum(["scheme","cli"]),urlTemplate:kt.string().optional(),supported:kt.boolean()}))})}}},async(e,t)=>(I(t),{openers:await ba()})),b.options("/open",async(e,t)=>(I(t),t.send())),b.options("/pick-directory",async(e,t)=>(I(t),t.send())),b.options("/validate-directory",async(e,t)=>(I(t),t.send())),b.post("/open",{schema:{body:kt.object({path:kt.string(),openerId:kt.string(),userId:kt.string().optional(),taskId:kt.string().optional()}),response:{200:kt.object({success:kt.boolean(),error:kt.string().optional()})}}},async(e,t)=>{I(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=xa(Ca()).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=A.resolve(e);if(!A.isAbsolute(s))throw new Error("Path must be absolute");if(!p(s).isDirectory())throw new Error("Path must be a directory");if(t&&n){const e=Me.getTaskCwd(t,n);if(e&&!function(e,t){const n=A.relative(t,e);return""===n||!n.startsWith("..")&&!A.isAbsolute(n)}(s,A.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 De.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),b.post("/pick-directory",{schema:{body:kt.object({defaultPath:kt.string().optional()}),response:{200:kt.object({path:kt.string().nullable(),error:kt.string().optional()})}}},async(e,t)=>{I(t);try{return{path:ka(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),b.post("/validate-directory",{schema:{body:kt.object({path:kt.string()}),response:{200:kt.object({ok:kt.boolean(),status:kt.enum(["active","missing","permission_lost"]),error:kt.string().optional()})}}},async(e,t)=>{I(t);try{if(!p(e.body.path).isDirectory())return{ok:!1,status:"missing",error:"Path is not a directory"};try{k(e.body.path,x.R_OK|x.W_OK)}catch{return{ok:!1,status:"permission_lost",error:"Directory is not readable and writable"}}return{ok:!0,status:"active"}}catch(e){return{ok:!1,status:"missing",error:e instanceof Error?e.message:"Directory is unavailable"}}}),b.post("/companion/ensure",{schema:{body:kt.object({preferredLanguage:kt.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:kt.object({agentDir:kt.string()})}}},async e=>await Ho({preferredLanguage:e.body?.preferredLanguage,credentials:l})),b.post("/companion/probe",{schema:{response:{200:kt.object({success:kt.boolean(),error:kt.string().optional()})}}},async()=>await Ki()),b.get("/companion/workspace/status",{schema:{response:{200:kt.object({exists:kt.boolean()})}}},async()=>{const e=bc();return{exists:r(e)}}),b.get("/companion/workspace",{schema:{response:{200:kt.object({files:kt.array(kt.object({name:kt.string(),path:kt.string(),size:kt.number(),modifiedAt:kt.number(),isDirectory:kt.boolean()}))})}}},async()=>{const e=bc();return r(e)?{files:wc(e,e)}:{files:[]}}),b.get("/companion/file",{schema:{querystring:kt.object({path:kt.string()}),response:{200:kt.object({content:kt.string()}),404:kt.object({error:kt.string()})}}},async(e,t)=>{const n=bc(),s=U(E(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),b.put("/companion/file",{schema:{body:kt.object({path:kt.string(),content:kt.string()}),response:{200:kt.object({success:kt.boolean()}),400:kt.object({error:kt.string()})}}},async(e,t)=>{const n=bc(),s=U(E(n,e.body.path));return s.startsWith(n)?(d(D(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),b.get("/companion/file/versions",{schema:{querystring:kt.object({path:kt.string(),limit:kt.coerce.number().int().positive().max(50).optional(),skip:kt.coerce.number().int().min(0).optional()}),response:{200:kt.object({versions:kt.array(kt.object({commit:kt.string(),shortCommit:kt.string(),subject:kt.string(),body:kt.string(),authoredAt:kt.string()})),hasMore:kt.boolean(),nextSkip:kt.number()}),404:kt.object({error:kt.string()})}}},async(e,t)=>{const n=bc(),s=kc(n,e.query.path);return s&&r(s.absolutePath)?function(e,t,n={}){const s=Math.min(Math.max(n.limit??10,1),50),a=Math.max(n.skip??0,0),i=Sc(e,["log",`--max-count=${s+1}`,`--skip=${a}`,"--date=iso-strict","--pretty=format:%H%x1f%h%x1f%aI%x1f%s%x1f%b%x1e","--",t]).split("").map(e=>e.trim()).filter(Boolean).map(e=>{const[t,n,s,a,i]=e.split("");return{commit:t||"",shortCommit:n||"",authoredAt:s||"",subject:a||"没有详细变更说明",body:i?.trim()||""}}).filter(e=>e.commit.length>0);return{versions:i.slice(0,s),hasMore:i.length>s,nextSkip:a+Math.min(i.length,s)}}(n,s.relativePath,{limit:e.query.limit??10,skip:e.query.skip??0}):t.code(404).send({error:"File not found"})}),b.get("/companion/file/diff",{schema:{querystring:kt.object({path:kt.string(),commit:kt.string()}),response:{200:kt.object({commit:kt.string(),path:kt.string(),diff:kt.string()}),404:kt.object({error:kt.string()})}}},async(e,t)=>{const n=bc(),s=kc(n,e.query.path);return s&&r(s.absolutePath)?{commit:e.query.commit,path:s.relativePath,diff:Tc(n,s.relativePath,e.query.commit)}:t.code(404).send({error:"File not found"})}),b.get("/companion/memory-events",{schema:{querystring:kt.object({after:kt.string().optional(),date:kt.string().optional()}),response:{200:kt.object({after:kt.string().optional(),date:kt.string().optional(),nextAfter:kt.string(),events:kt.array(kt.object({id:kt.string(),createdAt:kt.union([kt.string(),kt.number()]),title:kt.string(),summary:kt.string(),files:kt.array(kt.string()),actions:kt.array(kt.string()).optional(),source:kt.string().optional(),trigger:kt.string().optional(),commit:kt.string().optional()})),hasMore:kt.boolean()}),400:kt.object({error:kt.string()})}}},async(e,t)=>{const n=bc();if(!e.query.after&&!e.query.date)return t.code(400).send({error:"Use after or date"});return Ic(n,e.query)||t.code(400).send({error:"Invalid after or date"})}),b.get("/companion/recent-activity",{schema:{querystring:kt.object({limit:kt.coerce.number().int().positive().max(50).optional()}),response:{200:kt.object({chats:kt.array(kt.object({type:kt.literal("chat"),title:kt.string(),summary:kt.string(),time:kt.string(),status:kt.string().optional()})),tasks:kt.array(kt.object({type:kt.literal("task"),title:kt.string(),summary:kt.string(),time:kt.string(),status:kt.string().optional()})),memories:kt.array(kt.object({type:kt.literal("memory"),title:kt.string(),summary:kt.string(),time:kt.string(),status:kt.string().optional()}))})}}},async e=>{const t=bc(),n=e.query.limit??1,s=E(t,"state.json");let a={};if(r(s))try{a=JSON.parse(c(s,"utf-8"))}catch{a={}}const[i,o,l]=await Promise.all([Nc(a,m?.(),n),Promise.resolve(Dc(a,n)),Promise.resolve(Oc(t,n))]);return{chats:o,tasks:i,memories:l}}),b.get("/companion/config",{schema:{querystring:kt.object({recentLimit:kt.coerce.number().int().positive().max(50).optional()}),response:{200:kt.object({heartbeatIntervalMs:kt.number(),heartbeatEnabled:kt.boolean(),lastHeartbeatTimestamp:kt.string().nullable(),lastHeartbeatDate:kt.string().nullable(),lastMaintenanceHeartbeatTimestamp:kt.string().nullable(),heartbeatTriggerCount:kt.number(),lastInteractionTimestamp:kt.string().nullable(),memoryOrganizationEnabled:kt.boolean(),memoryOrganizationIntervalHours:kt.number(),allowedMemoryOrganizationIntervalHours:kt.array(kt.number()),lastMemoryOrganizationTimestamp:kt.string().nullable(),memoryOrganizationTaskId:kt.string().nullable(),heartbeatRecentRecords:kt.array(kt.object({time:kt.string(),summary:kt.string(),updated:kt.boolean()})),memoryOrganizationRecentRecords:kt.array(kt.object({time:kt.string(),summary:kt.string(),updated:kt.boolean()}))})}}},async e=>{const t=bc(),n=e.query.recentLimit??1,s=E(t,"state.json");let a=9e5,i=!1,o=null,l=null,d=null,p=0,u=null,m=!1,h=4,g=null,f=null,y={};if(r(s))try{y=JSON.parse(c(s,"utf-8")),"number"==typeof y.heartbeatIntervalMs&&(a=y.heartbeatIntervalMs),"boolean"==typeof y.heartbeatEnabled&&(i=y.heartbeatEnabled),"string"==typeof y.lastHeartbeatTimestamp&&(o=y.lastHeartbeatTimestamp),"string"==typeof y.lastHeartbeatDate&&(l=y.lastHeartbeatDate),"string"==typeof y.lastMaintenanceHeartbeatTimestamp&&(d=y.lastMaintenanceHeartbeatTimestamp),"number"==typeof y.heartbeatTriggerCount&&(p=y.heartbeatTriggerCount),"string"==typeof y.lastInteractionTimestamp&&(u=y.lastInteractionTimestamp),"boolean"==typeof y.memoryOrganizationEnabled&&(m=y.memoryOrganizationEnabled),h=Xo(y.memoryOrganizationIntervalHours),"string"==typeof y.lastMemoryOrganizationTimestamp&&(g=y.lastMemoryOrganizationTimestamp),"string"==typeof y.memoryOrganizationTaskId&&(f=y.memoryOrganizationTaskId)}catch{}const v=jc(y,"heartbeat",n),w=jc(y,"memory-organization",n);return{heartbeatIntervalMs:a,heartbeatEnabled:i,lastHeartbeatTimestamp:o,lastHeartbeatDate:l,lastMaintenanceHeartbeatTimestamp:d,heartbeatTriggerCount:p,lastInteractionTimestamp:u,memoryOrganizationEnabled:m,memoryOrganizationIntervalHours:h,allowedMemoryOrganizationIntervalHours:[...Ko],lastMemoryOrganizationTimestamp:g,memoryOrganizationTaskId:f,heartbeatRecentRecords:v,memoryOrganizationRecentRecords:w}}),b.put("/companion/config",{schema:{body:kt.object({heartbeatIntervalMs:kt.number().optional(),heartbeatEnabled:kt.boolean().optional(),memoryOrganizationEnabled:kt.boolean().optional(),memoryOrganizationIntervalHours:kt.number().optional()}),response:{200:kt.object({success:kt.boolean()}),400:kt.object({error:kt.string()})}}},async(t,n)=>{const s=bc(),a=E(s,"state.json");let i={};if(r(a))try{i=JSON.parse(c(a,"utf-8"))}catch{}const{heartbeatIntervalMs:o,heartbeatEnabled:l,memoryOrganizationEnabled:p,memoryOrganizationIntervalHours:m}=t.body;if(void 0!==o&&(i.heartbeatIntervalMs=o),void 0!==l&&(i.heartbeatEnabled=l),void 0!==p&&(i.memoryOrganizationEnabled=p),void 0!==m){if(!Vo(m))return n.code(400).send({error:`memoryOrganizationIntervalHours must be one of: ${Ko.join(", ")}`});i.memoryOrganizationIntervalHours=m}return d(D(a),{recursive:!0}),u(a,JSON.stringify(i,null,2),"utf-8"),e.companionScheduler?.reloadStateAndReschedule(),{success:!0}}),b.post("/agent/install",{schema:{body:kt.object({agentId:kt.string(),gitUrl:kt.string(),branch:kt.string().optional(),subDir:kt.string().optional()}),response:{200:kt.object({agentDir:kt.string()}),500:kt.object({error:kt.string()})}}},async(e,t)=>{try{return await Ha(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),b.post("/git-server/bind",{schema:{body:kt.object({name:kt.string().min(1),baseUrl:kt.string().url(),apiUrl:kt.string().url(),pat:kt.string().min(1),useAsProxy:kt.boolean().optional().default(!0)}),response:{200:kt.object({success:kt.literal(!0),gitServer:Hc,machineId:kt.string(),proxyRegistered:kt.boolean(),webhookEndpointPath:kt.string(),webhookUrl:kt.string().optional(),patConfigured:kt.literal(!0),patMeta:kt.object({username:kt.string(),email:kt.string(),lastValidatedAt:kt.string(),expiresAt:kt.string().nullable().optional()}),webhookSecret:kt.string()}),502:kt.object({error:kt.string()})}}},async(e,t)=>{try{const n=m?.();if(!n)throw new Error("Machine WebSocket is not connected");const s=await yc(n,l,{name:e.body.name,baseUrl:e.body.baseUrl,apiUrl:e.body.apiUrl,pat:e.body.pat,useAsProxy:e.body.useAsProxy});return t.send(s)}catch(n){const s=Bc(n);return De.warn(`[GIT SERVER] bind failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),b.post("/git-server/list",{schema:{response:{200:kt.object({gitServers:kt.array(Hc)}),502:kt.object({error:kt.string()})}}},async(e,t)=>{try{const e=await Gc(m?.(),"POST","/v1/git-servers/machine-list",{machineId:l.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=Bc(e);return De.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),b.post("/git-server/delete",{schema:{body:kt.object({gitServerId:kt.string().min(1)}),response:{200:kt.object({success:kt.boolean(),machineId:kt.string()}),502:kt.object({error:kt.string()})}}},async(e,t)=>{try{const n=await Gc(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=Bc(n);return De.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),b.post("/webhooks/gitlab/:gitServerId",{schema:{params:kt.object({gitServerId:kt.string()}),body:kt.record(kt.string(),kt.unknown()),response:{200:kt.object({status:kt.enum(["delivered","ignored","failed"]),deliveryId:kt.string(),providerEventName:kt.string(),events:kt.array(kt.unknown()),deliveries:kt.array(kt.object({target:kt.string(),eventId:kt.string(),status:kt.enum(["delivered","failed","ignored"]),reason:kt.string().optional(),output:kt.unknown().optional(),error:kt.object({message:kt.string(),detail:kt.string().optional(),upstreamStatus:kt.number().optional()}).optional()}))}),400:kt.object({error:kt.string()}),401:kt.object({error:kt.string()}),403:kt.object({error:kt.string()}),404:kt.object({error:kt.string()}),502:kt.object({error:kt.string()}),500:kt.object({error:kt.string()})}}},async(e,t)=>{const n=Se(),s=Date.now(),a=(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.providerEventName??"-"),a=Array.isArray(t.deliveries)?t.deliveries:[],i=a.filter(e=>e&&"object"==typeof e&&"delivered"===e.status).length,o=a.filter(e=>e&&"object"==typeof e&&"failed"===e.status).length,r=a.filter(e=>e&&"object"==typeof e&&"ignored"===e.status).length,c=a.find(e=>e&&"object"==typeof e),l=c?.error&&"object"==typeof c.error?c.error:void 0,d=String(c?.reason??"-"),p=String(l?.upstreamStatus??"-"),u=String(l?.message??"-"),m=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)}`}(c?.output);return`status=${n}, providerEventName=${s}, deliveries=${a.length}, deliveredCount=${i}, failedCount=${o}, ignoredCount=${r}, reason=${d}, upstreamStatus=${p}, errorMessage=${u}, pipeline=${m}`}(i);return De[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};De.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body)}, remote=${e.ip||"-"}, userAgent=${"string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-"}`);const i=await Qo();if(!i)return a(500,{error:"Git server encryption key not available"});const o=er(e.params.gitServerId,i),r=o?.webhookSecret;if(!r)return a(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});try{const t=Zo(e.params.gitServerId);return a(200,await async function({gitServerId:e,payload:t,config:n,pat:s}){const a=n.baseUrl??n.apiUrl,i={headers:{...n.headers??{},...n.deliveryId?{"x-gitlab-webhook-uuid":n.deliveryId}:{}},body:t},o=cn(i,n.webhookSecret);if(0===o.events.length)return{status:"ignored",deliveryId:o.deliveryId,providerEventName:o.providerEventName,events:[],deliveries:[]};if(!a)throw{status:400,message:"GitLab base URL or API URL is required"};if(!s)throw{status:403,message:`No PAT configured for git server ${e}`};const r={baseUrl:a,token:s,webhookSecret:n.webhookSecret,...n.apiUrl?{apiUrl:n.apiUrl}:{}},c=n.store??(n.encryptionKey&&n.webhookSecret?function(e){const t=`gitlab:pipeline-trigger:${ln(e.gitlab)}:`,n=`gitlab-webhook:${e.gitServerId}:`;return{async get(s){if(s.startsWith(t)){const n=s.slice(t.length),a=er(e.gitServerId,e.encryptionKey);return a?.projectTriggerTokens?.[n]??null}return Or.get(`${n}${s}`)},async set(s,a,i){if(s.startsWith(t)){const n=s.slice(t.length),i=er(e.gitServerId,e.encryptionKey)??{webhookSecret:e.webhookSecret,projectTriggerTokens:{}};return void tr(e.gitServerId,{webhookSecret:i.webhookSecret||e.webhookSecret,projectTriggerTokens:{...i.projectTriggerTokens??{},[n]:a}},e.encryptionKey)}await Or.set(`${n}${s}`,a,i)},async delete(s){if(s.startsWith(t)){const n=s.slice(t.length),a=er(e.gitServerId,e.encryptionKey);if(!a?.projectTriggerTokens?.[n])return;const i={...a.projectTriggerTokens};return delete i[n],void tr(e.gitServerId,{webhookSecret:a.webhookSecret||e.webhookSecret,projectTriggerTokens:i},e.encryptionKey)}await(Or.delete?.(`${n}${s}`))}}}({gitServerId:e,gitlab:r,webhookSecret:n.webhookSecret,encryptionKey:n.encryptionKey}):Nr),l=function(e){return new dn({gitlab:e.gitlab,store:e.store,targets:[pn({variables:un([mn(),hn({AGENTRIX_GIT_SERVER_ID:e.gitServerId})]),...e.ref?{ref:()=>e.ref}:{},...e.triggerToken?{triggerToken:e.triggerToken}:{},...void 0!==e.createTriggerIfMissing?{createTriggerIfMissing:e.createTriggerIfMissing}:{}})]})}({gitServerId:e,gitlab:r,store:c,ref:n.ref,triggerToken:n.triggerToken,createTriggerIfMissing:n.createTriggerIfMissing});return l.handle(i)}({gitServerId:e.params.gitServerId,payload:e.body,pat:sr(e.params.gitServerId,i)??void 0,config:{baseUrl:t?.baseUrl,apiUrl:t?.apiUrl,headers:e.headers,webhookSecret:r,encryptionKey:i}}))}catch(t){const s=t,i="number"==typeof s.status?s.status:s.statusCode,o="number"==typeof i&&i>=400&&i<600?i:500,r="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return De.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${o}, message=${r}`),a(o,{error:r})}}),b.post("/schedule",{schema:{body:kt.object({task:kt.string(),type:kt.enum(["once","recurring"]),due:kt.string().optional(),cron:kt.string().optional(),timezone:kt.string().optional(),timeType:kt.enum(["utc","local"]).optional()}),response:{200:kt.object({id:kt.string(),task:kt.string(),type:kt.enum(["once","recurring"]),due:kt.string().optional(),cron:kt.string().optional(),timezone:kt.string().optional(),timeType:kt.enum(["utc","local"]).optional(),createdAt:kt.string()}),400:kt.object({error:kt.string()}),503:kt.object({error:kt.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'})}),b.get("/schedule",{schema:{response:{200:kt.object({tasks:kt.array(kt.object({id:kt.string(),task:kt.string(),type:kt.enum(["once","recurring"]),due:kt.string().optional(),cron:kt.string().optional(),timezone:kt.string().optional(),timeType:kt.enum(["utc","local"]).optional(),createdAt:kt.string()}))}),503:kt.object({error:kt.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),b.delete("/schedule/:id",{schema:{params:kt.object({id:kt.string()}),response:{200:kt.object({success:kt.boolean()}),404:kt.object({error:kt.string()}),503:kt.object({error:kt.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 S=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);b.options("/channels",async(e,t)=>(I(t),t.send())),b.options("/channels/platforms",async(e,t)=>(I(t),t.send())),b.options("/channels/wechat/login/qrcode",async(e,t)=>(I(t),t.send())),b.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(I(t),t.send())),b.options("/channels/:id",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/connect",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/disconnect",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/contacts",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/bindings",async(e,t)=>(I(t),t.send())),b.options("/channels/:id/bindings/:bindingId",async(e,t)=>(I(t),t.send())),b.options("/channels/task-message",async(e,t)=>(I(t),t.send())),b.options("/channels/group-history",async(e,t)=>(I(t),t.send())),b.get("/channels",{schema:{response:{200:kt.object({channels:kt.array(Ar)}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return{channels:n.getChannels()}}),b.get("/channels/platforms",{schema:{response:{200:kt.object({platforms:kt.array(kt.enum(Ir))})}}},async(e,t)=>(I(t),{platforms:[...Ir]})),b.get("/channels/wechat/login/qrcode",{schema:{response:{200:kt.object({qrcode:kt.string(),qrcodeContent:kt.string(),qrcodeTerminal:kt.string(),baseUrl:kt.string()}),502:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);try{return await xr.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return De.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),b.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:kt.object({qrcode:kt.string()}),response:{200:kt.object({status:kt.string(),token:kt.string().optional(),baseUrl:kt.string().optional(),ilinkBotId:kt.string().optional(),ilinkUserId:kt.string().optional()}),502:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);try{return await xr.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return De.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),b.post("/channels",{schema:{body:Er,response:{200:Ar,503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return n.addChannel(e.body)}),b.delete("/channels/:id",{schema:{params:kt.object({id:kt.string()}),response:{200:kt.object({success:kt.boolean()}),404:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),b.post("/channels/:id/connect",{schema:{params:kt.object({id:kt.string()}),response:{200:Ar,404:kt.object({error:kt.string()}),500:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/:id/disconnect",{schema:{params:kt.object({id:kt.string()}),response:{200:Ar,404:kt.object({error:kt.string()}),500:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.get("/channels/:id/contacts",{schema:{params:kt.object({id:kt.string()}),response:{200:kt.object({contacts:kt.array(Mr)}),404:kt.object({error:kt.string()}),500:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.get("/channels/:id/bindings",{schema:{params:kt.object({id:kt.string()}),response:{200:kt.object({bindings:kt.array($r)}),404:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/task-message",{schema:{body:kt.object({taskId:kt.string(),content:kt.string().optional(),attachments:kt.array(kt.object({filePath:kt.string(),fileName:kt.string().optional(),mimeType:kt.string().optional(),kind:kt.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:kt.object({channelId:kt.string(),chatId:kt.string()}).optional()}),response:{200:kt.object({success:kt.boolean()}),404:kt.object({error:kt.string()}),503:kt.object({error:kt.string()}),500:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/channels/group-history",{schema:{body:kt.object({taskId:kt.string(),limit:kt.number().int().positive().max(100).optional(),beforeSeq:kt.number().int().positive().optional(),afterSeq:kt.number().int().nonnegative().optional(),target:kt.object({channelId:kt.string(),chatId:kt.string(),platform:kt.string().optional(),chatType:kt.string().optional(),chatName:kt.string().optional()})}),response:{200:kt.object({historyXml:kt.string(),hasMoreBefore:kt.boolean(),hasMoreAfter:kt.boolean()}),400:kt.object({error:kt.string()}),503:kt.object({error:kt.string()}),500:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.delete("/channels/:id/bindings/:bindingId",{schema:{params:kt.object({id:kt.string(),bindingId:kt.string()}),response:{200:kt.object({success:kt.boolean()}),404:kt.object({error:kt.string()}),503:kt.object({error:kt.string()})}}},async(e,t)=>{I(t);const n=S(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})}}),b.post("/list",{schema:{response:{200:kt.object({children:kt.array(kt.object({startedBy:kt.string(),taskId:kt.string(),pid:kt.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),b.post("/stop-session",{schema:{body:kt.object({sessionId:kt.string()}),response:{200:kt.object({success:kt.boolean()})}}},async e=>{const{sessionId:t}=e.body;return De.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),b.post("/stop",{schema:{response:{200:kt.object({status:kt.string()})}}},async()=>(De.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{De.debug("[CONTROL SERVER] Triggering daemon shutdown"),i()},50),{status:"stopping"})),"127.0.0.1"!==y&&De.warn(`[CONTROL SERVER] Listening on ${y}; ensure daemon control endpoints are protected by network policy`);const T=e=>new Promise((t,n)=>{w.listen({port:e,host:y},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{await function(e,t=300){return new Promise(n=>{const s=yn({host:"127.0.0.1",port:e});let a=!1;const i=e=>{a||(a=!0,s.destroy(),n(e))};s.once("connect",()=>i(!0)),s.once("error",()=>i(!1)),s.setTimeout(t,()=>i(!1))})}(30624)?(De.info("[CONTROL SERVER] Port 30624 already accepts loopback connections, falling back to dynamic port"),e=await T(0)):e=await T(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw De.info("[CONTROL SERVER] Failed to start:",t),t;De.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await T(0)}const t=parseInt(e.split(":").pop());De.info(`[CONTROL SERVER] Started on port ${t}`),f({port:t,host:y,webhookHost:v,stop:async()=>{await w.close(),De.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw De.info("[CONTROL SERVER] Failed to start:",e),e})})}function zc(e,t={}){const n=Ne(),s=E(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw De.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return gt(process.execPath,a,t)}function Kc(e,t){if(!e)return t;const n=Number.parseFloat(e);return!Number.isFinite(n)||n<=0?t:n}function Vc(e=process.env){return Boolean(e.CLOUD_AUTH_TOKEN?.trim())}function Xc(e=process.env){const t=e.AGENTRIX_EVENT_FORWARD_WS_URL?.trim();return t?{wsUrl:t,token:e.AGENTRIX_EVENT_FORWARD_TOKEN?.trim()||null,retentionHours:Kc(e.AGENTRIX_EVENT_FORWARD_RETENTION_HOURS,24),maxDbMb:Kc(e.AGENTRIX_EVENT_FORWARD_MAX_DB_MB,512)}:null}const Jc=Oe(import.meta.url);class Yc{constructor(e){this.options=e}worker=null;pending=new Map;nextRequestId=1;closed=!1;lastWorkerFailureAt=0;async append(e){const t={eventId:e.eventId,taskId:e.taskId,chatId:e.chatId??null,eventType:e.eventType,direction:e.direction,eventData:JSON.stringify(e.eventData??null),createdAt:e.createdAt??(new Date).toISOString()};try{await this.request("append",t)}catch(t){Jc.warn(`[FORWARD OUTBOX] Dropping event after append failure eventId=${e.eventId} error=${t instanceof Error?t.message:String(t)}`)}}pageAfter(e,t){return this.request("pageAfter",{cursor:e,limit:t})}getAckedCursor(){return this.request("getAckedCursor",{})}async setAckedCursor(e){await this.request("setAckedCursor",{cursor:e})}getDroppedBeforeCursor(){return this.request("getDroppedBeforeCursor",{})}cleanup(e){return this.request("cleanup",{cutoffIso:new Date(Date.now()-e.retentionMs).toISOString(),maxDbBytes:e.maxDbBytes,batchSize:1e3,sizeDropBatchSize:100})}async close(){if(this.closed)return;this.closed=!0;const e=this.worker;if(!e)return;const t=new Promise(t=>{const n=this.nextRequestId++;this.pending.set(n,{resolve:()=>t(),reject:()=>t()}),e.ref();try{e.postMessage({id:n,op:"close",args:{}})}catch{t()}}),n=new Promise(e=>{setTimeout(e,3e3).unref()});await Promise.race([t,n]),await e.terminate().catch(()=>{}),this.worker=null}request(e,t){if(this.closed)return Promise.reject(new Error("Forward outbox is closed"));let n;try{n=this.ensureWorker()}catch(e){return Promise.reject(e instanceof Error?e:new Error(String(e)))}const s=this.nextRequestId++;return new Promise((a,i)=>{this.pending.set(s,{resolve:a,reject:i}),1===this.pending.size&&n.ref();try{n.postMessage({id:s,op:e,args:t})}catch(e){this.pending.delete(s),i(e instanceof Error?e:new Error(String(e)))}})}ensureWorker(){if(this.worker)return this.worker;if(Date.now()-this.lastWorkerFailureAt<3e4)throw new Error("Forward outbox worker recently failed; backing off");const e=ht(import.meta.url),t=new vn("\n'use strict';\nconst { parentPort, workerData } = require('node:worker_threads');\nconst Database = require(workerData.betterSqlite3Path);\n\nconst SCHEMA_VERSION = 1;\n\nfunction log(level, message) {\n try {\n parentPort.postMessage({ kind: 'log', level: level, message: message });\n } catch (error) {\n // Nothing else we can do from the worker thread.\n }\n}\n\nfunction errorMessage(error) {\n return error && error.message ? String(error.message) : String(error);\n}\n\nconst db = new Database(workerData.dbPath);\ndb.pragma('busy_timeout = ' + workerData.busyTimeoutMs);\nconst initialVersion = db.pragma('user_version', { simple: true });\nif (initialVersion === 0) {\n // Must be set before the first table is created to apply without a full VACUUM.\n db.pragma('auto_vacuum = INCREMENTAL');\n}\ndb.pragma('journal_mode = WAL');\ndb.pragma('synchronous = NORMAL');\ndb.exec(\n 'CREATE TABLE IF NOT EXISTS forward_event (' +\n ' cursor INTEGER PRIMARY KEY AUTOINCREMENT,' +\n ' event_id TEXT UNIQUE NOT NULL,' +\n ' task_id TEXT NOT NULL,' +\n ' chat_id TEXT,' +\n ' event_type TEXT NOT NULL,' +\n ' direction TEXT NOT NULL,' +\n ' event_data TEXT NOT NULL,' +\n ' created_at TEXT NOT NULL' +\n '); ' +\n 'CREATE TABLE IF NOT EXISTS forward_state (' +\n ' key TEXT PRIMARY KEY,' +\n ' value TEXT NOT NULL' +\n ');'\n);\nif (initialVersion < SCHEMA_VERSION) {\n db.pragma('user_version = ' + SCHEMA_VERSION);\n}\n\nconst insertEvent = db.prepare(\n 'INSERT OR IGNORE INTO forward_event (event_id, task_id, chat_id, event_type, direction, event_data, created_at)' +\n ' VALUES (@eventId, @taskId, @chatId, @eventType, @direction, @eventData, @createdAt)'\n);\nconst selectAfter = db.prepare(\n 'SELECT cursor, event_id, task_id, chat_id, event_type, direction, event_data, created_at' +\n ' FROM forward_event WHERE cursor > ? ORDER BY cursor ASC LIMIT ?'\n);\nconst selectState = db.prepare('SELECT value FROM forward_state WHERE key = ?');\nconst upsertMaxState = db.prepare(\n 'INSERT INTO forward_state (key, value) VALUES (?, ?)' +\n ' ON CONFLICT(key) DO UPDATE SET value = CAST(MAX(CAST(value AS INTEGER), CAST(excluded.value AS INTEGER)) AS TEXT)'\n);\nconst deleteExpiredBatch = db.prepare(\n 'DELETE FROM forward_event WHERE cursor IN (' +\n ' SELECT cursor FROM forward_event WHERE cursor <= ? AND created_at < ? ORDER BY cursor ASC LIMIT ?' +\n ')'\n);\nconst selectOldestBatch = db.prepare(\n 'SELECT COUNT(*) AS n, MAX(cursor) AS maxCursor FROM (' +\n ' SELECT cursor FROM forward_event ORDER BY cursor ASC LIMIT ?' +\n ')'\n);\nconst deleteUpToCursor = db.prepare('DELETE FROM forward_event WHERE cursor <= ?');\n\nfunction readIntState(key) {\n const row = selectState.get(key);\n if (!row) {\n return null;\n }\n const value = Number.parseInt(row.value, 10);\n return Number.isFinite(value) ? value : null;\n}\n\nconst retryQueue = [];\nlet retryTimer = null;\nlet retryDelayMs = workerData.retryBaseDelayMs;\n\nfunction scheduleRetry() {\n if (retryTimer) {\n return;\n }\n retryTimer = setTimeout(runRetries, retryDelayMs);\n}\n\nfunction runRetries() {\n retryTimer = null;\n const entries = retryQueue.splice(0, retryQueue.length);\n for (const entry of entries) {\n try {\n insertEvent.run(entry.row);\n } catch (error) {\n entry.attempts += 1;\n if (entry.attempts >= workerData.retryMaxAttempts) {\n log('warn', 'retry attempts exhausted, dropping event eventId=' + entry.row.eventId + ' error=' + errorMessage(error));\n } else {\n retryQueue.push(entry);\n }\n }\n }\n if (retryQueue.length > 0) {\n retryDelayMs = Math.min(retryDelayMs * 2, workerData.retryMaxDelayMs);\n scheduleRetry();\n } else {\n retryDelayMs = workerData.retryBaseDelayMs;\n }\n}\n\nfunction appendRow(row) {\n try {\n insertEvent.run(row);\n if (retryQueue.length > 0) {\n scheduleRetry();\n }\n } catch (error) {\n if (retryQueue.length >= workerData.retryQueueLimit) {\n log('warn', 'retry queue overflow, dropping event eventId=' + row.eventId + ' error=' + errorMessage(error));\n } else {\n retryQueue.push({ row: row, attempts: 1 });\n scheduleRetry();\n }\n }\n return { queued: retryQueue.length };\n}\n\nfunction rowToEvent(row) {\n let eventData;\n try {\n eventData = JSON.parse(row.event_data);\n } catch (error) {\n eventData = { raw: row.event_data };\n }\n return {\n cursor: row.cursor,\n eventId: row.event_id,\n taskId: row.task_id,\n chatId: row.chat_id,\n eventType: row.event_type,\n direction: row.direction,\n eventData: eventData,\n createdAt: row.created_at,\n };\n}\n\nfunction dbSizeBytes() {\n const pageCount = db.pragma('page_count', { simple: true });\n const pageSize = db.pragma('page_size', { simple: true });\n const freelistCount = db.pragma('freelist_count', { simple: true });\n return (pageCount - freelistCount) * pageSize;\n}\n\nfunction cleanup(args) {\n const ackedCursor = readIntState('acked_cursor') || 0;\n let deletedExpired = 0;\n for (;;) {\n const result = deleteExpiredBatch.run(ackedCursor, args.cutoffIso, args.batchSize);\n deletedExpired += result.changes;\n if (result.changes < args.batchSize) {\n break;\n }\n }\n\n let deletedForSize = 0;\n let droppedUnackedCursor = null;\n while (dbSizeBytes() > args.maxDbBytes) {\n const oldest = selectOldestBatch.get(args.sizeDropBatchSize);\n if (!oldest || !oldest.n || oldest.maxCursor === null) {\n break;\n }\n const result = deleteUpToCursor.run(oldest.maxCursor);\n deletedForSize += result.changes;\n if (oldest.maxCursor > ackedCursor) {\n droppedUnackedCursor = oldest.maxCursor;\n }\n if (result.changes === 0) {\n break;\n }\n }\n if (droppedUnackedCursor !== null) {\n upsertMaxState.run('dropped_before_cursor', String(droppedUnackedCursor));\n }\n\n // Reclaim disk in small slices so cross-process writers never wait long.\n let vacuumGuard = 0;\n while (db.pragma('freelist_count', { simple: true }) > 64 && vacuumGuard < 1024) {\n db.pragma('incremental_vacuum(512)');\n vacuumGuard += 1;\n }\n try {\n db.pragma('wal_checkpoint(TRUNCATE)');\n } catch (error) {\n // Best effort: checkpoint can fail while other processes hold readers.\n }\n\n return {\n deletedExpired: deletedExpired,\n deletedForSize: deletedForSize,\n droppedUnackedCursor: droppedUnackedCursor,\n dbSizeBytes: dbSizeBytes(),\n };\n}\n\nfunction handleOp(op, args) {\n if (op === 'append') {\n return appendRow(args);\n }\n if (op === 'pageAfter') {\n return selectAfter.all(args.cursor, args.limit).map(rowToEvent);\n }\n if (op === 'getAckedCursor') {\n return readIntState('acked_cursor') || 0;\n }\n if (op === 'setAckedCursor') {\n upsertMaxState.run('acked_cursor', String(args.cursor));\n return null;\n }\n if (op === 'getDroppedBeforeCursor') {\n return readIntState('dropped_before_cursor');\n }\n if (op === 'cleanup') {\n return cleanup(args);\n }\n if (op === 'close') {\n if (retryTimer) {\n clearTimeout(retryTimer);\n retryTimer = null;\n }\n // Final best-effort flush of the retry queue before closing.\n for (const entry of retryQueue.splice(0, retryQueue.length)) {\n try {\n insertEvent.run(entry.row);\n } catch (error) {\n log('warn', 'dropping event on close eventId=' + entry.row.eventId + ' error=' + errorMessage(error));\n }\n }\n try {\n db.close();\n } catch (error) {\n // Ignore close errors.\n }\n return null;\n }\n throw new Error('Unknown forward outbox op: ' + op);\n}\n\nparentPort.on('message', (message) => {\n let reply;\n try {\n reply = { kind: 'result', id: message.id, ok: true, result: handleOp(message.op, message.args) };\n } catch (error) {\n reply = { kind: 'result', id: message.id, ok: false, error: errorMessage(error) };\n }\n parentPort.postMessage(reply);\n if (message.op === 'close') {\n process.exit(0);\n }\n});\n",{eval:!0,workerData:{dbPath:this.options.dbPath,betterSqlite3Path:e.resolve("better-sqlite3"),busyTimeoutMs:this.options.busyTimeoutMs,retryQueueLimit:this.options.retryQueueLimit,retryMaxAttempts:this.options.retryMaxAttempts,retryBaseDelayMs:this.options.retryBaseDelayMs,retryMaxDelayMs:this.options.retryMaxDelayMs}});return t.on("message",e=>this.handleWorkerMessage(e)),t.on("error",e=>{Jc.warn(`[FORWARD OUTBOX] Worker thread error: ${e instanceof Error?e.message:String(e)}`),this.handleWorkerExit(t,e instanceof Error?e:new Error(String(e)))}),t.on("exit",e=>{this.handleWorkerExit(t,0===e?null:new Error(`Forward outbox worker exited with code ${e}`))}),t.unref(),this.worker=t,t}handleWorkerMessage(e){if("log"===e.kind){const t=`[FORWARD OUTBOX] ${e.message}`;return void("warn"===e.level?Jc.warn(t):"info"===e.level?Jc.info(t):Jc.debug(t))}const t=this.pending.get(e.id);t&&(this.pending.delete(e.id),0===this.pending.size&&this.worker?.unref(),e.ok?t.resolve(e.result):t.reject(new Error(e.error)))}handleWorkerExit(e,t){this.worker===e&&(this.worker=null),t&&(this.lastWorkerFailureAt=Date.now());const n=[...this.pending.values()];this.pending.clear();for(const e of n)e.reject(t??new Error("Forward outbox worker exited"))}}let Qc=null;function Zc(){return function(e=process.env){return Vc(e)&&null!==Xc(e)}()?(Qc||(e={dbPath:E(Me.resolveForwardDir(),"outbox.db")},Qc=new Yc({dbPath:e.dbPath,busyTimeoutMs:e.busyTimeoutMs??5e3,retryQueueLimit:e.retryQueueLimit??1e3,retryMaxAttempts:e.retryMaxAttempts??10,retryBaseDelayMs:e.retryBaseDelayMs??500,retryMaxDelayMs:e.retryMaxDelayMs??3e4})),Qc):null;var e}async function el(){const e=Qc;Qc=null,e&&await e.close()}const tl={".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"},nl={"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 sl(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=M(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=M(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 tl[t]||"application/octet-stream"}(a),r=a||function(e){return nl[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=$(t);c=n&&M(n)?n:`${Se()}${r||".dat"}`}catch{c=`${Se()}${r||".dat"}`}else c=`${Se()}${r||".dat"}`;const d=E(t,c),p=s.body,u=l(d);return await mt(p,u),{filePath:d,mimeType:o,filename:c}}catch(t){throw new Error(`Failed to download file from ${e}: ${t instanceof Error?t.message:String(t)}`)}}const al=Oe(import.meta.url);async function il(e,t){const{attachmentsDir:n}=t;if(!Array.isArray(e.message.content))return e;const s=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t){try{const n=e.source.url;al.info(`image.download.started url=${n}`);const{filePath:s,mimeType:a}=await sl(n,t,!0);return al.info(`image.download.completed filePath=${s}`),{type:"text",text:`Image file: ${s}\nType: ${a}`}}catch(t){return al.error(`image.download.failed error=${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t){try{const n=e.source.url;al.info(`document.download.started url=${n}`);const{filePath:s,mimeType:a,filename:i}=await sl(n,t,!0);return al.info(`document.download.completed filePath=${s}`),{type:"text",text:`Document: ${s}\nTitle: ${e.title||i}\nType: ${a}`}}catch(t){return al.error(`document.download.failed error=${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n):e));return{...e,message:{...e.message,content:s}}}const ol="Agentrix-DevOps",rl="main";function cl(e){return(e.supportedFeatures??[]).includes(se)}function ll(e){return"zh-Hans"===e.preferredLanguage||`${process.env.AGENTRIX_LANG??""} ${process.env.LANG??""}`.toLowerCase().includes("zh")?"zh-Hans":"en"}function dl(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 pl(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 ul(e,t){return E(Me.resolveDataDir(e,t),"devops-init")}function ml(e,t){return E(ul(e,t),"original-input.json")}function hl(e,t){return E(ul(e,t),"handoff.json")}function gl(e){const t=ul(e.userId,e.taskId);d(t,{recursive:!0}),u(ml(e.userId,e.taskId),JSON.stringify(e,null,2))}function fl(e,t){const n=ml(e,t);return r(n)?JSON.parse(c(n,"utf-8")):null}function yl(e,t){const n=hl(e,t);if(!r(n))return null;const s=JSON.parse(c(n,"utf-8"));return f(n),s}class vl{pidToTrackedSession;taskToStartPromise;sandboxPool;channelManager=null;socketClientProvider=null;acceptingNewWorkers=!0;workerStartGateCode=null;workerStartGateMessage=null;drainCallback=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}setWorkerStartGate(e,t,n){this.acceptingNewWorkers=e,this.workerStartGateCode=e?null:t??"daemon_control_busy",this.workerStartGateMessage=e?null:n??"Daemon is not accepting new workers"}isAcceptingNewWorkers(){return this.acceptingNewWorkers}setDrainCallback(e){this.drainCallback=e}createWorkerGateAck(e){return this.acceptingNewWorkers?null:{eventId:X(),status:"failed",opCode:e,message:this.workerStartGateMessage??"Daemon is not accepting new workers",data:{errorCode:this.workerStartGateCode??"daemon_control_busy"}}}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 De.warn(`[SESSION] Missing PID for task ${e}`);De.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 Me.getSecretKey();if(!t)return;const n=K(G(e.dataEncryptionKey),t);if(!n)return void De.warn("[SESSION] Failed to decrypt data encryption key");if(e.dataEncryptionKey=F(n),"task-message"!==e.event)return;const s=e.eventData;if(!s.encryptedMessage)return;const a=ae(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:De.warn("[SESSION] Failed to decrypt task message")}appendForwardTaskStartEvent(e,t){const n=Zc();n&&(n.append({eventId:e.eventId,taskId:e.taskId,chatId:e.chatId,eventType:"agentSessionId"in e?"resume-task":"create-task",direction:"inbound",eventData:{eventId:e.eventId,taskId:e.taskId,chatId:e.chatId,agentId:e.agentId,agentType:e.agentType,model:e.model,taskType:e.taskType,customTitle:e.customTitle,repositoryId:e.repositoryId,gitServerId:e.gitServerId,serverRepoId:e.serverRepoId,issueNumber:e.issueNumber,metadata:e.metadata}}),n.append({eventId:t.eventId,taskId:e.taskId,chatId:e.chatId,eventType:e.event,direction:"inbound",eventData:t}))}async persistCreateTaskStart(e){const t=Me.resolveDataDir(e.userId,e.taskId),n=Me.resolveAttachmentsDir(e.userId,e.taskId),s=Bo({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}),this.appendForwardTaskStartEvent(e,t);let a=null;if(t.message){let e=t.message;ie(e)&&(e=await il(e,{attachmentsDir: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=Me.resolveDataDir(e.userId,e.taskId),n=Me.resolveAttachmentsDir(e.userId,e.taskId),s=Bo({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}),this.appendForwardTaskStartEvent(e,t);let i=null;if(t.message){let e=t.message;ie(e)&&(e=await il(e,{attachmentsDir: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||!ie(t.message))return;const n=Me.resolveAttachmentsDir(e.userId,e.taskId),s=await il(t.message,{attachmentsDir: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=>{De.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after DevOps worker exit:`,t)}),0===this.pidToTrackedSession.size&&this.drainCallback?.()}),t.on("error",n=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId),0===this.pidToTrackedSession.size&&this.drainCallback?.()})}async maybeContinueAfterDevOpsInit(e){const t=yl(e.userId,e.taskId);t&&(De.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=fl(e,t);if(!n)return void De.warn(`[DEVOPS_INIT] Missing original task input for ${t}; cannot continue original worker`);if(De.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),Me.writeTaskInput(n);const a={eventId:X(),status:"success",opCode:n.eventId};await this.startWorkerInternal(n,"create-task",a)}restoreOriginalWorkerAfterSlashDevOpsInit(e){const t=Bo({dataDir:Me.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const n=t.pageRecentMessages(1).data[0]?.localSequence??0;t.updateAgentLastSequence(e.agentId,n),De.info(`[DEVOPS_INIT] Restored original worker ${e.agentId} for task ${e.taskId} at sequence ${n}; waiting for the next user message`)}finally{t.close()}Me.writeTaskInput(e)}positionOriginalWorkerHistoryCursor(e,t){if(null===t)return void De.warn(`[DEVOPS_INIT] Original worker message for task ${e.taskId} has no local sequence; cannot isolate DevOps init history`);const n=Bo({dataDir:Me.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),De.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:X(),taskId:e.taskId,agentSessionId:e.agentSessionId,cwd:e.cwd??e.userCwd}),void De.info(`[DEVOPS_INIT] Restored original agent session for task ${e.taskId}`);t.send("reset-task-session",{eventId:X(),taskId:e.taskId}),De.info(`[DEVOPS_INIT] Cleared DevOps init agent session for task ${e.taskId}`)}else De.warn(`[DEVOPS_INIT] No daemon socket client available to sync task session for ${e.taskId}`)}completeDevOpsInit(e){De.info(`[DEVOPS_INIT] Completion received for task ${e.taskId}, action=${e.action}`),function(e,t,n){const s=ul(e,t);d(s,{recursive:!0}),u(hl(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=>{De.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after completion signal:`,t)})},100)}startDevOpsInit(e){this.startDevOpsInitAsync(e).catch(t=>{De.error(`[DEVOPS_INIT] Failed to start slash-command DevOps init for task ${e.taskId}:`,t)})}async startDevOpsInitAsync(e){const t=Me.readTaskInput(e.userId,e.taskId);gl(t);const n=await this.buildDevOpsWorkerInput(t,!0);Me.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:X(),status:"success",opCode:e.eventId};return void await this.startWorkerInternal(e,t,n)}De.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 De.info(`[DEVOPS_INIT] Original worker for task ${t} is already running with PID ${s.pid}`);if(s)continue;const a=yl(e,t);if(!a)return void De.info(`[DEVOPS_INIT] Handoff for task ${t} was already consumed`);if(De.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)}De.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:X(),status:"success",opCode:e.eventId},s=this.createWorkerGateAck(e.eventId);if(s)return De.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;await this.decryptTaskMessage(e),await this.processTaskMessageAttachments(e),"create-task"===t?e=await this.resolveDevOpsInitCreateInput(e):"resume-task"===t&&(e=this.stripStaleDevOpsAgentSession(e)),Me.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const a=this.taskToStartPromise.get(e.taskId);if(a)return De.info(`[SESSION] Task ${e.taskId} is already starting, skip duplicate ${t}`),a;const i=this.startWorkerInternal(e,t,n).finally(()=>{this.taskToStartPromise.get(e.taskId)===i&&this.taskToStartPromise.delete(e.taskId)});return this.taskToStartPromise.set(e.taskId,i),i}stripStaleDevOpsAgentSession(e){if(e.agentId===ol||!cl(e))return e;const t=fl(e.userId,e.taskId);if(!t||"agentSessionId"in t)return e;De.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(!cl(e)||e.agentId===ol)return e;if(this.isLocalDirectoryDevOpsTarget(e)){if(!function(e,t={}){const n=t.checkLocalState??!0,s=E(e,".agentrix"),a=E(s,"env"),i=E(a,"init"),o=E(i,"state","local"),c=!r(s),l=!r(E(a,"README.md")),d=!r(E(i,"README.md")),p=!(!n||r(o)&&0!==function(e){try{return g(e)}catch{return[]}}(o).length);return{needsInit:c||l||d||p,missingAgentrixDir:c,missingEnvReadme:l,missingEnvModeDocs:d,missingLocalInitState:p}}(Me.resolveProjectCWD(e.userCwd,e.userId,e.taskId),{checkLocalState:!0}).needsInit)return De.info(`[DEVOPS_INIT] Local project init state complete for task ${e.taskId}; starting original worker`),e}else{if(!this.isCodeRepositoryDevOpsTarget(e))return De.info(`[DEVOPS_INIT] No project directory or code repository selected for task ${e.taskId}; skipping Agentrix DevOps init`),e;De.info(`[DEVOPS_INIT] Code repository target selected for task ${e.taskId}; starting Agentrix-DevOps without local init-state precheck`)}gl(e);const t=await this.buildDevOpsWorkerInput(e,!1);return De.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=E(Me.agentrixAgentsHomeDir,ol),t=E(Me.agentrixHomeDir,"tmp","agentrix-agent-devops-init"),n=`${e}.tmp-${Date.now()}`,s=`${e}.backup-${Date.now()}`;d(E(Me.agentrixHomeDir,"tmp"),{recursive:!0}),r(E(t,".git"))?(Et("git",["fetch","--depth=1","origin",`${rl}:refs/remotes/origin/${rl}`],{cwd:t,stdio:"pipe"}),Et("git",["checkout",rl],{cwd:t,stdio:"pipe"}),Et("git",["reset","--hard",`origin/${rl}`],{cwd:t,stdio:"pipe"})):(h(t,{recursive:!0,force:!0}),Et("git",["clone","--depth=1","--branch",rl,"https://github.com/xmz-ai/agentrix-agent.git",t],{stdio:"pipe"}));const a=E(t,"agentrix-dev-init");if(!r(E(a,"agent.json")))throw new Error(`Agentrix DevOps agent definition not found at ${a}`);h(n,{recursive:!0,force:!0}),y(a,n,{recursive:!0}),Fa(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"===ll(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?X():i.eventId,agentId:ol,agentType:"claude",agentDir:n,eventData:{...a,eventId:X(),senderType:"system",senderId:"agentrix-devops-init",senderName:"Agentrix DevOps init",message:{uuid:wn(),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.createWorkerGateAck(e.eventId);if(s)return De.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;const a=this.getAliveSessionByTaskId(e.taskId);if(a)return De.info(`[SESSION] Task ${e.taskId} already has worker PID ${a.pid}, skip duplicate ${t}`),n.message=`Worker already running (PID ${a.pid})`,n;const i=Me.resolveProjectCWD(e.userCwd,e.userId,e.taskId),o=["worker","--type",e.agentType||"claude","--started-by","daemon","--task-id",e.taskId,"--user-id",e.userId,"--idle-timeout","120"],r=this.resolveChannelReplyTarget(e),c=this.buildWorkerEnv(r);let l;if(this.sandboxPool?.isEnabled())try{if(!await this.sandboxPool.createWorkerSandbox(e.taskId,e.userId,i))throw new Error("Failed to create sandbox instance");const{projectPath:t}=await import("./logger-CVvo37Gw.mjs").then(function(e){return e.f}),{join:n}=await import("path"),s=["--no-warnings","--no-deprecation",n(t(),"dist","index.mjs"),...o],a=`"${process.execPath}" ${s.map(e=>`"${e}"`).join(" ")}`,r=await this.sandboxPool.wrapWorkerCommand(e.taskId,a);De.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${r}`),l=gt(r,{shell:!0,cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),De.info(`[SESSION] Worker started with sandbox, PID: ${l.pid}`)}catch(t){return De.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 l=zc(o,{cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),De.info(`[SESSION] Worker started without sandbox, PID: ${l.pid}`);return process.env.DEBUG&&(l.stdout?.on("data",e=>{De.debug(`[Daemon] worker stdout: ${e.toString()}`)}),l.stderr?.on("data",e=>{De.debug(`[Daemon] worker stderr: ${e.toString()}`)})),l.pid?(this.trackWorkerProcess(e,l),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"),De.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"),De.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){De.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){De.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return De.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(){De.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){De.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:X(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return De.warn(`[SESSION] Rejecting hive-publish for task ${e.taskId}: ${n.message}`),n;Me.writeTaskInput(e);try{const n=zc(["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=>{De.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{De.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;De.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:X(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return De.warn(`[SESSION] Rejecting hive-install for task ${e.taskId}: ${n.message}`),n;Me.writeTaskInput(e);try{const n=zc(["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=>{De.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{De.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;De.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:X(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return De.warn(`[SESSION] Rejecting deployment for task ${e.taskId}: ${n.message}`),n;Me.writeTaskInput(e);try{const n=zc(["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=>{De.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{De.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;De.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 wl{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=wt()}async initialize(e){if(this.settings=e,!e.enabled)return De.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!bn(this.platform))return De.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL(Me.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new kn,await this.networkManager.initialize(t),De.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw De.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=Me.resolveUserWorkSpaceDir(t),a=Me.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=at.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new xn(this.networkManager,c);return this.workerSandboxes.set(e,l),De.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return De.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 De.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),De.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){De.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),De.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,De.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class bl{constructor(e,t){this.client=e,this.machineId=t;const n=Me.agentrixAgentsHomeDir,s=E(n,"companion"),a=E(s,"claude");this.bootstrapPath=E(a,"BOOTSTRAP.md"),this.countPath=E(s,"BOOTSTRAP.count"),this.stateFilePath=E(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?De.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):(De.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):De.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 De.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void De.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return De.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),De.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:X(),machineId:t.machineId,agentId:t.agentId,chatId:t.chatId,chatTaskId:t.chatTaskId,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){De.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 kl(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function xl(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 Il(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 Sl(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 Tl(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 Cl(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class _l{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:kl((t=e.credentials).appId,"appId"),appSecret:kl(t.appSecret,"appSecret")},this.client=new In.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:In.AppType.SelfBuild,domain:In.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 In.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:In.Domain.Feishu,loggerLevel:In.LoggerLevel.info,onReady:()=>{De.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{De.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{De.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{De.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new In.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: ${Tl(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:I(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.filePath),s=await this.client.im.file.create({data:{file_type:this.resolveLarkFileType(n,t.mimeType),file_name:n,file:I(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?(De.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return De.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 De.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 De.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${Tl(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=hs(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 De.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${Tl(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 De.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){De.warn(`[CHANNEL][LARK] bot identity lookup failed: ${Tl(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=M(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 De.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,d=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===d||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,d;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:Sl(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:xl(n),fileKey:i?Cl(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?Cl(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:Il(t.create_time??e?.create_time??e?.ts),raw:e}}}const Al="https://api.telegram.org",El=4e4,$l=1e3;function Ml(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function Pl(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Rl(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function Dl(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function Nl(e){return e.photo?.[e.photo.length-1]?.file_id}class Ol{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=$l;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=Pl(e.token)??Pl(e.botToken)??Pl(e.bot_token);return{token:t||Ml(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:El}),this.polling=!0,this.retryDelayMs=$l,this.pollPromise=this.pollLoop(),this.setState("connected"),De.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:El})}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.filePath),r=await Bt(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:El})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:El});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||$(n.file_path);return await ys(`${Al}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return De.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:El});return t.title||Rl(t)||t.username||e}catch(t){return De.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:El});return Rl(t)||t.username||e}catch(t){return De.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:El,isPoll:!0});this.retryDelayMs=$l,"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));De.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(`${Al}/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(`${Al}/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 De.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||Se()),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?Rl(t.from):void 0,type:Dl(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:Nl(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 Ul(e){const t=Bl(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${Ll({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 jl(e){const t=Bl(e);return t?`<msg ${Ll({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 Ll(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 ql(e){const t=[];for(const n of e){const e=jl(n);e&&t.push(e)}return t.join("\n")}function Hl(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 Fl(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 Bl(e){const{text:t,nonTextBlocks:n}=(s=e.message,oe(s)?{text:Hl(s),nonTextBlocks:[]}:re(s)?{text:Fl(s),nonTextBlocks:[]}:ce(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 Gl{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=E(Me.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=E(Me.agentrixHomeDir,"channels","group-history"),this.loadState()}stateFilePath;groupHistoryFilePath;adapters=new Map;reconnectTimers=new Map;pendingMessages=new Map;store={version:1,channels:[],bindings:[]};taskDataKeyCache=new Map;stopping=!1;createTaskLocks=new Map;async start(){this.loadState();const e=this.store.channels.filter(e=>e.enabled);for(const t of e)try{await this.connectChannel(t.id)}catch(e){De.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}De.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=>{De.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),De.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:Se(),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(),De.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(),De.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=>{De.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),De.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):(De.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(),De.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 _l({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new xr({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new Ol({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){De.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 De.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);De.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=>{De.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),De.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=Ll({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){De.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)||d(t,{recursive:!0}),Bo({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return E(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&&(De.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(De.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void De.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void De.warn(`[CHANNEL] Task ${t.taskId} is pending, skipping message forward`);const n=this.readCompanionState(),s=n?.chatId||t.taskId,a=await this.getTaskDataKeyForTask(t.taskId);if(!a)return void De.warn(`[CHANNEL] Missing task data key, skipping encrypted channel message forward: task=${t.taskId}`);const{plainMessage:i,encryptedMessage:o}=await this.buildEncryptedMessage(e,a);this.client.send("task-message",{eventId:X(),taskId:t.taskId,chatId:s,from:"machine",message:i,encryptedMessage:o,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}}),De.info(`[CHANNEL] Forwarded message to task ${t.taskId}`)}async buildEncryptedMessage(e,t){const n=e.attachmentPaths??[],s=n.length>0?`[User sent the following attachments: ${n.join(", ")}]`:void 0,a={type:"user",message:{role:"user",content:[s,e.text||(s?void 0:`[${e.type}]`)].filter(Boolean).join("\n\n")}};let i,o=a;if(t)try{i=ue(a,t),o=void 0}catch(e){De.warn("[CHANNEL] Failed to encrypt message, sending plaintext",e)}return{plainMessage:o,encryptedMessage:i}}async getOrCreateBindingForMessage(e){const t=this.store.bindings.find(t=>t.channelId===e.channelId&&t.chatId===e.chatId);if(t&&!this.isPendingTaskId(t.taskId))return{binding:t,isNew:!1};t&&(this.store.bindings=this.store.bindings.filter(e=>e.id!==t.id),this.saveState(),De.warn(`[CHANNEL] Removed pending binding before retry: channel=${t.channelId}, chat=${t.chatId}, task=${t.taskId}`));const n=await this.resolveChatName(e),s=await this.createTaskForChat(e,n),a=(new Date).toISOString(),i={id:Se(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.isPendingTaskId(s)?(De.warn(`[CHANNEL] Task creation did not complete; not persisting pending binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0}):(this.store.bindings.push(i),this.saveState(),De.info(`[CHANNEL] Auto-created binding: channel=${e.channelId}, chat=${e.chatId}, task=${s}`),{binding:i,isNew:!0})}isPendingTaskId(e){return e.startsWith("pending-")}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 De.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${Se()}`;if(!this.client.connected)return De.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${Se()}`;const s=await this.createChannelTaskEncryptionPayload();if(!s)return De.error("[CHANNEL] Cannot create encrypted channel task: missing local machine encryption credentials"),`pending-encryption-unavailable-${Se()}`;const{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e,s.taskDataKey);try{const o=await this.client.sendWithAck("channel-task-create",{eventId:X(),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:s.dataEncryptionKey,ownerEncryptedDataKey:s.ownerEncryptedDataKey,message:a,encryptedMessage:i,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"===o?.status&&o.taskId?(this.taskDataKeyCache.set(o.taskId,s.taskDataKey),De.info(`[CHANNEL] Created task ${o.taskId} for chat ${e.chatId}`),o.taskId):(De.error(`[CHANNEL] API task creation failed: ${o?.message||"unknown"}`),`pending-api-error-${Se()}`)}catch(e){return De.error("[CHANNEL] Failed to create task via API",e),`pending-error-${Se()}`}}async resolveChatName(e){try{De.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(De.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if(De.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 De.warn(`[CHANNEL] Failed to resolve chat name for ${e.chatId}: ${t?.message||String(t)}`),e.senderName||e.senderId||e.chatId}}async createChannelTaskEncryptionPayload(){const e=await Me.readCredentials();if(!e?.secret)return De.warn("[CHANNEL] Missing machine secret; cannot create encrypted channel task key"),null;const t=await async function(e){if(!e.secret)return null;const t=function(e){if(!e.machineAesKey)return null;try{const t=G(e.machineAesKey);return 32===t.length?t:null}catch{return null}}(e);if(!t)return null;const n=await le(e.secret),s=z();return{taskDataKey:s,dataEncryptionKey:F(pe(s,n.publicKey)),ownerEncryptedDataKey:F(de(F(s),t))}}(e);return t||(De.warn("[CHANNEL] Missing machineAesKey in credentials; rebind this machine before creating encrypted channel tasks"),null)}async getTaskDataKeyForTask(e){const t=this.taskDataKeyCache.get(e);if(t)return t;if(!this.client.connected)return De.debug(`[CHANNEL] Socket not connected, cannot fetch encryption key for task ${e}`),null;try{const t=await this.client.sendWithAck("get-task-encryption-keys",{eventId:X(),taskId:e});if("success"===t?.status&&t.dataEncryptionKey){const n=await Me.getSecretKey();if(!n)return De.warn(`[CHANNEL] Missing machine secret key while decrypting task key: task=${e}`),null;const s=K(G(t.dataEncryptionKey),n);return s&&32===s.length?(this.taskDataKeyCache.set(e,s),s):(De.warn(`[CHANNEL] Failed to decrypt valid task data key: task=${e}`),null)}De.warn(`[CHANNEL] Failed to fetch encryption keys for task ${e}: ${t?.message||"unknown"}`)}catch(t){De.warn(`[CHANNEL] Error fetching encryption keys for task ${e}`,t)}return null}readCompanionState(){const e=E(Me.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return De.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}:(De.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return De.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=>{De.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),De.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=Dr.parse(e),(e.companionDataEncryptionKey||e.companionOwnerEncryptedDataKey||e.companionKeyMachineId||e.companionKeyChatId)&&this.saveState()}catch(e){De.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=D(this.stateFilePath);r(e)||d(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]))}}function Wl(){try{const e=it(Ne(),"package.json"),t=JSON.parse(Ge(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}async function zl(){const e=Wl();try{const t=ft("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}}}async function Kl(e,t={}){const n=function(){const e=it(ot(Me.getStatePaths().daemonStateFile),"upgrade.lock");if(We(e))try{const t=Ge(e,"utf-8"),n=JSON.parse(t);"number"!=typeof n.pid||function(e){try{return process.kill(e,0),!0}catch{return!1}}(n.pid)||ze(e)}catch{ze(e)}try{const t=Ke(e,"wx");Ve(t,JSON.stringify({pid:process.pid,createdAt:(new Date).toISOString()})),Xe(t)}catch{return null}return{release:()=>{try{const t=Ge(e,"utf-8");JSON.parse(t).pid===process.pid&&ze(e)}catch{}}}}();if(!n)return{status:"busy",message:"CLI upgrade already in progress"};try{const n=e??await zl();if(!n.hasUpgrade)return{status:"already_latest",currentVersion:n.currentVersion,latestVersion:n.latestVersion};try{return await async function(e){await new Promise((t,n)=>{const s=gt("npm",["install","-g","@agentrix/cli@latest"],{stdio:e,env:process.env});s.on("error",n),s.on("exit",e=>{0!==e?n(new Error(`npm install exited with code ${e??"unknown"}`)):t()})})}(t.stdio??"inherit"),{status:"upgraded",fromVersion:n.currentVersion,toVersion:n.latestVersion??"latest"}}catch(e){return{status:"failed",currentVersion:n.currentVersion,latestVersion:n.latestVersion,error:e instanceof Error?e.message:String(e)}}}finally{n.release()}}const Vl=Zt(At),Xl=/^task-(.+)\.log(?:\.\d+)?(?:\.gz)?$/;function Jl(e,t){return N(e,t).split(R).join("/")}async function Yl(e){let t=0;const n=[e];for(;n.length>0;){const e=n.pop();let s,a;try{s=await Vt(e)}catch{continue}if(t+=s.size,s.isDirectory()&&!s.isSymbolicLink())try{a=await Xt(e);for await(const t of a)n.push(E(e,t.name))}catch{continue}}return t}function Ql(e,t){const n=E(Me.agentrixWorkspaceHomeDir,"users",e,t,"data"),s=E(n,"workspace.json");if(r(s))try{return JSON.parse(c(s,"utf-8"))}catch{return null}const a=E(n,"cwd.txt");if(!r(a))return null;try{const e=c(a,"utf-8").trim();return e?{initialized:!0,initializedAt:new Date(p(a).mtimeMs).toISOString(),cwd:e}:null}catch{return null}}function Zl(){const e=Me.agentrixWorkspaceHomeDir,t=E(e,"users");if(!r(t))return[];const n=[];for(const e of g(t,{withFileTypes:!0})){if(!e.isDirectory())continue;const s=e.name,a=E(t,s);for(const e of g(a,{withFileTypes:!0})){if(!e.isDirectory())continue;const t=e.name,i=E(a,t);n.push({userId:s,taskId:t,taskDir:i,projectDir:E(i,"project"),dataDir:E(i,"data"),state:Ql(s,t)})}}return n}function ed(e){return"directory"===e?.repositorySourceType&&(!0===e.forceUserCwd||!1===e.useWorktree)}function td(e){const t=e.relativePath??Jl(Me.agentrixHomeDir,e.absolutePath);return{id:e.id,kind:e.kind,label:e.label,relativePath:t,pathDisplay:t,bytes:e.bytes,reclaimable:e.reclaimable,defaultSelected:e.defaultSelected??e.reclaimable,deleteMode:e.deleteMode,reasonCode:e.reasonCode,reason:e.reason,childrenSummary:e.childrenSummary}}async function nd(e){const t=await async function(e){try{const{stdout:t}=await Vl("git",["-C",e,"rev-parse","--path-format=absolute","--git-common-dir"],{windowsHide:!0}),n=t.trim();return n?n.endsWith(`${R}.git`)?D(n):n:null}catch{return null}}(e);if(!t)return null;try{const n=await Yi(t),s=S(e);return n.some(e=>{try{return S(e.path)===s&&!e.isMain}catch{return!1}})?t:null}catch{return null}}async function sd(e,t){const n=await async function(e,t){const n=function(e){const t=e.trim().replace(/\\/g,"/");if(!t||t.includes("\0")||t.startsWith("/"))return null;const n=t.split("/").filter(Boolean);return 0===n.length||n.some(e=>"."===e||".."===e)?null:n.join("/")}(t);if(!n)return null;const s=await Jt(e),a=P(s,...n.split("/"));if(a!==s&&!a.startsWith(s+R))return null;if(!r(a))return{relativePath:n,absolutePath:a};const i=await Jt(a);return i===s||i.startsWith(s+R)?{relativePath:n,absolutePath:a}:null}(Me.agentrixHomeDir,e);if(!n)return{relativePath:e,releasable:!1,reasonCode:"invalid_path",message:"Path must stay inside the Agentrix home directory"};const{relativePath:s,absolutePath:a}=n;if(!r(a))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"missing",message:"Path no longer exists"};const i=s.split("/")[0];if("logs"===i){const e=function(e){const t=e.split("/");return"logs"!==t[0]?null:Xl.exec(t[t.length-1])?.[1]??null}(s);return e&&t.has(e)?{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"active_task",message:"Task is currently running"}:{relativePath:s,absolutePath:a,kind:"logs",method:"rm",releasable:!0}}if("tmp"===i)return{relativePath:s,absolutePath:a,kind:"tmp",method:"rm",releasable:!0};if("repos"===i)return 4===s.split("/").length?{relativePath:s,absolutePath:a,kind:"repos",method:"rm",releasable:!0}:{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_repo_path",message:"Only repository-level paths are cleanable"};if("workspaces"!==i)return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"protected_area",message:"This Agentrix area is not cleanable"};const o=function(e){const t=e.split("/");if(t.length<4||"workspaces"!==t[0]||"users"!==t[1])return null;const[,,n,s]=t,a=E(Me.agentrixWorkspaceHomeDir,"users",n,s);return{userId:n,taskId:s,taskDir:a,projectDir:E(a,"project"),dataDir:E(a,"data"),state:Ql(n,s)}}(s);if(!o)return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_workspace_path",message:"Only task project and task data paths are cleanable"};if(t.has(o.taskId))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"active_task",message:"Task is currently running"};if(ed(o.state))return{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"user_directory",message:"This task uses a user-owned directory"};const c=s.split("/").slice(4).join("/");if("project"===c){const e=await nd(a);return e?{relativePath:s,absolutePath:a,kind:"workspaces",method:"remove-worktree",releasable:!0,workspace:o,mainRepoDir:e}:{relativePath:s,absolutePath:a,kind:"workspaces",method:"rm-stale-directory",releasable:!0,workspace:o}}return"data"===c?{relativePath:s,absolutePath:a,kind:"workspaces",method:"rm",releasable:!0,workspace:o}:{relativePath:s,absolutePath:a,releasable:!1,reasonCode:"unsupported_workspace_path",message:"Only task project and task data paths are cleanable"}}async function ad(e){const t=await Yl(e.absolutePath);if("remove-worktree"===e.method){if(!e.mainRepoDir)throw new Error("Missing main repository for worktree removal");await Zi(e.mainRepoDir,e.absolutePath,!0)}else{const t=v(e.absolutePath);t.isDirectory()&&!t.isSymbolicLink()?await zt(e.absolutePath,{recursive:!0,force:!1}):await Kt(e.absolutePath)}return t}function id(e){try{if(!Ye(e).isDirectory())return{ok:!1,status:"missing",error:"Path is not a directory"};try{Qe(e,Ze.R_OK|Ze.W_OK)}catch{return{ok:!1,status:"permission_lost",error:"Directory is not readable and writable"}}return{ok:!0,status:"active"}}catch(e){return{ok:!1,status:"missing",error:e instanceof Error?e.message:"Directory is unavailable"}}}function od(e,t,n){const s=Ye(e);return{name:t,path:e,type:n,size:s.size,modifiedAt:s.mtime.toISOString()}}function rd(e){const t=rt(e?.trim()||Tn()),n=id(t);if("active"!==n.status)return{ok:!1,status:n.status,path:t,parentPath:null,entries:[],error:n.error};const s=ct(t).root,a=t===s?null:ot(t),i=et(t,{withFileTypes:!0}).map(e=>{const n=it(t,e.name);try{if(e.isDirectory())return od(n,e.name,"directory");if(e.isFile())return od(n,e.name,"file")}catch{return null}return null}).filter(e=>Boolean(e)).sort((e,t)=>e.type!==t.type?"directory"===e.type?-1:1:e.name.localeCompare(t.name));return{ok:!0,status:"active",path:t,parentPath:a,entries:i}}class cd{state="ready";machineId;workerManager;getSocketClient;requestRestartCallback;restartRequested=!1;pendingRestartReport=null;activeStorageOperations={};activeStorageChildren=new Map;cancelledStorageOperations=new Set;constructor(e){this.machineId=e.machineId,this.workerManager=e.workerManager,this.getSocketClient=e.getSocketClient,this.requestRestartCallback=e.requestRestart,this.workerManager.setDrainCallback(()=>this.handleSessionDrain())}getState(){return this.state}isAcceptingNewWorkers(){return this.workerManager.isAcceptingNewWorkers()}clearGracefulRestartGate(){"pending_restart"===this.state&&(this.state="ready"),this.restartRequested=!1,this.pendingRestartReport=null,this.workerManager.setWorkerStartGate(!0)}rollbackGracefulRestart(){"pending_restart"!==this.state&&"restarting"!==this.state||(this.state="ready"),this.restartRequested=!1,this.pendingRestartReport=null,this.workerManager.setWorkerStartGate(!0)}prepareGracefulRestart(e,t,n){this.workerManager.setWorkerStartGate(!1,"daemon_pending_restart",t??"Daemon restart is pending"),this.workerManager.pruneStaleSessions();const s=this.workerManager.getCurrentSessions().length;if(0===s){this.state="restarting";const a=n??this.pendingRestartReport??void 0;return this.pendingRestartReport=null,this.requestRestart(e,t,a),{state:"restarting",activeSessions:s}}return this.state="pending_restart",this.pendingRestartReport=n??this.pendingRestartReport,{state:"pending_restart",activeSessions:s}}buildPingResult(){this.workerManager.pruneStaleSessions();const e="pending_restart"===this.state||"restarting"===this.state;return{machineId:this.machineId,runningCliVersion:Ue.version,installedCliVersion:Wl(),restartRequired:e,restartPending:e,platform:process.platform,uptimeMs:Math.max(0,Math.floor(1e3*process.uptime())),activeSessions:this.workerManager.getCurrentSessions().length,capabilities:["ping","upgrade-cli","storage-scan","storage-clean","pick-directory","validate-directory","list-directory","create-directory"]}}handleCommand(e,t){if(this.matchesTarget(e))if("ping"!==e.action){if("validate-directory"===e.action){const n="string"==typeof e.params?.path?e.params.path:"";return n.trim()?void t({eventId:X(),status:"success",opCode:e.eventId,data:{result:id(n)}}):void t(this.failedAck(e.eventId,"operation_failed","Directory path is required"))}if("pick-directory"!==e.action){if("list-directory"===e.action){const n="string"==typeof e.params?.path?e.params.path:void 0;return void t({eventId:X(),status:"success",opCode:e.eventId,data:{result:rd(n)}})}if("create-directory"!==e.action)"upgrade-cli"!==e.action?"storage-scan"!==e.action&&"storage-clean"!==e.action?t(this.failedAck(e.eventId,"unsupported_operation","Unsupported machine control operation")):this.handleStorageManagement(e,t):this.handleUpgradeCli(e,t);else try{const n=function(e,t){const n=t.trim();if(!n||"."===n||".."===n||n.includes("/")||n.includes("\\"))throw new Error("Directory name is invalid");const s=rt(e),a=id(s);if("active"!==a.status)throw new Error(a.error||"Parent directory is unavailable");const i=rt(s,n);if(i!==s&&!i.startsWith(s.endsWith(lt)?s:s+lt))throw new Error("Directory path is invalid");return tt(i),{path:i,validation:id(i)}}("string"==typeof e.params?.parentPath?e.params.parentPath:"","string"==typeof e.params?.name?e.params.name:"");t({eventId:X(),status:"success",opCode:e.eventId,data:{result:n}})}catch(n){const s=n instanceof Error?n.message:"Failed to create directory";t(this.failedAck(e.eventId,"operation_failed",s))}}else try{const n=ka("string"==typeof e.params?.defaultPath?e.params.defaultPath:void 0);t({eventId:X(),status:"success",opCode:e.eventId,data:{result:{path:n??null,...n?{validation:id(n)}:{}}}})}catch(n){const s=n instanceof Error?n.message:"Failed to pick directory";t(this.failedAck(e.eventId,"operation_failed",s))}}else t({eventId:X(),status:"success",opCode:e.eventId,data:{result:this.buildPingResult()}});else t(this.failedAck(e.eventId,"machine_not_found","Machine control target does not match this daemon"))}handleUpgradeCli(e,t){"ready"===this.state?(this.state="upgrading",t({eventId:X(),status:"success",opCode:e.eventId}),this.runUpgrade(e).catch(t=>{De.error("[MACHINE CONTROL] upgrade-cli failed unexpectedly:",t),this.state="ready",this.sendProgress({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t instanceof Error?t.message:"CLI upgrade failed"})})):t(this.failedAck(e.eventId,"pending_restart"===this.state?"daemon_pending_restart":"daemon_control_busy","Daemon is not ready for CLI upgrade"))}async runUpgrade(e){this.sendProgress({eventId:X(),opCode:e.eventId,status:"running",message:"Checking and installing CLI upgrade"});const t=await Kl(void 0,{stdio:"ignore"});if("busy"===t.status)return this.state="ready",void this.sendProgress({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_busy",errorMessage:t.message});if("already_latest"===t.status)return this.state="ready",void this.sendProgress({eventId:X(),opCode:e.eventId,status:"succeeded",message:"CLI is already up to date",result:{alreadyLatest:!0,currentVersion:t.currentVersion,latestVersion:t.latestVersion,restartRequired:!1,restartDeferred:!1,activeSessions:this.workerManager.getCurrentSessions().length}});if("failed"===t.status)return this.state="ready",void this.sendProgress({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t.error});const n={opCode:e.eventId,target:e.target,fromVersion:t.fromVersion,toVersion:t.toVersion},s=this.prepareGracefulRestart("machine-control","CLI upgrade installed",n);this.sendProgress({eventId:X(),opCode:e.eventId,status:"running",message:"pending_restart"===s.state?"CLI upgrade installed; restart deferred until active sessions finish":"CLI upgrade installed; restarting daemon",result:{fromVersion:t.fromVersion,toVersion:t.toVersion,restartRequired:!0,restartDeferred:"pending_restart"===s.state,activeSessions:s.activeSessions}})}handleStorageManagement(e,t){t(this.startStorageManagement(e,e=>this.sendProgress(e)))}startStorageManagement(e,t){if(!this.matchesTarget(e))return this.failedAck(e.eventId,"machine_not_found","Machine control target does not match this daemon");if("ready"!==this.state)return this.failedAck(e.eventId,"daemon_control_busy","Daemon is not ready for storage management");const n="storage-scan"===e.action||"storage-clean"===e.action?e.action:null;if(!n)return this.failedAck(e.eventId,"unsupported_operation","Unsupported storage operation");if(this.activeStorageOperations[n])return this.failedAck(e.eventId,"operation_busy",`Another ${n} operation is already running`);const s=this.buildStorageWorkerRequest(e);return"storage-clean"!==e.action||s.items&&0!==s.items.length?(this.activeStorageOperations[n]=e.eventId,this.runStorageManagementWorker(e,s,t).catch(n=>{De.error("[MACHINE CONTROL] storage management failed unexpectedly:",n),t({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:n instanceof Error?n.message:"Storage operation failed"})}).finally(()=>{this.activeStorageChildren.delete(e.eventId),this.cancelledStorageOperations.delete(e.eventId),this.activeStorageOperations[n]===e.eventId&&delete this.activeStorageOperations[n]}),{eventId:X(),status:"success",opCode:e.eventId}):this.failedAck(e.eventId,"operation_failed","No storage items selected")}cancelStorageManagement(e,t){const n=Object.entries(this.activeStorageOperations).find(([,t])=>t===e);return n?(this.cancelledStorageOperations.add(e),this.activeStorageChildren.get(e)?.kill?.("SIGTERM"),delete this.activeStorageOperations[n[0]],t({eventId:X(),opCode:e,status:"failed",errorCode:"operation_cancelled",errorMessage:"Storage operation cancelled"}),{eventId:X(),status:"success",opCode:e}):this.failedAck(e,"operation_failed","Storage operation is not running")}buildStorageWorkerRequest(e){const t={activeTaskIds:this.workerManager.getCurrentSessions().map(e=>e.taskId)};if("storage-clean"===e.action){t.dryRun=!0===e.params?.dryRun;const n=Array.isArray(e.params?.items)?e.params.items:[];t.items=n.map(e=>e&&"object"==typeof e&&"string"==typeof e.relativePath?{relativePath:e.relativePath}:null).filter(e=>Boolean(e))}return t}async runStorageManagementWorker(e,t,n){let s=null;try{s=Je(it(Sn(),`agentrix-${e.action}-`));const a=it(s,"request.json");Ve(a,JSON.stringify(t));const i=e.action,o=zc([i,"--op-code",e.eventId,"--request-file",a],{stdio:["ignore","pipe","pipe"],env:process.env});this.activeStorageChildren.set(e.eventId,o),n({eventId:X(),opCode:e.eventId,status:"running",message:"storage-scan"===e.action?"Scanning Agentrix storage":"Cleaning Agentrix storage"}),await new Promise(t=>{let s="",a=!1;const r=t=>{"completed"!==t.type&&"failed"!==t.type||(a=!0),n(this.mapStorageWorkerEventToProgress(e,t))};o.stdout?.setEncoding("utf8"),o.stdout?.on("data",e=>{s+=e;const t=s.split(/\r?\n/);s=t.pop()??"";for(const e of t){const t=e.trim();if(t)try{r(JSON.parse(t))}catch(e){De.warn(`[MACHINE CONTROL] Ignoring malformed storage worker event: ${t}`,e)}}}),o.stderr?.setEncoding("utf8"),o.stderr?.on("data",e=>{De.warn(`[MACHINE CONTROL] ${i} stderr: ${e.trim()}`)}),o.on("error",t=>{a||(a=!0,n({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:t.message}))}),o.on("close",i=>{if(s.trim())try{r(JSON.parse(s.trim()))}catch(e){De.warn(`[MACHINE CONTROL] Ignoring malformed trailing storage worker event: ${s.trim()}`,e)}if(!a){if(this.cancelledStorageOperations.has(e.eventId))return a=!0,void t();n({eventId:X(),opCode:e.eventId,status:"failed",errorCode:"operation_failed",errorMessage:0===i?"Storage operation ended before reporting completion; please retry":`Storage worker exited with code ${i}`})}t()})})}finally{s&&function(e){try{p(e).isDirectory()?h(e,{recursive:!0,force:!0}):f(e)}catch{}}(s)}}mapStorageWorkerEventToProgress(e,t){return"failed"===t.type?{eventId:X(),opCode:e.eventId,status:"failed",message:t.message,errorCode:"operation_failed",errorMessage:t.message,result:{phase:t.type,...t}}:"completed"===t.type?{eventId:X(),opCode:e.eventId,status:"succeeded",message:"storage-scan"===e.action?"Storage scan completed":"Storage clean completed",result:t.result??{summary:t.summary}}:{eventId:X(),opCode:e.eventId,status:"running",message:this.describeStorageWorkerEvent(e.action,t),result:{phase:t.type,...t}}}describeStorageWorkerEvent(e,t){return"category-started"===t.type?`Scanning ${t.label}`:"item"===t.type?`Scanned ${t.item.pathDisplay??t.item.relativePath}`:"item-validating"===t.type?`Validating ${t.relativePath}`:"item-cleaning"===t.type?`Cleaning ${t.relativePath}`:"item-completed"===t.type?`Cleaned ${t.relativePath}`:"item-skipped"===t.type?`Skipped ${t.relativePath}`:"item-failed"===t.type?`Failed ${t.relativePath}`:"storage-scan"===e?"Scanning Agentrix storage":"Cleaning Agentrix storage"}handleSessionDrain(){if("pending_restart"!==this.state)return;const e=this.pendingRestartReport??void 0,t=this.prepareGracefulRestart("machine-control","Active sessions drained after CLI upgrade",e);e&&this.sendProgress({eventId:X(),opCode:e.opCode,status:"running",message:"Active sessions drained; restarting daemon",result:{fromVersion:e.fromVersion,toVersion:e.toVersion,restartRequired:!0,restartDeferred:!1,activeSessions:t.activeSessions}})}requestRestart(e,t,n){this.restartRequested||(this.restartRequested=!0,this.requestRestartCallback(e,t,n))}sendProgress(e){const t=this.getSocketClient();t?.connected?t.send("machine-control-progress",e):De.warn(`[MACHINE CONTROL] Dropping progress ${e.opCode}; socket not connected`)}matchesTarget(e){return e.target.machineId===this.machineId}failedAck(e,t,n){return{eventId:X(),status:"failed",opCode:e,message:n,data:{errorCode:t}}}}function ld(){return E(D(Me.getStatePaths().daemonStateFile),"daemon-restart-report.json")}function dd(e){return new Promise(t=>setTimeout(t,e))}function pd(e){try{return process.kill(e,0),!0}catch{return!1}}function ud(e){return id(e).status}class md{constructor(e,t={}){this.credentials=e,this.intervalMs=t.intervalMs??3e5,this.stateFilePath=t.stateFilePath??E(Me.agentrixHomeDir,"workspace-mode.state.json")}timer=null;running=!1;intervalMs;stateFilePath;start(){this.timer||(this.syncOnce(),this.timer=setInterval(()=>{this.syncOnce()},this.intervalMs),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=null)}async syncOnce(){if(!this.running){this.running=!0;try{const e=await this.loadState(),t=this.buildStatusReports(e);if(0===t.length)return;const n=this.markStatusesObserved(e,t);await this.saveState(n);const s={statuses:t};await async function(e,t){const n=await fetch(e,t);if(!n.ok){const e=await n.text().catch(()=>"");throw new Error(`HTTP ${n.status}${e?`: ${e}`:""}`)}return n.json()}(`${Me.serverUrl}/v1/workspaces/machine/path-statuses`,{method:"POST",headers:{Authorization:`Bearer ${this.credentials.token}`,"Content-Type":"application/json"},body:JSON.stringify(s)}),await this.saveState(this.markStatusesSynced(n,t))}catch(e){De.warn("[WORKSPACE SYNC] Failed to sync workspace path statuses",e)}finally{this.running=!1}}}async applyCacheUpdate(e){if(e.machineId!==this.credentials.machineId)return;const t=await this.loadState(),n=(new Date).toISOString(),s={...t.workspaces};if("replace"===e.action){const t={};for(const s of e.workspaces??[])t[s.id]=this.entryFromWorkspace(s,n);return void await this.saveState({version:1,machineId:this.credentials.machineId,workspaces:t})}if("upsert"===e.action&&e.workspace)return s[e.workspace.id]=this.entryFromWorkspace(e.workspace,n),void await this.saveState({...t,workspaces:s});"remove"===e.action&&e.workspaceId&&(delete s[e.workspaceId],await this.saveState({...t,workspaces:s}))}async loadState(){const e={version:1,machineId:this.credentials.machineId,workspaces:{}};if(!r(this.stateFilePath))return e;try{const t=JSON.parse(await Bt(this.stateFilePath,"utf-8"));return 1===t.version&&t.machineId===this.credentials.machineId&&t.workspaces&&"object"==typeof t.workspaces?t:e}catch(t){return De.warn("[WORKSPACE SYNC] Failed to read workspace sync state; rebuilding cache",t),e}}async saveState(e){await Ft(D(this.stateFilePath),{recursive:!0}),await Gt(this.stateFilePath,JSON.stringify(e,null,2),"utf-8")}buildStatusReports(e){const t=[];for(const n of Object.values(e.workspaces)){const e=ud(n.path);e!==n.lastSyncedStatus&&t.push({workspaceId:n.workspaceId,pathStatus:e})}return t}markStatusesSynced(e,t){const n={...e.workspaces};for(const e of t){const t=n[e.workspaceId];t&&(n[e.workspaceId]={...t,lastKnownStatus:e.pathStatus,lastSyncedStatus:e.pathStatus,updatedAt:(new Date).toISOString()})}return{...e,workspaces:n}}markStatusesObserved(e,t){const n={...e.workspaces};for(const e of t){const t=n[e.workspaceId];t&&(n[e.workspaceId]={...t,lastKnownStatus:e.pathStatus,updatedAt:(new Date).toISOString()})}return{...e,workspaces:n}}entryFromWorkspace(e,t){return{workspaceId:e.id,path:e.path,lastKnownStatus:e.pathStatus,lastSyncedStatus:e.pathStatus,updatedAt:t}}}const hd=kt.enum(["outbound","inbound"]),gd=kt.object({cursor:kt.number().int().positive(),eventId:kt.string(),taskId:kt.string(),chatId:kt.string().nullish(),eventType:kt.string(),direction:hd,eventData:kt.record(kt.string(),kt.unknown()),createdAt:kt.string()});kt.object({type:kt.literal("hello"),protocolVersion:kt.number().int(),machineId:kt.string(),cloudId:kt.string().optional(),hostname:kt.string(),cliVersion:kt.string().optional()});const fd=kt.object({type:kt.literal("hello-ack"),resumeFromCursor:kt.number().int().nonnegative().optional()});kt.object({type:kt.literal("events"),events:kt.array(gd),droppedBeforeCursor:kt.number().int().positive().optional()});const yd=kt.object({type:kt.literal("ack"),cursor:kt.number().int().nonnegative()}),vd=kt.discriminatedUnion("type",[fd,yd]),wd=Oe(import.meta.url),bd=(e,t)=>new Cn(e,t);class kd{machineId;cloudId;settings;outbox;pollIntervalMs;batchSize;maxUnackedEvents;reconnectBaseDelayMs;reconnectMaxDelayMs;cleanupIntervalMs;heartbeatIntervalMs;createWebSocket;ws=null;started=!1;stopped=!1;helloAcked=!1;pumping=!1;cleaning=!1;sendCursor=0;flowAckedCursor=0;pendingDroppedBeforeCursor=null;reconnectDelayMs;reconnectTimer=null;pollTimer=null;cleanupTimer=null;heartbeatTimer=null;lastPongAt=0;constructor(e){this.machineId=e.machineId,this.cloudId=e.cloudId,this.settings=e.settings,this.outbox=e.outbox,this.pollIntervalMs=e.pollIntervalMs??300,this.batchSize=e.batchSize??200,this.maxUnackedEvents=e.maxUnackedEvents??1e3,this.reconnectBaseDelayMs=e.reconnectBaseDelayMs??1e3,this.reconnectMaxDelayMs=e.reconnectMaxDelayMs??6e4,this.cleanupIntervalMs=e.cleanupIntervalMs??3e5,this.heartbeatIntervalMs=e.heartbeatIntervalMs??3e4,this.createWebSocket=e.createWebSocket??bd,this.reconnectDelayMs=this.reconnectBaseDelayMs}start(){this.started||(this.started=!0,wd.info(`[FORWARD] Task event forwarding enabled url=${this.settings.wsUrl} retentionHours=${this.settings.retentionHours} maxDbMb=${this.settings.maxDbMb}`),this.connect(),this.pollTimer=setInterval(()=>{this.pump()},this.pollIntervalMs),this.pollTimer.unref(),this.cleanupTimer=setInterval(()=>{this.runCleanup()},this.cleanupIntervalMs),this.cleanupTimer.unref(),this.heartbeatTimer=setInterval(()=>{this.heartbeat()},this.heartbeatIntervalMs),this.heartbeatTimer.unref(),this.runCleanup())}async stop(){this.stopped=!0;for(const e of[this.pollTimer,this.cleanupTimer,this.heartbeatTimer,this.reconnectTimer])e&&clearInterval(e);this.pollTimer=null,this.cleanupTimer=null,this.heartbeatTimer=null,this.reconnectTimer=null;const e=this.ws;if(this.ws=null,this.helloAcked=!1,e){try{e.close(1e3)}catch{}setTimeout(()=>e.terminate(),500).unref()}wd.info("[FORWARD] Task event forwarding stopped")}connect(){if(this.stopped)return;let e;try{e=this.createWebSocket(this.settings.wsUrl,{handshakeTimeout:1e4,...this.settings.token?{headers:{Authorization:`Bearer ${this.settings.token}`}}:{}})}catch(e){return wd.warn(`[FORWARD] Failed to create WebSocket: ${e instanceof Error?e.message:String(e)}`),void this.scheduleReconnect()}this.ws=e,this.helloAcked=!1,e.on("open",()=>{if(this.ws!==e)return;this.lastPongAt=Date.now();const t={type:"hello",protocolVersion:1,machineId:this.machineId,...this.cloudId?{cloudId:this.cloudId}:{},hostname:n.hostname(),cliVersion:Ue.version};e.send(JSON.stringify(t))}),e.on("message",t=>{this.ws===e&&this.handleFrame(String(t))}),e.on("pong",()=>{this.lastPongAt=Date.now()}),e.on("error",e=>{wd.warn(`[FORWARD] WebSocket error: ${e.message}`)}),e.on("close",t=>{this.ws===e&&(this.ws=null,this.helloAcked=!1,this.stopped||(wd.info(`[FORWARD] Connection closed (code=${t}), reconnecting in ${this.reconnectDelayMs}ms`),this.scheduleReconnect()))})}scheduleReconnect(){this.stopped||this.reconnectTimer||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.reconnectDelayMs),this.reconnectTimer.unref(),this.reconnectDelayMs=Math.min(2*this.reconnectDelayMs,this.reconnectMaxDelayMs))}async handleFrame(e){let t;try{t=JSON.parse(e)}catch{return void wd.warn("[FORWARD] Ignoring non-JSON frame from receiver")}const n=vd.safeParse(t);if(n.success){if("hello-ack"===n.data.type){try{const e=await this.outbox.getAckedCursor();this.sendCursor=n.data.resumeFromCursor??e,this.flowAckedCursor=this.sendCursor;const t=await this.outbox.getDroppedBeforeCursor();this.pendingDroppedBeforeCursor=null!==t&&t>this.sendCursor?t:null}catch(e){return void wd.warn(`[FORWARD] Failed to resolve resume cursor: ${e instanceof Error?e.message:String(e)}`)}return this.helloAcked=!0,this.reconnectDelayMs=this.reconnectBaseDelayMs,wd.info(`[FORWARD] Handshake complete, resuming after cursor ${this.sendCursor}`),void this.pump()}if("ack"===n.data.type){const e=n.data.cursor;e>this.flowAckedCursor&&(this.flowAckedCursor=e),this.outbox.setAckedCursor(e).catch(t=>{wd.warn(`[FORWARD] Failed to persist acked cursor ${e}: ${t instanceof Error?t.message:String(t)}`)}),this.pump()}}else wd.warn("[FORWARD] Ignoring unknown frame from receiver")}async pump(){if(this.pumping||this.stopped)return;const e=this.ws;if(e&&e.readyState===Cn.OPEN&&this.helloAcked){this.pumping=!0;try{for(;;){if(this.stopped||this.ws!==e||e.readyState!==Cn.OPEN||!this.helloAcked)return;const t=this.maxUnackedEvents-(this.sendCursor-this.flowAckedCursor);if(t<=0)return;const n=Math.min(this.batchSize,t),s=await this.outbox.pageAfter(this.sendCursor,n);if(0===s.length)return;const a={type:"events",events:s,...null!==this.pendingDroppedBeforeCursor?{droppedBeforeCursor:this.pendingDroppedBeforeCursor}:{}};if(e.send(JSON.stringify(a)),this.pendingDroppedBeforeCursor=null,this.sendCursor=s[s.length-1].cursor,s.length<n)return}}catch(e){wd.warn(`[FORWARD] Push failed: ${e instanceof Error?e.message:String(e)}`)}finally{this.pumping=!1}}}async runCleanup(){if(!this.cleaning&&!this.stopped){this.cleaning=!0;try{const e=await this.outbox.cleanup({retentionMs:36e5*this.settings.retentionHours,maxDbBytes:1024*this.settings.maxDbMb*1024});e.deletedForSize>0?wd.warn(`[FORWARD] Outbox exceeded ${this.settings.maxDbMb}MB, dropped ${e.deletedForSize} oldest events`+(null!==e.droppedUnackedCursor?` (gap up to cursor ${e.droppedUnackedCursor})`:"")):e.deletedExpired>0&&wd.debug(`[FORWARD] Outbox cleanup removed ${e.deletedExpired} expired events (size=${e.dbSizeBytes} bytes)`)}catch(e){wd.warn(`[FORWARD] Outbox cleanup failed: ${e instanceof Error?e.message:String(e)}`)}finally{this.cleaning=!1}}}heartbeat(){const e=this.ws;if(e&&e.readyState===Cn.OPEN){if(Date.now()-this.lastPongAt>2*this.heartbeatIntervalMs+5e3)return wd.warn("[FORWARD] Heartbeat timeout, terminating connection"),void e.terminate();try{e.ping()}catch{}}}}function xd(e){const t=is(e);return"machine_binding_revoked"===t.code||t.message.includes("Machine binding revoked")}function Id(e){const t=is(e);return t.code||t.action?t:null}function Sd(e,t){Me.writeDaemonState({status:"starting",pid:process.pid,...void 0!==t.port?{port:t.port}:{},...t.host?{host:t.host}:{},...t.webhookHost?{webhookHost:t.webhookHost}:{},phase:e,startTime:t.startTime,updatedAt:(new Date).toISOString(),cliVersion:Ue.version,logPath:t.logPath})}async function Td(){je({type:"daemon"});const e=Le(),t=(new Date).toLocaleString();let n="boot";const{requestShutdown:s,shutdownPromise:a}=function(){const{processType:e,onShutdownRequest:t,forceExitTimeoutMs:n=3e4}={processType:"daemon"},s=`[${e.toUpperCase()}]`;let a,i=!1;const o=new Promise(e=>{a=(a,o)=>{i?De.debug(`${s} Shutdown already requested; ignoring duplicate request from ${a}`):(i=!0,De.info(`${s} Requesting shutdown (source: ${a}, errorMessage: ${o})`),t&&t(a,o),setTimeout(()=>process.exit(1),n).unref?.(),e({source:a,errorMessage:o}))}}),r=e=>{process.on(e,()=>{a("os-signal")})};return r("SIGINT"),r("SIGTERM"),process.on("uncaughtException",e=>{De.info(`${s} FATAL: Uncaught exception`,e),De.info(`${s} Stack trace: ${e.stack}`),a("exception",e.message)}),process.on("unhandledRejection",e=>{De.info(`${s} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);De.info(`${s} Stack trace: ${t.stack}`),a("exception",t.message)}),process.on("exit",e=>{De.info(`${s} Process exiting with code: ${e}`)}),{requestShutdown:a,shutdownPromise:o}}();console.log("[DAEMON RUN] Starting daemon process..."),De.debug("[DAEMON RUN] Environment",ya()),await Kn()&&(console.log("Daemon already running..."),process.exit(0));let i=await Me.acquireDaemonLock(5,200);for(;!i;)await Xn(),i=await Me.acquireDaemonLock(5,200),i||(De.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{n="machine_auth",Sd(n,{startTime:t,logPath:e}),function(){if(Me.disableCaffeinate)return De.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return De.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(ca&&!ca.killed)return De.debug("[caffeinate] Caffeinate already running"),!0;try{return ca=gt("caffeinate",["-im"],{stdio:"ignore",detached:!1}),ca.on("error",e=>{De.debug("[caffeinate] Error starting caffeinate:",e),ca=null}),ca.on("exit",(e,t)=>{De.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),ca=null}),De.info(`[caffeinate] Started with PID ${ca.pid}`),function(){if(pa)return;pa=!0;const e=()=>{da()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{De.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{De.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return De.info("[caffeinate] Failed to start caffeinate:",e),!1}}()&&De.debug("[DAEMON RUN] Sleep prevention enabled");const o=await ts();De.debug("[DAEMON RUN] Auth and machine setup complete");const l=new wl;await l.initialize(Me.getSandboxSettings());const d=new vl(l);let p,u,m,h,g=!1;d.setSocketClientProvider(()=>p?.client),h=new cd({machineId:o.machineId,workerManager:d,getSocketClient:()=>p?.client,requestRestart:(e,t,n)=>{!function(e){try{const t=zc(function(e){const t=["restart-daemon"];return void 0!==e.oldPid&&t.push("--old-pid",String(e.oldPid)),e.expectedCliVersion&&t.push("--expected-version",e.expectedCliVersion),e.reason&&t.push("--reason",e.reason),e.report&&t.push("--report-json",JSON.stringify(e.report)),t}(e),{detached:!0,stdio:"ignore",env:process.env});return t.unref(),t}catch(e){return De.error("[DAEMON RESTART] Failed to launch restart command",e),null}}({oldPid:process.pid,expectedCliVersion:n?.toVersion??Wl(),reason:t,report:n})?h.rollbackGracefulRestart():(g=!0,s("agentrix-cli",t))}});const{port:y,host:v,webhookHost:w,stop:b}=await Wc({getChildren:()=>d.getCurrentSessions(),stopSession:e=>d.stopSession(e),startDevOpsInit:e=>d.startDevOpsInit(e),completeDevOpsInit:e=>d.completeDevOpsInit(e),requestShutdown:()=>s("agentrix-cli"),registerSession:(e,t)=>d.registerTaskWorker(e,t),prepareGracefulRestart:e=>h.prepareGracefulRestart(e.source,e.reason),clearGracefulRestartGate:()=>h.clearGracefulRestartGate(),getSocketClient:()=>p?.client,credentials:o,get companionScheduler(){return u},get channelManager(){return m}});n="machine_socket",Sd(n,{port:y,host:v,webhookHost:w,startTime:t,logPath:e});try{await ba(),De.debug("[DAEMON RUN] Openers detected")}catch(e){De.warn("[DAEMON RUN] Failed to detect openers",e)}const k=new md(o),x=new ra({machineId:o.machineId,serverUrl:Me.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:me(o.token,o.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:X(),machineId:o.machineId,timestamp:Date.now().toString(),controlPort:y})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:Oe(import.meta.url,void 0,{filter:e=>!function(e){return e.includes("daemon-gitlab-request")||e.includes("daemon-gitlab-response")}(e)})},d,{requestShutdown:s,machineControl:h,workspaceStatusSync:k}),I=new Gl(x.client,o.machineId);m=I,d.setChannelManager(I),await x.connect(),p=x;const S={status:"ready",pid:process.pid,port:y,host:v,webhookHost:w,machineId:o.machineId,startTime:t,cliVersion:Ue.version,logPath:e};Me.writeDaemonState(S),De.debug("[DAEMON RUN] Daemon ready state written"),De.info("[DAEMON RUN] Machine client connected to server"),await async function(e){const t=function(){const e=ld();if(!r(e))return null;try{const t=JSON.parse(c(e,"utf-8"));return t.opCode&&t.target?.machineId?t:null}catch{return null}}();if(!t)return!1;const n=Ue.version,s={eventId:X(),opCode:t.opCode,status:"succeeded",message:"CLI upgrade installed; daemon restarted",result:{fromVersion:t.fromVersion,toVersion:t.toVersion??t.expectedCliVersion,currentVersion:n,runningCliVersion:n,installedCliVersion:n,restartRequired:!1,restartDeferred:!1,activeSessions:0}};return e.send("machine-control-progress",s),await e.flush(3e3).catch(e=>{De.warn("[DAEMON RESTART] Could not confirm restart report flush",e)}),function(){try{const e=ld();r(e)&&f(e)}catch{}}(),De.info(`[DAEMON RESTART] Flushed pending restart report for ${t.opCode}`),!0}(x.client).catch(e=>{De.warn("[DAEMON RUN] Failed to flush pending restart report",e)}),await vc(x.client,o),k.start();const T=new Jo(x.client,o.machineId);u=T,T.start();const C=function(e){const t=Xc();if(!t)return wd.debug("[FORWARD] AGENTRIX_EVENT_FORWARD_WS_URL not set, task event forwarding disabled"),null;if(!Vc())return wd.warn("[FORWARD] AGENTRIX_EVENT_FORWARD_WS_URL is set but task event forwarding only supports cloud mode (CLOUD_AUTH_TOKEN); forwarding disabled"),null;const n=Zc();return n?new kd({machineId:e.machineId,cloudId:e.cloudId,settings:t,outbox:n}):null}({machineId:o.machineId,cloudId:o.cloudId});C?.start(),await I.start(),x.setCompanionInteractionCallback(e=>{T.recordInteraction(e)});const _=new bl(x.client,o.machineId);_.start(),x.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&T.setHeartbeatTaskId(e.taskId)}),x.client.onEvent("companion-memory-organization-response",e=>{e?.taskId&&T.setMemoryOrganizationTaskId(e.taskId)});const A=async(e,t)=>{await I.stop(),k.stop(),T.stop(),_.stop(),await(C?.stop()),await x.disconnect(),await b(),await el(),await l.shutdown(),await Vn(),await da(),await Me.releaseDaemonLock(i),g&&De.info("[DAEMON RUN] Restart command owns replacement daemon startup"),De.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};De.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const E=await a;await A(E.source,E.errorMessage)}catch(t){!function(e,t,n){const s=Id(t),a=xd(t),i=s?.message||(a?"Machine binding is no longer valid.":t instanceof Error?t.message:String(t)),o=s?.action||(a?"Run `agentrix logout` and bind this machine again.":void 0);Me.writeDaemonState({status:"failed",phase:e,...s?.code?{code:s.code}:{},message:i,...o?{action:o}:{},failedAt:(new Date).toISOString(),cliVersion:Ue.version,logPath:n,pid:process.pid})}(n,t,e);const s=Id(t);s?(console.error(s.message),s.action&&console.error(s.action),De.error(`[DAEMON RUN][FATAL] ${s.code??"socket_auth_failed"}: ${s.message}`+(s.action?`\n${s.action}`:""))):xd(t)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again."),De.error("[DAEMON RUN][FATAL] Machine binding revoked.\nRun `agentrix logout` and bind this machine again.")),De.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",t),process.exit(1)}}const Cd="\n\n[Tool result truncated to 1024 bytes]";function _d(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(Cd,"utf8");return n>t?Ed(Cd,t):`${Ed(e,t-n)}${Cd}`}function Ad(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Ed(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}function $d(e,t){return[`eventId=${e.eventId}`,void 0!==e.sequence?`sequence=${e.sequence}`:void 0,e.opCode?`opCode=${e.opCode}`:void 0,`senderType=${e.senderType}`,`messageType=${t?.type??e.messageType??"unknown"}`,`encrypted=${Boolean(e.encryptedMessage)}`].filter(Boolean).join(" ")}function Md(e,t,n={}){const s=function(e){return ie(e)?di(e):re(e)?{answers:e.answers,...e.details?{details:e.details}:{},...e.status?{status:e.status}:{},...e.reason?{reason:e.reason}:{}}:null}(t);if(null===s)return null;const a="string"==typeof s?s:JSON.stringify(s);return["message.user_content",n.source?`source=${n.source}`:void 0,$d(e,t),`chars=${a.length}`,`content=${JSON.stringify(s)}`].filter(Boolean).join(" ")}const Pd=Oe(import.meta.url),Rd={senderType:"system",senderId:"system",senderName:"system"};class Dd{client;context;historyDb;getPermissionMode;outbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;forwardOutbox;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new ds(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onReconnect:t.onReconnect,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.forwardOutbox=void 0!==t.forwardOutbox?t.forwardOutbox:Zc(),this.initHandlers()}appendForwardEvent(e,t,n="outbound"){this.forwardOutbox&&this.forwardOutbox.append({eventId:t.eventId,taskId:this.context.taskId,chatId:t.chatId??this.context.chatId,eventType:e,direction:n,eventData:t})}sendForwarded(e,t){this.appendForwardEvent(e,t),this.client.send(e,t)}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=X();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:X(),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.sendForwarded("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:X(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.sendForwarded("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:X(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.sendForwarded("worker-ready",n),Pd.info([`worker.ready taskId=${this.context.taskId}`,void 0!==e?`activeMs=${e}`:void 0,null!==t?`permissionMode=${t}`:void 0].filter(Boolean).join(" "))}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:X(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.sendForwarded("worker-running",n)}sendPermissionMode(e){const t={eventId:X(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.sendForwarded("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:X(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.sendForwarded("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(Rd,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(Rd,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(Rd,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(Rd,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 _d(e,t);const n=Ad(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?_d(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:Ad(e);var t}).join("\n"),t):_d(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??X(),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 d=this.buildTaskUsageReport(s,c);if(this.appendForwardEvent("task-message",l),this.context.dataEncryptionKey){const e=ue(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,{payload:l,usageReport:d??void 0,sentAt:Date.now(),messageType:l.messageType,isResult:"result"===s.type}),d&&(this.appendForwardEvent("task-usage-report",d),this.client.send("task-usage-report",d)),this.client.send("task-message",l),"result"===s.type&&Pd.info([`outbound.result.sent eventId=${c}`,d?.eventId?`usageEventId=${d.eventId}`:"usageEventId=none",`encrypted=${Boolean(l.encryptedMessage)}`,`artifacts=${Boolean(o)}`,`outboxSize=${this.outbox.size}`].join(" ")),c}waitForEventAcks(e,t){const n=new Set(e.filter(e=>this.outbox.has(e)));return 0===n.size?Promise.resolve():new Promise(e=>{const s=t=>{this.ackWaiters.delete(t),n.delete(t),0===n.size&&(clearTimeout(a),e())},a=setTimeout(()=>{for(const e of n){const n=this.outbox.get(e),s=n?Date.now()-n.sentAt:t;Pd.warn(`${n?.isResult?"outbound.result.ack_timeout":"outbound.event.ack_timeout"} eventId=${e} pendingMs=${s} outboxSize=${this.outbox.size}`),this.ackWaiters.delete(e)}e()},t);for(const e of n)this.ackWaiters.set(e,()=>s(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:X(),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:X(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.sendForwarded("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:X(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.sendForwarded("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:X(),taskId:this.context.taskId,title:e};this.sendForwarded("change-task-title",t),Pd.info(`task.title_changed title=${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:X(),taskId:this.context.taskId,agentId:e,...t};this.sendForwarded("update-agent-info",n),Pd.info(`agent.info_updated updates=${JSON.stringify(t)}`)}async sendVisionPlanCard(e){const t={eventId:X(),taskId:this.context.taskId,issueId:e.issueId,repoRoot:e.repoRoot,createdAt:(new Date).toISOString()};this.appendForwardEvent("vision-plan-card",t);const n=await this.client.sendWithAck("vision-plan-card",t);if("success"!==n.status)throw new Error(n.message||"Failed to send Vision Plan card");return Pd.info(`vision_plan_card.sent issueId=${e.issueId}`),n}sendResetTaskSession(){const e={eventId:X(),taskId:this.context.taskId};this.sendForwarded("reset-task-session",e),Pd.info(`session.reset_requested taskId=${this.context.taskId}`)}async sendMergeRequest(e,t,n){const s={eventId:X(),taskId:this.context.taskId,summary:e,description:t,sourceBranch:n};Pd.info(`merge_request.sent taskId=${this.context.taskId}`),this.appendForwardEvent("merge-request",s);const a=await this.client.sendWithAck("merge-request",s);if(!a.success)throw new Error(`Failed to create pull request: ${a.error||"Unknown error"}`);return Pd.info(`merge_request.created pullRequestNumber=${a.data.pullRequestNumber}`),{pullRequestNumber:a.data.pullRequestNumber,pullRequestUrl:a.data.pullRequestUrl}}async sendMergePr(){const e={eventId:X(),taskId:this.context.taskId,mergeMethod:"squash"};return Pd.info(`merge_pr.sent taskId=${this.context.taskId}`),this.appendForwardEvent("merge-pr",e),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:X(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};Pd.info(`repo.association.sent repository=${e}/${t}/${n}`),this.sendForwarded("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:X(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},a=this.forwardOutbox?(e,t)=>this.appendForwardEvent(e,t,"inbound"):null,{"cancel-task":async e=>{e.taskId===t.taskId&&(Pd.info(`worker.cancelled taskId=${t.taskId}`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&(Pd.info(`worker.stopped taskId=${t.taskId} reason=${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;Pd.debug(`message.received ${$d(e)}`);let i=e.message??null;if(!i&&e.encryptedMessage&&t.dataEncryptionKey&&(i=ae(e.encryptedMessage,t.dataEncryptionKey)??null),!i&&e.encryptedMessage&&!t.dataEncryptionKey)return void Pd.warn(`message.decrypt_failed ${$d(e)} reason=missing_data_encryption_key`);if(!i&&e.encryptedMessage)return void Pd.warn(`message.decrypt_failed ${$d(e)} reason=invalid_encrypted_payload`);if(!i)return void Pd.warn(`message.empty ${$d(e)} reason=missing_message_payload`);e.channelReplyTarget&&"object"==typeof i&&(i.__channelReplyTarget=e.channelReplyTarget);const o={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&ie(i)&&(i=await il(i,{attachmentsDir:t.attachmentsDir})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(i,o))return void Pd.debug(`message.dropped ${$d(e,i)} reason=should_not_persist`);if(!n.saveMessage({eventId:e.eventId,message:i,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return s(e.eventId),void Pd.debug(`message.duplicate ${$d(e,i)} acked=true`);const r=Md(e,i,{source:"runtime"});r&&Pd.info(r);const c={...e,message:i,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:c,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),a?.("task-message",c),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(i,o),Pd.info(`message.accepted ${$d(e,i)} persisted=true duplicate=false acked=true dispatched=${Boolean(t.onTaskMessage)}`)},"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,a;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;if(void 0!==e.opCode){const n=this.outbox.get(e.opCode),s=n?Date.now()-n.sentAt:void 0;this.outbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.(),n?.isResult?Pd.info([`outbound.result.acked eventId=${e.opCode}`,"number"==typeof t?`sequence=${t}`:"sequence=unknown",void 0!==s?`ackMs=${s}`:void 0].filter(Boolean).join(" ")):Pd.debug([`outbound.event.acked eventId=${e.opCode}`,n?.messageType?`messageType=${n.messageType}`:void 0,"number"==typeof t?`sequence=${t}`:void 0,void 0!==s?`ackMs=${s}`:void 0].filter(Boolean).join(" "))}void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(Promise.resolve(this.context.onReconnect?.()).catch(e=>{Pd.warn(`reconnect.handler_failed error=${e instanceof Error?e.message:String(e)}`)}),this.outbox.size>0){Pd.info(`reconnect.outbox_flush count=${this.outbox.size}`);for(const[e,t]of this.outbox.entries())t.usageReport&&this.client.send("task-usage-report",t.usageReport),this.outbox.set(e,{...t,sentAt:Date.now()}),this.client.send("task-message",t.payload)}}else this.hasConnectedOnce=!0})}}const Nd=Zt(At),Od="xmz-ai",Ud="agentrix-hive",jd="https://github.com/xmz-ai/agentrix-hive.git",Ld="github";class qd{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=X();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,initPolicies:e.initPolicies};return this.taskDataKey?t.encryptedMessage=ue(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=ue(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,initPolicies:e.initPolicies};return this.taskDataKey?t.encryptedMessage=ue(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:e.senderType??"agent",senderId:e.senderId??this.taskId,senderName:e.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=Me.resolveRepoStoreCheckoutDir(Ld,Od,Ud),t=Me.resolveRepoStoreLockPath(Ld,Od,Ud),n=await Me.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await Ji(e)){if(!ro(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await no(jd,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await vo(e,"origin",yo(jd));try{return await Nd("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 Me.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 Be.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||Ss.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 Be.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 Hd(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=ae(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 Fd(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=ae(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 Bd(){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()}}}const Gd=Oe(import.meta.url);function Wd(e){return Pt("agentrix_computer_use","Execute a concrete operation on the user's local computer through Agentrix Computer Use.\n\nUse this tool when the user asks you to operate local desktop apps, windows, documents, menus, dialogs, browsers, Finder, or other GUI surfaces on this machine. Provide the requested operation as a natural-language instruction. Do not decompose the task into low-level click coordinates; Agentrix Computer Use will operate the GUI through its configured desktop-control tools.\n\nThis tool can control the local computer. Call it only for explicit user-requested computer operation.",{instruction:kt.string().describe("Concrete natural-language desktop operation to perform, including the app/document/target and desired outcome."),expectedResult:kt.string().optional().describe("Optional concise success condition the computer-use sub-task should verify before returning."),title:kt.string().optional().describe('Optional title for the computer-use sub-task. Defaults to "Computer use".')},async t=>{try{const n=await async function(e,t){if(!e.instruction.trim())throw new Error("instruction is required.");const n=t.status??hc();if(!n.enabled||n.missing.length>0)throw new Error(function(e){const t=["Agentrix Computer Use execution bridge is not ready.","","Enablement: "+(e.enabled?`enabled by ${e.enabledBy}`:"disabled"),`Codex home checked: ${e.codexHome}`,""];return e.enabled||t.push("Enable it with one of:","- set AGENTRIX_COMPUTER_USE_ENABLED=true for the worker/daemon environment;","- set settings.json field agentrixComputerUse.enabled=true;",`- create marker file ${e.markerPath}.`,""),e.missing.length>0&&t.push("Missing configuration:",...e.missing.map(e=>`- ${e}`),""),t.push("Agentrix tries to configure Codex automatically after this bridge is enabled:","1. cua-driver mcp-config --client codex","2. link the Cua Driver SKILL.md pack into Codex when a valid local skill source can be discovered","If automatic configuration fails, run the official Cua Driver installer/update flow or set AGENTRIX_CUA_DRIVER_PATH / AGENTRIX_CUA_DRIVER_SKILL_SOURCE.","Grant macOS Accessibility and Screen Recording permissions to Cua Driver when prompted."),t.join("\n")}(n));const s=function(e){const t=e.expectedResult?.trim();return["You are the Agentrix Computer Use execution worker for the current Agentrix task.","","Use the configured Cua Driver skill and MCP tools in this Codex environment to operate the local computer. Do not implement or modify Agentrix code unless the desktop operation explicitly requires editing a file. Prefer Cua Driver app-control tools over shell commands for GUI work. If the request needs a permission grant or user login that you cannot complete, stop and explain exactly what the user must do.","","Desktop operation instruction:",e.instruction.trim(),"",t?`Expected result:\n${t}`:void 0,"","Return a concise report of what you did, what result you observed, and any blocker or follow-up required."].filter(e=>Boolean(e)).join("\n")}(e),a=e.title?.trim()||"Computer use",i=t.historyDb.getAgentSessions().get(Zr);if(i)return Qr.info(`Emitting computer-use instruction to existing sub-task ${i} for task ${t.taskId}`),await t.sendMessage({taskId:i,target:"agent",message:{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}),{taskId:i,title:a,action:"emitted"};Qr.info(`Starting computer-use sub-task for task ${t.taskId}`);const o=await t.startSubTask({agentId:"codex",message:{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:"new"},title:a,cwd:t.cwd,forceUserCwd:!0,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}});return t.historyDb.upsertAgentSession(Zr,o.taskId),{taskId:o.taskId,title:a,action:"created"}}({instruction:t.instruction,expectedResult:t.expectedResult,title:t.title},{taskId:e.taskId,cwd:e.workingDirectory,historyDb:e.historyDb,startSubTask:t=>e.agentContext.startSubTask(t),sendMessage:t=>e.agentContext.sendMessage(t)});return{content:[{type:"text",text:"created"===n.action?[`computer-use sub-task created: ${n.taskId}`,`Title: ${n.title}`,"","The computer operation is now running asynchronously in that sub-task. Use this same agentrix_computer_use tool again for follow-up instructions or corrections; it will route them to the same computer-use sub-task."].join("\n"):[`computer-use instruction sent to existing sub-task: ${n.taskId}`,"","The computer-use sub-task will continue from its existing context."].join("\n")}]}}catch(e){return{content:[{type:"text",text:e instanceof Error?e.message:String(e)}],isError:!0}}})}function zd({workClient:e}){return Pt("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:kt.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function Kd(e){return Pt("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:kt.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=ne.parse({previewUrl:t}),s=await fetch(`${Me.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 Vd(e){return Pt("send_vision_artifact","Send the issue vision artifacts (visual plan and test report) to the Agentrix platform so the user can review them.\n\nUse this after generating or materially updating the visual plan, and again after generating the visual test report. Pass only the repository root and issue id; Agentrix derives the current task routing from platform context.",{repoRoot:qr.shape.repoRoot,issueId:qr.shape.issueId},async t=>{const n=await Hr(t);if(!e.workClient.sendVisionPlanCard)throw new Error("Vision artifact publishing is not available in this worker");return await e.workClient.sendVisionPlanCard({issueId:n.issueId,repoRoot:t.repoRoot}),{content:[{type:"text",text:`Agentrix vision artifacts sent for issue ${n.issueId}.`}]}})}function Xd({agentContext:e}){return Pt("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:kt.string().describe("Sub-task ID to send the message to"),instructions:kt.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:kt.array(kt.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async t=>{try{let n;return n=t.answers&&t.answers.length>0?{type:"ask_user_response",answers:t.answers}:{type:"user",message:{role:"user",content:t.instructions??""}},await e.sendMessage({taskId:t.taskId,message:n,target:"agent",senderType:"system",senderId:"agentrix-emit-to-task",senderName:"Agentrix emit_to_task"}),{content:[{type:"text",text:`${t.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${t.taskId}.`}]}}catch(e){return Gd.error(`Failed to send message to sub-task ${t.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Jd({historyDb:e}){return Pt("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:kt.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:kt.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=ql(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 Yd({agentContext:e}){return Pt("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 Qd({agentContext:e}){return Pt("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 Gd.error("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 Zd({agentContext:e,agentId:t,setPendingNavigateTaskId:n}){return Pt("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:kt.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:kt.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:kt.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:kt.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:kt.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:kt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:kt.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:kt.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async s=>{try{if(s.autoNavigate&&!s.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const a=s.agentId||t;let i;return s.independent?(i=await e.startIndependentTask({agentId:a,message:{type:"user",message:{role:"user",content:s.instructions}},title:s.title,cwd:s.cwd,forceUserCwd:!s.useWorktree,autoNavigate:s.autoNavigate}),s.autoNavigate&&n(i.taskId),Gd.info(`Created independent task ${i.taskId} for agent ${a} (autoNavigate: ${s.autoNavigate??!1})`)):(i=await e.startSubTask({agentId:a,message:{type:"user",message:{role:"user",content:s.instructions}},title:s.title,cwd:s.cwd,forceUserCwd:!s.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}}),Gd.info(`Created sub-task ${i.taskId} for agent ${a}`)),{content:[{type:"text",text:`🚀 Task created: ${i.taskId}\n${s.agentId?`Agent: ${a}\n`:""}${s.independent?"Mode: Independent\n":""}Summary: ${s.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return Gd.error("Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ep({agentContext:e}){return Pt("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:kt.string().min(1).max(200).describe("Task title"),instructions:kt.string().describe("Instructions for the owner agent"),briefSummary:kt.string().optional().describe("One-line summary shown to user immediately"),agentId:kt.string().describe("Target agent ID"),cwd:kt.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:kt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async t=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:t.agentId,message:{type:"user",message:{role:"user",content:t.instructions}},title:t.title,cwd:t.cwd,forceUserCwd:!t.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}})).taskId}\n${t.briefSummary?`Summary: ${t.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return Gd.error("Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function tp({agentContext:e}){return Pt("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:kt.string().min(1).max(200).describe("Task title"),requirement:kt.string().describe("Overall requirement"),briefSummary:kt.string().optional().describe("One-line summary shown to user immediately"),todos:kt.array(kt.object({agentId:kt.string().describe("Agent ID responsible for the todo"),title:kt.string().min(1).max(200).describe("Todo title"),instructions:kt.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async t=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:t.title,todos:t.todos,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"},message:{type:"user",message:{role:"user",content:t.requirement}}})).taskId}\n${t.briefSummary?`Summary: ${t.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return Gd.error("Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function np({askUser:e}){return Pt("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:kt.array(kt.object({question:kt.string().describe("The complete question to ask the user"),header:kt.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:kt.boolean().describe("Set to true to allow multiple option selections"),options:kt.array(kt.object({label:kt.string().describe("Option label (1-5 words)"),description:kt.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 t=>{try{const n=t.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(n);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 Gd.error("Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function sp({invokeAgent:e}){return Pt("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:kt.string().describe("Target agent ID"),hint:kt.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 ap({workClient:e,agentId:t,uploadFile:n}){return Pt("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:kt.string().optional().describe("Your display name"),avatarPath:kt.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:kt.string().optional().describe("Short status line or tagline shown under your name")},async s=>{let a;if(s.avatarPath)try{a=(await n({name:"avatar.png",path:s.avatarPath,visibility:"public"})).fileId}catch(e){return Gd.error("Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:s.displayName,avatar:a,signature:s.signature});const i=[];return s.displayName&&i.push(`name → ${s.displayName}`),a&&i.push("avatar → uploaded"),s.signature&&i.push(`signature → ${s.signature}`),{content:[{type:"text",text:`Profile updated: ${i.join(", ")}`}]}})}function ip({assign:e}){return Pt("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:kt.string().describe("Target agent ID"),instruction:kt.string().describe("Task instruction for the agent"),acknowledgment:kt.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 op({agentContext:e}){return Pt("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:kt.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:kt.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async t=>{try{const n=await e.listTasks({limit:t.limit??10,status:t.status??"all"});return n.length?{content:[{type:"text",text:JSON.stringify(n,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return Gd.error("Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function rp({chatHistoryDb:e}){return Pt("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:kt.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:kt.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=ql(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 cp({agentContext:e}){return Pt("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:kt.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:kt.string().optional().describe("Path to detailed analysis file in workspace, if any")},async t=>{try{const n=e.getChatId();return await e.sendMessage({taskId:n,message:{type:"companion_reminder",content:t.content,filePath:t.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return Gd.error("Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}const lp=kt.enum(["created","updated","deleted"]);function dp({taskId:e}){return Pt("record_memory_change","Append a structured JSONL record for an actual Companion memory change.\nUse this from Companion chat, heartbeat shadow, or memory-organization shadow after memory files were really created, updated, deleted, merged, compressed, or cleaned.\nDo not call this tool when the memory review found nothing to change.\nAfter recording an actual change, use send_reminder separately if the main Companion should be awakened.",{title:kt.string().optional().describe("Deprecated compatibility field; each change.summary is used for the JSONL record and semantic git commit title."),trigger:kt.enum(["scheduled","user_request"]).describe("What triggered this memory change."),source:kt.string().optional().describe("Where the changed memory fact came from, such as user correction, recent conversation, task history, reminder, existing memory consolidation, or verified project evidence. This is the memory evidence source, not the Companion execution path."),notifiedCompanion:kt.boolean().describe("Whether a reminder has already been sent or will be sent immediately after this record."),changes:kt.array(kt.object({file:kt.string().describe("Current primary self-evolution file path, relative to Companion claude home, such as memory/agentrix-companion-memory/memory.md or MEMORY.md. Legacy memory/-relative paths are accepted and normalized."),action:lp,summary:kt.string().describe("One-sentence summary of what changed."),reasons:kt.array(kt.string()).min(1).describe("Short reasons for this change."),deletedFiles:kt.array(kt.string()).optional().describe("Optional old allowlisted files removed while consolidating into file.")})).min(1).describe("One or more concrete file-bound memory changes for this topic.")},async t=>{try{const n=process.env.AGENTRIX_COMPANION_HOME;if(!n)throw new Error("AGENTRIX_COMPANION_HOME is not set; memory changes can only be recorded by Companion workers.");const s=new Date,a=s.toISOString().slice(0,10),i=E(n,"memory-changes"),o=E(i,`${a}.jsonl`),r=t.changes.map(e=>({file:Ai(n,e.file).relativePath,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles?.map(e=>Ai(n,e).relativePath)??[]}));await Ei({companionHome:n});const c=new Map;for(const e of r){const t=c.get(e.file);t?t.push(e):c.set(e.file,[e])}const l=[];for(const a of c.values()){const i=a[0],o=Array.from(new Set(a.flatMap(e=>e.deletedFiles))),r=await Pi({companionHome:n,title:i.summary,body:Mi({trigger:t.trigger,source:t.source,action:i.action,file:i.file,reasons:a.flatMap(e=>e.reasons),deletedFiles:o,notifiedCompanion:t.notifiedCompanion,taskId:e}),paths:[i.file,...o]});if(r)for(const n of a)l.push(JSON.stringify({time:s.toISOString(),trigger:t.trigger,source:t.source,taskId:e,file:n.file,action:n.action,summary:n.summary,reasons:n.reasons,deletedFiles:n.deletedFiles,notifiedCompanion:t.notifiedCompanion,commit:r}));else Gd.warn(`Skipping memory change JSONL record because no semantic git commit was created: file=${i.file}`)}return l.length>0&&(await An(i,{recursive:!0}),await En(o,`${l.join("\n")}\n`,"utf-8")),Gd.info(`Memory changes recorded: path=${o}, source=${t.source??"unspecified"}, trigger=${t.trigger}, records=${l.length}, requestedChanges=${r.length}, taskId=${e}`),{content:[{type:"text",text:l.length>0?`Memory changes recorded: ${l.length} JSONL record(s) at ${o}`:"No memory change JSONL records were written because no semantic git commit was created."}]}}catch(e){return Gd.error("Failed to record memory change:",e),{content:[{type:"text",text:`Failed to record memory change: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function pp({uploadFile:e}){return Pt("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:kt.string().describe("Absolute path to the local file to upload"),name:kt.string().optional().describe("Display name for the file (defaults to filename)")},async n=>{try{const s=t("path"),a=n.name||s.basename(n.filePath);return{content:[{type:"text",text:(await e({name:a,path:n.filePath,visibility:"public"})).url}]}}catch(e){return Gd.error("File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const up=2147483648,mp=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function hp({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a}){return Pt("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:kt.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:kt.array(kt.object({filePath:kt.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:kt.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:kt.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 i=>{const o=s?.()??null;if(!o)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=i.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await fp(n));return t}(i.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const r=await Wn(e,{content:s||void 0,attachments:a.length>0?a:void 0},o);return r?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:o.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:r.error}}),{content:[{type:"text",text:`Failed to send channel message: ${r.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:o.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 Gd.warn("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 gp({taskId:e,getChannelReplyTarget:t}){return Pt("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:kt.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:kt.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:kt.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 Hn("/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 fp(e){if(!O(e.filePath))throw new Error("filePath must be absolute");const t=await $n(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>up)throw new Error(`file is too large for channel delivery (${t.size} bytes; max 2147483648 bytes)`);const n=e.fileName||$(e.filePath),s=$(e.filePath);if(mp.test(s)||mp.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=Ss.lookup(n)||Ss.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 yp({agentContext:e}){return Pt("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 Gd.error("Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*vp(e){yield e}function wp({visionModel:e}){return Pt("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:kt.string().describe("Absolute path to the image file to analyze"),prompt:kt.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async t=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const n=(await _n(t.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[t.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=t.prompt||"Describe this image in detail.",i=Mt({prompt:vp({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:n}},{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 Gd.error("Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function bp({agentContext:e}){return Pt("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 Gd.error("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 kp({agentContext:e}){return Pt("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:kt.enum(["agent","skill"]),draftAgentId:kt.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:kt.string().optional().describe("Absolute local skill directory for skill publishing"),name:kt.string().optional().describe("Listing name, lowercase kebab-case"),displayName:kt.string().optional().describe("Human-readable listing name"),description:kt.string().optional(),readme:kt.string().optional(),category:kt.string().optional(),tags:kt.array(kt.string()).optional(),authorType:kt.enum(["user","agent"]).default("user"),authorId:kt.string(),machineId:kt.string().optional(),cloudId:kt.string().optional()},async t=>{try{const n=await e.publishToHive(t);return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return Gd.error("Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function xp({agentContext:e}){return Pt("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:kt.string().describe("Owned HiveListing ID to update"),version:kt.string().optional().describe("Optional new version; defaults to next patch version"),changelog:kt.string().optional(),sourceDir:kt.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:kt.string().optional(),cloudId:kt.string().optional()},async t=>{try{const{listingId:n,...s}=t,a=await e.updateHiveListingVersion(n,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return Gd.error("Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Ip({agentContext:e}){return Pt("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:kt.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:kt.string().describe("Absolute local directory where the agent or skill was installed"),name:kt.string().optional().describe("Optional local name for installed agent"),machineId:kt.string().optional(),cloudId:kt.string().optional(),installedVersion:kt.string().optional()},async t=>{try{const{listingId:n,...s}=t,a=await e.recordHiveInstall(n,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return Gd.error("Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Sp({agentContext:e}){return Pt("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:kt.string().describe("HiveListing ID"),rating:kt.number().int().min(1).max(5),comment:kt.string().optional().describe("Markdown review text")},async t=>{try{const n=await e.createHiveReview(t.listingId,{rating:t.rating,comment:t.comment??null});return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return Gd.error("Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Tp({agentContext:e}){return Pt("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:kt.string().describe("HiveListing ID"),content:kt.string().min(1).describe("Markdown comment content"),parentId:kt.string().optional().describe("Parent comment ID for replies")},async t=>{try{const n=await e.createHiveComment(t.listingId,{content:t.content,parentId:t.parentId});return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(e){return Gd.error("Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Cp(e){if(e)return e.replace(/\/+$/g,"")||"/"}function _p(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,headRef:e.headRef,headSha:e.headSha,checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,branchName:e.branchName,branchBinding:e.branchBinding,cwd:Cp(e.cwd)||"",userCwd:Cp(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,initPolicies:e.initPolicies,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,workspaceId:e.workspaceId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function Ap(e){return!!e.branchName&&"none"!==e.branchBinding&&"external-observed"!==e.branchBinding}function Ep(e,t,n){return t||(n?.trim()?`agentrix/${function(e){return e.replace(/^[a-z]+(?:\([^)]+\))?!?:\s*/i,"").normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/['’]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48).replace(/-+$/g,"")||"task"}(n)}-${function(e){return e.replace(/^task-/,"").replace(/[^a-zA-Z0-9]/g,"").toLowerCase().slice(0,8)||"task"}(e)}`:`agentrix/${e}`)}async function $p(e,t){const n=en(e);await n.raw(["checkout","-B",t,"HEAD"])}function Mp(e){return`HEAD:refs/heads/${e}`}function Pp(e,t){return`Cannot create PR: current branch is ${e}, but this task is bound to ${t}. Switch to ${t} or choose Keep during branch mismatch handling before creating the PR.`}async function Rp(e){if(!e)return null;const t=await Qo();return t?sr(e,t):null}async function Dp(e,t){const n=nr(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 Vi("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await Vi("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 Np(e,t,n){const s=await Rp(n);s?await async function(e,t){const n=To();try{await Vi("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:Co(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await Vi("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,env:_o(),windowsHide:!0})}(t,e)}function Op(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.")}function Up(...e){return e.find(e=>"string"==typeof e&&e.trim().length>0)?.trim()}function jp(e,t){const n=Up(e.checkoutSha,e.headSha);if(n)return n;const s=Up(e.checkoutRef,e.headRef,e.baseBranch);if(!s)throw new Error("Cannot create worktree: no checkout ref, checkout SHA, or base branch was provided.");const a=function(e){return e.trim().replace(/^refs\/heads\//,"").replace(/^origin\//,"")}(s);return t.includes(a)?`origin/${a}`:s}async function Lp(e,t,n){const s=en(e);try{await s.raw(["rev-parse","--verify","--quiet",`${t}^{commit}`])}catch{const e=[n.checkoutSha?`checkoutSha=${n.checkoutSha}`:void 0,n.headSha?`headSha=${n.headSha}`:void 0,n.checkoutRef?`checkoutRef=${n.checkoutRef}`:void 0,n.headRef?`headRef=${n.headRef}`:void 0,n.baseBranch?`baseBranch=${n.baseBranch}`:void 0].filter(Boolean).join(", ");throw new Error(`Cannot create worktree: checkout start point ${t} does not exist after fetch${e?` (${e})`:""}.`)}}async function qp(e,t,n,s,a,i,o={}){const c=yo(t),l=await Ji(e);if(!ro(e)&&!l)throw new Error(`Directory ${e} exists but is not a git repository`);const p=await Rp(a);if(ro(e)){p?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=D(n);r(s)||d(s,{recursive:!0});const a=To();try{await Vi("git",["-c","credential.helper=","clone",t,n],{env:Co(a,e),windowsHide:!0})}finally{f(a)}}(p,c,e),a&&await Dp(e,a)):await no(t,e),await fo(e,"origin",c),await Np(e,t,a),a&&await Dp(e,a);const n=await wo(e),l=Op(n,s),u=jp({...o,baseBranch:l},n);return await Lp(e,u,{...o,baseBranch:l}),i?await so(e,i,u):await en(e).raw(["checkout","--detach",u]),await io(e)}if(await vo(e,"origin",c),await Np(e,t,a),a&&await Dp(e,a),i){const t=await wo(e),n=Op(t,s),a=jp({...o,baseBranch:n},t);await Lp(e,a,{...o,baseBranch:n}),await so(e,i,a)}return await io(e)}async function Hp(e,t,n,s={}){const a=await Rp(s.gitServerId);a?await async function(e,t,n,s=!1){const a=To();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await Vi("git",i,{cwd:t,env:Co(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 Vi("git",a,{cwd:t,env:_o(),windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=Xi(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function Fp(e,t,n){const s=n.trim();if(!s)return;const a=Me.resolveDataDir(e,t),i=E(a,"patch.diff");return await Ft(a,{recursive:!0}),await Gt(i,`${s}\n`),i}async function Bp(e,t,n){await Me.writeLastSentArtifactVersion(e,t,n)}function Gp(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 Wp(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:wn()}}function zp(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:wn()}}function Kp(e){const t="```sh\n",n="\n```";return`${t}${_d(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function Vp(e,t,n,s=6e4){return new Promise(a=>{const i=gt("/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,d;if(o&&clearTimeout(o),r){i=124,d=!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,d=0!==i,l=c;const p=Kp(l);n.onOutput(zp(p)),n.onOutput(Wp(p,i,d)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=Kp(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(zp(t)),n.onOutput(Wp(t,1,!0)),n.onComplete(1),a(1)})})}const Xp=Oe(import.meta.url);class Jp{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="idle";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 Xp.warn("Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void Xp.warn("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),Xp.debug(`message.enqueued id=${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();Xp.debug(`message.processing id=${e.id} type=${e.type}`),await this.processMessage(e),Xp.debug(`message.dispatched id=${e.id} type=${e.type}`)}catch(e){Xp.error(`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:Xp.warn(`Unknown message type: ${e.type}`)}}async processNormalMessage(e){Xp.debug("message.dispatching_to_agent_queue type=normal");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){Xp.info(`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){Xp.info("Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){Xp.info("Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){Xp.info("Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processAgentrixDevInit(e){Xp.info("Processing agentrix-dev-init command"),await this.processCommand(async()=>{await(this.config.handlers.onAgentrixDevInit?.(e.originalMessage))},e)}async processPlanMode(e){Xp.info("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");Xp.debug("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.workerState=e,Xp.info(`worker.state.changed from=${t} to=${e} activeAgents=${this.agentRunningMap.size} backgroundTasks=${this.backgroundTaskMap.size+this.anonymousBackgroundTaskCount}`),"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,Xp.debug(`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,Xp.debug(`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,Xp.debug(`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)Xp.warn("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||(Xp.info(`worker.idle_timer.started timeoutMs=${this.idleTimeoutMs}`),this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(Xp.info(`worker.stop.requested reason=idle_timeout source=coordinator timeoutMs=${this.idleTimeoutMs}`),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.isStopped?Xp.debug("coordinator.stop.ignored alreadyStopped=true"):(Xp.info("coordinator.stop requested=true"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait())}}function Yp(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(Rd,n)}async function Qp(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 go(t),s=await ao(t),d=await async function(e,t){const n=Xi(e);try{return(await n.log([`origin/${t}..HEAD`])).total>0}catch{return!0}}(t,e);if(s||d){if(!r)throw new Error("merge-pr requires user input to resolve git state, which is not supported in oneshot execution mode");const p=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,d,c,o);if("Pause"===p)return void Yp(n,"Operation paused. Please handle git state and run merge again.");if(("Push"===p||"PushAndMerge"===p)&&(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 Hp(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===p))return void Yp(n,"✅ All changes pushed to remote. You can now review and run merge again if everything looks good.")}const p=await n.sendMergePr();if(p.success)Yp(n,`✅ PR merged successfully! Branch ${e} has been merged into the target branch.`);else{let e;switch(p.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: ${p.error||"Unknown error"}`;break;default:e=`Failed to merge PR: ${p.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.")}async function Zp(e,t,n){let s=!1;const a=e.updates??{};if(Object.prototype.hasOwnProperty.call(a,"model")){const e=a.model,n="string"==typeof e&&e.trim().length>0?e.trim():null===e?void 0:t.model;t.model!==n&&(n?t.model=n:delete t.model,s=!0)}const i={},o=a.repositoryId;"string"==typeof o&&o.length>0&&t.repositoryId!==o&&(t.repositoryId=o,i.taskRepositoryId=o,s=!0);const r=a.branchName;"string"==typeof r&&r.length>0&&t.branchName!==r&&(t.branchName=r,i.branchName=r,s=!0);const c=a.branchBinding;return"none"!==c&&"explicit"!==c&&"platform-managed"!==c&&"external-observed"!==c||t.branchBinding===c||(t.branchBinding=c,i.branchBinding=c,s=!0),Object.keys(i).length>0&&n&&await n.updateTaskMetadata(i),s}function eu(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 tu(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:Se(),session_id:e.sessionId}}function nu(e,t){const n=Se();return t.set(e,n),n}function su(e,t){return t.get(e)||e}function au(e,t,n={}){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"error"===e.type?iu(e.message):"event_msg"===e.type?function(e){const t=e.payload??e.msg;if(!t)return null;switch(t.type){case"thread_goal_updated":return function(e){if(!e)return null;const t=[`Codex goal update: ${e.status??"unknown"}`];if(e.objective?.trim()&&t.push(`Objective: ${e.objective.trim()}`),"number"==typeof e.tokensUsed){const n="number"==typeof e.tokenBudget?` / ${e.tokenBudget}`:"";t.push(`Tokens used: ${e.tokensUsed}${n}`)}return"number"==typeof e.timeUsedSeconds&&t.push(`Time used: ${e.timeUsedSeconds}s`),iu(t.join("\n"))}(t.goal);case"thread_goal_cleared":return iu("Codex goal cleared");default:return null}}(e):"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:nu(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:nu(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 lu(e,nu(e.id,t))}(e,t);case"web_search":return function(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:nu(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"collab_tool_call":return function(e,t){return ou(e,nu(e.id,t))}(e,t);default:return null}}(e.item,t):"item.updated"===e.type?function(e){switch(e.type){case"collab_tool_call":return function(e){return{type:"system",subtype:"temporary",content:cu(e,"Subagent update")}}(e);case"todo_list":return mu(e);default:return null}}(e.item):"item.completed"===e.type?function(e,t,n){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:Se().toString()}}(e);case"reasoning":case"plan":default:return null;case"command_execution":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:su(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??nu(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,n){const s=t.get(e.id),a=s??nu(e.id,t),i=!s,o="failed"===e.status&&e.error,r=o?e.error.message:function(e,t){const n=e.result?.content||"";if(!t.taskDataDir||"get_window_state"!==(s=e.tool)&&"screenshot"!==s&&!s.endsWith("__get_window_state")&&!s.endsWith("__screenshot"))return n;var s;if(!Array.isArray(n)){const s=du(n,t.taskDataDir);if(s!==n)return[s];const a=pu(e,t.taskDataDir);return a?[n,a]:n}const a=n.map(e=>du(e,t.taskDataDir)),i=pu(e,t.taskDataDir);return i?[...a,i]:a}(e,n),c={type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:a,is_error:o,content:r}]},parent_tool_use_id:null,session_id:""};return i?[lu(e,a),c]:c}(e,t,n);case"web_search":return function(e,t){return{type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:su(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"collab_tool_call":return function(e,t){const n=t.get(e.id),s=n??nu(e.id,t),a=!n,i={type:"user",message:{role:"user",content:[{type:"tool_result",tool_use_id:s,is_error:"failed"===e.status,content:cu(e,"Subagent action completed")}]},parent_tool_use_id:null,session_id:""};return a?[ou(e,s),i]:i}(e,t);case"todo_list":return mu(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,n):null}function iu(e){return{type:"system",subtype:"temporary",content:e}}function ou(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:t,name:"Subagent",input:{action:e.tool,sender_thread_id:e.sender_thread_id,receiver_thread_ids:e.receiver_thread_ids,prompt:e.prompt??void 0,agents:ru(e)}}]},parent_tool_use_id:null,session_id:""}}function ru(e){const t=e.agents_states;return t&&Object.keys(t).length>0?t:void 0}function cu(e,t){const n=[`${t}: ${e.tool} (${e.status})`,`Sender: ${e.sender_thread_id}`];e.receiver_thread_ids.length>0&&n.push(`Receivers: ${e.receiver_thread_ids.join(", ")}`),e.prompt?.trim()&&n.push(`Prompt: ${e.prompt.trim()}`);const s=Object.entries(e.agents_states??{}).map(([e,t])=>{const n=t.message?.trim();return n?`- ${e}: ${t.status} - ${n}`:`- ${e}: ${t.status}`});return s.length>0&&n.push("Agents:",...s),n.join("\n")}function lu(e,t){return{type:"assistant",message:{role:"assistant",content:[{type:"tool_use",id:t,server_name:e.server,name:e.tool,input:e.arguments}]},parent_tool_use_id:null,session_id:""}}function du(e,t){const n=function(e){if("object"!=typeof e||null===e)return null;const t=e,n=t.data,s=n&&"object"==typeof n?n:void 0,a="string"==typeof t.mimeType?t.mimeType:"string"==typeof t.mime_type?t.mime_type:"string"==typeof s?.mimeType?s.mimeType:"string"==typeof s?.mime_type?s.mime_type:"image/png";if(!a.startsWith("image/"))return null;const i="string"==typeof t.base64String?t.base64String:"string"==typeof t.base64_string?t.base64_string:"string"==typeof s?.base64String?s.base64String:"string"==typeof s?.base64_string?s.base64_string:"string"==typeof n?n:void 0;return i?{base64:uu(i),mimeType:a}:null}(e);if(!n)return e;try{const e=E(t,"attachments");d(e,{recursive:!0});const s=function(e){switch(e.toLowerCase()){case"image/jpeg":case"image/jpg":return".jpg";case"image/webp":return".webp";case"image/gif":return".gif";default:return".png"}}(n.mimeType),a=E(e,`${Se()}${s}`);return u(a,Buffer.from(n.base64,"base64")),{type:"text",text:`Image file: ${a}\nType: ${n.mimeType}`}}catch(e){return{type:"text",text:`[Image unavailable: failed to save tool result image: ${e instanceof Error?e.message:String(e)}]`}}}function pu(e,t){const n=function(e){const t=e.arguments,n=t?.screenshot_out_file;return"string"==typeof n&&n.trim()?n.trim():null}(e);if(!n||!r(n))return null;try{const e=E(t,"attachments");d(e,{recursive:!0});const s=function(e){const t=M(e).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(t)?".jpeg"===t?".jpg":t:".png"}(n),a=function(e){switch(e.toLowerCase()){case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";default:return"image/png"}}(s),i=E(e,`${Se()}${s}`);return T(n,i),{type:"text",text:`Image file: ${i}\nType: ${a}`}}catch(e){return{type:"text",text:`[Image unavailable: failed to copy screenshot_out_file: ${e instanceof Error?e.message:String(e)}]`}}}function uu(e){const t=e.match(/^data:[^;]+;base64,(.*)$/s);return t?t[1]:e}function mu(e){return function(e){const t=e.todos.map(e=>{const t=e.content.trim();if(!t)return null;const n={content:t,activeForm:e.activeForm?.trim()||t,status:e.status};return e.id&&(n.id=e.id),n}).filter(e=>null!==e);if(0===t.length)return null;const n={type:"system",subtype:"todolist",source:e.source,todos:t,updatedAt:(new Date).toISOString()};return e.title&&(n.title=e.title),n}({source:"codex_todo_list",title:"Todo List",todos:e.items.map(e=>({id:e.id,content:e.text,activeForm:e.text,status:e.completed?"completed":"pending"}))})}let hu,gu,fu;function yu(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 vu(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 wu(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||E(n.homedir(),".codex");return E(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(gu===e&&void 0!==hu)return hu;if(gu=e,hu=null,!r(e))return hu;let t;try{t=c(e,"utf8")}catch{return hu}for(const e of t.split(/\r?\n/)){const t=yu(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=vu(n[1])?.trim();return hu=s||null,hu}return hu}()}const bu=ht(import.meta.url),ku="CODEX_INTERNAL_ORIGINATOR_OVERRIDE",xu={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};function Iu(){if(void 0!==fu)return fu??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return fu=e,e;fu=null}function Su(e){try{return p(e).isDirectory()}catch{return!1}}function Tu(...e){return e.filter(Su)}function Cu(){if("darwin"===process.platform&&"arm64"===process.arch)return"aarch64-apple-darwin";if("darwin"===process.platform&&"x64"===process.arch)return"x86_64-apple-darwin";if("linux"===process.platform&&"arm64"===process.arch)return"aarch64-unknown-linux-musl";if("linux"===process.platform&&"x64"===process.arch)return"x86_64-unknown-linux-musl";if("win32"===process.platform&&"arm64"===process.arch)return"aarch64-pc-windows-msvc";if("win32"===process.platform&&"x64"===process.arch)return"x86_64-pc-windows-msvc";throw new Error(`Unsupported Codex app-server target: ${process.platform} (${process.arch})`)}function _u(e){return"win32"!==process.platform?"PATH":Object.keys(e).find(e=>"path"===e.toLowerCase())??"PATH"}function Au(e){const t=e.config?.developer_instructions;return"string"==typeof t&&t.trim()?t:null}function Eu(e,t){const n=function(e){const t={...e.config??{}};return e.baseUrl&&(t.openai_base_url=e.baseUrl),Object.keys(t).length>0?t:null}(e.codexOptions),s={cwd:e.cwd,model:e.model??null,approvalPolicy:"never",sandbox:"danger-full-access",config:n,developerInstructions:Au(e.codexOptions)};return t&&(s.ephemeral=!1,s.threadSource="agentrix"),s}class $u{constructor(e){this.options=e}child=null;rl=null;nextRequestId=1;pending=new Map;notificationQueue=[];notificationWaiter=null;stderrChunks=[];closing=!1;closed=!1;async start(){if(this.child)return;const e=function(){const e=Iu();if(e)return{executablePath:e,pathDirs:[]};try{const e=bu.resolve("@openai/codex/package.json"),t=ht(e).resolve(`${function(){if("darwin"===process.platform&&"arm64"===process.arch)return"@openai/codex-darwin-arm64";if("darwin"===process.platform&&"x64"===process.arch)return"@openai/codex-darwin-x64";if("linux"===process.platform&&"arm64"===process.arch)return"@openai/codex-linux-arm64";if("linux"===process.platform&&"x64"===process.arch)return"@openai/codex-linux-x64";if("win32"===process.platform&&"arm64"===process.arch)return"@openai/codex-win32-arm64";if("win32"===process.platform&&"x64"===process.arch)return"@openai/codex-win32-x64";throw new Error(`Unsupported Codex app-server platform: ${process.platform} (${process.arch})`)}()}/package.json`),n=E(D(t),"vendor"),s="win32"===process.platform?"codex.exe":"codex",a=[{executablePath:E(n,Cu(),"bin",s),pathDirs:Tu(E(n,Cu(),"codex-path"))},{executablePath:E(n,Cu(),"codex",s),pathDirs:Tu(E(n,Cu(),"path"))}].find(e=>function(e){try{return p(e).isFile()}catch{return!1}}(e.executablePath));if(a)return a}catch{}return{executablePath:"codex",pathDirs:[]}}(),t=function(e,t){const n={};if(e.env)Object.assign(n,e.env);else for(const[e,t]of Object.entries(process.env))void 0!==t&&(n[e]=t);n[ku]||(n[ku]="codex_sdk_ts");const s=_u(n);return!n[s]&&process.env[s]&&(n[s]=process.env[s]),e.apiKey&&(n.CODEX_API_KEY=e.apiKey),function(e,t){if(0===t.length)return;const n=_u(e),s=(e[n]??"").split(j).filter(e=>e&&!t.includes(e));e[n]=[...t,...s].join(j)}(n,t),n}(this.options.codexOptions,e.pathDirs),n=Ct(e.executablePath,["app-server","--listen","stdio://"],{env:t});this.child=n,n.stderr.on("data",e=>{this.stderrChunks.push(e),this.options.stderr?.(e.toString("utf8"))}),n.once("error",e=>this.failAll(e)),n.once("exit",(e,t)=>{if(this.closed=!0,this.notificationWaiter){const e=this.notificationWaiter;this.notificationWaiter=null,e(null)}if(this.closing||0===e&&!t)this.failAll(new Error("Codex app-server closed"));else{const n=t?`signal ${t}`:`code ${e??1}`,s=Buffer.concat(this.stderrChunks).toString("utf8");this.failAll(new Error(`Codex app-server exited with ${n}: ${s}`))}}),this.rl=He.createInterface({input:n.stdout,crlfDelay:1/0}),this.readStdout(),await this.request("initialize",{clientInfo:{name:"agentrix",title:"Agentrix",version:"0.47.0"},capabilities:{experimentalApi:!0}}),this.notify("initialized",{})}async request(e,t){if(!this.child||this.closed)throw new Error("Codex app-server is not running");const n=this.nextRequestId++,s=JSON.stringify({id:n,method:e,params:t}),a=new Promise((e,t)=>{this.pending.set(n,{resolve:e,reject:t})});return this.child.stdin.write(`${s}\n`),a}notify(e,t){if(!this.child||this.closed)throw new Error("Codex app-server is not running");this.child.stdin.write(`${JSON.stringify({method:e,params:t})}\n`)}async nextNotification(){return this.notificationQueue.length>0?this.notificationQueue.shift()??null:this.closed?null:new Promise(e=>{this.notificationWaiter=e})}close(){if(this.closing=!0,this.rl?.close(),this.child?.kill(),this.child=null,this.closed=!0,this.notificationWaiter){const e=this.notificationWaiter;this.notificationWaiter=null,e(null)}this.failAll(new Error("Codex app-server closed"))}async readStdout(){if(this.rl)try{for await(const e of this.rl)e.trim()&&this.handleMessage(JSON.parse(e))}catch(e){this.failAll(e instanceof Error?e:new Error(String(e)))}}handleMessage(e){if(void 0!==e.id&&this.pending.has(e.id)){const t=this.pending.get(e.id);return this.pending.delete(e.id),void(e.error?t.reject(new Error(e.error.message||`Codex app-server request ${e.id} failed`)):t.resolve(e.result))}if(e.method&&void 0!==e.id)this.child?.stdin.write(JSON.stringify({id:e.id,error:{code:-32601,message:`Unsupported app-server request: ${e.method}`}})+"\n");else if(e.method){const t={method:e.method,params:e.params};if(this.notificationWaiter){const e=this.notificationWaiter;this.notificationWaiter=null,e(t)}else this.notificationQueue.push(t)}}failAll(e){for(const t of this.pending.values())t.reject(e);this.pending.clear()}}class Mu{constructor(e,t,n,s={}){this.client=e,this.options=n,this.adapterOptions=s,this.sessionId=t}sessionId;threadLoaded=!1;activeTurn=null;lastCompletedTurn=null;goalMayContinue=!1;lastUsage=xu;turnCount=0;itemState=new Map;toolIdMap=new Map;idMapper={get:e=>this.toolIdMap.get(e),set:(e,t)=>{this.toolIdMap.set(e,t)}};get currentThreadId(){return this.sessionId}get turnsCompleted(){return this.turnCount}setModel(e){this.options.model=e}async ensureThread(){if(this.sessionId)return this.threadLoaded||(await this.client.request("thread/resume",{threadId:this.sessionId,...Eu(this.options,!1)}),this.threadLoaded=!0),{sessionId:this.sessionId,isNew:!1};const e=await this.client.request("thread/start",Eu(this.options,!0)),t=e?.thread?.id;if(!t)throw new Error("Codex app-server did not return a thread id");return this.sessionId=t,this.threadLoaded=!0,{sessionId:t,isNew:!0}}async*runTurn(e,t){const{sessionId:n,isNew:s}=await this.ensureThread();for(s&&(yield{type:"sdk",message:tu({sessionId:n,cwd:this.options.cwd,model:this.options.model??void 0})}),await this.client.request("turn/start",function(e,t,n,s){return{threadId:e,input:[{type:"text",text:t,text_elements:[]}],cwd:n.cwd,approvalPolicy:"never",model:n.model??null,outputSchema:s??null}}(n,e,this.options,t));;){const e=await this.client.nextNotification();if(!e)return;if(!this.isThreadNotification(e,n))continue;const t=this.convertNotification(e);for(const e of t)yield{type:"sdk",message:e};if(this.lastCompletedTurn&&this.shouldFinishCompletedTurn(e))return void(yield this.consumeCompletedTurnResult(n))}}consumeCompletedTurnResult(e){const t=this.lastCompletedTurn;return this.lastCompletedTurn=null,this.emitStatePatch({activeTurn:null}),{type:"result",result:{sessionId:e,finalResponse:t.finalResponse,usage:this.lastUsage,durationMs:Date.now()-t.startedAt}}}isThreadNotification(e,t){const n=e.params?.threadId??e.params?.thread?.id;return!n||n===t}convertNotification(e){switch(e.method){case"thread/started":default:return[];case"thread/goal/updated":return this.goalMayContinue=function(e){if("string"!=typeof e)return!1;const t=e.toLowerCase().replace(/[-\s]/g,"_");return"active"===t||"running"===t||"in_progress"===t}(e.params?.goal?.status),this.emitStatePatch({goal:e.params?.goal??null}),this.adaptEvent({type:"event_msg",payload:{type:"thread_goal_updated",goal:e.params?.goal}});case"thread/goal/cleared":return this.goalMayContinue=!1,this.emitStatePatch({goal:null}),this.adaptEvent({type:"event_msg",payload:{type:"thread_goal_cleared"}});case"thread/tokenUsage/updated":return this.lastUsage=function(e){const t=e?.last??e?.total??e;return{input_tokens:Number(t?.inputTokens??t?.input_tokens??0),cached_input_tokens:Number(t?.cachedInputTokens??t?.cached_input_tokens??0),output_tokens:Number(t?.outputTokens??t?.output_tokens??0),reasoning_output_tokens:Number(t?.reasoningOutputTokens??t?.reasoning_output_tokens??0)}}(e.params?.tokenUsage),this.emitStatePatch({tokenUsage:e.params?.tokenUsage??null}),this.adaptEvent({type:"event_msg",payload:{type:"thread_token_usage_updated",tokenUsage:e.params?.tokenUsage}});case"turn/started":return this.lastCompletedTurn=null,this.activeTurn={turnId:e.params?.turn?.id??e.params?.turnId??"",startedAt:Date.now(),finalResponse:""},this.emitStatePatch({activeTurn:{id:this.activeTurn.turnId,status:"in_progress",startedAt:new Date(this.activeTurn.startedAt).toISOString()}}),[];case"turn/completed":{const t=e.params?.turn,n=t?.id??this.activeTurn?.turnId??"",s=this.activeTurn?.startedAt??Date.now(),a="string"==typeof t?.status?t.status:"completed",i=this.findFinalResponse(t?.items)??this.activeTurn?.finalResponse??"";if(this.activeTurn=null,this.emitStatePatch({activeTurn:{id:n,status:a}}),"failed"===a||"interrupted"===a){this.lastCompletedTurn=null;const e="interrupted"===a?"Codex app-server turn interrupted":"Codex app-server turn failed";throw new Error(t?.error?.message??e)}return this.turnCount+=1,this.lastCompletedTurn={turnId:n,startedAt:s,finalResponse:i},[]}case"error":return this.adaptEvent({type:"error",message:e.params?.error?.message??e.params?.error??"Codex app-server error"});case"item/started":case"item/completed":return this.convertItemNotification(e);case"item/agentMessage/delta":case"item/commandExecution/outputDelta":case"item/fileChange/outputDelta":case"item/fileChange/patchUpdated":case"item/plan/delta":return this.convertItemDeltaNotification(e);case"turn/plan/updated":return this.convertTurnPlanUpdated(e)}}convertItemNotification(e){const t=this.normalizeAppServerItem(e.params?.item);return t?(this.itemState.set(t.id,t),"agent_message"===t.type&&"item/completed"===e.method&&t.text&&this.activeTurn&&(this.activeTurn.finalResponse=t.text),this.adaptEvent({type:"item/started"===e.method?"item.started":"item.completed",item:t})):[]}convertItemDeltaNotification(e){const t=e.params?.itemId;if(!t)return[];const n=this.itemState.get(t);return n?("item/agentMessage/delta"===e.method?(n.text=`${n.text??""}${e.params?.delta??""}`,this.activeTurn&&(this.activeTurn.finalResponse=n.text)):"item/commandExecution/outputDelta"===e.method?n.aggregated_output=`${n.aggregated_output??""}${e.params?.delta??""}`:"item/fileChange/patchUpdated"===e.method?n.changes=e.params?.changes??n.changes??[]:"item/plan/delta"===e.method&&(n.text=`${n.text??""}${e.params?.delta??""}`),this.itemState.set(t,n),this.adaptEvent({type:"item.updated",item:n})):[]}convertTurnPlanUpdated(e){return function(e){if(!Array.isArray(e))return[];const t=e.map(e=>{const t=String(e?.step??e?.text??"").trim();return t?{content:t,activeForm:t,status:(n=e?.status,"completed"===n?"completed":"inProgress"===n||"in_progress"===n?"in_progress":"pending")}:null;var n}).filter(e=>null!==e);return 0===t.length?[]:[{type:"system",subtype:"todolist",source:"codex_plan",title:"Plan",todos:t,updatedAt:(new Date).toISOString()}]}(e.params?.plan)}normalizeAppServerItem(e){if(!e||"object"!=typeof e||"string"!=typeof e.id)return null;switch(e.type){case"agentMessage":return{id:e.id,type:"agent_message",text:e.text??""};case"plan":return{id:e.id,type:"plan",text:e.text??""};case"reasoning":return{id:e.id,type:"reasoning",text:[...e.summary??[],...e.content??[]].join("\n")};case"commandExecution":return{id:e.id,type:"command_execution",command:e.command??"",aggregated_output:e.aggregatedOutput??"",exit_code:e.exitCode??void 0,status:this.normalizeStatus(e.status)};case"fileChange":return{id:e.id,type:"file_change",changes:e.changes??[],status:e.status??"completed"};case"mcpToolCall":return{id:e.id,type:"mcp_tool_call",server:e.server??"",tool:e.tool??"",arguments:e.arguments,result:e.result,error:e.error,status:this.normalizeStatus(e.status)};case"dynamicToolCall":return{id:e.id,type:"mcp_tool_call",server:e.namespace??"dynamic",tool:e.tool??"",arguments:e.arguments,result:e.contentItems?{content:e.contentItems,structured_content:e.contentItems}:void 0,error:!1===e.success?{message:"Dynamic tool call failed"}:void 0,status:this.normalizeStatus(e.status)};case"collabAgentToolCall":return{id:e.id,type:"collab_tool_call",tool:this.normalizeCollabTool(e.tool),sender_thread_id:e.senderThreadId,receiver_thread_ids:e.receiverThreadIds??[],prompt:e.prompt,agents_states:e.agentsStates??{},status:this.normalizeStatus(e.status)};case"webSearch":return{id:e.id,type:"web_search",query:e.query??""};case"subAgentActivity":return{id:e.id,type:"collab_tool_call",tool:"interrupted"===e.kind?"close_agent":"spawn_agent",sender_thread_id:this.sessionId??"",receiver_thread_ids:[e.agentThreadId].filter(Boolean),prompt:e.agentPath??null,agents_states:e.agentThreadId?{[e.agentThreadId]:{status:"interrupted"===e.kind?"interrupted":"running"}}:{},status:"interrupted"===e.kind?"failed":"in_progress"};default:return null}}normalizeStatus(e){return"inProgress"===e?"in_progress":"succeeded"===e?"completed":"string"==typeof e?e:"completed"}normalizeCollabTool(e){switch(e){case"spawnAgent":return"spawn_agent";case"sendInput":case"resumeAgent":return"send_input";case"closeAgent":return"close_agent";default:return"string"==typeof e?e:"wait"}}findFinalResponse(e){if(!Array.isArray(e))return null;const t=e.filter(e=>"agentMessage"===e?.type&&"string"==typeof e.text);return t.at(-1)?.text??null}adaptEvent(e){const t=au(e,this.idMapper,this.adapterOptions);return t?Array.isArray(t)?t:[t]:[]}shouldFinishCompletedTurn(e){return"thread/status/changed"===e.method&&"idle"===e.params?.status?.type||"thread/goal/cleared"===e.method||"thread/goal/updated"===e.method&&!this.goalMayContinue||"turn/completed"===e.method&&!this.goalMayContinue}emitStatePatch(e){this.sessionId&&this.options.onStatePatch&&this.options.onStatePatch({threadId:this.sessionId,...e})}}class Pu{createCodexOptions(e){const t={},n=Iu();n&&(t.codexPathOverride=n),e.env&&(t.env=ri(e.env));const s=function(e){const t=[];e.modeConfig.supportChangeTitle&&e.codexAgentrixEventMcp&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Wa({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.titleToolName})),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.previewToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(za({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.previewToolName})),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.sendVisionArtifactToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Xa({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.sendVisionArtifactToolName}));const n=e.projectAgentrixGuidance?.systemPromptAppend?.trim();return n&&t.push(n),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),t}getAgentConfiguration(){return null}getHooks(){}getMcpServers(){}async executeHook(e,t,n){}async run(e,t){let n=null;for await(const s of this.runStreamed(e,t))"result"===s.type&&(n=s);if(!n)throw new Error("Codex app-server did not produce a result message");return n}async*runStreamed(e,t){const n=t.abortController,s=this.createCodexOptions(t),a=wu(t.model),i=new $u({codexOptions:s,stderr:t.stderr}),o=()=>i.close();n.signal.addEventListener("abort",o,{once:!0});try{await i.start();const n=new Mu(i,t.agentSessionId??null,{cwd:t.cwd,model:a??void 0,codexOptions:s,onStatePatch:t.onCodexAppServerState},{taskDataDir:t.taskDataDir});for await(const s of n.runTurn("string"==typeof e?e:di(e),t.structuredOutputSchema?.schema||void 0))"sdk"===s.type?yield s.message:yield pi({sessionId:s.result.sessionId,model:a??"unknown",numTurns:n.turnsCompleted,usage:s.result.usage,result:s.result.finalResponse,structuredOutput:ui(s.result.finalResponse,Boolean(t.structuredOutputSchema)),durationMs:s.result.durationMs})}finally{n.signal.removeEventListener("abort",o),i.close()}}loop(e){const t=e.abortController,n=this.createCodexOptions(e);let s=e.model;const a=()=>wu(e.getModel?e.getModel():s)??void 0;let i=a(),o=!1;const r=[];let c=null,l=e.agentSessionId??null;const d=()=>{if(!o&&(o=!0,c)){const e=c;c=null,e(null)}},p=e=>"string"==typeof e?e:di(e),u=async function*(){const s=new $u({codexOptions:n,stderr:e.stderr}),u=()=>s.close();t.signal.addEventListener("abort",u,{once:!0});try{await s.start();const d=new Mu(s,l,{cwd:e.cwd,model:i??void 0,codexOptions:n,onStatePatch:e.onCodexAppServerState},{taskDataDir:e.taskDataDir});for(;!o&&!t.signal.aborted;){const t=r.length>0?r.shift():await new Promise(e=>{c=e});if(!t)break;const n=a();n!==i&&(i=n),d.setModel(i??void 0);for await(const n of d.runTurn(p(t),e.structuredOutputSchema?.schema||void 0)){if(o)break;if("sdk"===n.type){const e=n.message;"system"===e.type&&"init"===e.subtype&&e.session_id&&(l=e.session_id),yield n.message;continue}l=n.result.sessionId,yield pi({sessionId:l,model:i??"unknown",numTurns:d.turnsCompleted,usage:n.result.usage,result:n.result.finalResponse,structuredOutput:ui(n.result.finalResponse,Boolean(e.structuredOutputSchema)),durationMs:n.result.durationMs})}}}finally{t.signal.removeEventListener("abort",u),s.close(),d()}}();return t.signal.addEventListener("abort",d,{once:!0}),{push:e=>{if(!o){if(c){const t=c;return c=null,void t(e)}r.push(e)}},events:u,stop:d,setModel:async e=>{s=e,i=wu(e)??void 0}}}}let Ru;class Du{createCodex(e){const t={},n=function(){if(void 0!==Ru)return Ru??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return Ru=e,e;Ru=null}();n&&(t.codexPathOverride=n),e.env&&(t.env=ri(e.env));const s=function(e){const t=[];e.modeConfig.supportChangeTitle&&e.codexAgentrixEventMcp&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Wa({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.titleToolName})),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.previewToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(za({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.previewToolName})),e.codexAgentrixEventMcp&&e.codexAgentrixEventMcp.sendVisionArtifactToolName&&("work"===e.modeConfig.mode||"group_work"===e.modeConfig.mode)&&t.push(Xa({serverName:e.codexAgentrixEventMcp.serverName,toolName:e.codexAgentrixEventMcp.sendVisionArtifactToolName}));const n=e.projectAgentrixGuidance?.systemPromptAppend?.trim();return n&&t.push(n),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 Mn(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=wu(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=Date.now(),c=await o.run("string"==typeof e?e:di(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0}),l=Date.now()-r;return pi({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:c.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:c.finalResponse??"",structuredOutput:ui(c.finalResponse??"",Boolean(t.structuredOutputSchema)),durationMs:l})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=wu(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=Date.now(),{events:c}=await o.runStreamed("string"==typeof e?e:di(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let l=t.agentSessionId||"",d="",p={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const u=new Map,m={get:e=>u.get(e),set:(e,t)=>{u.set(e,t)}};for await(const e of c){if("thread.started"===e.type&&(l=e.thread_id,yield tu({sessionId:l,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);"item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(d=e.item.text);const n=e,s=n.type;if("error"===s||"event_msg"===s||"item.started"===s||"item.updated"===s||"item.completed"===s){const e=au(n,m,{taskDataDir:t.taskDataDir});if(!e)continue;const s=Array.isArray(e)?e:[e];for(const e of s)yield e}}const h=pi({sessionId:l,model:a??"unknown",numTurns:1,usage:p,result:d,structuredOutput:ui(d,Boolean(t.structuredOutputSchema)),durationMs:Date.now()-r});yield h}loop(e){const t=e.abortController,n=this.createCodex(e),s={workingDirectory:e.cwd,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let a=e.model;const i=()=>wu(e.getModel?e.getModel():a)??void 0;let o=i(),r=e.agentSessionId?n.resumeThread(e.agentSessionId,{...s,model:o??void 0}):n.startThread({...s,model:o??void 0}),c=!1;const l=[];let d=null,p=e.agentSessionId??null,u=0;const m=()=>{if(!c&&(c=!0,d)){const e=d;d=null,e(null)}},h=e=>"string"==typeof e?e:di(e),g=async function*(){try{for(;!c&&!t.signal.aborted;){const a=l.length>0?l.shift():await new Promise(e=>{d=e});if(!a)break;let m="";const g=i();g!==o&&(o=g),p&&(r=n.resumeThread(p,{...s,model:o??void 0}));const f=new Map,y={get:e=>f.get(e),set:(e,t)=>{f.set(e,t)}},v=Date.now(),{events:w}=await r.runStreamed(h(a),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of w){if(c)break;if("thread.started"===t.type){p=t.thread_id,yield tu({sessionId:p,cwd:e.cwd,model:o??void 0});continue}if("turn.completed"===t.type){p&&(yield pi({sessionId:p,model:o??"unknown",numTurns:u+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:m,structuredOutput:ui(m,Boolean(e.structuredOutputSchema)),durationMs:Date.now()-v}));break}if("turn.failed"===t.type)throw new Error(t.error.message);const n=t,s=n.type;if("error"===s||"event_msg"===s||"item.started"===s||"item.updated"===s||"item.completed"===s){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(m=t.item.text);const s=au(n,y,{taskDataDir:e.taskDataDir});if(!s)continue;const a=Array.isArray(s)?s:[s];for(const e of a)yield e}}u+=1}}finally{m()}}();return t.signal.addEventListener("abort",m,{once:!0}),{push:e=>{if(!c){if(d){const t=d;return d=null,void t(e)}l.push(e)}},events:g,stop:m,setModel:async e=>{a=e,o=wu(e)??void 0}}}}const Nu="AGENTRIX_CODEX_USE_LEGACY_SDK";class Ou{appServerRunner=new Pu;sdkRunner=new Du;selectRunner(e){return function(e){return t=e?.env?.[Nu]??process.env[Nu],["1","true","yes","on"].includes((t??"").trim().toLowerCase());var t}(e)?this.sdkRunner:this.appServerRunner}getAgentConfiguration(){return null}getHooks(){}getMcpServers(){}async executeHook(e,t,n){}run(e,t){return this.selectRunner(t).run(e,t)}runStreamed(e,t){return this.selectRunner(t).runStreamed(e,t)}loop(e){return this.selectRunner(e).loop(e)}}const Uu=new Function("specifier","return import(specifier)");function ju(e){return Uu(e)}const Lu=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification"];function qu(e){const t={};for(const n of Lu){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}const Hu=Oe(import.meta.url);class Fu{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}=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{Bi.info(`Loading agent: ${t}`);const e=await Nt({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return Bi.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 s=e.claude,a=s.plugins.map(e=>({type:"local",path:e})),i=n||Ot().resolveAgentDir(t),o=s.config.sdkMcpTools?.map(e=>E(i,"claude",e)),r={customSystemPrompt:s.systemPrompt,customModel:s.config.model,customFallbackModel:s.config.fallbackModel,customMaxTurns:s.config.maxTurns,customExtraArgs:s.config.extraArgs,customPermissionMode:s.config.settings?.permissionMode,customPlugins:a,systemPromptMode:s.config.systemPrompt?.mode??"append",customPRPromptTemplate:s.prPromptTemplate,prPromptMode:s.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:o};return Bi.info(`Agent ${t} loaded successfully (${a.length} plugins)`),r}catch{return Bi.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});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=he(),a=t||s.resolveAgentDir(e),i=E(a,"claude");return await async function(e,t){const n=it(e,"hooks");if(!We(n))return{};const s=[it(n,"dist","index.mjs"),it(n,"dist","index.js"),it(n,"index.mjs"),it(n,"index.js")];let a=null;for(const e of s)if(We(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] ${it(n,"index.js")} or ${it(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${an(a).href}?t=${Date.now()}`,n=await ju(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),qu(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return qu(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){const n={};for(const s of e)try{Hu.info(`Loading SDK MCP tools from: ${s}`);const e=await ju(s),a=e.default||e;if(!a){Hu.warn(`No default export found in ${s}`);continue}const i="function"==typeof a?a(t):a,o=i.name;n[o]=i,Hu.info(`Loaded MCP server: ${o}`)}catch(e){const t=e instanceof Error?e.message:String(e);Hu.error(`Failed to load SDK MCP tools from ${s}: ${t}`)}return n}(s.customSdkMcpTools,n.context)),a=new Fi(t,e,s,i,o)}else a=new Ou;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class Bu{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=st.join(this.workingDirectory,e);return Be.existsSync(t)?Be.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=st.join(this.workingDirectory,e);return Be.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=Be.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?fe.includes(o.name)||this.listFilesRecursively(st.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class Gu{constructor(e){this.params=e}state=null;persistedState=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=Me.getWorkspaceState(n,s),o=e.repositorySourceType,r="string"==typeof e.branchName&&e.branchName.length>0,c="string"==typeof i?.branchName&&i.branchName.length>0,l={...e,repositorySourceType:o,taskRepositoryId:e.taskRepositoryId??i?.taskRepositoryId,headRef:e.headRef??i?.headRef,headSha:e.headSha??i?.headSha,checkoutRef:e.checkoutRef??i?.checkoutRef,checkoutSha:e.checkoutSha??i?.checkoutSha,branchName:r?e.branchName:c?i.branchName:e.branchName,branchBinding:r?e.branchBinding:c?i.branchBinding:e.branchBinding},{initialCommitHash:d,isGitRepository:p,setupAction:u,useWorktree:m,initPolicyUpdates:h}=await this.ensureWorkspace(l,t,i),g={initialized:!0,initializedAt:(new Date).toISOString(),cwd:a,repositorySourceType:l.repositorySourceType,useWorktree:m,userCwd:e.userCwd,forceUserCwd:e.forceUserCwd,gitUrl:e.gitUrl,baseBranch:e.baseBranch,headRef:e.headRef??i?.headRef,headSha:e.headSha??i?.headSha,checkoutRef:e.checkoutRef??i?.checkoutRef,checkoutSha:e.checkoutSha??i?.checkoutSha,branchName:l.branchName,branchBinding:l.branchBinding,taskRepositoryId:l.taskRepositoryId,initialCommitHash:d,initPolicies:{...i?.initPolicies,...e.initPolicies,...h}};await Me.writeWorkspaceState(n,s,g),this.persistedState=g;const f=await async function(e,t,n,s){return async function(e,t,n,s){if(!await Ji(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await ao(e),i=await io(e),o=s||Me.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await ho(e,o),c=r?await Fp(t,n,r.patch):void 0,l=await Me.readLastSentArtifactVersion(t,n),d=!!r&&r.artifactVersion!==l;return{currentCommitHash:i,currentArtifactVersion:r?.artifactVersion,hadUncommittedChanges:a,hasNewArtifacts:d,lastSentArtifactVersion:l??void 0,patchPath:c,diffStats:r?.stats}}(e,t,n,s)}(a,n,s,d);return this.state={cwd:a,initialCommitHash:d,isGitRepository:p,setupAction:u,gitStateResult:f,taskRepositoryId:g.taskRepositoryId,branchName:g.branchName,branchBinding:g.branchBinding},p&&!e.taskRepositoryId&&await async function(e,t){try{const n=await ko(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 updateBranchBinding(e,t){await this.updateTaskMetadata({branchName:e,branchBinding:t})}async updateTaskMetadata(e){if(!this.state||!this.persistedState)throw new Error("[WORKSPACE] Workspace not initialized");const{userId:t,taskId:n}=this.params.options,s={...this.persistedState};"taskRepositoryId"in e&&(s.taskRepositoryId=e.taskRepositoryId),"branchName"in e&&(s.branchName=e.branchName),"branchBinding"in e&&(s.branchBinding=e.branchBinding),this.persistedState=s,await Me.writeWorkspaceState(t,n,s);const a={...this.state};"taskRepositoryId"in e&&(a.taskRepositoryId=e.taskRepositoryId),"branchName"in e&&(a.branchName=e.branchName),"branchBinding"in e&&(a.branchBinding=e.branchBinding),this.state=a}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 ho(t,n);if(!o)return{};try{await Fp(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new Bu(e);return ge(t)}(t),c=await Me.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,gitServerId:c}=e;if(!a)throw new Error("[WORKSPACE] gitUrl is required for git-server mode");const l=Ap(e)?e.branchName:void 0,d=e.forceUserCwd||!1===e.useWorktree,p="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await Ji(s),m=ro(s);if(d)return this.ensureDirectGitServerWorkspace(e,t,n,u,m);if(Boolean(e.taskRepositoryId&&c)&&(!u||p)){const i=await async function(e,t,n,s,a,i,o={}){const c=Cp(e)||e,l=yo(n),d=bo(l);if(!d)throw new Error(`Unable to resolve repository owner/name from git URL: ${l}`);const p=Me.resolveRepoStoreCheckoutDir(s,d.owner,d.repo),u=Me.resolveRepoStoreLockPath(s,d.owner,d.repo),m=await Me.acquireFileLock(u);if(!m)throw new Error(`Timed out waiting for repo store lock at ${u}`);try{const e=await async function(e,t,n,s){const a=yo(t);if(!await Ji(e)){if(!ro(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await eo(e)}await vo(e,"origin",a),await Np(e,t,n);const i=await wo(e),o=Op(i,s);return await async function(e,t,n){await Vi("git",["checkout","--force","-B",t,n],{cwd:e,windowsHide:!0}),await Vi("git",["reset","--hard",n],{cwd:e,windowsHide:!0}),await Vi("git",["clean","-fd"],{cwd:e,windowsHide:!0})}(e,o,`origin/${o}`),{baseBranch:o,remoteBranches:i}}(p,n,s,a),t={...o,baseBranch:e.baseBranch},l=jp(t,e.remoteBranches);await Lp(p,l,t);const d=i,u=await Yi(p);if(u.find(e=>Cp(e.path)===c))return s&&await Dp(c,s),{initialCommitHash:await io(c)};const m=d?u.find(e=>e.branch===d&&Cp(e.path)!==c):void 0;if(d&&m)throw new Error(`Branch ${d} is already attached to worktree ${m.path}. Remove it before retrying.`);const h=en(p),g=await h.branchLocal(),f=!!d&&g.all.includes(d);if(r(c)&&!ro(c))throw new Error(`Worktree directory already exists at ${c}. This may be from a previous task. To clean up: git worktree remove ${c} OR rm -rf ${c}`);try{d?f?await h.raw(["worktree","add",c,d]):await Qi(p,c,d,l):await h.raw(["worktree","add","--detach",c,l])}catch(e){try{await Zi(p,c,!0)}catch{}throw e}return await Dp(c,s),{initialCommitHash:await io(c)}}finally{await Me.releaseFileLock(u,m)}}(s,0,a,c,o,l,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha});return u?{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}:{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,i.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 t=await qp(s,a,0,o,c,l,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha})||await io(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await fo(s,"origin",yo(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,gitServerId:l}=e;if(!o)throw new Error("[WORKSPACE] gitUrl is required for git-server direct directory mode");const d=Ap(e)?e.branchName:void 0;if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const t=await qp(i,o,0,c,l,d,{checkoutRef:e.checkoutRef,checkoutSha:e.checkoutSha,headRef:e.headRef,headSha:e.headSha})||await io(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"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=bo(yo(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${yo(t)}`);const s=await ko(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 Ji(s))return this.tryResolveDirtyRepo(e,t,n);if(!ro(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(ro(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await Ji(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await oo(t)||await to(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=Cp(t)||t;if(!await Ji(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await oo(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=s;if((await Yi(i)).find(e=>Cp(e.path)===o))return{initialCommitHash:await io(o)};const l=en(i),d=await l.branchLocal(),p=!!c&&d.all.includes(c);if(r(o)&&!ro(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{c?p?await l.raw(["worktree","add",o,c]):await Qi(i,o,c,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await Zi(i,o,!0)}catch{}throw e}return{initialCommitHash:await io(o)}}(t,s,0,Ap(e)?e.branchName:void 0)}return{...await this.tryResolveDirtyRepo(e,t,n),setupAction:"reuse",useWorktree:!0}}async ensureTemporaryWorkspace(e,t,n){const{cwd:s}=e;if(!await Ji(s)){await async function(e){return{initialCommitHash:await async function(e){return await eo(e),await to(e),await io(e)}(e)}}(s),Ap(e)&&e.branchName&&await so(s,e.branchName,e.baseBranch);const t=await io(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,t,"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 Ji(e)&&await ao(e)}(e.cwd)){const s=this.getPersistedInitPolicy(n,e,"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}:Me.shouldPromptOnUncommittedChanges()&&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=Xi(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;await oo(e.cwd)||await to(e.cwd),r=Ap(e)?"Ignore"===a?await go(e.cwd)===e.branchName?"none":"kept":await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch"):"none";const c=await io(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,s){const a=e?.initPolicies?.[n]??t.initPolicies?.[n];return a&&s.includes(a)?a:null}resolveInitialCommitHash(e,t,n){return e?"kept"===n?t:e:t}async tryResolveBranchMismatch(e,t,n,s,a){if(!Ap(e)||!e.branchName)return"none";const i=e.branchName,o=await go(e.cwd);if(o===i)return"none";const r=this.getPersistedInitPolicy(n,e,"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 so(e.cwd,i,e.baseBranch),"switched")}}const Wu=kt.object({title:kt.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:kt.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:kt.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),zu=xt(Wu,{target:"draft-07"}),Ku=xt(Wu);function Vu(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?Wu.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=Xu(e),n=JSON.parse(t);return Wu.parse(n)}(t.result??"")}function Xu(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class Ju{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const Yu=[{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 Qu(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function Zu(e=[]){const t=[],n=new Set;for(const e of Yu.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(Qu).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 em=kt.object({message:kt.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),tm=xt(em,{target:"draft-07"}),nm=xt(em);async function sm(e){if(!await ao(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await io(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,env:e.env,disableClaudePlanModeTools:e.disableClaudePlanModeTools,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?tm:nm}});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?em.parse(t.structured_output):em.parse(JSON.parse(Xu(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=Xi(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 io(e)}(e.workingDirectory,n);if(await ao(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 am(e){if(e)return{type:"json_schema",schema:e}}async function im(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=A.join(e,s.name),a=A.join(t,s.name);s.isDirectory()?await im(n,a):await o.promises.copyFile(n,a)}}function om(e){return"oneshot"===function(e){return e.workerExecutionMode??ye}(e)}async function rm(e){const t=E(e,".agentrix"),n=E(t,"prompt.md"),s=E(t,"plugins"),[a,i]=await Promise.all([cm(n),lm(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function cm(e){try{if(!(await C.stat(e)).isFile())return;const t=(await C.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(dm(e))return;throw e}}async function lm(e){let t;try{t=await C.readdir(e,{withFileTypes:!0})}catch(e){if(dm(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=E(e,s.name),a=E(t,".claude-plugin","plugin.json");try{(await C.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(dm(e))continue;throw e}}return n}function dm(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}function pm(e){const t=e,n=ve({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}function um(e){if(!e)return!1;const t=E(e,".agentrix","vision");try{return r(t)&&p(t).isDirectory()}catch{return!1}}function mm(e){const t=e?.trim();if(t)return t.replace(/\/+$/,"")}async function hm(e){const t=await async function(e){const t=function(e){if(!e)return null;try{const t=new URL(e),n=decodeURIComponent(t.username),s=decodeURIComponent(t.password);if(t.host.toLowerCase(),"x-access-token"===n&&s)return s}catch{return null}return null}(e.gitUrl);if(t)return{GITHUB_TOKEN:t,GH_TOKEN:t};if(!e.gitServerId)return{};const n=await Qo();if(!n)return{};const s=sr(e.gitServerId,n);if(!s)return{};const a=Zo(e.gitServerId);return function(e,t,n){return{GITLAB_TOKEN:e,...t?{GITLAB_BASE_URL:t,CI_SERVER_URL:t}:{},...n?{GITLAB_API_URL:n}:{}}}(s,mm(a?.baseUrl),mm(a?.apiUrl))}(e);for(const[e,n]of Object.entries(t))process.env[e]=n;return t}function gm(e,t,n){if(null==n)return;const s=String(n);0!==s.length&&(e[t]=s)}function fm(e,t){const n={},s=e.machineId??t.machineId;return gm(n,"AGENTRIX_TASK_ID",e.taskId),gm(n,"AGENTRIX_USER_ID",e.userId),gm(n,"AGENTRIX_AGENT_ID",e.agentId),gm(n,"AGENTRIX_AGENT_TYPE",e.agentType),gm(n,"AGENTRIX_CHAT_ID",e.chatId),gm(n,"AGENTRIX_MACHINE_ID",s),gm(n,"AGENTRIX_CLOUD_ID",e.cloudId),gm(n,"AGENTRIX_ROOT_TASK_ID",e.rootTaskId),gm(n,"AGENTRIX_PARENT_TASK_ID",e.parentTaskId),gm(n,"AGENTRIX_TASK_TYPE",e.taskType),gm(n,"AGENTRIX_WORKSPACE_ID",e.workspaceId),gm(n,"AGENTRIX_WORKING_DIR",t.workingDirectory),gm(n,"AGENTRIX_BASE_REF",e.baseBranch),gm(n,"AGENTRIX_HEAD_REF",e.headRef),gm(n,"AGENTRIX_HEAD_SHA",e.headSha),gm(n,"AGENTRIX_CHECKOUT_REF",e.checkoutRef),gm(n,"AGENTRIX_CHECKOUT_SHA",e.checkoutSha),gm(n,"AGENTRIX_TASK_BRANCH",e.branchName),gm(n,"AGENTRIX_TASK_BRANCH_BINDING",e.branchBinding),gm(n,"AGENTRIX_WORKING_USER",e.userId),gm(n,"AGENTRIX_WORKING_TASK",e.taskId),n}function ym(e,t){if(e.environmentVariables)for(const[t,n]of Object.entries(e.environmentVariables))null!=n&&(process.env[t]=String(n));Object.assign(process.env,fm(e,t))}function vm(e,t){const n={};if(t.baseEnv)for(const[e,s]of Object.entries(t.baseEnv))"string"==typeof s&&(n[e]=s);return{...n,...fm(e,t)}}const wm=Oe(import.meta.url),bm=Symbol("companionHeartbeatContext"),km=Symbol("companionMemoryOrganizationContext");class xm{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=qe(),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=Me.resolveDataDir(i,a);this.historyDb=Bo({dataDir:l,taskId:a}),this.workClient=new Dd(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new qd({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:Me.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:Me.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const d={..._p(this.options.input),cwd:this.workingDirectory};this.workspace=new Gu({options:d,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=Bd();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;loopModelSetter=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 om(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=re(t);return!!we(t)||!!be(t)||!!ke(t)||!(!ce(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)){wm.info("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!(!ce(t)||"user"!==t.type)&&"![plan]"===di(t).trim()}deduplicateHeartbeats(e){let t=-1;for(let n=e.length-1;n>=0;n--)we(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(!ce(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=Ul(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)}clearRuntimeInputMetadata(e){delete e.__localSequence,delete e.__isChannelInput,delete e.__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(we(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionHeartbeatPrompt(e)},parent_tool_use_id:null,session_id:""};return n[bm]=e,n}if(ke(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:""}}if(be(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionMemoryOrganizationPrompt(e)},parent_tool_use_id:null,session_id:""};return n[km]=e,n}return ce(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")}buildCompanionMemoryOrganizationPrompt(e){const t=this.options.input,n=[`trigger: ${e.trigger}`,`timestamp: ${e.timestamp}`,e.triggerTime?`local trigger time: ${e.triggerTime}`:void 0,"number"==typeof e.intervalHours?`configured interval hours: ${e.intervalHours}`:void 0,`current worker taskId: ${t.taskId}`,t.chatId?`companion chatId: ${t.chatId}`:void 0].filter(e=>Boolean(e));return wm.info(`Memory organization input received: trigger=${e.trigger}, timestamp=${e.timestamp}, intervalHours=${e.intervalHours??"unset"}, taskId=${t.taskId}`),["[memory organization] You are being awakened for Companion memory organization.",...n.map(e=>`- ${e}`),"","Use the available conversation, task, and history tools to gather the current signals needed for this memory organization run. Follow the memory organization mode instructions from your system prompt and MEMORY_ORGANIZATION.md."].join("\n")}extractCompanionPromptPlaceholders(e){const t=e[km];return t?(delete e[km],{COMPANION_SHADOW_TASK:"memory_organization",COMPANION_MEMORY_ORGANIZATION_TRIGGER:t.trigger,COMPANION_MEMORY_ORGANIZATION_TIMESTAMP:t.timestamp,COMPANION_MEMORY_ORGANIZATION_INTERVAL_HOURS:"number"==typeof t.intervalHours?String(t.intervalHours):""}):e[bm]?(delete e[bm],{COMPANION_SHADOW_TASK:"heartbeat"}):void 0}async prepareMessageForRunner(e){return il(e,{attachmentsDir:Me.resolveAttachmentsDir(this.options.input.userId,this.taskId)})}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 Rt)){e="error",wm.warn("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{wm.info(`Auto-installing agent ${e} from git`),await Ha({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){wm.warn(`Auto-install failed for agent ${e}: ${t}`)}else wm.warn(`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=Me.agentrixAgentsHomeDir,a=E(s,`${e}.new`),i=E(s,`${e}-bak`);try{wm.info(`Applying upgrade for ${e}`),Fa(n),m(n,a),await im(t,i),h(t,{recursive:!0,force:!0}),m(a,t),We(i)&&h(i,{recursive:!0,force:!0}),wm.info(`Upgrade applied for ${e}`)}catch(n){wm.warn(`Upgrade failed for ${e}: ${n}`),!We(t)&&We(i)&&m(i,t),We(a)&&h(a,{recursive:!0,force:!0})}}async initialize(){const e=this.options.input,t="filesystem"===e.agentSource;let n=null;const s=e.agentDir??Me.resolveAgentDir(e.agentId,this.workingDirectory);Boolean(t&&"git-server"===e.repositorySourceType&&!e.agentDir&&!We(E(s,"agent.json")))&&(n=await this.workspace.setup());const a=e.agentDir??Me.resolveAgentDir(e.agentId,this.workingDirectory),i=E(a,"upgrade"),o=Boolean(a)&&Boolean(e.agentGitUrl)&&!t,r=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&o&&!We(a)),c=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!t&&!r&&We(i));if(await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:r,upgradingAgent:c}),r&&await this.autoInstallAgent(e.agentId),t&&"default"!==e.agentId&&!We(E(a,"agent.json")))throw new Error(`Filesystem agent not found: ${e.agentId} (${a})`);c&&await this.applyAgentUpgrade(e.agentId,a,i),wm.info(`Resolved agent ${e.agentId}: ${a}`);const l=await Fu.create(e.agentType,e.agentId,{agentDir:a,context:this.agentContext});this.runner=l,this.initializePermissionModeState(),n??=await this.workspace.setup(),this.projectAgentrixGuidance=await rm(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),wm.info(`Prepared ${this.options.input.repositorySourceType} workspace via ${n.setupAction} at ${this.workingDirectory} (${n.initialCommitHash||"none"})`),await this.setEnvironmentVariables(),this.lastProcessedSequence=this.historyDb.getAgentLastSequences().get(this.primaryAgentId)??0,wm.info(`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(Zu())}createWorkspaceHandlers(e){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: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)},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 Fn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?wm.warn(`Failed to report session ${t}:`,n.error):wm.info(`Session ${t} registered`)}async setEnvironmentVariables(){ym(this.options.input,{workingDirectory:this.workingDirectory,machineId:this.credentials.machineId}),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),await hm(this.options.input)}buildClaudeRunEnvironment(){return vm(this.options.input,{workingDirectory:this.workingDirectory,machineId:this.credentials.machineId,baseEnv:process.env})}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new Jp({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 Gn(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)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}sendCurrentWorkerStatus(){const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning(this.coordinator.getActiveAgents()):"idle"===e&&this.workClient.sendWorkerReady()}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=Hd(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=Fd(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}if("task-message"===e){const e=t;if(e.message){const t=Md(e,e.message,{source:"startup"});t&&wm.info(t)}}if(this.isOneShotExecution())await this.processPendingMessages(),this.coordinator.hasAgentMessages()||this.isStopping||this.stopTask("oneshot_complete");else{if("task-message"===e){const n=t,s=n.message;s&&be(s)&&this.historyDb.saveMessage({eventId:n.eventId,message:s,senderType:n.senderType,senderId:n.senderId,senderName:n.senderName}).inserted&&this.historyDb.saveTaskEvent({eventType:e,eventId:n.eventId,eventData:n,taskId:this.taskId,chatId:n.chatId??this.options.input.chatId,sequence:n.sequence??null})}this.triggerMessageProcessing()}"task-message"===e&&t?.eventId&&this.workClient.sendEventAck(t.eventId)}async executeMergeRequest(){wm.info("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 wm.warn("No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await ao(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await io(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return wm.error(e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await lo(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=this.workspace.getState(),o=i.branchName?{branchName:i.branchName,branchBinding:i.branchBinding}:this.options.input,r=Ap(o),c=r?Ep(this.options.input.taskId,o.branchName):void 0;if(r&&c){const e=await go(this.workingDirectory);if(e!==c){const t=Pp(e,c);return wm.warn(t),void this.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}const l=this.runner?.getAgentConfiguration(),d=Gp(a,(l?.customPRPromptTemplate?(n=l.customPRPromptTemplate,s={initialCommitHash:a,currentCommitHash:e,branchName:c??"to-be-generated-from-pr-title"},n.replace(/\{\{initialCommitHash\}\}/g,s.initialCommitHash).replace(/\{\{currentCommitHash\}\}/g,s.currentCommitHash).replace(/\{\{branchName\}\}/g,s.branchName)):void 0)??void 0);wm.debug(`PR prompt: ${d.substring(0,200)}...`);const p=this.runner;let u=null;const m=p.runStreamed(d,{cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:zu}});for await(const e of m){if(this.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){u=e;break}const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}if(!u)throw new Error("Merge-request did not return a result message");if("success"!==u.subtype)throw new Error("Merge-request did not return a successful result message");const h=Vu(u),g=Ep(this.options.input.taskId,c,h.title);r||await $p(this.workingDirectory,g);const f=Mp(g);wm.info(`Pushing HEAD to remote branch ${g}`),await Hp(this.workingDirectory,f,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),wm.info("Successfully pushed branch to remote");const y=await this.workClient.sendMergeRequest(h.title,h.description,g);"explicit"!==o.branchBinding&&await this.workspace.updateBranchBinding(g,"platform-managed");const v=`${h.userMessage}\n\n✅ Pull request created successfully!\nNumber: #${y.pullRequestNumber}\nURL: ${y.pullRequestUrl}`,w={input_tokens:u.usage.input_tokens??0,cached_input_tokens:u.usage.cache_read_input_tokens??0,output_tokens:u.usage.output_tokens??0,reasoning_output_tokens:0};this.workClient.sendTaskMessage(this.getChatSenderMeta(),pi({sessionId:u.session_id,model:this.options.input.model??"unknown",numTurns:u.num_turns,usage:w,result:v}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);wm.error("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(!Me.isDirectBashAllowed())return wm.warn("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});wm.info(`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await Vp(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{wm.info(`Command completed with exit code: ${e}`)}});wm.info(`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await Qp({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(){wm.info("Generating commit message with agent"),await sm({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),env:this.buildClaudeRunEnvironment(),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})}}),wm.info("Committed changes with agent-generated message")}async executeNewSession(){wm.info("Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),wm.info("Session reset sent, stopping task for clean restart"),this.stopTask("event")}isAgentrixDevOpsInitWorker(){return this.options.input.agentId===ol}async maybeConfirmAgentrixDevOpsInit(){if(!this.isAgentrixDevOpsInitWorker())return!0;const e=ll(this.options.input),t=(await this.askUser([dl(e)],{onTimeout:"abort_task"})).answers[0]??"";return("zh-Hans"===e?"先初始化"===t:"Initialize first"===t)||(await Bn(this.taskId,this.options.input.userId,"continue"),!1)}getAgentrixExtraTools(){if(this.isAgentrixDevOpsInitWorker())return[Pt("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:kt.string().describe("Short user-visible summary of what initialization completed")},async e=>{const t=ll(this.options.input),n=await this.askUser([pl(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(wm.info(`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 Bn(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(wm.info(`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void wm.info(`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=>{wm.debug(e)},modeConfig:n,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.workingDirectory),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.loopModelSetter=o.setModel??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);const t=e.__localSequence;if(void 0!==t&&this.markPrimaryMessageProcessed(t),Boolean(e.__isChannelInput)){const t=e.__channelReplyTarget;this.pendingChannelReplies.push({target:this.isChannelReplyTarget(t)?t:null,channelMessageInvocationCountAtStart:this.channelMessageInvocationCount})}this.clearRuntimeInputMetadata(e),o.push(await this.prepareMessageForRunner(e)),delete e.__isChannelInput,delete e.__channelReplyTarget}}catch(e){wm.error("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(),wm.info(`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.loopModelSetter=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 wm.info(`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&this.markPrimaryMessageProcessed(o),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.extractCompanionPromptPlaceholders(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=>{wm.debug(e)},modeConfig:t,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.workingDirectory),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(),wm.info(`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(Zu(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.loopModelSetter=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",wm.info("One-shot execution completed, stopping task")),"idle"===e?wm.info("Idle timeout reached, stopping task"):"ask_user_timeout"===e&&wm.info("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 wm.warn("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 wm.warn(`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 wm.info(`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return wm.info(`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;wm.info(`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 nt.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 wm.warn(`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 eu(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:")?(wm.info(`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 wm.warn(`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:")?(wm.info(`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 wm.warn(`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 am(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=Me.resolveDataDir(t,e);this.chatHistoryDb=Bo({dataDir:n,taskId:e})}return{createTask:Zd(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),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,workingDirectory:this.workingDirectory}),createSoloTask:ep(t),createGroupTask:tp(t),replyToSubTask:Xd(t),changeTaskTitle:zd(t),publishTaskPreviewUrl:Kd(t),sendVisionArtifact:Vd(t),askUser:np(t),getTaskHistory:Jd(t),getTaskAgents:Yd(t),listSubTask:Qd(t),invoke:sp(t),assign:ip(t),updateAgentInfo:ap(t),sendReminder:cp(t),recordMemoryChange:dp(t),listTasks:op(t),readConversation:rp(t),uploadFile:pp(t),sendChannelMessage:hp(t),getChannelGroupHistory:gp(t),listAgents:yp(t),analyzeImage:wp(t),scheduleTask:Pt("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:kt.enum(["create","list","delete"]).describe("Operation to perform"),task:kt.string().optional().describe("Task description (required for create)"),type:kt.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:kt.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:kt.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:kt.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:kt.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:kt.string().optional().describe("Task ID (required for delete)")},async e=>{try{const t=await Me.readDaemonState();if(!t?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${t.port}`;if("list"===e.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"===e.action){if(!e.task||!e.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const t=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:e.task,type:e.type,due:e.due,cron:e.cron,timezone:e.timezone,timeType:e.timeType})}),s=await t.json();if(!t.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"===e.action){if(!e.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const t=await fetch(`${n}/schedule/${e.id}`,{method:"DELETE"}),s=await t.json();return t.ok?{content:[{type:"text",text:`Deleted: ${e.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${e.action}`}],isError:!0}}catch(e){return Gd.error("Schedule task failed:",e),{content:[{type:"text",text:`Failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}}),prepareHiveRepository:bp(t),publishToHive:kp(t),updateHiveListingVersion:xp(t),recordHiveInstall:Ip(t),createHiveReview:Sp(t),createHiveComment:Tp(t),computerUse:Wd(t)};var t}isComputerUseEnabled(){try{return hc().enabled}catch(e){return wm.warn(`Failed to evaluate Agentrix Computer Use enablement: ${e instanceof Error?e.message:String(e)}`),!1}}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 Ju,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 Fu.create(a,e,{context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),d=this.buildSystemHooks({trackBackgroundTasks:!1}),p=Bd(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.workingDirectory),allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,channelBound:this.isChannelBoundTask(),channelGroupBound:this.isChannelGroupBoundTask(),channelContext:this.getExternalChannelPromptContext(),canUseTool:l,hooks:d,maxTurns:this.options.input.maxTurns??void 0,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});let m=n.message;if("codex"===a&&!n.sessionId){const t=[oi(e,i),"=== CONVERSATION STREAM START FROM HERE ===",di(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:p.filter(n);s&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},s,{groupId:t})}}catch(t){wm.error(`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 Ju,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 Fu.create(a,e,{context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),d=Bd(),p=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,env:this.buildClaudeRunEnvironment(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.workingDirectory),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()});p.push(t);let u=!1;for await(const t of p.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:d.filter(t);n&&this.workClient.sendTaskEvent({senderType:"agent",senderId:e,senderName:o},n,{groupId:s})}}catch(t){wm.error(`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 wm.warn("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=jl(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 wm.debug("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 wm.debug(`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),wm.info(`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),wm.info(`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&&wm.warn(`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:Me.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:xe(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:X(),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}},handlers:{attachmentsDir:Me.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!we(e)||!this.shouldDropHeartbeatWhileBusy()||(wm.debug("Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(re(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{const t=this.options.input.model;await Zp(e,this.options.input,this.workspace),t!==this.options.input.model&&Object.prototype.hasOwnProperty.call(e.updates??{},"model")&&(wm.info(`Task model updated from ${t??"default"} to ${this.options.input.model??"default"}; applying to subsequent Claude responses`),await(this.loopModelSetter?.(this.options.input.model)))},onReconnect:async()=>{this.sendCurrentWorkerStatus()},onWorkerStatusRequest:async()=>{this.sendCurrentWorkerStatus()},onSubTaskResultUpdated:async e=>{const t=Hd(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=Fd(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){wm.info(`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})}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{wm.warn("Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){wm.warn("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 Bp(this.options.input.userId,this.taskId,n)}catch(e){wm.warn("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 Wn(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&&wm.debug(`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){wm.debug("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 Im{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>Cp(e)||e;if(n)return l(n);const d=Me.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return await this.assertUsableUserCwd(e),e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.assertUsableUserCwd(e),await this.shouldUseWorktree(e)?l(d):e}return l(d)}static async shouldUseWorktree(e){try{return!ro(e)&&await Ji(e)}catch{return!1}}static async assertUsableUserCwd(e){let t;try{t=await Yt(e)}catch{throw new Error(`Workspace directory is unavailable: ${e}. Restore or relink the workspace before starting a filesystem task.`)}if(!t.isDirectory())throw new Error(`Workspace path is not a directory: ${e}`);try{await Qt(e,x.R_OK|x.W_OK)}catch{throw new Error(`Workspace directory is not readable and writable: ${e}. Restore permissions before starting a filesystem task.`)}}}const Sm=Oe(import.meta.url);class Tm{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;currentTurnComplete=null;workerStartedAt=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return om(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${Se()}`}beginCurrentTurn(){return this.finishCurrentTurn(),new Promise(e=>{this.currentTurnComplete=()=>{this.currentTurnComplete=null,e()}})}finishCurrentTurn(){const e=this.currentTurnComplete;e&&e()}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(),Sm.warn("Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}Sm.info(`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,n=Date.now();this.workerStartedAt=n,this.logger=qe(),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const s=_p(this.options.input),a=await Im.calculateFinalCwd(s),i={...s,cwd:a};Sm.debug(`Phase 1: Working directory: ${a}`);const o=1e3*Math.max(0,this.options.idleTimeoutSecond??0);Sm.info([`worker.start taskId=${e}`,"workerType=codex",`agentId=${this.options.input.agentId??"unknown"}`,`cwd=${a}`,`repositorySourceType=${this.options.input.repositorySourceType??"unknown"}`,"sandboxMode=danger-full-access",`idleTimeoutMs=${o}`].join(" "));const r=this.createWorkerClientConfig(t,e,a),c=Me.resolveDataDir(t,e);this.historyDb=Bo({dataDir:c,taskId:e});const l=new Dd(r.config,{...r.handlers,historyDb:this.historyDb});this.workClient=l,Sm.debug("Phase 2: WorkerClient created"),this.coordinator=this.createMessageCoordinator(l,o),Sm.debug("Phase 3: Coordinator created");const d=Date.now();await l.connect();const p=Date.now()-d;l.sendWorkerInitializing(),Sm.debug("Phase 4: Connected to server"),Sm.debug("Phase 5: Skipped (no AgentContext for Codex)"),Sm.debug("Phase 6: Skipped (no custom resources for Codex)");const u=new Gu({options:i,handlers:this.createWorkspaceHandlers(l,a)}),m=Date.now(),{initialCommitHash:h,gitStateResult:g,setupAction:f,branchName:y}=await u.setup(),v=Date.now()-m;this.workspace=u,this.projectAgentrixGuidance=await rm(a),Sm.debug("Phase 7: Workspace setup complete"),Sm.info([`workspace.ready action=${f}`,`cwd=${a}`,`branch=${y??"unknown"}`,`commit=${h||"none"}`,`repositorySourceType=${this.options.input.repositorySourceType??"unknown"}`,`workspaceMs=${v}`,`hadUncommittedChanges=${Boolean(g?.hadUncommittedChanges)}`].join(" ")),l.sendWorkerInitialized(),l.sendTaskSlashCommandsUpdate(Zu()),Sm.debug("Phase 8: Initialization finalized");const w=Date.now();await this.registerWithDaemon(a);const b=Date.now()-w;Sm.debug("Phase 9: Registered with daemon"),Sm.debug(`Prepared ${this.options.input.repositorySourceType} workspace via ${f} at ${a} (${h||"none"})`),Sm.info(["worker.init.completed totalMs="+(Date.now()-n),`connectMs=${p}`,`workspaceMs=${v}`,`daemonRegisterMs=${b}`,`cwd=${a}`,"workerType=codex",`model=${this.options.input.model??"auto"}`].join(" ")),this.context={credentials:this.credentials,options:this.options,workClient:l,workingDirectory:a,dataDir:c,initialCommitHash:h,logger:this.logger},ym(this.options.input,{workingDirectory:a,machineId:this.credentials.machineId}),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),await hm(this.options.input),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,Sm.info(`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 Fn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?Sm.warn(`Failed to report session ${t}:`,n.error):Sm.info(`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new Jp({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 Gn(this.taskId,this.options.input.userId),this.stopTask("event")}},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}sendCurrentWorkerStatus(){const e=this.workClient;if(!e||!this.coordinator)return;const{state:t}=this.coordinator.getStatus();"running"===t?e.sendWorkRunning(this.coordinator.getActiveAgents()):"idle"===t&&e.sendWorkerReady()}async handleEvent(){if("task-message"===this.options.input.event){const e=this.options.input.eventData,t=e.message;if(t){const n=Md(e,t,{source:"startup"});n&&Sm.info(n)}t&&ce(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e.eventId&&this.workClient?.sendEventAck(e.eventId))}}async executeMergeRequest(){this.refreshGroupId(),Sm.info("Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return Sm.warn("No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await ao(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await io(this.context.workingDirectory),t=this.context.initialCommitHash,n=this.workspace.getState(),s=n.branchName?{branchName:n.branchName,branchBinding:n.branchBinding}:this.options.input,a=Ap(s),i=a?Ep(this.options.input.taskId,s.branchName):void 0;if(a&&i){const e=await go(this.context.workingDirectory);if(e!==i){const t=Pp(e,i);return Sm.warn(t),void this.context.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}if(!t){const e="Cannot create PR: initial commit hash is missing.";return Sm.error(e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await lo(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 o=Gp(t);Sm.debug(`PR prompt: ${o.substring(0,200)}...`);const r=this.options.input.agentId??"default",c=await Fu.create("codex",r),l={mode:"work",supportChangeTitle:!1},d=c.runStreamed(o,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,abortController:this.abortController,modeConfig:l,env:this.buildCodexRunEnvironment(),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:Ku}});let p=null;for await(const e of d){if(this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),"result"===e.type){p=e;break}const t=this.filterMessages(e);null!==t&&this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}if(!p)throw new Error("Merge-request did not return a result message");const u=Vu(p),m=Ep(this.options.input.taskId,i,u.title);a||await $p(this.context.workingDirectory,m);const h=Mp(m);Sm.info(`Pushing HEAD to remote branch ${m}`),await Hp(this.context.workingDirectory,h,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),Sm.info("Successfully pushed branch to remote"),await this.createPullRequest(u.title,u.description,m),"explicit"!==s.branchBinding&&await this.workspace.updateBranchBinding(m,"platform-managed"),this.sendMessage(u.userMessage)}catch(e){const t=e instanceof Error?e.message:String(e);Sm.error("Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){Sm.info(`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!Me.isDirectBashAllowed())return Sm.warn("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});Sm.info(`Executing command: ${e}`);const t=await Vp(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{Sm.info(`Command completed with exit code: ${e}`)}});Sm.info(`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await Qp({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 Fu.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");Sm.info("Generating commit message with agent"),await sm({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},env:this.buildCodexRunEnvironment(),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})}}),Sm.info("Committed changes with agent-generated message")}async executeNewSession(){Sm.info("Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),Sm.info("Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return am(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 Me.readDaemonState();if(!Pe(e))return Sm.debug("Agentrix event MCP broker unavailable: daemon state not found"),null;const t=pm(this.options.input),n=um(this.context?.workingDirectory),s=function(e,t){const n={taskId:t.taskId,userId:t.userId,machineId:t.machineId??e.machineId,nonce:Ie(16).toString("base64url"),taskPreviewEnabled:t.taskPreviewEnabled,visionPlanEnabled:t.visionPlanEnabled},s=(a=JSON.stringify(n),Buffer.from(a,"utf8").toString("base64url"));var a;return`${s}.${jr(s,Ur(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId,taskPreviewEnabled:t,visionPlanEnabled:n});return{serverName:Fr,url:qn(e,Br),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:Gr,previewToolName:t?Wr:void 0,sendVisionArtifactToolName:n?zr:void 0,token:s}}buildCodexRunEnvironment(){const e=vm(this.options.input,{workingDirectory:this.context.workingDirectory,machineId:this.credentials.machineId,baseEnv:process.env});return this.codexAgentrixEventMcp&&(e[this.codexAgentrixEventMcp.tokenEnvVar]=this.codexAgentrixEventMcp.token),e}async runCodex(){Sm.info(`Starting Codex agent for task ${this.taskId}`),this.currentModel=wu(this.options.input.model),this.currentModel?Sm.info(`Using model: ${this.currentModel}`):Sm.info("Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await Fu.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void Sm.info(`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,getModel:()=>this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,onCodexAppServerState:this.persistCodexAppServerState,enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(!e){if(this.isStopping)break;continue}const t=this.beginCurrentTurn();this.refreshGroupId(),this.startAgentTurn(e),this.updateAgentRunning(!0),s.push(e),await t}}catch(e){Sm.error("Message pump failed:",e),this.stopTask("event")}})();try{for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e)}catch(e){throw this.logAgentTurnFailed(e),e}finally{this.finishCurrentTurn()}Sm.info(`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 Sm.info(`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId(),this.startAgentTurn(n);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,taskDataDir:this.context.dataDir,onCodexAppServerState:this.persistCodexAppServerState,enableTaskPreviewUrl:pm(this.options.input),enableVisionPlan:um(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});try{for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e)}catch(e){throw this.logAgentTurnFailed(e),e}this.isStopping||this.stopTask("oneshot_complete")}finally{Sm.info(`Codex oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e){if("system"===e.type&&"init"===e.subtype)return this.threadId=e.session_id,this.historyDb?.upsertAgentSession(this.options.input.agentId,e.session_id),this.context.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.context.workClient.sendTaskSlashCommandsUpdate(Zu(e.slash_commands??[]),e.session_id),Sm.debug(`Thread started: ${e.session_id}`),Sm.info(`agent.thread.started sessionId=${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);if(null!==t&&("result"===e.type?(this.logAgentTurnCompleted(e),await this.handleSdkResultMessage(t)):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"===e.type)return this.updateAgentRunning(!1),void this.finishCurrentTurn();this.updateAgentRunning(!0)}persistCodexAppServerState=e=>{this.threadId=e.threadId,this.historyDb?.updateAgentAppServerState(this.options.input.agentId,e.threadId,{...Object.prototype.hasOwnProperty.call(e,"activeTurn")?{activeTurn:e.activeTurn??null}:{},...Object.prototype.hasOwnProperty.call(e,"goal")?{goal:e.goal??null}:{},...Object.prototype.hasOwnProperty.call(e,"tokenUsage")?{tokenUsage:e.tokenUsage??null}:{}})};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!==Fr?!("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:Se().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:Se().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 eu(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}startAgentTurn(e){Sm.info([`agent.turn.started groupId=${this.currentGroupId??"none"}`,`model=${this.currentModel??this.options.input.model??"auto"}`,"session="+(this.threadId?"resume":"new"),`inputChars=${e.length}`].join(" "))}logAgentTurnCompleted(e){const t=e.usage;Sm.info([`agent.turn.completed sessionId=${e.session_id||this.threadId||"unknown"}`,`subtype=${e.subtype}`,`isError=${e.is_error}`,`durationMs=${e.duration_ms}`,`turns=${e.num_turns}`,`inputTokens=${t?.input_tokens??0}`,`outputTokens=${t?.output_tokens??0}`,`cacheRead=${t?.cache_read_input_tokens??0}`,`resultChars=${"success"===e.subtype?(e.result??"").length:0}`].join(" "))}logAgentTurnFailed(e){const t=e instanceof Error?e.message:String(e);Sm.warn([`agent.turn.failed sessionId=${this.threadId??"unknown"}`,`error=${JSON.stringify(t)}`].filter(Boolean).join(" "))}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:")?(Sm.info(`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 Sm.warn(`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:")?(Sm.info(`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 Sm.warn(`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t,n){Sm.info(`Creating PR: ${e}`);const s=await this.context.workClient.sendMergeRequest(e,t,n);this.sendMessage(`✅ Pull request created successfully!\nNumber: #${s.pullRequestNumber}\nURL: ${s.pullRequestUrl}`)}async convertSDKMessageToCodexInput(e){const t=e.message.content;if("string"==typeof t)return t;if(Array.isArray(t)){const e=[],n=Me.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 sl(t,n,!1);Sm.info(`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){Sm.error(`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 sl(t,n,!0);Sm.info(`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){Sm.error(`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",Sm.info("One-shot execution completed, stopping task")),"idle"===e?(this.exitReason="idle_timeout",Sm.info("worker.stop.requested reason=idle_timeout source=codex_worker")):"ask_user_timeout"===e&&(this.exitReason="ask_user_timeout",Sm.info("ask_user timed out, stopping task")),this.askUserAwaiter.clear(),this.coordinator?.stop(),this.finishCurrentTurn(),"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:Me.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:xe(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:X(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3}},handlers:{attachmentsDir:Me.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(re(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}ce(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{const t=this.options.input.model;await Zp(e,this.options.input,this.workspace),t!==this.options.input.model&&Object.prototype.hasOwnProperty.call(e.updates??{},"model")&&(this.currentModel=wu(this.options.input.model),Sm.info(`Task model updated from ${t??"default"} to ${this.options.input.model??"default"}; applying to subsequent Codex turns`))},onReconnect:async()=>{this.sendCurrentWorkerStatus()},onWorkerStatusRequest:async()=>{this.sendCurrentWorkerStatus()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),Sm.info(`worker.exit reason=${e} taskId=${this.taskId} totalMs=${this.workerStartedAt?Date.now()-this.workerStartedAt:"unknown"}`);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())}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=>{Sm.warn("Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){Sm.warn("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 Bp(this.options.input.userId,this.taskId,n)}catch(e){Sm.warn("Failed to mark artifact version as sent:",e)}}}function Cm(){const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(!e)return;if(e.includes("/")||e.includes("\\")||e.startsWith(".")){const t=A.isAbsolute(e)?e:A.resolve(e);return o.existsSync(t)?t:void 0}const t="win32"===process.platform?"where":"which",n=Tt(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 _m(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 Am(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(...Am(A.join(e,a.name),n)):s.push(n))}return s}async function Em(e,t,n){const s=Am(e).map(e=>` - ${e}`).join("\n");return new Promise((a,i)=>{let o=!1,r=null;const c=e=>{o||(o=!0,clearTimeout(d),a(e))},l=e=>{o||(o=!0,clearTimeout(d),i(e))},d=setTimeout(()=>{c({approved:!1,reasons:["Review timed out after 10 minutes"],tags:[]})},6e5),p=(u=e=>{r=e,c(e)},Pt("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:kt.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:kt.array(kt.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:kt.array(kt.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:_m(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=$t({name:"hive_review",version:"1.0.0",tools:[p]}),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=Mt({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:Cm(),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 $m=Zt(At);function Mm(e,t,n){const s=Me.serverUrl.replace(/^http/,"ws");return pt(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function Pm(e,...t){const{stdout:n}=await $m("git",t,{cwd:e});return n.trim()}function Rm(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const Dm=Zt(At);function Nm(e,t,n){const s=Me.serverUrl.replace(/^http/,"ws");return pt(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const Om=["claude","codex","deployment","companion","hive-publish","hive-install"],Um={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Me.readTaskInput(n,s),o=i.dataEncryptionKey?G(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=_p(t.input),s=await Im.calculateFinalCwd(n),a=new xm(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Me.readTaskInput(n,s),o=i.dataEncryptionKey?G(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 Tm(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:Me.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:d,supportLocal:p}=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=A.join(Me.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await im(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=Me.serverUrl.replace(/^http/,"ws");return pt(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:X(),taskId:s,targetAgentId:i,success:!0,name:c,avatar:l,isSystemAgent:d,supportLocal:p}),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:X(),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:Me.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 d,p,{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(A.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=A.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:Rm(r),displayName:r,description:c,readme:n,repoDirName:Rm(r)}}(r);m=e.name,h=e.displayName,g=e.description,f=e.readme,u=A.posix.join(u,e.repoDirName),console.log(`[HivePublish] Parsed skill metadata name=${m}, displayName=${h}`)}v=A.join(Me.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(v,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await Pm(v,"clone","--depth","1",c,".");const t=A.join(v,u);if(o.mkdirSync(A.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 im(r,t),o.writeFileSync(A.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await Pm(v,"add",".");const i=await async function(e){try{return await $m("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 Em(r,m,n.type);if(d=e.reasons,p=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 Pm(v,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await Pm(v,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const w=await Pm(v,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${w}`),y=Mm(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:X(),taskId:s,listingId:a,success:!0,gitCommitHash:w,hasChanges:i,tags:p,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??Mm(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{y.emit("hive-publish-complete",{eventId:X(),taskId:s,listingId:a,success:!1,error:t instanceof Error?t.message:String(t),reviewReasons:d}),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:Me.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,d=n.installDir??n.draftAgentDir;let p=null,u=null;try{console.log(`[HiveInstall] Starting for task ${s}, name=${c}`),u=A.join(Me.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 Dm("git",t,{cwd:e});return n.trim()}(u,"clone","--depth","1",r,".");const t=A.join(u,i);if(!o.existsSync(t))throw new Error(`Source directory not found in hive repo: ${i}`);if("skill"===l&&!o.existsSync(A.join(t,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${i}`);const n=(m=d).startsWith("~/")?A.join(process.env.HOME||"",m.slice(2)):A.isAbsolute(m)?m:A.join(Me.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 im(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),Fa(n)}catch(e){try{o.rmSync(n,{recursive:!0,force:!0})}catch{}throw e}const a=A.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"),p=Nm(e,0,s),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);p.on("connect",()=>{clearTimeout(a),p.emit("hive-install-complete",{eventId:X(),taskId:s,success:!0,agentDir:n}),console.log("[HiveInstall] Sent hive-install-complete (success)"),setTimeout(e,1e3)}),p.on("connect_error",e=>{clearTimeout(a),t(e)})})}catch(t){console.error("[HiveInstall] Failed:",t);try{p=p??Nm(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{p.emit("hive-install-complete",{eventId:X(),taskId:s,success:!1,error:t instanceof Error?t.message:String(t)}),clearTimeout(n),setTimeout(e,1e3)};p.connected?a():(p.on("connect",a),p.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HiveInstall] Failed to send error event")}throw t}finally{if(p&&p.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=Me.readTaskInput(n,s),o=i.dataEncryptionKey?G(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 Ho();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=_p(t.input),i=await Im.calculateFinalCwd(a),o=new xm(e,t,i);await o.start()}(e,r)}}};async function jm(e,t){const n=`${Me.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function Lm(e){try{const t=c(E(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function qm(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}function Hm(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 Fm(e,t){if(!Pn.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=Dn({input:Pn,output:Rn});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}function Bm(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function Gm(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function Wm(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||Me.serverUrl}function zm(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return k(E(t,e),x.X_OK),!0}catch{return!1}})}function Km(e,t,n){return new Promise((s,a)=>{const i=Ct(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 Vm(e){try{return await Qt(e),!0}catch{return!1}}function Xm(e){return e.filter(e=>e.required&&!e.installed)}async function Jm(e,t){zm(e)?console.log(H.green(`✓ ${e} is installed`)):zm("npm")?(console.log(H.blue(`Installing ${e} with npm...`)),await Km("npm",["install","-g",t])):console.log(H.yellow(`npm is not available. Install ${t} manually.`))}async function Ym(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function Qm(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 Zm(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(H.yellow("Invalid selection"))}}function eh(e){return JSON.stringify(e)}async function th(e,t){const n=await async function(e){try{return(await $e.get(`${Me.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||Wm()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(H.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),Wm()}}(t),s=Dn({input:Pn,output:Rn});try{await async function(e,t,n){const s=E(Me.claudeConfigDir,"settings.json");if(!t&&await Vm(s)&&!await Qm(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(H.gray("Skipped Claude config"));const a=await Zm(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(H.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await Ym(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await Ym(e,"Agentrix API key for Claude");else{const t=await Ym(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await Ym(e,"Anthropic auth token")}const o=await Ym(e,"Claude primary model","claude-sonnet-4-6"),r=await Ym(e,"Claude fast model","claude-haiku-4-5"),c=await Ym(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 Ft(Me.claudeConfigDir,{recursive:!0}),await Gt(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(H.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=E(Me.codexHomeDir,"config.toml");if(!t&&await Vm(s)&&!await Qm(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(H.gray("Skipped Codex config"));const a=await Zm(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(H.gray("Skipped Codex config"));const i=await Ym(e,"Codex model","gpt-5.5"),o=await Zm(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 Ym(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await Ym(e,"OpenAI API key")):(c=await Ym(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await Ym(e,"Custom API key")),await Ft(Me.codexHomeDir,{recursive:!0}),await Gt(s,function(e){const t=e.provider,n=[`model = ${eh(e.model)}`,`model_provider = ${eh(t)}`,"",`[model_providers.${t}]`,`name = ${eh("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${eh(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${eh(s)}`)}return e.envKey&&n.push(`env_key = ${eh(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=Me.readOrInitSettings({sandbox:Me.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0,promptOnUncommittedChanges:!1}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};Me.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(H.green(`✓ Wrote Codex config: ${s}`)),console.log(H.green(`✓ Wrote Codex env vars to ${Me.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function nh(e={}){console.log(H.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=ga(),t=[...Xm(e.cli.filter(e=>"claude"!==e.name)),...Xm(e.sandbox)];"linux"!==process.platform||zm("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(H.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(H.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(H.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=>zm(e.name))||null;if(!t){console.log(H.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(H.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(H.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await Km(s.join(" "),[],{shell:!0}):await Km(s[0],s.slice(1))}(t),await Jm("claude","@anthropic-ai/claude-code@latest"),await Jm("codex","@openai/codex@latest");const n=fa();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await ts();await th(Boolean(e.force),t),e.skipDaemon||await async function(){if(await Kn())console.log(H.green("✓ Daemon is already running"));else{console.log(H.blue("Starting Agentrix daemon...")),zc(["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 zn())return void console.log(H.green("✓ Daemon started successfully"));console.log(H.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(H.green("\n✓ Agentrix CLI initialization complete"))}function sh(e,t){const n=e[t]?.trim();return n||void 0}function ah(e,t){return e.replace(/^~(?=\/|$)/,t)}function ih(e){const t=e.trim().replace(/\/+$/,"");try{const e=new URL(t);if("http:"!==e.protocol&&"https:"!==e.protocol)throw new Error("unsupported protocol")}catch{throw new Error("AGENTRIX_BASE_URL must be a valid http(s) URL")}return t}async function oh(e,t){const n=sh(e,"AGENTRIX_API_KEY");if(n)return n;const s=sh(e,"AGENTRIX_API_KEY_FILE");if(!s)return;const a=(await async function(e,t){try{return(await Bt(ah(e,t),"utf-8")).replace(/[\r\n]/g,"")}catch{throw new Error(`AGENTRIX_API_KEY_FILE is set but is not readable: ${e}`)}}(s,t)).trim();return a||void 0}function rh(e){return JSON.stringify(e)}function ch(e,t){return`${JSON.stringify({env:{ANTHROPIC_BASE_URL:e.baseUrl,ANTHROPIC_AUTH_TOKEN:t,ANTHROPIC_MODEL:e.claudeModel,CLAUDE_CODE_SUBAGENT_MODEL:e.claudeSubagentModel,ANTHROPIC_SMALL_FAST_MODEL:e.claudeFastModel,ANTHROPIC_DEFAULT_OPUS_MODEL:"claude-opus-4-6",ANTHROPIC_DEFAULT_SONNET_MODEL:"claude-sonnet-4-6",ANTHROPIC_DEFAULT_HAIKU_MODEL:"claude-haiku-4-5"},model:e.claudeModel},null,2)}\n`}function lh(e){var t;return`${[`model = ${rh(e.codexModel)}`,'model_provider = "agentrix"',`approval_policy = ${rh("never")}`,`model_reasoning_effort = ${rh("high")}`,"","[model_providers.agentrix]",'name = "Agentrix"','wire_api = "responses"',`base_url = ${rh((t=e.baseUrl,`${t.replace(/\/+$/,"")}/v1`))}`,'env_key = "AGENTRIX_API_KEY"'].join("\n")}\n`}function dh(e,t){return`${JSON.stringify({connectionMode:"gemini-compatible",baseUrl:e.baseUrl,apiKey:t,imageModel:e.geminiImageModel},null,2)}\n`}async function ph(e={}){const t=e.env||process.env,s=!0===e.force,a=!0===e.dryRun,i=await async function(e){const t=function(e){return sh(e,"HOME")||n.homedir()}(e),s=ah(sh(e,"AGENTRIX_HOME_DIR")||sh(e,"AGENTRIX_DIR")||E(t,".agentrix"),t),a=ah(sh(e,"AGENTRIX_CLAUDE_HOME")||E(t,".claude"),t),i=ah(sh(e,"AGENTRIX_CODEX_HOME")||E(t,".codex"),t),o=ah(sh(e,"AGENTRIX_GEMINI_HOME")||E(s,"config","gemini"),t),r=sh(e,"AGENTRIX_CLAUDE_MODEL")||"claude-sonnet-4-6";return{agentrixHomeDir:s,claudeConfigDir:a,codexHomeDir:i,geminiConfigDir:o,baseUrl:ih(sh(e,"AGENTRIX_BASE_URL")||"https://api.xmz.ai"),apiKey:await oh(e,t),codexModel:sh(e,"AGENTRIX_CODEX_MODEL")||"gpt-5.5",claudeModel:r,claudeFastModel:sh(e,"AGENTRIX_CLAUDE_FAST_MODEL")||"claude-haiku-4-5",claudeSubagentModel:sh(e,"AGENTRIX_CLAUDE_SUBAGENT_MODEL")||r,geminiImageModel:sh(e,"AGENTRIX_GEMINI_IMAGE_MODEL")||"gemini-2.5-flash-image"}}(t);if(function(e,t){return!(!t&&r(E(e.claudeConfigDir,"settings.json"))&&r(E(e.codexHomeDir,"config.toml"))&&r(E(e.geminiConfigDir,"settings.json")))}(i,s)&&!i.apiKey)throw new Error("AGENTRIX_API_KEY or AGENTRIX_API_KEY_FILE is required to generate missing LLM config files");i.apiKey&&(t.AGENTRIX_API_KEY=i.apiKey);const o=function(e,t){return[{kind:"claude",path:E(e.claudeConfigDir,"settings.json"),content:ch(e,t)},{kind:"codex",path:E(e.codexHomeDir,"config.toml"),content:lh(e)},{kind:"gemini",path:E(e.geminiConfigDir,"settings.json"),content:dh(e,t)}]}(i,i.apiKey||""),c=[];for(const e of o)s||!r(e.path)?(c.push({kind:e.kind,path:e.path,action:"write"}),a||(await Ft(D(e.path),{recursive:!0}),await Gt(e.path,e.content,"utf-8"))):c.push({kind:e.kind,path:e.path,action:"skip"});return{dryRun:a,files:c,env:i.apiKey?{AGENTRIX_API_KEY:i.apiKey}:{}}}function uh(e,t){return"skip"===e?"skip":t?"would write":"write"}const mh={workspaces:"Task workspaces",logs:"Logs",tmp:"Temporary files",repos:"Repository store",runtime:"Runtime assets",monitor:"Monitor data",config:"Configuration",other:"Other"},hh=864e5,gh=/^task-(.+)\.log(?:\.\d+)?(?:\.gz)?$/;function fh(e){return{kind:e,label:mh[e],bytes:0,reclaimableBytes:0,itemCount:0}}function yh(e){const t=e.state?.initializedAt?Date.parse(e.state.initializedAt):Number.NaN;return Number.isFinite(t)?t:p(e.taskDir).mtimeMs}function vh(e){return gh.exec(e)?.[1]??null}function wh(e){return{kind:e.kind,label:e.label,bytes:e.bytes,reclaimableBytes:e.reclaimableBytes,itemCount:e.itemCount}}async function bh(e,t,n,s,a){n.bytes+=a.bytes,n.itemCount+=1,a.reclaimable&&(n.reclaimableBytes+=a.bytes),s.push(a),t({type:"item",opCode:e,item:a})}async function kh(e,t,n,s,a,i){const o=fh(s);t({type:"category-started",opCode:e,kind:o.kind,label:o.label});const c=E(Me.agentrixHomeDir,a);if(!r(c)){const n=wh(o);return t({type:"category-completed",opCode:e,category:n}),n}for(const a of g(c,{withFileTypes:!0})){const r=E(c,a.name);try{const c=await Yl(r);await bh(e,t,o,n,td({id:`${s}:${Jl(Me.agentrixHomeDir,r)}`,kind:s,label:a.name,absolutePath:r,bytes:c,reclaimable:i,deleteMode:i?"rm":"protected",reasonCode:i?void 0:`${s}_protected`,reason:i?void 0:"This area is shown for visibility only"}))}catch(n){t({type:"item-error",opCode:e,kind:s,pathDisplay:Jl(Me.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}const l=wh(o);return t({type:"category-completed",opCode:e,category:l}),l}async function xh(e){if(!e)return{};const t=await Bt(e,"utf8");return JSON.parse(t)}function Ih(e){process.stdout.write(`${JSON.stringify(e)}\n`)}const Sh=["local_machine_limit_reached","Online local machine limit reached","Current subscription does not allow online local machines","Disconnect another local machine or upgrade your subscription","machine_limited","Local machine is unavailable under current subscription","Machine binding revoked","Run `agentrix logout` and bind"];async function Th(){const e=await Me.readDaemonState();if("failed"===e?.status)return console.log(H.red("✗ Daemon failed to start")),console.log(H.yellow(e.message)),void(e.action&&console.log(H.yellow(e.action)));const t=await async function(){const e=E(Me.getStatePaths().logsDir,"daemon.log");try{return(await Bt(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(H.red("✗ Daemon exited shortly after startup")),!t)return;const n=function(e){const t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&Sh.some(t=>e.includes(t)));return 0===t.length?null:[...new Set(t.slice(-3))].join("\n")}(t);n?console.log(H.yellow(n)):(console.log(H.gray("Recent daemon log:")),console.log(t))}const Ch=L(q(process.argv)).scriptName("agentrix").version(Ue.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");function _h(e){try{return process.kill(e,0),!0}catch{return!1}}async function Ah(e){let t;if("string"==typeof e["report-json"])try{t=JSON.parse(e["report-json"])}catch{console.error(H.red("Error:"),"Invalid restart report JSON"),process.exit(1)}const n="number"==typeof e["old-pid"]?e["old-pid"]:void 0,s="string"==typeof e["expected-version"]?e["expected-version"]:void 0,a=await async function(e){const t=void 0===e.oldPid?await Me.readDaemonState():null,n=e.oldPid??(t&&Pe(t)&&pd(t.pid)?t.pid:void 0),s=e.expectedCliVersion??Wl();var a;if(e.report&&(a={...e.report,oldPid:n,expectedCliVersion:s,reason:e.reason,createdAt:(new Date).toISOString()},u(ld(),JSON.stringify(a,null,2),"utf-8")),e.stopExistingDaemon&&void 0!==n&&pd(n)&&await Xn(),void 0!==n){const t=await async function(e,t){const n=Date.now()+t;for(;Date.now()<n;){if(!pd(e))return!0;await dd(100)}return!pd(e)}(n,e.oldDaemonExitTimeoutMs??12e4);if(!t)return{success:!1,error:`Old daemon PID ${n} did not exit before timeout`}}try{zc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}const i=await async function(e,t,n){const s=Date.now()+n;for(;Date.now()<s;){const n=await Me.readDaemonState();if(n&&Pe(n)&&n.pid!==e&&n.cliVersion===t&&pd(n.pid))return n;await dd(100)}return null}(n,s,e.newDaemonStartTimeoutMs??3e4);return i?{success:!0}:{success:!1,error:`Replacement daemon did not report version ${s} before timeout`}}({oldPid:n,expectedCliVersion:s,reason:"string"==typeof e.reason?e.reason:void 0,report:t,stopExistingDaemon:void 0===n});a.success||(console.error(H.red("Error:"),a.error??"Daemon restart failed"),process.exit(1))}Me.getStatePaths,Ch.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(H.dim(`Current version: ${Ue.version}`));const t=await zn(),n=t?await Me.readDaemonState():null;await async function(e){try{if(console.log(""),e||(console.log(H.blue("🔄 Checking for upgrades...")),e=await zl()),!e.hasUpgrade)return console.log(H.green("✓ Already on latest version")),console.log(""),!0;console.log(H.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`));const t=await Kl(e,{stdio:"inherit"});if("busy"===t.status)return console.log(H.yellow(`⚠️ ${t.message}`)),!1;if("failed"===t.status)throw new Error(t.error);return console.log(H.green("✓ Upgrade complete")),console.log(""),!0}catch(e){return console.log(""),console.log(H.yellow("⚠️ CLI upgrade failed")),console.log(H.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}()||process.exit(1);try{const e=await Me.readCredentials();e&&(console.log(H.dim("Checking agent updates...")),await async function(e){const t=Me.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>p(E(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=E(t,s),a=E(n,"upgrade");if(r(a))continue;const i=Lm(n);De.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await jm(s,e);if(!t||!t.gitUrl){De.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];_t(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?E(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=Lm(o);if(!c||i&&!qm(c,i)){De.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}De.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),De.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){De.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}(e))}catch{}if(t){console.log(H.blue("Preparing daemon restart..."));const e=await async function(){return await Hn("/prepare-graceful-restart",{source:"agentrix-cli",reason:"CLI upgrade installed"})}();let t=!0;const s=Wl();e.error?(console.log(H.yellow(`⚠️ Could not prepare graceful restart: ${e.error}`)),console.log(H.blue("Restarting daemon directly...")),await Xn(),zc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()):"pending_restart"===e.state&&(console.log(H.yellow(`Daemon restart deferred until ${e.activeSessions??0} active session(s) finish.`)),t=!1);let a=!1;t&&(a=await async function(e,t,n=15e3){const s=Date.now()+n;let a=!e;for(;Date.now()<s;){if(e?.pid&&!a){if(_h(e.pid)){await new Promise(e=>setTimeout(e,100));continue}a=!0}const n=await Me.readDaemonState();if(n&&Pe(n)&&n.pid!==e?.pid&&n.cliVersion===t&&_h(n.pid))return!0;await new Promise(e=>setTimeout(e,100))}return!1}(n,s),a?console.log(H.green("✓ Daemon restarted successfully")):console.log(H.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check.")))}const s=Wl();"0.0.0"!==s?console.log(H.green(`\n✓ Now running version: ${s}`)):console.log(H.dim("\nRun 'agentrix --version' to see the new version")),process.exit(0)}),Ch.command("doctor","System diagnostics & troubleshooting",{},async e=>{await va(),process.exit(0)}),Ch.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await Me.readCredentials())return void console.log(H.yellow("Not currently authenticated"));console.log(H.blue("This will log you out of Agentrix")),console.log(H.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=Fe({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(H.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await Xn(),console.log(H.gray("Stopped daemon"))}catch{}await Me.clearCredentials(),console.log(H.gray("Removed credentials")),console.log(H.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(H.blue("Logout cancelled"))}()}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),Ch.command("stop","Stop the daemon",{},async e=>{await Xn(),process.exit(0)}),Ch.command("restart","Restart the daemon",e=>e.option("old-pid",{type:"number",describe:"PID of the daemon that must exit before replacement starts"}).option("expected-version",{type:"string",describe:"CLI version expected from the replacement daemon"}).option("reason",{type:"string",describe:"Restart reason"}),async e=>{await Ah(e),console.log(H.green("✓ Daemon restarted successfully")),process.exit(0)}),Ch.command("status","Show daemon and authentication status",{},async e=>{await va("daemon"),console.log(""),await async function(){const e=await Me.readCredentials();if(console.log(H.bold("\nAuthentication Status\n")),!e)return void console.log(H.red("✗ Not authenticated"));console.log(H.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(H.gray(` Token: ${t}`)),e.machineId?(console.log(H.green("✓ Machine registered")),console.log(H.gray(` Machine ID: ${e.machineId}`)),console.log(H.gray(` Host: ${n.hostname()}`))):console.log(H.yellow("⚠️ Machine not registered")),console.log(H.gray(`\n Data directory: ${Me.agentrixHomeDir}`));try{await zn()?console.log(H.green("✓ Daemon running")):console.log(H.gray("✗ Daemon not running"))}catch{console.log(H.gray("✗ Daemon not running"))}}(),process.exit(0)}),Ch.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await Hn("/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)}),Ch.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await ma()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===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=vt.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 yt()).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("name",{type:"string",describe:"Git server display name, defaults to the GitLab hostname"}).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"}).option("proxy",{type:"boolean",describe:"Register this machine as a Git proxy node (use --no-proxy to save PAT locally only)"}),async e=>{try{await async function(e){const t=Hm(Bm(e["base-url"])??await Fm("GitLab base URL"),"baseUrl"),n=Hm(Bm(e["api-url"])??await Fm("GitLab API URL",function(e){return`${Hm(e,"baseUrl")}/api/v4`}(t)),"apiUrl"),s=new URL(t).hostname,a=Bm(e.name)??await Fm("Git server name",s),i=(Bm(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()}(Bm(e["pat-file"])):void 0)??await async function(e){return Pn.isTTY&&Rn.isTTY&&"function"==typeof Pn.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{Pn.setRawMode(!1),Pn.pause(),Pn.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Rn.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Rn.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Rn.write(`${e}: `),Pn.setRawMode(!0),Pn.resume(),Pn.on("data",i)}):Fm(e)}("GitLab PAT");if(!i)throw new Error("GitLab PAT is required");const o=("boolean"==typeof(l=e.proxy)?l:void 0)??await async function(e,t){if(!Pn.isTTY)return t;const n=(await Fm("Use this machine as a Git proxy node (Y/n)")).toLowerCase();return n?["y","yes"].includes(n):t}(0,!0);var l;const d=await async function(e){return await Hn("/git-server/bind",e)}({name:a,baseUrl:t,apiUrl:n,pat:i,useAsProxy:o});if(d.error||!d.success||!d.gitServer)throw new Error(`Git server add failed: ${d.error||"Daemon did not return a bound Git server"}`);const p=d.gitServer;console.log(JSON.stringify({id:p.id,type:"gitlab",baseUrl:p.baseUrl,apiUrl:p.apiUrl,webhookEndpointPath:d.webhookEndpointPath??Ht(p.id),webhookUrl:d.webhookUrl??qt(p.id,await Me.readDaemonState()),backendRegistered:!0,proxyRegistered:d.proxyRegistered??o,patConfigured:!0,patMeta:d.patMeta??nr(p.id),webhookSecret:d.webhookSecret},null,2))}(e),process.exit(0)}catch(e){Gm(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await async function(){const e=await Qo();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}(),t=await Me.readDaemonState(),n=await async function(){return await Hn("/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=Zo(e.id)??{},a=er(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:Ht(e.id),webhookUrl:qt(e.id,n),patConfigured:(i=e.id,Yo.hasPat(i)),patMeta:nr(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){Gm(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(Ch),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 nh({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(Ch),function(e){e.command("llm-config apply","Generate Claude, Codex, and Gemini config from Agentrix environment variables",e=>e.option("source",{type:"string",choices:["env"],default:"env",describe:"Configuration source"}).option("force",{type:"boolean",default:!1,describe:"Overwrite existing LLM config files"}).option("dry-run",{type:"boolean",default:!1,describe:"Show planned writes without changing files"}).option("verbose",{type:"boolean",default:!1,describe:"Show detailed file actions"}),async e=>{try{const t=await ph({force:!0===e.force,dryRun:!0===e.dryRun,env:process.env}),n=t.files.filter(e=>"write"===e.action).length,s=t.files.filter(e=>"skip"===e.action).length,a=t.dryRun?"LLM config dry run":"LLM config applied";if(console.log(H.green(`✓ ${a}: ${n} write(s), ${s} skipped`)),!0===e.verbose||t.dryRun)for(const e of t.files)console.log(`${uh(e.action,t.dryRun)} ${e.kind}: ${e.path}`);t.env.AGENTRIX_API_KEY&&console.log(H.gray("AGENTRIX_API_KEY prepared for this process.")),process.exit(0)}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(Ch),function(e){e.command("storage-scan",!1,e=>e.option("op-code",{type:"string",demandOption:!0}).option("request-file",{type:"string"}),async e=>{const t=e["op-code"];try{const n=await xh(e["request-file"]);await async function(e){const{opCode:t,emit:n}=e,s=new Set(e.activeTaskIds??[]),a=Me.getStorageManagementSettings(),i=[],o=[];n({type:"started",opCode:t,root:Me.agentrixHomeDir,startedAt:(new Date).toISOString()}),o.push(await async function(e,t,n,s,a){const i=fh("workspaces");t({type:"category-started",opCode:e,kind:i.kind,label:i.label});const o=Date.now()-a*hh;for(const a of Zl()){const c=n.has(a.taskId),l=ed(a.state),d=!c&&!l&&yh(a)<o,p=c?{reasonCode:"active_task",reason:"Task is currently running"}:l?{reasonCode:"user_directory",reason:"Task uses a user-owned directory"}:{},u=r(a.projectDir),m=r(a.dataDir),h=u?await Yl(a.projectDir):0,g=m?await Yl(a.dataDir):0;if(u){const n=c||l?null:await nd(a.projectDir);await bh(e,t,i,s,td({id:`workspace:${a.userId}:${a.taskId}:project`,kind:"workspace-project",label:a.taskId,absolutePath:a.projectDir,bytes:h,reclaimable:!c&&!l,defaultSelected:d,deleteMode:c||l?"protected":n?"remove-worktree":"rm-stale-directory",childrenSummary:[{label:"project",bytes:h},...m?[{label:"data",bytes:g}]:[]],...p}))}m&&await bh(e,t,i,s,td({id:`workspace:${a.userId}:${a.taskId}:data`,kind:"workspace-data",label:`${a.taskId} data`,absolutePath:a.dataDir,bytes:g,reclaimable:!c&&!l,defaultSelected:d,deleteMode:c||l?"protected":"rm",childrenSummary:[{label:"data",bytes:g}],...p}))}const c=wh(i);return t({type:"category-completed",opCode:e,category:c}),c}(t,n,s,i,a.autoSelectTaskOlderThanDays)),o.push(await async function(e,t,n,s,a){const i=fh("logs");t({type:"category-started",opCode:e,kind:i.kind,label:i.label});const o=E(Me.agentrixHomeDir,"logs");if(!r(o)){const n=wh(i);return t({type:"category-completed",opCode:e,category:n}),n}const c=new Map(Zl().map(e=>[e.taskId,e])),l=Date.now()-a*hh;for(const a of g(o,{withFileTypes:!0})){const r=E(o,a.name);try{const o=await Yl(r),d=vh(a.name),u=d?c.get(d):void 0,m=!!d&&n.has(d),h=u?yh(u):p(r).mtimeMs,g=Boolean(d)&&h<l;await bh(e,t,i,s,td({id:`logs:${Jl(Me.agentrixHomeDir,r)}`,kind:"logs",label:a.name,absolutePath:r,bytes:o,reclaimable:!m,defaultSelected:!m&&g,deleteMode:m?"protected":"rm",reasonCode:m?"active_task":void 0,reason:m?"Task is currently running":void 0}))}catch(n){t({type:"item-error",opCode:e,kind:"logs",pathDisplay:Jl(Me.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}const d=wh(i);return t({type:"category-completed",opCode:e,category:d}),d}(t,n,s,i,a.autoSelectTaskOlderThanDays)),o.push(await kh(t,n,i,"tmp","tmp",!0)),o.push(await async function(e,t,n){const s=fh("repos");t({type:"category-started",opCode:e,kind:s.kind,label:s.label});const a=E(Me.agentrixHomeDir,"repos");if(!r(a)){const n=wh(s);return t({type:"category-completed",opCode:e,category:n}),n}for(const i of g(a,{withFileTypes:!0})){if(!i.isDirectory())continue;const o=E(a,i.name);for(const a of g(o,{withFileTypes:!0})){if(!a.isDirectory())continue;const i=E(o,a.name);for(const o of g(i,{withFileTypes:!0})){if(!o.isDirectory())continue;const r=E(i,o.name);try{const i=await Yl(r);await bh(e,t,s,n,td({id:`repos:${Jl(Me.agentrixHomeDir,r)}`,kind:"repos",label:`${a.name}/${o.name}`,absolutePath:r,bytes:i,reclaimable:!0,defaultSelected:!1,deleteMode:"rm"}))}catch(n){t({type:"item-error",opCode:e,kind:"repos",pathDisplay:Jl(Me.agentrixHomeDir,r),errorCode:"stat_failed",message:n instanceof Error?n.message:"Failed to scan item"})}}}}const i=wh(s);return t({type:"category-completed",opCode:e,category:i}),i}(t,n,i)),o.push(await kh(t,n,i,"runtime","node-runtime",!1)),o.push(await kh(t,n,i,"monitor","monitor",!1));const c=o.reduce((e,t)=>e+t.bytes,0),l=o.reduce((e,t)=>e+t.reclaimableBytes,0),d={scanId:`scan-${t}`,root:Me.agentrixHomeDir,generatedAt:(new Date).toISOString(),totalBytes:c,reclaimableBytes:l,categories:o,items:i.sort((e,t)=>Number(t.reclaimable)-Number(e.reclaimable)||t.bytes-e.bytes)};return n({type:"completed",opCode:t,result:d,summary:{totalBytes:c,reclaimableBytes:l,itemCount:i.length,skippedCount:i.filter(e=>!e.reclaimable).length},completedAt:d.generatedAt}),d}({opCode:t,activeTaskIds:n.activeTaskIds,emit:Ih}),process.exitCode=0}catch(e){Ih({type:"failed",opCode:t,errorCode:"operation_failed",message:e instanceof Error?e.message:"Storage scan failed"}),process.exitCode=1}}),e.command("storage-clean",!1,e=>e.option("op-code",{type:"string",demandOption:!0}).option("request-file",{type:"string",demandOption:!0}),async e=>{const t=e["op-code"];try{const n=await xh(e["request-file"]);await async function(e){const{opCode:t,emit:n}=e,s=new Set(e.activeTaskIds??[]),a={releasedBytes:0,deletedCount:0,skippedCount:0,failedCount:0,dryRunCount:0};n({type:"started",opCode:t,itemCount:e.items.length,startedAt:(new Date).toISOString()});for(const i of e.items){n({type:"item-validating",opCode:t,relativePath:i.relativePath});const o=await sd(i.relativePath,s);if(o.releasable)if(n({type:"item-cleaning",opCode:t,relativePath:o.relativePath,method:o.method}),e.dryRun)a.dryRunCount+=1,n({type:"item-completed",opCode:t,relativePath:o.relativePath,releasedBytes:0,method:o.method});else try{const e=await ad(o);a.releasedBytes+=e,a.deletedCount+=1,n({type:"item-completed",opCode:t,relativePath:o.relativePath,releasedBytes:e,method:o.method})}catch(e){a.failedCount+=1,n({type:"item-failed",opCode:t,relativePath:o.relativePath,errorCode:"delete_failed",message:e instanceof Error?e.message:"Failed to clean item"})}else a.skippedCount+=1,n({type:"item-skipped",opCode:t,relativePath:o.relativePath,reasonCode:o.reasonCode,message:o.message})}return n({type:"completed",opCode:t,summary:{...a},result:{summary:{...a}},completedAt:(new Date).toISOString()}),a}({opCode:t,activeTaskIds:n.activeTaskIds,items:n.items??[],dryRun:!0===n.dryRun,emit:Ih}),process.exitCode=0}catch(e){Ih({type:"failed",opCode:t,errorCode:"operation_failed",message:e instanceof Error?e.message:"Storage clean failed"}),process.exitCode=1}})}(Ch),Ch.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 Hn("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?H.green("✓ Session stopped"):H.red("Failed to stop session"))}catch(e){console.log(H.red("No daemon running"))}process.exit(0)}),Ch.command("daemon",!1,{},async e=>{try{await ts()}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await Td(),process.exit(0)}),Ch.command("worker",!1,e=>e.option("type",{type:"string",choices:Om,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=Um[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=e["user-id"],i=e["task-id"],o=e["idle-timeout"];je({type:"worker",taskId:i});const r=await ts();await n.run({credentials:r,startedBy:s,userId:a,taskId:i,idleTimeoutSecond:o}),await el()}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),Ch.command("restart-daemon",!1,e=>e.option("old-pid",{type:"number",describe:"PID of the daemon that must exit before replacement starts"}).option("expected-version",{type:"string",describe:"CLI version expected from the replacement daemon"}).option("reason",{type:"string",describe:"Restart reason"}).option("report-json",{type:"string",describe:"Machine-control restart report context"}),async e=>{await Ah(e),process.exit(0)}),Ch.command("start","Start daemon (if not running) and show status",{},async e=>{try{await ts()}catch(e){console.error(H.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=fa();if(t.ok||(console.log(H.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(H.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(H.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await Kn()){console.log("Starting Agentrix background service..."),zc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1,t=!1;const n=Date.now()+12e4;for(;Date.now()<n;){await new Promise(e=>setTimeout(e,100));const n=await Me.readDaemonState();if("failed"===n?.status){t=!0;break}if(await zn()){e=!0;break}}t&&(await Th(),process.exit(1)),e?(await new Promise(e=>setTimeout(e,1200)),await zn()?console.log(H.green("✓ Daemon started successfully")):(await Th(),process.exit(1))):console.log(H.yellow("⚠️ Daemon may still be starting..."))}await va("daemon"),process.exit(0)}),Ch.demandCommand(1,"Please specify a command. Use --help to see available commands.").parse();
|