@agentrix/cli 0.34.0 → 0.36.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.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 b,readlinkSync as w,createReadStream as x,copyFileSync as k,promises as I,accessSync as S,constants as T}from"node:fs";import*as C from"node:path";import E,{join as A,basename as _,extname as $,resolve as P,sep as R,dirname as M,relative as N,isAbsolute as D,normalize as O}from"node:path";import U from"yargs";import{hideBin as j}from"yargs/helpers";import L from"chalk";import{encodeBase64 as H,encryptMachineEncryptionKey as q,decodeBase64 as G,createKeyPairWithUit8Array as F,generateAESKey as B,decryptWithEphemeralKey as W,createEventId as z,encryptFileContent as K,VisionPlanReviewWriteEventSchema as V,splitRtcChunkFrame as X,RtcChunkFlags as J,buildRtcChunkFrame as Y,decodeGitPath as Q,UpdateTaskPreviewUrlRequestSchema as Z,AGENTRIX_DEV_INIT_FEATURE as ee,decryptSdkMessage as te,isSDKUserMessage as ne,isAskUserMessage as se,isAskUserResponseMessage as ae,isSDKMessage as ie,createKeyPair as oe,encryptAES as re,encryptWithEphemeralKey as ce,encryptSdkMessage as le,machineAuth as de,getAgentContext as pe,detectPreview as ue,IGNORED_DIRECTORIES as me,DEFAULT_WORKER_EXECUTION_MODE as he,getTaskExecutionMode as ge,isCompanionHeartbeatMessage as fe,isCompanionMemoryOrganizationMessage as ye,isCompanionReminderMessage as ve,workerAuth as be}from"@agentrix/shared";import{randomBytes as we,randomUUID as xe,createHash as ke,createDecipheriv as Ie,createCipheriv as Se,createHmac as Te,timingSafeEqual as Ce}from"node:crypto";import Ee from"axios";import{m as Ae,l as _e,p as $e,a as Pe,c as Re,g as Me,b as Ne}from"./logger-CWSO7ijQ.mjs";import{createInterface as De}from"node:readline";import*as Oe from"fs";import Ue,{readFileSync as je,existsSync as Le,unlinkSync as He,openSync as qe,writeFileSync as Ge,closeSync as Fe,promises as Be}from"fs";import*as We from"path";import ze,{join as Ke,dirname as Ve}from"path";import Xe from"open";import{io as Je}from"socket.io-client";import{EventEmitter as Ye}from"node:events";import{pipeline as Qe}from"node:stream/promises";import{GitServerLocalStore as Ze,validateGitLabPatToken as et,deriveLocalGitServerEncryptionKey as tt,replacePromptPlaceholders as nt,loadAgentConfig as st,getAgentContext as at,buildGitLabWebhookUrl as it,buildGitLabWebhookEndpointPath as ot}from"@agentrix/shared/node";import{createRequire as rt}from"node:module";import{spawn as ct,execSync as lt}from"child_process";import dt from"ps-list";import pt from"cross-spawn";import{getPlatform as ut}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import mt from"fastify";import{z as ht,toJSONSchema as gt}from"zod";import{validatorCompiler as ft,serializerCompiler as yt}from"fastify-type-provider-zod";import{spawnSync as vt,spawn as bt,execSync as wt,execFile as xt,execFileSync as kt}from"node:child_process";import{createSdkMcpServer as It,query as St,tool as Tt,AbortError as Ct}from"@anthropic-ai/claude-agent-sdk";import{mkdir as Et,readFile as At,writeFile as _t,readdir as $t,access as Pt}from"node:fs/promises";import{promisify as Rt}from"node:util";import Mt from"simple-git";import{EventEmitter as Nt}from"events";import Dt from"better-sqlite3";import{fileURLToPath as Ot,pathToFileURL as Ut}from"url";import{Cron as jt}from"croner";import{McpServer as Lt}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Ht}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as qt}from"crypto";import{isSupportedPlatform as Gt,NetworkManager as Ft,SandboxManager as Bt}from"@xmz-ai/sandbox-runtime";import*as Wt from"@larksuiteoapi/node-sdk";import{readFile as zt,mkdir as Kt,appendFile as Vt,stat as Xt}from"fs/promises";import{Codex as Jt}from"@openai/codex-sdk";import{stdin as Yt,stdout as Qt}from"node:process";import{createInterface as Zt}from"node:readline/promises";import"winston";import"os";const en=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_GEMINI_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function tn(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 sn(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=tn(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=tn(s)))}async function an(e){return new Promise(t=>setTimeout(t,e))}function on(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function rn(e,t){const n=await Ae.readDaemonState();if(!n?.port){const e="No daemon running, no state file found";return _e.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=on(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 _e.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${on(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 _e.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function cn(e,t){return await rn("/session-started",{sessionId:e,metadata:t})}async function ln(e,t,n){return await rn("/devops-init-complete",{taskId:e,userId:t,action:n})}async function dn(e,t){return await rn("/devops-init-start",{taskId:e,userId:t})}async function pn(e,t,n){const s="string"==typeof t?{content:t}:t;return await rn("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function un(e){return await rn("/prepare-graceful-restart",{source:"agentrix-cli",reason:e})}async function mn(){const e=await Ae.readDaemonState();if(!e)return!1;try{return process.kill(e.pid,0),!0}catch{return _e.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await gn(),!1}}async function hn(){if(_e.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await mn())return _e.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await Ae.readDaemonState();if(!e)return _e.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=Ke($e(),"package.json"),n=JSON.parse(je(t,"utf-8")).version;return _e.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return _e.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function gn(){try{await Ae.clearDaemonState(),_e.debug("[DAEMON RUN] Daemon state file removed")}catch(e){_e.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function fn(){try{const e=await Ae.readDaemonState();if(!e)return void _e.debug("No daemon state found");_e.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await rn("/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){_e.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){_e.debug("Error stopping daemon",e)}}function yn(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function vn(e,t){if(Ee.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?yn(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?yn(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?yn(e.message):e instanceof Error?`${t}: ${e.message}`:t}function bn(){return H(new Uint8Array(we(32)))}async function wn(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=B();return e.machineAesKey=H(n),n}(e);a.dataEncryptionKey=q(s.publicKey,t,G(n))}await Ee.post(`${Ae.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(vn(e,"Failed to sync machine data"))}}async function xn(){const e=await Ae.readCredentials();if(e){await async function(e){try{await Ee.get(`${Ae.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})}catch(e){throw new Error(vn(e,"Stored machine credentials are no longer valid"))}}(e);let t=e;e.secret||(t={...e,secret:bn()},await Ae.writeCredentials(t),_e.info("[AUTH] Generated missing local auth secret"));try{await wn(t,Ae.metadata()),_e.info("[AUTH] Machine metadata synced")}catch(e){_e.warn("[AUTH] Failed to sync machine metadata",e)}return _e.info("[AUTH] Using existing credentials"),t}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=Ae.generateMachineId();n={token:t,secret:bn(),machineId:e},_e.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=Ae.generateMachineId(),t=new Uint8Array(we(32)),n=await F(t);try{console.log(`[AUTH] Sending auth request to: ${Ae.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${H(n.publicKey).substring(0,20)}...`);const t={machineId:e};await Ee.post(`${Ae.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(vn(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`${Ae.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?(_e.debug("[browser] Headless environment detected, skipping browser open"),!1):(_e.debug(`[browser] Attempting to open URL: ${e}`),await Xe(e),_e.debug("[browser] Browser opened successfully"),!0)}catch(e){return _e.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(`${Ae.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=W(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${vn(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 an(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}return await wn(n,Ae.metadata(),a,s),await Ae.writeCredentials(n),_e.info("[AUTH] Machine setup completed"),n}!function(e=process.env){!function(e=process.env,t){if(!t?.variables)return e;const n=!0===t.enabled;for(const[s,a]of Object.entries(t.variables)){const t=s.trim();if(!t)continue;const i=String(a),o=en.has(t);(n||o)&&(e[t]=i,nn(e,t,i),sn(e,t,i))}}(e,function(e=process.env){const t=A(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?tn(t):A(n.homedir(),".agentrix")}(e),"settings.json");if(!r(t))return null;try{const e=c(t,"utf-8"),n=JSON.parse(e);return n?.daemonEnv||null}catch{return null}}(e))}();class kn{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 In(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=[];return t.message&&n.push(t.message),t.type&&n.push(`type=${t.type}`),void 0!==t.description&&n.push(`description=${JSON.stringify(t.description)}`),void 0!==t.data&&n.push(`data=${JSON.stringify(t.data)}`),void 0!==t.context&&n.push(`context=${JSON.stringify(t.context)}`),n.filter(Boolean).join(" ")||"unknown socket error"}class Sn{socket=null;config;eventHandlers=new Map;eventEmitter=new Ye;KeepAliveManager=null;healthCheckInterval=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new kn(e.keepAliveConfig))}connect(){if(this.socket)return void this.log("Already connected or connecting");const{serverUrl:e,path:t,auth:n={},options:s={}}=this.config,a={path:t,auth:n,transports:["websocket"],reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:5e3,reconnectionAttempts:1/0,...s};this.socket=Je(e,a),this.setupSocketHandlers(),this.log(`Connecting to ${e}`)}disconnect(){this.socket&&(this.log("Disconnecting"),this.stopHealthCheck(),this.socket.close(),this.socket=null)}get connected(){return this.socket?.connected??!1}replaceSocketHandler(e,t,n){this.socket&&(t&&this.socket.off(e,t),this.socket.on(e,n))}onEvent(e,t){const n=async n=>(this.log(`received event ${e}, data: ${JSON.stringify(n)}`),t(n)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}onEventWithAck(e,t){const n=async(n,s)=>(this.log(`received event with ack ${e}, data: ${JSON.stringify(n)}`),t(n,s)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}unregisterHandler(e){this.eventHandlers.delete(e),this.socket&&this.socket.off(e)}send(e,t){this.socket?(this.log(`send event ${e}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.log("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.log(`send event ${e}, data: ${JSON.stringify(t)}`),this.socket.emitWithAck(e,t)}sendVolatile(e,t){this.socket&&(void 0!==t?this.socket.volatile.emit(e,t):this.socket.volatile.emit(e))}async flush(e=1e4){if(this.connected)return new Promise(t=>{const n=setTimeout(()=>t(),e);this.socket.emit("ping",()=>{clearTimeout(n),t()})})}updateAuth(e){this.socket&&(this.socket.auth=e),this.config.auth=e}onLifecycle(e,t){this.eventEmitter.on(`lifecycle:${e}`,t)}offLifecycle(e){this.eventEmitter.removeAllListeners(`lifecycle:${e}`)}setupSocketHandlers(){this.socket&&(this.socket.on("connect",()=>{this.log("Connected"),this.eventEmitter.emit("lifecycle:connect",this.socket);for(const[e,t]of this.eventHandlers.entries())this.socket.off(e,t),this.socket.on(e,t);this.KeepAliveManager?.start(this.socket),this.startHealthCheck()}),this.socket.on("disconnect",e=>{this.log(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck()}),this.socket.on("connect_error",e=>{this.log(`Connection error: ${In(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.log(`Socket error: ${In(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}startHealthCheck(){const e=this.config.healthCheckConfig;if(!1===e?.enabled)return;const t=e?.intervalMs??3e4,n=e?.timeoutMs??5e3;this.stopHealthCheck(),this.healthCheckInterval=setInterval(()=>{if(!this.socket||!this.connected)return;const e=setTimeout(()=>{this.log("Health check timeout - forcing reconnect"),this.socket&&(this.socket.disconnect(),this.socket.connect())},n);this.socket.once("pong",()=>{clearTimeout(e)}),this.socket.emit("ping")},t)}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null)}log(e,...t){this.config.logger&&this.config.logger(`[SocketClient] ${e}`,...t)}}const Tn="attachment",Cn={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function En(){const e=A(Ae.agentrixHomeDir,"tmp","channel-files");return r(e)||d(e,{recursive:!0}),e}function An(e){const t=function(e){if(!e)return;return _(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||Tn;return A(En(),`${xe()}-${t}`)}function _n(e){const t=P(En()),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 $n(e,t){if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);if(!e.body)throw new Error("Response body is null");const n=function(e,t){if(!e){const e=Rn(t);return e?`${Tn}${e}`:void 0}if($(e))return e;const n=Rn(t);return n?`${e}${n}`:e}(t||function(e){if(!e)return;const t=e.match(/filename\*=UTF-8''([^;]+)/i);if(t?.[1])return decodeURIComponent(t[1]);const n=e.match(/filename="?([^";]+)"?/i);return n?.[1]}(e.headers.get("content-disposition")),e.headers.get("content-type")),s=An(n),a=l(s);return await Qe(e.body,a),s}async function Pn(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=_(new URL(e).pathname);return $(t)?t:void 0}catch{return}}(e);return $n(s,t||a)}function Rn(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?Cn[t]:void 0}function Mn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var n=function e(){var n=!1;try{n=this instanceof e}catch{}return n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}),n}var Nn,Dn,On,Un={},jn={"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}},Ln=(On||(On=1,function(e){var t,n,s,a=Dn?Nn:(Dn=1,Nn=jn),i=ze.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}}})}(Un)),Un);function Hn(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return _n(decodeURIComponent(e))}return Ae.resolveWorkspaceFilePath(e,t,n)}function qn(e,t){e?e.send("workspace-file-response",t):_e.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function Gn(e,t){e?e.send("workspace-file-mutation-response",t):_e.error("[WORKSPACE] Cannot send workspace-file-mutation-response: client not available")}function Fn(e,t,n,s){return{eventId:z(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function Bn(e,t,n,s){return{eventId:z(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function Wn(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,operation:r,content:c,createOnly:l}=t;_e.debug(`[WORKSPACE] File mutation request: taskId=${n}, userId=${s}, relativePath=${a}, operation=${r}, createOnly=${!!l}`);try{if(a.startsWith("channel-attachment/"))return void Gn(e.client,Bn(o,n,"permission_denied","Channel attachments are read-only"));const t=Hn(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=C.normalize(Ae.resolveWorkspaceFilePath(e,t,i)),r=C.normalize(s);return r===o||r.startsWith(o+C.sep)}(s,n,a,t))return void Gn(e.client,Bn(o,n,"permission_denied","Path escapes workspace"));if("delete"===r)return await i.promises.rm(t,{force:!1}),void Gn(e.client,{eventId:z(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r}});if(void 0===c)return void Gn(e.client,Bn(o,n,"bad_request","File content is required"));await i.promises.mkdir(C.dirname(t),{recursive:!0});try{await i.promises.writeFile(t,c,l?{flag:"wx"}:void 0)}catch(t){if("EEXIST"===t.code)return void Gn(e.client,Bn(o,n,"file_exists","File already exists"));throw t}const d=await i.promises.stat(t);Gn(e.client,{eventId:z(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r,modifiedAt:d.mtime.toISOString()}})}catch(t){_e.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";Gn(e.client,Bn(o,n,s,t.message))}}}function zn(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;_e.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,d=Hn(s,n,a);if(!i.existsSync(d))return _e.warn(`[WORKSPACE] File not found: ${d}`),void qn(e.client,Fn(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){_e.debug(`[WORKSPACE] File not modified: ${s}`),qn(e,{eventId:z(),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=C.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}}));qn(e,{eventId:z(),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=Ln.lookup(d)||"application/octet-stream";return p.size>t?void function(e,t,n,s,a,i,o){_e.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),qn(e,{eventId:z(),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=Ln.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 Ae.getSecretKey();if(!t)return _e.warn("[WORKSPACE] Machine secret key not available"),null;const n=G(e);return W(n,t)||(_e.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return _e.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=K(c,l):d.content=c,qn(e,{eventId:z(),requestId:t,taskId:n,success:!0,data:d})}(e.client,o,n,d,p,l)}}catch(t){_e.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";qn(e.client,Fn(o,n,s,t.message))}}}function Kn(e,t){return{eventId:z(),status:"failed",opCode:e,message:t}}function Vn(e,t){const n=C.relative(t,e);if(n.startsWith("..")||C.isAbsolute(n))throw new Error("Vision Plan review path is outside the bound issue directory")}const Xn=new Ze({credentialsDir:A(Ae.agentrixHomeDir,"credentials")});async function Jn(){const e=await Ae.readCredentials();return e?.secret?tt(e.secret):null}function Yn(e){return Xn.loadGitServerConfig(e)}function Qn(e,t){return Xn.loadGitLabWebhookBridgeSecrets(e,t)}function Zn(e){return Xn.loadPatMeta(e)}function es(e,t){return Xn.loadPat(e,t)}const ts=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 ss{apiUrl;pat;requestId;gitServerId;constructor(e,t,n){this.apiUrl=e,this.pat=t,this.requestId=n?.requestId,this.gitServerId=n?.gitServerId}logPrefix(){return`[GITLAB EXECUTOR] reqId=${this.requestId??"-"}, gitServer=${this.gitServerId??"-"}`}summarizeResult(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"id"in n&&"status"in n?`id=${String(n.id??"-")}, status=${String(n.status??"-")}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}truncateText(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}async requestWithResponse(e,t="GET",n){const s=`${this.apiUrl}${e}`,a={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/json"},i=Date.now();_e.debug(`${this.logPrefix()} request start: ${t} ${e}`);try{const o=await fetch(s,{method:t,headers:a,body:n?JSON.stringify(n):void 0}),r=Date.now()-i;if(!o.ok){const n=await o.text().catch(()=>"Unknown error"),s=this.truncateText(n);throw _e.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 _e.debug(`${this.logPrefix()} request success: ${t} ${e}, elapsedMs=${r}`),{data:await o.json(),headers:o.headers}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw _e.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();_e.debug(`${this.logPrefix()} form request start: POST ${e}`);try{const i=await fetch(n,{method:"POST",headers:s,body:t}),o=Date.now()-a;if(!i.ok){const t=await i.text().catch(()=>"Unknown error"),n=this.truncateText(t);throw _e.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 _e.debug(`${this.logPrefix()} form request success: POST ${e}, elapsedMs=${o}`),await i.json()}catch(t){if("object"==typeof t&&null!==t&&"status"in t)throw t;const n=t instanceof Error?t.message:"Unknown network error";throw _e.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:ts,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:ts,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===ts){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:ts,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<ts)break;t+=1}}return s}async executeOperation(e,t){_e.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let n;switch(e){case"listRepos":n=await this.listRepos();break;case"listBranches":n=await this.listBranches(t.owner,t.name);break;case"createMergeRequest":n=await this.createMergeRequest(t);break;case"getMergeRequest":n=await this.getMergeRequest(t.owner,t.name,t.iid);break;case"listMergeRequests":n=await this.listMergeRequests(t.owner,t.name);break;case"triggerPipeline":n=await this.triggerPipeline(t);break;case"ensurePipelineTriggerToken":n=await this.ensurePipelineTriggerToken(t);break;case"requestGitlabApi":n=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":n={authMode:"local_pat",hasPat:!0};break;default:throw{status:400,message:`Unknown operation: ${e}`}}return _e.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,n)}`),n}catch(t){const n=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw _e.error(`${this.logPrefix()} operation failed: op=${e}, message=${n}`),t}}async listRepos(){return(await this.requestPaginated("/projects?membership=true&order_by=updated_at&sort=desc")).map(e=>({id:e.id,owner:e.path_with_namespace.split("/").slice(0,-1).join("/")||e.namespace.path,name:e.path,fullName:e.path_with_namespace,defaultBranch:e.default_branch,isPrivate:"private"===e.visibility,description:e.description,url:e.web_url,createdAt:e.created_at,updatedAt:e.updated_at}))}async listBranches(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.requestPaginated(`/projects/${n}/repository/branches`)).map(e=>({name:e.name,commit:{sha:e.commit.id,url:""},protected:e.protected}))}async createMergeRequest(e){const t=encodeURIComponent(`${e.owner}/${e.repo}`),n=await this.request(`/projects/${t}/merge_requests`,"POST",{source_branch:e.head,target_branch:e.base,title:e.title,description:e.body||""});return{number:n.iid,title:n.title,body:n.description,state:"opened"===n.state?"open":n.state,url:n.web_url,head:n.source_branch,base:n.target_branch,createdAt:n.created_at,updatedAt:n.updated_at}}async getMergeRequest(e,t,n){const s=encodeURIComponent(`${e}/${t}`),a=await this.request(`/projects/${s}/merge_requests/${n}`);return{number:a.iid,title:a.title,body:a.description,state:"opened"===a.state?"open":a.state,url:a.web_url,head:a.source_branch,base:a.target_branch,createdAt:a.created_at,updatedAt:a.updated_at}}async listMergeRequests(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.request(`/projects/${n}/merge_requests?state=opened&per_page=20`)).map(e=>({number:e.iid,title:e.title,body:e.description,state:"opened"===e.state?"open":e.state,url:e.web_url,head:e.source_branch,base:e.target_branch,createdAt:e.created_at,updatedAt:e.updated_at}))}parseNonEmptyString(e,t){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} is required`};return e.trim()}parseOptionalString(e,t){if(null!=e){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} must be a non-empty string`};return e.trim()}}resolveProjectPath(e){if("number"==typeof e.projectId||"string"==typeof e.projectId){const t=String(e.projectId).trim();if(t.length>0)return encodeURIComponent(t)}const t=this.parseOptionalString(e.projectPath,"projectPath");if(t)return encodeURIComponent(t);const n=this.parseOptionalString(e.owner,"owner"),s=this.parseOptionalString(e.repo??e.name,"repo");if(!n||!s)throw{status:400,message:"projectId, projectPath, or owner + repo is required"};return encodeURIComponent(`${n}/${s}`)}parsePipelineVariables(e){if(null==e)return{};if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Pipeline variables must be an object"};const t={};for(const[n,s]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw{status:400,message:`Pipeline variable name is invalid: ${n}`};if(null!=s){if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Pipeline variable value for "${n}" is invalid`};t[n]=String(s)}}return t}isUsableTriggerToken(e){return"string"==typeof e&&e.length>=20&&!e.includes("*")}async resolvePipelineTriggerToken(e,t){const n=this.parseOptionalString(t.triggerToken,"triggerToken");if(n)return n;if(!0!==t.createTriggerIfMissing)throw{status:400,message:"triggerToken is required unless createTriggerIfMissing is true"};const s=this.parseOptionalString(t.triggerDescription,"triggerDescription")??"Agentrix webhook bridge",a=(await this.requestPaginated(`/projects/${e}/triggers`)).find(e=>e.description===s&&this.isUsableTriggerToken(e.token));if(a?.token)return a.token;const i=new URLSearchParams;i.set("description",s);const o=await this.requestForm(`/projects/${e}/triggers`,i);if(!this.isUsableTriggerToken(o.token))throw{status:502,message:"GitLab did not return a usable pipeline trigger token"};return o.token}async ensurePipelineTriggerToken(e){const t=this.resolveProjectPath(e);return{token:await this.resolvePipelineTriggerToken(t,{...e,createTriggerIfMissing:!0})}}async triggerPipeline(e){const t=this.resolveProjectPath(e),n=this.parseNonEmptyString(e.ref,"ref"),s=this.parsePipelineVariables(e.variables),a=await this.resolvePipelineTriggerToken(t,e),i=new URLSearchParams;i.set("token",a),i.set("ref",n);for(const[e,t]of Object.entries(s))i.set(`variables[${e}]`,t);const o=await this.requestForm(`/projects/${t}/trigger/pipeline`,i);return{id:o.id,iid:o.iid,projectId:o.project_id,ref:o.ref,sha:o.sha,status:o.status,source:o.source,url:o.web_url,createdAt:o.created_at,updatedAt:o.updated_at}}parseProxyMethod(e){const t="string"==typeof e?e.toUpperCase():"GET";if("GET"===t||"POST"===t||"PUT"===t||"PATCH"===t||"DELETE"===t)return t;throw{status:400,message:`Unsupported proxy method: ${String(e)}`}}parseProxyPath(e){if("string"!=typeof e||0===e.length)throw{status:400,message:"Proxy path is required"};if(!e.startsWith("/"))throw{status:400,message:'Proxy path must start with "/"'};if(e.includes("://")||e.includes(".."))throw{status:400,message:"Proxy path contains invalid segments"};if(e.includes("?"))throw{status:400,message:"Proxy path must not contain query string; use payload.query"};return e}buildProxyQueryString(e){if(null==e)return"";if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Proxy query must be an object"};const t=new URLSearchParams;for(const[n,s]of Object.entries(e))if(null!=s)if(Array.isArray(s))for(const e of s){if("string"!=typeof e&&"number"!=typeof e&&"boolean"!=typeof e)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(e))}else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(s))}return t.toString()}isProxyAllowed(e,t){return 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}`};return"GET"===t?await this.request(a,t):await this.request(a,t,e.body)}}function as(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function is(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function os(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 rs(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(as(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 cs(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){_e.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${is(as(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await rs(e,a);return _e.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=os(t);_e.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 ls(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 ds(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}}(A(Ae.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:ls(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=A(Ae.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)}_e.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${is(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 cs(e))n.add(t)}catch(t){const n=os(t);s.push({source:e.source,baseUrl:is(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?_e.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):_e.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function ps(e,t){return{eventId:z(),status:"failed",opCode:e,message:t}}function us(e){return async(t,n)=>{if(_e.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 _e.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(ps(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&_e.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){_e.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function ms(e){return async(t,n)=>{_e.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&&_e.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){_e.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function hs(e){return async(t,n)=>{if(_e.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return _e.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(ps(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await ds(t.agentType);if(0===e.length&&!s)return _e.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(ps(t.eventId,"No models available from configured endpoints"));_e.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:z(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){_e.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function gs(e){return async t=>{_e.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function fs(e){return async(t,n)=>{_e.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&&_e.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){_e.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function ys(e){return async(t,n)=>{_e.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&&_e.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){_e.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function vs(e){return async(t,n)=>{_e.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&&_e.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){_e.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(ps(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function bs(e){return async t=>{_e.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||_e.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function ws(e){return async t=>{_e.info(`[GITLAB PROXY] request received: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, ttlMs=${t.ttlMs}, payloadKeys=${function(e){const t=Object.keys(e||{});return t.length>0?t.join(","):"-"}(t.payload)}`);const n=Date.now(),s=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?(e.client.send("daemon-gitlab-response",s),_e.info(`[GITLAB PROXY] response sent: reqId=${t.requestId}, op=${t.operation}, success=${n.success}, executionMs=${n.executionTimeMs}`)):_e.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=await Jn();if(!e)return _e.warn(`[GITLAB PROXY] git server encryption key unavailable: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"Git server encryption key not available",executionTimeMs:Date.now()-n});const a=es(t.gitServerId,e);if(!a)return _e.warn(`[GITLAB PROXY] PAT missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:`No PAT configured for git server ${t.gitServerId}`,executionTimeMs:Date.now()-n});const i=t.payload.apiUrl;if(!i)return _e.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:Date.now()-n});_e.info(`[GITLAB PROXY] executing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, apiHost=${function(e){try{return new URL(e).host}catch{return"invalid-url"}}(i)}`);const o=new ss(i,a,{requestId:t.requestId,gitServerId:t.gitServerId}),r=await o.executeOperation(t.operation,t.payload);_e.info(`[GITLAB PROXY] execution succeeded: reqId=${t.requestId}, op=${t.operation}, summary=${function(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}(t.operation,r)}`),s({success:!0,data:r,executionTimeMs:Date.now()-n})}catch(e){const a=e;let i="GITLAB_CONNECTIVITY_FAILED";401===a.status?i="PAT_INVALID":403===a.status?i="PAT_SCOPE_INSUFFICIENT":404===a.status&&(i="RESOURCE_NOT_FOUND");const o="string"==typeof a.message?a.message:"Unknown error",r="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,c="number"==typeof a.status?String(a.status):"unknown";_e.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${i}, status=${c}, message=${o}${r?`, detail=${r}`:""}`),s({success:!1,errorCode:i,errorMessage:o,executionTimeMs:Date.now()-n})}}}function xs(e){return async(t,n)=>{e.machineControl?e.machineControl.handleCommand(t,n):n(ps(t.eventId,"Machine control is not available"))}}const ks=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function Is(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)}function Ss(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return _n(decodeURIComponent(e))}return Ae.resolveWorkspaceFilePath(e,t,n)}class Ts{client;machineId;iceServers=[];sessions=new Map;rtcModule={};peerConstructor;constructor(e,t){this.client=e,this.machineId=t;const n=rt(import.meta.url);try{this.rtcModule=n("node-datachannel"),this.peerConstructor=(s=this.rtcModule).RTCPeerConnection||s.PeerConnection||s.RTCConnection||s.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}catch(e){const t=e instanceof Error?e.message:String(e);_e.warn(`[RTC] node-datachannel unavailable; RTC support disabled: ${t}`)}var s}registerHandlers(){this.peerConstructor?(this.client.onLifecycle("connect",()=>{this.requestIceServers()}),this.client.onEvent("rtc-ice-servers-response",e=>this.handleIceServersResponse(e)),this.client.onEvent("machine-rtc-request",e=>this.handleRtcRequest(e)),this.client.onEvent("rtc-signal",e=>this.handleRtcSignal(e))):_e.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:z()})}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),_e.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void _e.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId))return void this.sendMachineRtcResponse(e.sessionId,t,!0);const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),this.sendMachineRtcResponse(e.sessionId,t,!0)}sendMachineRtcResponse(e,t,n,s){this.client.send("machine-rtc-response",{eventId:z(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void _e.warn("[RTC] rtc-signal missing userId");const n=e.workspaceUserId||t,s=e.taskId;let a=this.sessions.get(e.sessionId);if(!a){const i=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers});a={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:i,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]},this.sessions.set(e.sessionId,a),this.registerPeerHandlers(a)}try{this.applyRemoteSignal(a,e.signal)}catch(e){_e.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{_e.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{_e.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:z(),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:z(),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?.(()=>{_e.info(`[RTC] Data channel open (${e.sessionId})`),e.lastActivity=Date.now(),Is(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?.(()=>{_e.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{_e.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{X(new Uint8Array(t))}catch(e){_e.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 _e.warn("[RTC] Non-JSON message",n)}s&&"string"==typeof s.type&&("file.request"!==s.type?"file.mutate"===s.type&&this.handleFileMutation(e,s).catch(e=>{_e.error("[RTC] Failed to handle file mutation",e)}):this.handleFileRequest(e,s).catch(e=>{_e.error("[RTC] Failed to handle file request",e)}))}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=Ss(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=C.normalize(Ae.resolveWorkspaceFilePath(e,t,i)),r=C.normalize(s);return r===o||r.startsWith(o+C.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=Ss(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=C.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??ks)*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=Ln.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(C.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=J.Binary|(0===o?J.Start:0),a=Buffer.isBuffer(e)?e:Buffer.from(e),i=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),r=Y({streamId:t,seq:o,flags:n,payloadLength:i.length},i);Is(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=Y({streamId:t,seq:o,flags:J.End|J.Binary,payloadLength:0},new Uint8Array);Is(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&Is(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){_e.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 Cs{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new Sn(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client,machineControl:n.machineControl},this.rtcManager=new Ts(this.client,s),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 30 seconds"))},3e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":us(t=this.context),"resume-task":ms(t),"list-models":hs(t),"stop-task":bs(t),"deploy-agent":fs(t),"hive-publish":ys(t),"hive-install":vs(t),"shutdown-machine":gs(t),"workspace-file-request":zn({client:t.client}),"workspace-file-mutation-request":Wn({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=V.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(Kn(n,"Vision Plan review write path does not match the bound issue"));const o=Ae.resolveWorkspaceFilePath(s.userId,s.taskId,a);Vn(o,Ae.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=C.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);Vn(r,o),await i.promises.writeFile(r,s.content.endsWith("\n")?s.content:`${s.content}\n`,"utf8");const c=C.posix.join(a,C.basename(r)).replace(/^project\//,"");t({eventId:z(),status:"success",opCode:s.eventId,data:{relativePath:c}})}catch(e){_e.error("[VisionPlanReviewWrite] Failed to write review:",e),t(Kn(n,e instanceof Error?e.message:"Failed to write Vision Plan review"))}},"daemon-gitlab-request":ws(t),"machine-control-command":xs(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.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"])}}let Es=null;let As=!1;async function _s(){if(As)_e.info("[caffeinate] Already stopping, skipping");else if(Es&&!Es.killed){As=!0,_e.info(`[caffeinate] Stopping caffeinate process PID ${Es.pid}`);try{Es.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),Es&&!Es.killed&&Es.kill("SIGKILL"),Es=null,As=!1}catch(e){_e.info("[caffeinate] Error stopping caffeinate:",e),As=!1}}}let $s=!1;function Ps(e){const{pid:t,name:n,cmd:s}=e;if(t===process.pid||t===process.ppid)return null;if(!(n.includes("agentrix")||"node"===n&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("dist\\index.mjs"))||("MainThread"===n||n.includes("MainThread"))&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("agentrix.mjs"))||s.includes("agentrix.mjs")||s.includes("agentrix-cli")||s.includes("tsx")&&s.includes("src/index.ts")&&s.includes("agentrix-cli")))return null;let a="unknown";const i=s.toLowerCase();return i.includes(" worker")?a="worker":i.includes(" upgrade-daemon")?a="upgrade-daemon":i.includes(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function Rs(){try{let e;e="win32"===process.platform?await async function(){try{const e=lt("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 dt()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=Ps(n);e&&t.push(e)}return t}catch(e){return[]}}function Ms(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:lt(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function Ns(){const e=ut(),t=function(){const e=Ms("git"),t=Ms("claude"),n=Ms("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=Ms("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=Ms("bwrap"),t=Ms("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 Ds(){const e=Ns(),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 Os(){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:Ae.agentrixHomeDir,serverUrl:Ae.serverUrl,logsDir:Ae.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 Us(e){if(e||(e="all"),console.log(L.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(L.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${L.green(Pe.version)}`),console.log(`Platform: ${L.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${L.green(process.version)}`),console.log(""),console.log(L.bold("🔧 Daemon Spawn Diagnostics"));const e=$e(),t=A(e,"bin","agentrix.mjs"),n=A(e,"dist","index.mjs");console.log(`Project Root: ${L.blue(e)}`),console.log(`Wrapper Script: ${L.blue(t)}`),console.log(`CLI Entrypoint: ${L.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?L.green("✓ Yes"):L.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?L.green("✓ Yes"):L.red("❌ No")}`),console.log(""),console.log(L.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${L.blue(Ae.agentrixHomeDir)}`),console.log(`Server URL: ${L.blue(Ae.serverUrl)}`),console.log(`Logs Dir: ${L.blue(Ae.getStatePaths().logsDir)}`),console.log(L.bold("\n🌍 Environment Variables"));const s=Os();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?L.green(s.AGENTRIX_HOME_DIR):L.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?L.green(s.AGENTRIX_SERVER_URL):L.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?L.yellow("ENABLED"):L.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?L.green(s.DEBUG):L.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?L.green(s.NODE_ENV):L.gray("not set")}`),console.log(L.bold("\n🔐 Authentication"));try{await Ae.readCredentials()?console.log(L.green("✓ Authenticated (credentials found)")):console.log(L.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(L.red("❌ Error reading credentials"))}!function(e=!1){const t=Ns(),n=ut();console.log(L.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(L.green(`✓ ${n.name}`),L.gray(`- ${n.description}`)),e&&n.path&&console.log(L.gray(` Location: ${n.path}`));else{const e=n.required?L.red("❌"):L.yellow("⚠️");console.log(`${e} ${n.name}`,L.gray(`- ${n.description}`)),n.installCommand&&console.log(L.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(L.bold("\n🔒 Sandbox Dependencies")),console.log(L.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(L.green(`✓ ${n.name}`),L.gray(`- ${n.description}`)),e&&n.path&&console.log(L.gray(` Location: ${n.path}`))):(console.log(L.red(`❌ ${n.name}`),L.gray(`- ${n.description}`)),n.installCommand&&console.log(L.blue(` Install: ${n.installCommand}`)))}else console.log(L.bold("\n🔒 Sandbox Dependencies")),console.log(L.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(L.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(L.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(L.red(` • ${t.name}`));console.log(L.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(L.bold("\n🤖 Daemon Status"));try{const t=await mn(),n=await Ae.readDaemonState();if(t&&n?(console.log(L.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(L.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(L.red("❌ Daemon is not running")),n){console.log(L.bold("\n📄 Daemon State:"));const e=Ae.getStatePaths();console.log(L.blue(`Location: ${e.daemonStateFile}`)),console.log(L.gray(JSON.stringify(n,null,2)))}const s=await Rs();if(s.length>0){console.log(L.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(L.blue(`\n${{daemon:"🤖 Daemon","upgrade-daemon":"🔄 Upgrade Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?L.cyan:e.includes("daemon")?L.blue:L.gray;console.log(` ${s(`PID ${t}`)}: ${L.gray(n)}`)})})}else console.log(L.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(L.bold("\n💡 Process Management")),console.log(L.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(L.red("❌ Error checking daemon status"))}}let js=null;async function Ls(){const e=Ws(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(js&&js.expiresAt>Date.now()&&js.overridesSignature===t)return js.openers;const n=qs(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 js={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function Hs(e){const t=process.platform;if("darwin"===t)return function(e){const t=Gs(e),n=[];if(t){const e=Qs(t);n.push("-e",`set defaultLocation to POSIX file "${e}"`,"-e","set chosenFolder to choose folder default location defaultLocation")}else n.push("-e","set chosenFolder to choose folder");return n.push("-e","POSIX path of chosenFolder"),Fs(Xs("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=Vs("powershell")?"powershell":Vs("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=Gs(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${Ys(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return Fs(Xs(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=Gs(e);if(Vs("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return Fs(Xs("zenity",e,{captureOutput:!0}))}if(Vs("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),Fs(Xs("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 qs(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:()=>zs("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>zs("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>zs("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>zs("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>zs("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?Vs("osascript")&&Ks("Terminal"):"win32"===e?Vs("wt")||Vs("powershell")||Vs("pwsh")||Vs("cmd"):"linux"===e&&Boolean(Bs())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(Vs("wt"))return void Js("wt",["-d",e]);const t=Vs("powershell")?"powershell":Vs("pwsh")?"pwsh":null;return t?void Js(t,["-NoExit","-Command",`Set-Location -LiteralPath '${Ys(e)}'`]):void Js("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=Bs();if(!t)throw new Error("No supported terminal is available");return void Js(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!Xs("osascript",["-e",'tell application "Terminal"',"-e",`do script "${Qs(`cd ${Zs(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?Vs("open"):"win32"===e||"linux"===e&&(Vs("xdg-open")||Vs("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return Vs("xdg-open")?void Xs("xdg-open",[e]):void Xs("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}Xs("explorer",[e])}else Xs("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?Vs("osascript"):"win32"===e?Vs("powershell")||Vs("pwsh"):"linux"===e&&Vs("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");Xs("gio",["open","--ask",e])}else Xs(Vs("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${Ys(e)}'`]);else if(null===Xs("osascript",["-e",`set targetPath to POSIX file "${Qs(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??Ws();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=>Ks(e)):E.isAbsolute(e)||e.includes(E.sep)?r(e):Vs(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!Xs(e,(t&&t.length>0?t:["{path}"]).map(e=>e.split("{path}").join(n))))throw new Error(`Command failed: ${e}`)}(n.command,n.args,e)}return a})}(c,t,e)}function Gs(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!p(t).isDirectory())return}catch{return}return t}}function Fs(e){if(!e)return null;return e.trim()||null}function Bs(){const e=Zs(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&Vs(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${Zs(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 ${Zs(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${Zs(t)} && exec ${e}`]}].find(e=>Vs(e.command))??null}function Ws(){try{const e=Ae.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return _e.warn("[OPENERS] Failed to read opener overrides",e),{}}}function zs(e,t,s){return"darwin"===t?function(e,t){if(Vs("mdfind")){const t=Xs("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(Vs("plutil")){const t=[E.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=Xs("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){_e.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>Ks(e))}(e,s):"win32"===t?function(e){return Vs("reg")&&(Boolean(Xs("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean(Xs("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(Vs("xdg-settings")){const t=Xs("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(Vs("gio")){const t=Xs("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function Ks(e){return"darwin"===process.platform&&Boolean(Xs("open",["-Ra",e]))}function Vs(e){return"win32"===process.platform?Boolean(Xs("where",[e])):Boolean(Xs("sh",["-c",`command -v ${e}`]))}function Xs(e,t,n){const s=vt(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&&_e.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function Js(e,t){bt(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function Ys(e){return e.replace(/'/g,"''")}function Qs(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Zs(e){return`'${e.replace(/'/g,"'\\''")}'`}function ea(e,t){if(t){const n=N(t,e),s=!n||n.startsWith("..")||D(n)?_(e):n;return A(t,"versions",s)}let n=M(e),s=0;for(;s<10;){if(r(A(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return A(n,"versions",t)}const t=M(n);if(t===n)break;n=t,s++}const a=M(e),i=_(e);return A(a,`.${i}.version`)}function ta(e,t){const n=ea(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=ea(e,n),a=M(s);r(a)||d(a,{recursive:!0}),u(s,t,"utf-8")}catch(e){}}function sa(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 aa(e,t,n){const s=ta(e,n),a=sa(t.metadata.version,s);if(!r(e)){const s=M(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 ia(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 oa(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=A(Ae.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),wt(e.join(" "),{stdio:"pipe"}),a){const e=A(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 ra(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function ra(e){const t=[],n=A(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=A(n,e);p(s).isDirectory()&&r(A(s,"package.json"))&&t.push(s)}const s=A(e,"claude","hooks");r(s)&&r(A(s,"package.json"))&&t.push(s);for(const e of t)wt("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),wt("yarn build",{cwd:e,stdio:"pipe"})}function ca(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 la=ca("\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 da(e){return ca(`\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 pa(e){return ca(`\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 ua(e){return ca(`\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 ma=ca("\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 ha(e){const t="group"===e?.chatType?.toLowerCase();return ca(`\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 ca(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?ca("\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`)}ha();const ga=ca('\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'),fa=ca('\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'),ya=ca('\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'),va=ca("\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"),ba=ca(`\n ${ya}\n\n ${ga}\n\n ${fa}\n`),wa=ca('\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 xa(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 ka(e,t){const n=t.find(t=>t.id===e);if(!n)return xa(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(wa),a.join("\n")}function Ia(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function Sa(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function Ta(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function Ca(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(Sa).map(e=>e.text).join("\n").trim():""}function Ea(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n={input_tokens:e.usage.input_tokens,output_tokens:e.usage.output_tokens,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:e.usage.cached_input_tokens,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"};return{type:"result",subtype:"success",duration_ms:0,duration_api_ms:0,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:n,modelUsage:{[e.model]:{inputTokens:t>0?t:0,outputTokens:e.usage.output_tokens,cacheReadInputTokens:e.usage.cached_input_tokens,cacheCreationInputTokens:0,webSearchRequests:0,costUSD:0,contextWindow:0,maxOutputTokens:0}},permission_denials:[],uuid:crypto.randomUUID(),session_id:e.sessionId,structured_output:e.structuredOutput}}function Aa(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 _a="agentrix",$a="1.0.0",Pa=Rt(xt),Ra=["*","","!.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"),Ma=new Set(["MEMORY.md","USER.md","SOUL.md","IDENTITY.md","SKILLS.md","system_prompt.md","HEARTBEAT.md","MEMORY_ORGANIZATION.md","UPGRADES.md"]),Na=["memory","memory-changes","plugins","versions"],Da={GIT_AUTHOR_NAME:"Agentrix Companion",GIT_AUTHOR_EMAIL:"companion@agentrix.local",GIT_COMMITTER_NAME:"Agentrix Companion",GIT_COMMITTER_EMAIL:"companion@agentrix.local"};function Oa(e){return function(e){return e.split(R).join("/")}(O(e)).replace(/^\.\//,"")}function Ua(e,t,n){e?e("warn","COMPANION_GIT",t,n):console.warn(`[COMPANION GIT] ${t}`,n)}async function ja(e,t){const{stdout:n}=await Pa("git",t,{cwd:e,encoding:"utf-8",windowsHide:!0,env:{...process.env,...Da}});return n}async function La(e){try{return await ja(e,["diff","--cached","--quiet","--exit-code"]),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}async function Ha(e,t,n){const s=["commit","-m",t];return n?.trim()&&s.push("-m",n.trim()),await ja(e,s),(await ja(e,["rev-parse","HEAD"])).trim()}async function qa(e){return(await ja(e,["ls-files"])).split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).filter(Ga)}function Ga(e){const t=Oa(e);return!(!t||"."===t||t.startsWith("../")||t.includes("/../"))&&(!!Ma.has(t)||!(t.includes("/")||!t.endsWith(".upgrade"))||Na.some(e=>t===e||t.startsWith(`${e}/`)))}function Fa(e,t){const n=O(e),s=O(t),a=D(s)?s:O(A(n,s)),i=Oa(N(n,a));if(!i.startsWith("../")&&!D(i)&&Ga(i))return{absolutePath:a,relativePath:i};if(!D(s)){const e=O(A(n,"memory",s)),t=Oa(N(n,e));if(!t.startsWith("../")&&!D(t)&&Ga(t))return{absolutePath:e,relativePath:t}}throw new Error(`Companion self-evolution path is not allowlisted: ${t}`)}async function Ba(e){const{companionHome:t,log:n}=e;if(!t)return n?.("warn","COMPANION_GIT","Skipping self-evolution git repo ensure: companion home is not set"),!1;if(!r(t))return n?.("warn","COMPANION_GIT",`Skipping self-evolution git repo ensure: companion home does not exist (${t})`),!1;try{await Et(t,{recursive:!0});const e=r(A(t,".git"));return e||await ja(t,["init"]),await async function(e){const t=A(e,".gitignore");await At(t,"utf-8").catch(()=>{})!==Ra&&await _t(t,Ra,"utf-8")}(t),e||(await Wa(t),await La(t)&&await Ha(t,"Initialize Companion self-evolution history","Initial snapshot before automatic Companion run checkpoints.")),!0}catch(e){return Ua(n,"Failed to ensure Companion self-evolution git repo",e),!1}}async function Wa(e){const t=await async function(e){const t=new Set;r(A(e,".gitignore"))&&t.add(".gitignore");for(const n of Ma)r(A(e,n))&&t.add(n);const n=await $t(e).catch(()=>[]);for(const s of n)!s.includes("/")&&s.endsWith(".upgrade")&&r(A(e,s))&&t.add(s);for(const n of Na)r(A(e,n))&&t.add(n);for(const n of await qa(e))t.add(n);return Array.from(t)}(e);0!==t.length&&await ja(e,["add","-A","--",...t])}function za(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 Ka(e){const{companionHome:t,title:n,body:s,paths:a,log:i}=e;try{const e=await async function(e,t){const n=new Set(await qa(e)),s=Array.from(new Set(t.map(Oa))).filter(Ga).filter(t=>r(A(e,t))||n.has(t));return 0===s.length?[]:(await ja(e,["add","-A","--",...s]),s)}(t,a);return 0===e.length?(i?.("warn","COMPANION_GIT","Skipping Companion memory change commit: no allowlisted paths to stage"),null):await La(t)?await Ha(t,n,s):null}catch(e){return Ua(i,"Failed to create Companion memory change semantic commit",e),null}}async function*Va(e){yield e}let Xa;const Ja=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],Ya=["EnterPlanMode","ExitPlanMode"],Qa=new Set(Ya),Za=["Glob","Grep","Read","Skill"],ei=["Read","Glob","Grep"],ti=["Read","Glob","Grep","TodoWrite"];function ni(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=[ma];switch(n){case"work":s&&i.unshift(la),a&&i.push(da("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(pa("mcp__agentrix__send_vision_artifact")),t?.enableAgentrixComputerUse&&i.push(ua("mcp__agentrix__agentrix_computer_use"));break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":i.unshift(va),t?.enableAgentrixComputerUse&&i.push(ua("mcp__agentrix__agentrix_computer_use"));break;case"group_work":s&&i.unshift(la),a&&i.push(da("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(pa("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=[ba];return g&&g.length>0&&e.push(xa(g)),v&&e.push(v),i&&e.push(ha(o)),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const b="reply"===h&&g&&g.length>0?ka(t,g):void 0,w={},x=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE,k="companion_shadow"===h?function(e){return"memory_organization"===e?.COMPANION_SHADOW_TASK?"memory_organization":"heartbeat"}(d):void 0;x&&(w.COMPANION_HOME=x,w.COMPANION_MODE="companion_shadow"===h?"shadow":"chat","companion_shadow"===h&&(w.COMPANION_SHADOW_TASK=k??"heartbeat")),Object.assign(w,d);const I=Object.keys(w).length>0?w:void 0,S=f?nt(f,s,I):void 0,T="companion_shadow"===h?function(e,t){if(!e||!t)return;const n=A(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}(x,k):void 0;if("replace"===y&&S){const e=[S];return b&&e.push(b),v&&e.push(v),i&&e.push(ha(o)),T&&e.push(T),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const C=[];return b&&C.push(b),v&&C.push(v),i&&C.push(ha(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[...Ja];case"reply":return[...Za];case"group_chat":return[...ei];case"group_work":return[...ti]}}(n.modeConfig.mode),Boolean(n.disableClaudePlanModeTools)&&u?u.filter(e=>!Qa.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!==Xa)return Xa??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=D(t)?t:P(t);return r(e)?e:void 0}return function(e){const t="win32"===process.platform?"where":"which",n=vt(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 Xa=t,t}Xa=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=_a,serverVersion:h=$a}=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=It({name:m,version:h,tools:y}),b=y.map(e=>((e,t)=>`mcp__${e}__${t}`)(m,e.name));return{server:v,toolNames:b}}({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:[...Ya]}:{},mcpServers:f,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?Ia(n.env):void 0,pathToClaudeCodeExecutable:h,maxTurns:s.customMaxTurns??n.maxTurns??l,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:m,outputFormat:n.structuredOutputSchema}}class si{constructor(e,t,n,s,a,i){this.agentId=e,this.agentType=t,this.agentConfig=n,this.agentHooks=s,this.agentMcpServers=a,this.logger=i}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?Ta(e):e;let a=null;await this.checkpointCompanionRun(t,"before_run");try{const e=St({prompt:Va(s),options:ni(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if(console.log("ClaudeRunner.run: received message",JSON.stringify(t)),"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?Ta(e):e;await this.checkpointCompanionRun(t,"before_run");try{const e=St({prompt:Va(s),options:ni(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=ni(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=St({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(console.log("ClaudeRunner.loop.push:",JSON.stringify(e,null,2)),i)return;const t="string"==typeof e?Ta(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)}}}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,log:a}=e;if("companion_chat"!==n&&"companion_shadow"!==n)return{committed:!1};try{if(!await Ba({companionHome:t,log:a})||!t)return{committed:!1};if(await Wa(t),!await La(t))return{committed:!1};const i="companion_shadow"===n?e.shadowTask??"unknown":"unknown",o=await Ha(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,i,s),function(e,t,n){return[`mode: ${e}`,`shadow_task: ${"companion_shadow"===e?t:"unknown"}`,`phase: ${n}`].join("\n")}(n,i,s));return a?.("info","COMPANION_GIT",`Created Companion self-evolution ${s} checkpoint ${o}`),{committed:!0,commit:o}}catch(e){return Ua(a,`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,log:this.logger})}}function ai(e,t,n){e&&e(t,"AGENT",n)}function ii(){return`Companion probe timed out after ${Math.round(45)}s`}function oi(e){return e instanceof Error&&e.message?e.message:String(e)}function ri(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 ci(){const e=A(Ae.agentrixHomeDir,"tmp","companion-probe");d(e,{recursive:!0});const t=new si("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?ii():ri(a)}:{success:!0}}catch(e){return{success:!1,error:s?ii():oi(e)}}finally{clearTimeout(a)}}const li=Rt(xt);function di(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),Mt(t)}async function pi(e){try{const t=di(e);return await t.checkIsRepo()}catch{return!1}}async function ui(e){const t=di(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 mi(e,t,n,s="HEAD"){const a=M(t);if(r(a)||d(a,{recursive:!0}),r(t)&&!ki(t))throw new Error(`Worktree directory already exists at ${t}`);const i=di(e);await i.raw(["worktree","add","-b",n,t,s])}async function hi(e,t,n=!1){const s=di(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function gi(e){const t=di(e);await t.init()}async function fi(e){const t=di(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function yi(e,t){const n=M(t);r(n)||d(n,{recursive:!0});const s=di();await s.clone(e,t)}async function vi(e,t,n){const s=di(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(await Mi(e).catch(()=>[])).includes(t)?await li("git",["checkout","-B",t,`origin/${t}`],{cwd:e,windowsHide:!0}):n?await li("git",["checkout","-b",t,n],{cwd:e,windowsHide:!0}):await s.checkoutLocalBranch(t)}async function bi(e){const t=di(e);return!(await t.status()).isClean()}async function wi(e){const t=di(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function xi(e){try{const t=di(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function ki(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function Ii(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function Si(e,t,n){const s=di(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:Ii(Q(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function Ti(e,t){try{const{stdout:n}=await li("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 Ci(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:Ii(Q(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function Ei(e,t){return ke("sha256").update(`${e}\n${t}`).digest("hex")}async function Ai(e,t){const n=await Ti(e,["diff","--binary","--find-renames",t,"--"]),s=Ci(await Ti(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await li("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=>Ti(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=Ci((await Promise.all(a.map(t=>Ti(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:Ei(t,r)}:null;var c}async function _i(e){const t=di(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function $i(e,t,n){const s=di(e);await s.remote(["set-url",t,n])}function Pi(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function Ri(e,t,n){const s=di(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await $i(e,t,n):await s.addRemote(t,n)}async function Mi(e,t="origin"){const{stdout:n}=await li("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 Ni(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 Di(e){try{const t=di(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?Ni(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const Oi="oauth2",Ui="AGENTRIX_GIT_USERNAME",ji="AGENTRIX_GIT_PASSWORD";function Li(){const e=A(s(),`git-askpass-${xe()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${Ui}:-${Oi}}" ;;\n *) printf '%s\\n' "\${${ji}:-}" ;;\nesac\n`,{mode:448}),e}function Hi(e,t,n=Oi){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[Ui]:n,[ji]:t}}function qi(){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 Gi=Rt(xt),Fi="github",Bi="xmz-ai",Wi="agentrix-agent",zi="https://github.com/xmz-ai/agentrix-agent.git",Ki="main";async function Vi(e,t,n){await Gi("git",["clone","--depth=1","--branch",t,e,n]),await Ri(n,"origin",Pi(e))}async function Xi(e){const t=Ae.resolveRepoStoreCheckoutDir(Fi,Bi,Wi),n=A(t,"companion"),s=Ae.resolveRepoStoreLockPath(Fi,Bi,Wi),a=await Ae.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=`${Ae.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||Ki}}return{gitUrl:zi,branch:Ki}}(e);if(!await pi(t)){if(!ki(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await Vi(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 Gi("git",["fetch","--depth=1",e,t],{cwd:n}),await Gi("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await Ri(n,"origin",Pi(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=A(M(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await Vi(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 Ae.releaseFileLock(s,a)}}function Ji(e){r(e)||d(e,{recursive:!0})}function Yi(e){return e.split("\\").join("/")}function Qi(e,t){const n=A(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 Zi(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 eo(e){return A(e,"versions/.companion-template-language.json")}async function to(e){const t=Ae.agentrixAgentsHomeDir,n=A(t,"companion"),s=A(n,"claude"),a=!r(A(n,"agent.json")),i=await Xi(e?.credentials);let o=r(A(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 ci();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(A(o,"agent.json")))y(o,n,{recursive:!0}),ra(n),console.log("[Companion] Installed from template repository");else try{await oa({agentId:"companion",gitUrl:zi,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(A(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await oa({agentId:"companion",gitUrl:zi,branch:"main",subDir:"companion"})),o=r(A(i.companionDir,"agent.json"))?i.companionDir:n}Ji(A(s,"memory"));const l=Zi(e?.preferredLanguage),d=function(e,t,n){if(n)return{language:t,source:"initial-install",verified:!0};const s=function(e){const t=eo(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=A(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=Zi(e),a=Qi("common",t),i=Qi(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=A(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n,language:"common",sourcePath:s})}const d=A(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=A(s,i);if(p(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=Yi(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:A(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=eo(e);Ji(M(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=aa(A(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/")))&&(ra(n),console.log("[Companion] Rebuilt plugins after template updates"));const{pendingUpgrades:v,blockedUpgrades:b}=function(e,t,n={}){const s=[],a=[];for(const i of e){if("notify-user"!==i.metadata.updateStrategy)continue;const e=A(t,i.relativePath);if(!r(e))continue;const o=ta(e,t);if(sa(i.metadata.version,o)>0){const r={template:i,targetPath:e,upgradePath:`${e}.upgrade`,versionPath:ea(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||b.length>0)try{const e=A(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:b,agentDir:n,language:m,languageSource:d.source});u(e,t,"utf-8");for(const e of v)u(e.upgradePath,ia(e),"utf-8");console.log(`[Companion] Created UPGRADES.md with ${v.length} pending upgrade(s) and ${b.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 no=[{version:1,fileName:"001_init.sql"}];function so(e){var t;return function(e,t){const n=new Dt(e),s=new Nt;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=Ve(Ot(import.meta.url)),t=[Ke(e,"migrations"),Ke(process.cwd(),"dist","migrations"),Ke(process.cwd(),"src","worker","history","migrations")];for(const e of t)if(Le(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=Ke(e,t);return je(n,"utf8")}(t,no[0].fileName);e.exec(s),n<no[0].version&&e.pragma(`user_version = ${no[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 "),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??z(),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??z(),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(io),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(io).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?io(s):null},pageRecentMessages:e=>{const t=p.all(e).map(ao).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(ao),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(ao).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(ao).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)=>{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,Ke(t,"data.bin")),e.taskId)}function ao(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 io(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 oo=[1,2,4,6,8,12,24];function ro(e){return"number"==typeof e&&oo.includes(e)}function co(e){return ro(e)?e:4}class lo{constructor(e,t,n={}){this.client=e,this.machineId=t;const s=Ae.agentrixAgentsHomeDir,a=A(s,"companion","claude");this.stateFilePath=n.stateFilePath??A(a,"state.json"),this.initialDelayMs=n.initialDelayMs??6e4}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;memoryOrganizationEnabled=!1;memoryOrganizationIntervalHours=4;memoryOrganizationTaskId=null;companionState=null;stateFilePath;initialDelayMs;started=!1;cronJobs=new Map;start(){this.started?this.reloadStateAndReschedule():(this.started=!0,this.loadState(),this.companionState?(_e.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):_e.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),_e.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(),_e.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),_e.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(),_e.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),_e.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),_e.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),_e.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&&(_e.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=co(this.companionState?.memoryOrganizationIntervalHours),this.memoryOrganizationTaskId=this.companionState?.memoryOrganizationTaskId??null,_e.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){_e.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=M(this.stateFilePath);r(s)||d(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),_e.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){_e.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 _e.debug(`[COMPANION SCHEDULER] Sending memory organization to existing task ${this.memoryOrganizationTaskId}`),void this.client.send("task-message",{eventId:z(),taskId:this.memoryOrganizationTaskId,chatId:e.chatId,from:"machine",message:a,senderType:"system",senderId:"system",senderName:"system"});_e.debug("[COMPANION SCHEDULER] Requesting initial memory organization task"),this.client.send("request-companion-memory-organization",{eventId:z(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours})}addScheduledTask(e){const t={id:xe(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),_e.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)),_e.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 _e.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 _e.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 jt(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),_e.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){_e.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){_e.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:z(),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()?_e.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);_e.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}tick(){if(this.loadState(),!this.companionState)return void _e.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");const e=this.companionState,t=[],n=new Date;if(this.isMemoryOrganizationDue(e,n)&&(_e.info("[COMPANION SCHEDULER] Memory organization triggered"),this.triggerMemoryOrganization(e,n)),!this.enabled)return void _e.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)return void _e.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");_e.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?(_e.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:z(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:o,senderType:"system",senderId:"system",senderName:"system"})):(_e.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:z(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a}))}}const po="https://ilinkai.weixin.qq.com",uo="https://novac2c.cdn.weixin.qq.com/c2c",mo=1e3,ho=rt(import.meta.url)("qrcode-terminal");function go(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function fo(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function yo(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 vo(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 bo(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function wo(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 xo(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 ko(e){if(e.image_item?.media?.full_url)return Io(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 Io(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 Io(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 So(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 To(e){return e.retcode??e.ret??e.errcode}function Co(e,t){const n=To(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function Eo(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function Ao(e){let t="";return ho.generate(e,{small:!0},e=>{t=e}),t}class _o{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=mo;contextTokens=new Map;clientId=we(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=fo(e.token)??fo(e.botToken)??fo(e.bot_token)??fo(e.apiKey)??fo(e.api_key);return{baseUrl:fo(e.baseUrl)??fo(e.base_url)??po,token:t||go(t,"token"),routeTag:fo(e.routeTag)??fo(e.route_tag),getUpdatesBuf:fo(e.getUpdatesBuf)??fo(e.get_updates_buf)??"",channelVersion:fo(e.channelVersion)??fo(e.channel_version)??"1.0.0",pollTimeoutMs:yo(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:yo(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:fo(e.fileDownloadEndpoint)??fo(e.file_download_endpoint)??fo(e.downloadEndpoint)??fo(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||po,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${Eo(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=To(a);if(i&&0!==i)throw new Error(Co(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:Ao(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||po,s=await fetch(`${Eo(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=To(a);if(i&&0!==i)throw new Error(Co(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=mo,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),_e.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()}-${we(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=To(s);if(a&&0!==a)throw new Error(Co(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 At(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()}-${we(4).toString("hex")}`,message_type:2,message_state:2,context_token:n,item_list:[d]}},{timeoutMs:this.credentials.requestTimeoutMs}),u=To(p);if(u&&0!==u)throw new Error(Co(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=we(16).toString("hex"),i=we(16).toString("hex"),o=this.encryptWechatMedia(t,i),r=ke("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=To(c);if(l&&0!==l)throw new Error(Co(c,"WeChat getuploadurl failed"));const d=this.extractUploadParam(c),p=await fetch(`${uo}/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:`${uo}/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 Pn(e,t.fileName);const s=await this.requestDownloadFile(e);return await $n(s,t.fileName||e)}catch(t){return _e.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=To(e);if(t&&0!==t)throw new Error(Co(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=mo,"connected"!==this.connectionState&&this.setState("connected");for(const e of So(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));_e.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=An(t||e.fileName||"attachment");return await _t(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=Ie("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=Ie("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=Se("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 Eo(this.credentials.baseUrl,e)}generateWechatUin(){const e=we(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 _e.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?Io(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?Io(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??xe()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:bo(n,["sender_name","nickname","user_name"]),type:xo(e),text:wo(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:ko(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:vo(e.timestamp??e.create_time),raw:e}}}const $o=["telegram","wechat","lark"],Po=ht.enum($o),Ro=ht.enum(["connecting","connected","disconnected","error"]),Mo=ht.enum(["text","image","file","voice"]),No=ht.record(ht.string(),ht.unknown()),Do=ht.object({id:ht.string(),platform:Po,name:ht.string().optional(),credentials:No,enabled:ht.boolean(),connectionState:Ro,lastConnectedAt:ht.string().optional(),lastDisconnectedAt:ht.string().optional(),lastError:ht.string().optional(),createdAt:ht.string(),updatedAt:ht.string()}),Oo=ht.object({platform:Po,name:ht.string().optional(),credentials:No,enabled:ht.boolean().optional()}),Uo=ht.object({id:ht.string(),channelId:ht.string(),chatId:ht.string(),taskId:ht.string(),chatName:ht.string().optional(),createdAt:ht.string(),updatedAt:ht.string()});ht.object({id:ht.string(),channelId:ht.string(),platform:Po,chatId:ht.string(),chatType:ht.string().optional(),senderId:ht.string().optional(),senderType:ht.string().optional(),senderName:ht.string().optional(),type:Mo,text:ht.string().optional(),fileKey:ht.string().optional(),fileName:ht.string().optional(),imageKey:ht.string().optional(),attachmentPaths:ht.array(ht.string()).optional(),mentionedBot:ht.boolean().optional(),replyToBot:ht.boolean().optional(),triggered:ht.boolean().optional(),rawContent:ht.unknown().optional(),timestamp:ht.string(),raw:ht.unknown().optional()});const jo=ht.object({id:ht.string(),name:ht.string(),avatar:ht.string().optional(),description:ht.string().optional(),chatStatus:ht.string().optional(),external:ht.boolean().optional()}),Lo=ht.enum(["auto","image","file","audio","video"]),Ho=ht.object({filePath:ht.string(),fileName:ht.string().optional(),mimeType:ht.string().optional(),kind:Lo.optional()});ht.object({content:ht.string().optional(),attachments:ht.array(Ho).optional()});const qo=ht.object({version:ht.literal(1),channels:ht.array(Do),bindings:ht.array(Uo)});function Go(e){return!e||"object"!=typeof e||Array.isArray(e)?null:e}function Fo(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Bo(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function Wo(e){const t=e?.trim().toLowerCase();return"issue"===t?"issue":"mergerequest"===t||"merge_request"===t?"merge_request":void 0}function zo(e){const t=e.split("/").filter(Boolean);if(t.length<2)return{owner:"",name:e};const n=t[t.length-1];return{owner:t.slice(0,-1).join("/"),name:n}}function Ko(e){const t=Go(e.project);return t?{id:Bo(t.id),path:Fo(t.path),path_with_namespace:Fo(t.path_with_namespace),default_branch:Fo(t.default_branch),web_url:Fo(t.web_url)}:null}function Vo(e){const t=Go(e.object_attributes);return t?{iid:Bo(t.iid),title:Fo(t.title),url:Fo(t.url),action:Fo(t.action),state:Fo(t.state)}:null}function Xo(e){const t=Go(e.object_attributes);return t?{iid:Bo(t.iid),title:Fo(t.title),url:Fo(t.url),action:Fo(t.action),state:Fo(t.state),source_branch:Fo(t.source_branch),target_branch:Fo(t.target_branch)}:null}function Jo(e){const t=Go(e.object_attributes);return t?{id:Bo(t.id),note:Fo(t.note),noteable_type:Fo(t.noteable_type),url:Fo(t.url),action:Fo(t.action),system:(n=t.system,"boolean"==typeof n?n:void 0)}:null;var n}function Yo(e){const t=Go(e.object_attributes);return t?{id:Bo(t.id),iid:Bo(t.iid),status:Fo(t.status),source:Fo(t.source),ref:Fo(t.ref),sha:Fo(t.sha),url:Fo(t.url)}:null}function Qo(e){return Fo(e.event_type)||Fo(e.object_kind)||"unknown"}function Zo(e){return!!e&&/(?:^|[^A-Za-z0-9._-])(?:@agentrix|\/agentrix)(?=$|[^A-Za-z0-9._-])/i.test(e)}function er(e,t,n,s){const{owner:a,name:i}=zo(s.path_with_namespace??"");return{AGENTRIX_EVENT_NAME:t,AGENTRIX_EVENT_ACTION:n,AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:a,AGENTRIX_REPOSITORY_NAME:i,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"}}function tr(e,t,n,s){const a={ref:t,variables:n};return e.id?a.projectId=e.id:e.path_with_namespace&&(a.projectPath=e.path_with_namespace),s.triggerToken&&(a.triggerToken=s.triggerToken),void 0!==s.createTriggerIfMissing&&(a.createTriggerIfMissing=s.createTriggerIfMissing),a}function nr(e,t,n){switch(Qo(t)){case"issue":return function(e,t,n){if("issue"!==Qo(t))return null;const s=Ko(t),a=Vo(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes project.default_branch"};const{owner:o,name:r}=zo(s.path_with_namespace),c=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"close":case"closed":return"closed";case"update":case"updated":case"edit":case"edited":return"edited";default:return"opened"===t?"opened":"closed"===t?"closed":e||"unknown"}}(a.action,a.state),l={AGENTRIX_EVENT_NAME:"issue",AGENTRIX_EVENT_ACTION:c,AGENTRIX_ISSUE_NUMBER:String(a.iid),AGENTRIX_GIT_SERVER_ID:e,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:o,AGENTRIX_REPOSITORY_NAME:r,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook"};a.title&&(l.AGENTRIX_ISSUE_TITLE=a.title);const d=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/issues/${t.iid}`:void 0}(s,a);return d&&(l.AGENTRIX_ISSUE_URL=d),{operationPayload:tr(s,i,l,n),action:c}}(e,t,n);case"note":return function(e,t,n){const s=Ko(t),a=Jo(t);if(!s?.path_with_namespace||!a?.note||!0===a.system||!Zo(a.note))return null;const i=Wo(a.noteable_type);if(!i)return null;const o=Go("issue"===i?t.issue:t.merge_request),r=Bo(o?.iid);if(!r)return null;const c="merge_request"===i?Fo(o?.source_branch):void 0,l="merge_request"===i?Fo(o?.target_branch):void 0,d=n.ref||l||s.default_branch||c;if(!d)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes a usable ref"};const p=function(e){switch(e){case void 0:case"create":case"created":return"created";case"update":case"updated":return"updated";case"delete":case"deleted":return"deleted";default:return e||"unknown"}}(a.action),u=er(e,"note",p,s);return u.AGENTRIX_NOTEABLE_TYPE=i,u.AGENTRIX_NOTE_BODY=a.note,a.id&&(u.AGENTRIX_NOTE_ID=String(a.id)),a.url&&(u.AGENTRIX_NOTE_URL=a.url),"issue"===i?u.AGENTRIX_ISSUE_NUMBER=String(r):(u.AGENTRIX_PR_NUMBER=String(r),c&&(u.AGENTRIX_HEAD_REF=c),l&&(u.AGENTRIX_BASE_REF=l)),{operationPayload:tr(s,d,u,n),action:p}}(e,t,n);case"merge_request":return function(e,t,n){const s=Ko(t),a=Xo(t);if(!s?.path_with_namespace||!a?.iid)return null;const i=n.ref||a.target_branch||s.default_branch||a.source_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes target_branch or project.default_branch"};const o=function(e,t){switch(e){case"open":case"opened":return"opened";case"reopen":case"reopened":return"reopened";case"update":case"updated":return"updated";case"merge":case"merged":return"merged";case"close":case"closed":return"closed";default:return"merged"===t?"merged":"closed"===t?"closed":"opened"===t?"opened":e||"unknown"}}(a.action,a.state),r=er(e,"merge_request",o,s);r.AGENTRIX_PR_NUMBER=String(a.iid),a.source_branch&&(r.AGENTRIX_HEAD_REF=a.source_branch),a.target_branch&&(r.AGENTRIX_BASE_REF=a.target_branch),a.title&&(r.AGENTRIX_MR_TITLE=a.title);const c=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/merge_requests/${t.iid}`:void 0}(s,a);return c&&(r.AGENTRIX_MR_URL=c),{operationPayload:tr(s,i,r,n),action:o}}(e,t,n);case"pipeline":return function(e,t,n){const s=Ko(t),a=Yo(t);if(!s?.path_with_namespace||!a?.status||"failed"!==a.status||"trigger"===a.source)return null;const i=n.ref||a.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes object_attributes.ref or project.default_branch"};const o=er(e,"pipeline",a.status,s);o.AGENTRIX_PIPELINE_STATUS=a.status,o.AGENTRIX_REF=i,a.source&&(o.AGENTRIX_PIPELINE_SOURCE=a.source),a.id&&(o.AGENTRIX_PIPELINE_ID=String(a.id)),a.iid&&(o.AGENTRIX_PIPELINE_IID=String(a.iid)),a.sha&&(o.AGENTRIX_SHA=a.sha);const r=function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.id?`${e.web_url}/-/pipelines/${t.id}`:void 0}(s,a);r&&(o.AGENTRIX_PIPELINE_URL=r);const c=function(e){const t=Go(e.merge_request);return Bo(t?.iid)}(t);return c&&(o.AGENTRIX_PR_NUMBER=String(c)),{operationPayload:tr(s,i,o,n),action:a.status}}(e,t,n);default:return null}}function sr(e){const t=Qo(e);if("note"===t){const t=Jo(e);return!0===t?.system?"system_note":Zo(t?.note)?"unsupported_note":"note_command_missing"}if("pipeline"===t){const t=Yo(e);return t?.status&&"failed"!==t.status?"pipeline_status_unsupported":"trigger"===t?.source?"pipeline_source_unsupported":"unsupported_pipeline"}return"issue"===t||"merge_request"===t?"missing_required_payload":"unsupported_event"}function ar(e){return e.secret||e.token}function ir(e,t){return Te("sha256",t).update(e).digest("base64url")}function or(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&&Ce(n,s)}(s,ir(n,ar(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 rr=ht.object({repoRoot:ht.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:ht.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 cr(e,t){return{issueId:rr.parse(e).issueId}}const lr="agentrix_event_broker",dr="/mcp/agentrix-event-broker",pr="change_title",ur="publish_task_preview_url",mr="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:z(),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(`${Ae.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 cr(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:z(),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 gr(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 Lt({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(pr,{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:ht.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(ur,{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:ht.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=Z.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(mr,{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:ht.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:ht.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=rr.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:or(n.credentials,s),dispatcher:n.dispatcher}),i=new Ht({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){_e.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 fr extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="MachineAesKeyUpdateError"}}function yr(e){if(!e)return null;try{const t=G(e);return 32===t.length?t:null}catch{return null}}function vr(e){return!!yr(e.machineAesKey)}const br="agentrix-computer-use";function wr(){const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return r(e)?{available:!0,path:e}:{available:!1,path:e};const t=vt("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=vt("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[A(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 kr(e){try{return p(e).isDirectory()}catch{return!1}}function Ir(e){return"boolean"==typeof e?e:void 0}function Sr(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Tr(e){return[A(e,"skills","cua-driver"),A(n.homedir(),".agents","skills","cua-driver")]}function Cr(){const e=process.env.AGENTRIX_CUA_DRIVER_SKILL_SOURCE?.trim();if(e){const t=Sr(e);return r(A(t,"SKILL.md"))?t:null}const t=[A(n.homedir(),".agents","skills","cua-driver"),A(n.homedir(),".claude","skills","cua-driver"),A(n.homedir(),".openclaw","skills","cua-driver")].filter(e=>Boolean(e));for(const e of t){const t=P(Sr(e));if(r(A(t,"SKILL.md")))return t}return null}function Er(e=Ae.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()):A(n.homedir(),".codex")}(),s=A(Ae.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=wr(),o=xr("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH),l=A(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);A(t,"skills","cua-driver");const m=null!==function(e){for(const t of Tr(e))if(kr(t)&&r(A(t,"SKILL.md")))return t;return null}(t),h=Cr()??void 0,g=function(e){if(!e||"darwin"!==process.platform)return{};const t=vt(e,["doctor","--json"],{encoding:"utf8",timeout:1e4});try{const e=JSON.parse(t.stdout);return{accessibilityGranted:Ir(e.ax_granted),screenRecordingGranted:Ir(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 ${Tr(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 Ar(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=wr();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=vt(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=vt(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 _r(e){const t=Cr(),n=A(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(A(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(M(n),{recursive:!0}),b(t,n,"dir"),null}catch(e){return`Failed to create Cua Driver skill symlink ${n} -> ${t}: ${e instanceof Error?e.message:String(e)}`}}function $r(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 Pr(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 Rr(e){try{if(!v(e).isSymbolicLink())return null;const t=w(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 Mr(){const e=Er(),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=Ae.readSettings()??{};return Ae.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&&(vt(a,["stop"],{encoding:"utf8",timeout:1e4}),t.push("Stopped Cua Driver daemon if it was running."));const i=["/Applications/CuaDriver.app","/Applications/CuaDriverRs.app",A(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_updater.plist"),A(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_daemon.plist"),A(n.homedir(),"Library","LaunchAgents","com.trycua.cua-driver-rs.plist"),A(n.homedir(),"Library","Application Support","Cua Driver"),A(n.homedir(),"Library","Caches","cua-driver"),A(n.homedir(),".cua-driver-rs")];for(const e of i){const n=$r(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const e of[A(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver"]){const n=Pr(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const a of[A(e.codexHome,"skills","cua-driver"),A(n.homedir(),".agents","skills","cua-driver")]){const e=Rr(a);e?s.push(e):t.push(`Removed ${a}.`)}const o=function(e){const t=A(e,"config.toml");try{const n=wr();if(n.available&&n.path&&vt(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=Er();"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 Nr(e=Ae.readSettings(),t){const n=Er(e);if(!n.enabled)return n;const s=[];if(!n.cuaDriverMcpConfigured){t?.("info","COMPUTER_USE","Configuring Cua Driver MCP for Codex");const e=Ar(n.codexHome);e&&s.push(e)}if(!n.cuaDriverSkillPresent){t?.("info","COMPUTER_USE","Configuring Cua Driver skill for Codex");const e=_r(n.codexHome);e&&s.push(e)}const a=Er(e);return 0===s.length?a:{...a,missing:[...a.missing,...s.map(e=>`Automatic Cua Driver configuration failed: ${e}`)]}}function Dr(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=A(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(...Dr(s,t))}return n}function Or(){return A(Ae.agentrixAgentsHomeDir,"companion","claude")}function Ur(e,t){const n=O(A(e,t));return n.startsWith(e)?{absolutePath:n,relativePath:N(e,n)}:null}function jr(e,t,n){const s=A(e,"memory-changes"),a=A(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 Lr(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?jr(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?jr(e,n,{after:t.after}):null}return null}function Hr(e,t){if(!r(A(e,".git")))return"";try{return kt("git",["-C",e,...t],{encoding:"utf8",timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return""}}function qr(e,t,n){const s=n.replace(/[^0-9a-f]/gi,"");return s?Hr(e,["show","--format=","--no-ext-diff",s,"--",t]):""}function Gr(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=Gr(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=Gr(n);if(e)return e}}return""}function Fr(e){if("string"==typeof e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{const e=Gr(JSON.parse(t));if(e)return e}catch{}return e}if(!e||"object"!=typeof e)return"";const t=Gr(e);if(t)return t;const n=e.content;return"string"==typeof n?Fr(n):Array.isArray(n)?n.map(e=>Fr(e)).filter(Boolean).join("\n"):""}function Br(e,t){return Fr(e).trim()||t}function Wr(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 zr(e){return!!e&&"object"==typeof e&&"companion_memory_organization"===e.type}function Kr(e){if(!e)return!1;if(Array.isArray(e))return e.some(Kr);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(Kr)}function Vr(e){if(!e||"object"!=typeof e)return"";const t=e;return"result"===t.type&&"string"==typeof t.result?t.result:""}function Xr(e,t,n=1){if(!e||!t)return[];try{const s=so({dataDir:Ae.resolveDataDir(e,t),taskId:t});try{return[...s.pageRecentMessages(50).data].reverse().filter(e=>"system"!==e.senderType&&Fr(e.message).trim()).slice(0,n).map(e=>({summary:Br(Fr(e.message),""),time:e.createdAt}))}finally{s.close()}}catch{return[]}}function Jr(e,t=1){return Xr("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 Yr(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 cc(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=Xr("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 Qr(e,t=1){const n=A(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=jr(e,{key:s,nextAfter:`${s}T00:00:00.000Z`},{date:s});for(const e of i.events){const n=Br(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 Zr(e,t){const n=[],s=so({dataDir:Ae.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(zr(i)){e=!0,t=!1;continue}if(!e)continue;Kr(i)&&(t=!0);const o="agent"===s.senderType?Vr(i):"";o&&(n.push({time:a.createdAt,summary:Br(o,"记忆整理已运行"),updated:t}),e=!1,t=!1)}}finally{s.close()}return n}function ec(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(...Zr(s,e))}catch{}if(c.length>0)return tc(c,n)}for(const e of[...new Set(o)]){const n=i.includes(e);try{const a=so({dataDir:Ae.resolveDataDir(s,e),taskId:e});try{for(const e of a.pageRecentMessages(160).data){if("agent"!==e.senderType)continue;const s=Fr(e.message);if(!s.trim())continue;if(!n&&!r.some(e=>s.toLowerCase().includes(e.toLowerCase())))continue;const a=Br(s,"heartbeat"===t?"Heartbeat 已运行":"记忆整理已运行");c.push({time:e.createdAt,summary:a,updated:Wr(s)})}}finally{a.close()}}catch{}}return tc(c,n)}function tc(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 nc(e){return"127.0.0.1"===e||"::1"===e||"::ffff:127.0.0.1"===e}const sc=ht.object({id:ht.string(),type:ht.string(),name:ht.string(),baseUrl:ht.string(),apiUrl:ht.string(),oauthServerId:ht.string().nullable().optional(),ownerId:ht.string().nullable().optional(),authModeDefault:ht.string().optional(),executionMode:ht.string().optional(),syncMode:ht.string().optional(),networkMode:ht.string().optional(),githubAppName:ht.string().nullable().optional(),enabled:ht.boolean().optional(),createdAt:ht.string().optional(),updatedAt:ht.string().optional()}).passthrough(),ac=ht.object({platform:ht.string(),enabled:ht.boolean(),enabledBy:ht.enum(["env","settings","marker"]).nullable(),codexHome:ht.string(),codexAvailable:ht.boolean(),codexPath:ht.string().optional(),codexConfigPresent:ht.boolean(),cuaDriverAvailable:ht.boolean(),cuaDriverPath:ht.string().optional(),cuaDriverAccessibilityGranted:ht.boolean().optional(),cuaDriverScreenRecordingGranted:ht.boolean().optional(),cuaDriverMcpConfigured:ht.boolean(),cuaDriverSkillPresent:ht.boolean(),cuaDriverSkillSource:ht.string().optional(),markerPath:ht.string(),missing:ht.array(ht.string())});async function ic(e,t,n){let s;try{return await Promise.race([e,new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)})])}finally{s&&clearTimeout(s)}}function oc(e){return Array.isArray(e)?e[0]:e}function rc(e){return e instanceof Error?e.message:"Unknown error"}async function cc(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:z(),method:t,path:n,body:s},o=await ic(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=Ae.getDaemonControlHost(),v=Ae.getDaemonWebhookHost(),b=mt({logger:!1});b.removeContentTypeParser("application/json"),b.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,{})}),b.setValidatorCompiler(ft),b.setSerializerCompiler(yt);const w=b.withTypeProvider();!function(e,t){const n=t.getSocketClient??(()=>{}),s={credentials:t.credentials,getSocketClient:n,dispatcher:t.dispatcher??hr(t.credentials,n)};e.post(dr,async(e,t)=>{try{await gr(e,t,s)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return _e.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(dr,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(dr,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(b,{credentials:l,getSocketClient:m});const x=e=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),e.header("Access-Control-Allow-Private-Network","true")};w.post("/session-started",{schema:{body:ht.object({sessionId:ht.string(),metadata:ht.any()}),response:{200:ht.object({status:ht.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return _e.debug(`[CONTROL SERVER] Session started: ${t}`),o(t,n),{status:"ok"}}),w.post("/devops-init-complete",{schema:{body:ht.object({taskId:ht.string(),userId:ht.string(),action:ht.enum(["continue","stop"])}),response:{200:ht.object({status:ht.literal("ok")})}}},async e=>{const{taskId:t,userId:n,action:s}=e.body;return _e.info(`[CONTROL SERVER] Agentrix DevOps init complete for task ${t}, action=${s}`),a?.({taskId:t,userId:n,action:s}),{status:"ok"}}),w.post("/devops-init-start",{schema:{body:ht.object({taskId:ht.string(),userId:ht.string()}),response:{200:ht.object({status:ht.literal("ok")})}}},async e=>{const{taskId:t,userId:n}=e.body;return _e.info(`[CONTROL SERVER] Starting Agentrix DevOps init for existing task ${t}`),s?.({taskId:t,userId:n}),{status:"ok"}}),w.post("/prepare-graceful-restart",{schema:{body:ht.object({source:ht.string().optional(),reason:ht.string().optional()}).optional(),response:{200:ht.object({state:ht.enum(["pending_restart","restarting"]),activeSessions:ht.number()}),503:ht.object({error:ht.string()}),403:ht.object({error:ht.string()})}}},async(e,t)=>nc(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"})),w.post("/clear-graceful-restart-gate",{schema:{response:{200:ht.object({success:ht.literal(!0)}),403:ht.object({error:ht.string()})}}},async(e,t)=>nc(e.ip)?(g?.(),{success:!0}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),w.options("/ping",async(e,t)=>(x(t),t.send())),w.get("/ping",{schema:{response:{200:ht.object({status:ht.literal("ok"),machineId:ht.string(),timestamp:ht.string(),controlHost:ht.string(),webhookHost:ht.string(),hasMachineAesKey:ht.boolean()})}}},async(e,t)=>(x(t),{status:"ok",machineId:l.machineId,timestamp:(new Date).toISOString(),controlHost:y,webhookHost:v,hasMachineAesKey:vr(l)})),w.get("/computer-use/status",{schema:{response:{200:ht.object({status:ac}),403:ht.object({error:ht.string()})}}},async(e,t)=>nc(e.ip)?{status:Er()}:t.code(403).send({error:"Computer Use status is only allowed from loopback"})),w.post("/computer-use/install",{schema:{response:{200:ht.object({success:ht.boolean(),status:ac,actions:ht.array(ht.string()),error:ht.string().optional()}),403:ht.object({error:ht.string()})}}},async(e,t)=>{if(!nc(e.ip))return t.code(403).send({error:"Computer Use installation is only allowed from loopback"});try{return function(){let e=Er();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=vt(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=Ar(e.codexHome);s?n.push(s):t.push("Configured Cua Driver MCP for Agentrix Computer Use.")}if(e=Er(),e.cuaDriverSkillPresent)t.push("Cua Driver skill is already available to Agentrix Computer Use.");else{const s=_r(e.codexHome);s?n.push(s):t.push("Linked Cua Driver skill for Agentrix Computer Use.")}const s=function(e){try{return d(M(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=Ae.readSettings()??{};return Ae.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=Er(),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:Er(),actions:[],error:rc(e)}}}),w.post("/computer-use/uninstall",{schema:{response:{200:ht.object({success:ht.boolean(),status:ac,actions:ht.array(ht.string()),error:ht.string().optional()}),403:ht.object({error:ht.string()})}}},async(e,t)=>{if(!nc(e.ip))return t.code(403).send({error:"Computer Use uninstall is only allowed from loopback"});try{return Mr()}catch(e){return{success:!1,status:Er(),actions:[],error:rc(e)}}}),w.post("/machine/aes-key",{schema:{body:ht.object({machineId:ht.string(),machineAesKey:ht.string()}),response:{200:ht.object({success:ht.literal(!0),updated:ht.boolean(),hasMachineAesKey:ht.literal(!0)}),400:ht.object({error:ht.string()}),403:ht.object({error:ht.string()}),409:ht.object({error:ht.string()}),500:ht.object({error:ht.string()})}}},async(e,t)=>{if(!nc(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=Ae){if(t.machineId!==e.machineId)throw new fr("machineId does not match daemon credentials",409);if(!yr(t.machineAesKey))throw new fr("machineAesKey must decode to a 32-byte key",400);const s=await n.readCredentials()??e;if(s.machineId!==e.machineId)throw new fr("stored credentials machineId does not match daemon credentials",409);if(vr(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 _e.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 fr?e.statusCode:500,s=400===n||409===n?n:500,a=e instanceof Error?e.message:"Failed to store machine AES key";return _e.warn(`[CONTROL SERVER] Failed to store recovered machine AES key: ${a}`),t.code(s).send({error:a})}}),w.options("/openers",async(e,t)=>(x(t),t.send())),w.get("/openers",{schema:{response:{200:ht.object({openers:ht.array(ht.object({id:ht.string(),label:ht.string(),kind:ht.enum(["system","file-manager","terminal","editor","ide"]),method:ht.enum(["scheme","cli"]),urlTemplate:ht.string().optional(),supported:ht.boolean()}))})}}},async(e,t)=>(x(t),{openers:await Ls()})),w.options("/open",async(e,t)=>(x(t),t.send())),w.options("/pick-directory",async(e,t)=>(x(t),t.send())),w.post("/open",{schema:{body:ht.object({path:ht.string(),openerId:ht.string(),userId:ht.string().optional(),taskId:ht.string().optional()}),response:{200:ht.object({success:ht.boolean(),error:ht.string().optional()})}}},async(e,t)=>{x(t);const{path:n,openerId:s,userId:a,taskId:i}=e.body;return await async function({openerId:e,targetPath:t,userId:n,taskId:s}){const a=qs(Ws()).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=E.resolve(e);if(!E.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=Ae.getTaskCwd(t,n);if(e&&!function(e,t){const n=E.relative(t,e);return""===n||!n.startsWith("..")&&!E.isAbsolute(n)}(s,E.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 _e.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),w.post("/pick-directory",{schema:{body:ht.object({defaultPath:ht.string().optional()}),response:{200:ht.object({path:ht.string().nullable(),error:ht.string().optional()})}}},async(e,t)=>{x(t);try{return{path:Hs(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),w.post("/companion/ensure",{schema:{body:ht.object({preferredLanguage:ht.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:ht.object({agentDir:ht.string()})}}},async e=>await to({preferredLanguage:e.body?.preferredLanguage,credentials:l})),w.post("/companion/probe",{schema:{response:{200:ht.object({success:ht.boolean(),error:ht.string().optional()})}}},async()=>await ci()),w.get("/companion/workspace/status",{schema:{response:{200:ht.object({exists:ht.boolean()})}}},async()=>{const e=Or();return{exists:r(e)}}),w.get("/companion/workspace",{schema:{response:{200:ht.object({files:ht.array(ht.object({name:ht.string(),path:ht.string(),size:ht.number(),modifiedAt:ht.number(),isDirectory:ht.boolean()}))})}}},async()=>{const e=Or();return r(e)?{files:Dr(e,e)}:{files:[]}}),w.get("/companion/file",{schema:{querystring:ht.object({path:ht.string()}),response:{200:ht.object({content:ht.string()}),404:ht.object({error:ht.string()})}}},async(e,t)=>{const n=Or(),s=O(A(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),w.put("/companion/file",{schema:{body:ht.object({path:ht.string(),content:ht.string()}),response:{200:ht.object({success:ht.boolean()}),400:ht.object({error:ht.string()})}}},async(e,t)=>{const n=Or(),s=O(A(n,e.body.path));return s.startsWith(n)?(d(M(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),w.get("/companion/file/versions",{schema:{querystring:ht.object({path:ht.string(),limit:ht.coerce.number().int().positive().max(50).optional(),skip:ht.coerce.number().int().min(0).optional()}),response:{200:ht.object({versions:ht.array(ht.object({commit:ht.string(),shortCommit:ht.string(),subject:ht.string(),body:ht.string(),authoredAt:ht.string()})),hasMore:ht.boolean(),nextSkip:ht.number()}),404:ht.object({error:ht.string()})}}},async(e,t)=>{const n=Or(),s=Ur(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=Hr(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"})}),w.get("/companion/file/diff",{schema:{querystring:ht.object({path:ht.string(),commit:ht.string()}),response:{200:ht.object({commit:ht.string(),path:ht.string(),diff:ht.string()}),404:ht.object({error:ht.string()})}}},async(e,t)=>{const n=Or(),s=Ur(n,e.query.path);return s&&r(s.absolutePath)?{commit:e.query.commit,path:s.relativePath,diff:qr(n,s.relativePath,e.query.commit)}:t.code(404).send({error:"File not found"})}),w.get("/companion/memory-events",{schema:{querystring:ht.object({after:ht.string().optional(),date:ht.string().optional()}),response:{200:ht.object({after:ht.string().optional(),date:ht.string().optional(),nextAfter:ht.string(),events:ht.array(ht.object({id:ht.string(),createdAt:ht.union([ht.string(),ht.number()]),title:ht.string(),summary:ht.string(),files:ht.array(ht.string()),actions:ht.array(ht.string()).optional(),source:ht.string().optional(),trigger:ht.string().optional(),commit:ht.string().optional()})),hasMore:ht.boolean()}),400:ht.object({error:ht.string()})}}},async(e,t)=>{const n=Or();if(!e.query.after&&!e.query.date)return t.code(400).send({error:"Use after or date"});return Lr(n,e.query)||t.code(400).send({error:"Invalid after or date"})}),w.get("/companion/recent-activity",{schema:{querystring:ht.object({limit:ht.coerce.number().int().positive().max(50).optional()}),response:{200:ht.object({chats:ht.array(ht.object({type:ht.literal("chat"),title:ht.string(),summary:ht.string(),time:ht.string(),status:ht.string().optional()})),tasks:ht.array(ht.object({type:ht.literal("task"),title:ht.string(),summary:ht.string(),time:ht.string(),status:ht.string().optional()})),memories:ht.array(ht.object({type:ht.literal("memory"),title:ht.string(),summary:ht.string(),time:ht.string(),status:ht.string().optional()}))})}}},async e=>{const t=Or(),n=e.query.limit??1,s=A(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([Yr(a,m?.(),n),Promise.resolve(Jr(a,n)),Promise.resolve(Qr(t,n))]);return{chats:o,tasks:i,memories:l}}),w.get("/companion/config",{schema:{querystring:ht.object({recentLimit:ht.coerce.number().int().positive().max(50).optional()}),response:{200:ht.object({heartbeatIntervalMs:ht.number(),heartbeatEnabled:ht.boolean(),lastHeartbeatTimestamp:ht.string().nullable(),lastHeartbeatDate:ht.string().nullable(),lastMaintenanceHeartbeatTimestamp:ht.string().nullable(),heartbeatTriggerCount:ht.number(),lastInteractionTimestamp:ht.string().nullable(),memoryOrganizationEnabled:ht.boolean(),memoryOrganizationIntervalHours:ht.number(),allowedMemoryOrganizationIntervalHours:ht.array(ht.number()),lastMemoryOrganizationTimestamp:ht.string().nullable(),memoryOrganizationTaskId:ht.string().nullable(),heartbeatRecentRecords:ht.array(ht.object({time:ht.string(),summary:ht.string(),updated:ht.boolean()})),memoryOrganizationRecentRecords:ht.array(ht.object({time:ht.string(),summary:ht.string(),updated:ht.boolean()}))})}}},async e=>{const t=Or(),n=e.query.recentLimit??1,s=A(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=co(y.memoryOrganizationIntervalHours),"string"==typeof y.lastMemoryOrganizationTimestamp&&(g=y.lastMemoryOrganizationTimestamp),"string"==typeof y.memoryOrganizationTaskId&&(f=y.memoryOrganizationTaskId)}catch{}const v=ec(y,"heartbeat",n),b=ec(y,"memory-organization",n);return{heartbeatIntervalMs:a,heartbeatEnabled:i,lastHeartbeatTimestamp:o,lastHeartbeatDate:l,lastMaintenanceHeartbeatTimestamp:d,heartbeatTriggerCount:p,lastInteractionTimestamp:u,memoryOrganizationEnabled:m,memoryOrganizationIntervalHours:h,allowedMemoryOrganizationIntervalHours:[...oo],lastMemoryOrganizationTimestamp:g,memoryOrganizationTaskId:f,heartbeatRecentRecords:v,memoryOrganizationRecentRecords:b}}),w.put("/companion/config",{schema:{body:ht.object({heartbeatIntervalMs:ht.number().optional(),heartbeatEnabled:ht.boolean().optional(),memoryOrganizationEnabled:ht.boolean().optional(),memoryOrganizationIntervalHours:ht.number().optional()}),response:{200:ht.object({success:ht.boolean()}),400:ht.object({error:ht.string()})}}},async(t,n)=>{const s=Or(),a=A(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(!ro(m))return n.code(400).send({error:`memoryOrganizationIntervalHours must be one of: ${oo.join(", ")}`});i.memoryOrganizationIntervalHours=m}return d(M(a),{recursive:!0}),u(a,JSON.stringify(i,null,2),"utf-8"),e.companionScheduler?.reloadStateAndReschedule(),{success:!0}}),w.post("/agent/install",{schema:{body:ht.object({agentId:ht.string(),gitUrl:ht.string(),branch:ht.string().optional(),subDir:ht.string().optional()}),response:{200:ht.object({agentDir:ht.string()}),500:ht.object({error:ht.string()})}}},async(e,t)=>{try{return await oa(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),w.post("/git-server/register",{schema:{body:ht.object({name:ht.string().min(1),baseUrl:ht.string().url(),apiUrl:ht.string().url()}),response:{200:ht.object({gitServer:ht.object({id:ht.string(),type:ht.string(),name:ht.string(),baseUrl:ht.string(),apiUrl:ht.string()}),machineId:ht.string()}),502:ht.object({error:ht.string()})}}},async(e,t)=>{try{const n=await cc(m?.(),"POST","/v1/git-servers/machine-register",{...e.body,machineId:l.machineId});return t.send(n)}catch(n){const s=rc(n);return _e.warn(`[GIT SERVER] register failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),w.post("/git-server/complete",{schema:{body:ht.object({gitServerId:ht.string().min(1)}),response:{200:ht.object({success:ht.boolean(),machineId:ht.string()}),502:ht.object({error:ht.string()})}}},async(e,t)=>{try{const n=await cc(m?.(),"POST",`/v1/git-servers/${encodeURIComponent(e.body.gitServerId)}/machine-complete`,{machineId:l.machineId});return t.send(n)}catch(n){const s=rc(n);return _e.warn(`[GIT SERVER] complete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),w.post("/git-server/list",{schema:{response:{200:ht.object({gitServers:ht.array(sc)}),502:ht.object({error:ht.string()})}}},async(e,t)=>{try{const e=await cc(m?.(),"POST","/v1/git-servers/machine-list",{machineId:l.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=rc(e);return _e.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),w.post("/git-server/delete",{schema:{body:ht.object({gitServerId:ht.string().min(1)}),response:{200:ht.object({success:ht.boolean(),machineId:ht.string()}),502:ht.object({error:ht.string()})}}},async(e,t)=>{try{const n=await cc(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=rc(n);return _e.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),w.post("/webhooks/gitlab/:gitServerId",{schema:{params:ht.object({gitServerId:ht.string()}),body:ht.record(ht.string(),ht.unknown()),response:{200:ht.object({status:ht.enum(["triggered","ignored","failed"]),eventType:ht.string(),action:ht.string().optional(),pipeline:ht.unknown().optional(),reason:ht.string().optional(),errorMessage:ht.string().optional(),errorDetail:ht.string().optional(),upstreamStatus:ht.number().optional()}),400:ht.object({error:ht.string()}),401:ht.object({error:ht.string()}),403:ht.object({error:ht.string()}),404:ht.object({error:ht.string()}),502:ht.object({error:ht.string()}),500:ht.object({error:ht.string()})}}},async(e,t)=>{const n=xe(),s=Date.now(),a=function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body),i=function(e){const t=Qo(e);if("issue"===t){const t=Vo(e);if(!t?.iid)return null}else if("merge_request"===t){const t=Xo(e);if(!t?.iid)return null}else if("note"===t){const t=Jo(e);if(!0===t?.system||!Zo(t?.note))return null;const n=Wo(t?.noteable_type),s="issue"===n?Go(e.issue):"merge_request"===n?Go(e.merge_request):null;if(!Bo(s?.iid))return null}else if("pipeline"===t){const t=Yo(e);if("failed"!==t?.status||"trigger"===t.source)return null}else if("issue"!==t&&"merge_request"!==t)return null;return function(e){const t=Ko(e);return t?.id?String(t.id):t?.path_with_namespace??null}(e)}(e.body),o=e.ip||"-",r="string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-",c=(a,i)=>{const o=Date.now()-s,r=function(e){if(!e||"object"!=typeof e)return"type="+typeof e;const t=e;if("string"==typeof t.error)return`error=${t.error}`;const n=String(t.status??"-"),s=String(t.eventType??"-"),a=String(t.action??"-"),i=String(t.reason??"-"),o=String(t.upstreamStatus??"-"),r=String(t.errorMessage??"-"),c=function(e){if(!e||"object"!=typeof e)return"-";const t=e,n=t.id??t.iid??"-",s=t.status??"-",a=t.ref??"-",i=t.web_url??t.webUrl??"-";return`id=${String(n)}, status=${String(s)}, ref=${String(a)}, webUrl=${String(i)}`}(t.pipeline);return`status=${n}, eventType=${s}, action=${a}, reason=${i}, upstreamStatus=${o}, errorMessage=${r}, pipeline=${c}`}(i);return _e[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};_e.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}, remote=${o}, userAgent=${r}`);const l=await Jn();if(!l)return c(500,{error:"Git server encryption key not available"});const d=Qn(e.params.gitServerId,l),p=d?.webhookSecret;if(!p)return c(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});if(!function(e,t){if("string"!=typeof e)return!1;const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&Ce(n,s)}(e.headers["x-gitlab-token"],p))return c(401,{error:"Invalid GitLab webhook token"});const u=oc(e.headers["x-gitlab-event-uuid"])??oc(e.headers["x-gitlab-delivery"]),h=a;(async function(e,t,n,s,a){if(!a?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:z(),provider:"gitlab",gitServerId:e,deliveryId:n,eventType:s,payload:t},o=await ic(a.sendWithAck("repository-inbox-webhook",i),5e3,"Timed out waiting for repository inbox webhook ack");if("success"!==o.status)throw new Error(o.message||"API failed to process repository inbox webhook")})(e.params.gitServerId,e.body,u,h,m?.()).catch(t=>{const s=t instanceof Error?t.message:String(t);_e.warn(`[GITLAB WEBHOOK] inbox side-channel failed: hookId=${n}, gitServer=${e.params.gitServerId}, message=${s}`)});const g=es(e.params.gitServerId,l);if(!g)return c(403,{error:`No PAT configured for git server ${e.params.gitServerId}`});try{const t=Yn(e.params.gitServerId),s=t?.apiUrl;if(!s)return c(400,{error:`GitLab API URL is not configured for git server ${e.params.gitServerId}`});let o;if(i)if(o=d.projectTriggerTokens?.[i],o)_e.info(`[GITLAB WEBHOOK] pipeline trigger token reused: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`);else{const t=function(e){const t=Ko(e);return t?.path_with_namespace?t.id?{projectId:t.id}:{projectPath:t.path_with_namespace}:null}(e.body);if(!t)return c(400,{error:"GitLab webhook payload is missing project information"});_e.info(`[GITLAB WEBHOOK] ensuring pipeline trigger token: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}, mode=create_or_reuse`);const a=new ss(s,g,{gitServerId:e.params.gitServerId}),r=await a.executeOperation("ensurePipelineTriggerToken",t);if(!r||"object"!=typeof r||"string"!=typeof r.token)return c(502,{error:"Failed to create GitLab pipeline trigger token"});o=r.token,function(e,t,n){Xn.saveGitLabWebhookBridgeSecrets(e,t,n)}(e.params.gitServerId,{webhookSecret:p,projectTriggerTokens:{...d.projectTriggerTokens??{},[i]:o}},l),_e.info(`[GITLAB WEBHOOK] pipeline trigger token stored: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`)}return _e.info(`[GITLAB WEBHOOK] triggering pipeline: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}`),c(200,await async function({gitServerId:e,payload:t,config:n,pat:s}){const a=Qo(t),i=nr(e,t,n);if(!i)return{status:"ignored",eventType:a,reason:sr(t)};if(!n.apiUrl)throw{status:400,message:"GitLab API URL is required"};const o=new ss(n.apiUrl,s,{gitServerId:e});let r;try{r=await o.executeOperation("triggerPipeline",i.operationPayload)}catch(e){const t=function(e){const t=e;return{message:"string"==typeof t?.message?t.message:e instanceof Error?e.message:"Failed to trigger GitLab pipeline",detail:"string"==typeof t?.detail?t.detail:void 0,upstreamStatus:"number"==typeof t?.status?t.status:void 0}}(e);return{status:"failed",eventType:a,action:i.action,reason:"pipeline_trigger_failed",errorMessage:t.message,errorDetail:t.detail,upstreamStatus:t.upstreamStatus}}return{status:"triggered",eventType:a,action:i.action,pipeline:r}}({gitServerId:e.params.gitServerId,payload:e.body,pat:g,config:{apiUrl:s,triggerToken:o}}))}catch(t){const s=t,a="number"==typeof s.status&&s.status>=400&&s.status<600?s.status:500,i="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return _e.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, message=${i}`),c(a,{error:i})}}),w.post("/schedule",{schema:{body:ht.object({task:ht.string(),type:ht.enum(["once","recurring"]),due:ht.string().optional(),cron:ht.string().optional(),timezone:ht.string().optional(),timeType:ht.enum(["utc","local"]).optional()}),response:{200:ht.object({id:ht.string(),task:ht.string(),type:ht.enum(["once","recurring"]),due:ht.string().optional(),cron:ht.string().optional(),timezone:ht.string().optional(),timeType:ht.enum(["utc","local"]).optional(),createdAt:ht.string()}),400:ht.object({error:ht.string()}),503:ht.object({error:ht.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'})}),w.get("/schedule",{schema:{response:{200:ht.object({tasks:ht.array(ht.object({id:ht.string(),task:ht.string(),type:ht.enum(["once","recurring"]),due:ht.string().optional(),cron:ht.string().optional(),timezone:ht.string().optional(),timeType:ht.enum(["utc","local"]).optional(),createdAt:ht.string()}))}),503:ht.object({error:ht.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),w.delete("/schedule/:id",{schema:{params:ht.object({id:ht.string()}),response:{200:ht.object({success:ht.boolean()}),404:ht.object({error:ht.string()}),503:ht.object({error:ht.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 k=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);w.options("/channels",async(e,t)=>(x(t),t.send())),w.options("/channels/platforms",async(e,t)=>(x(t),t.send())),w.options("/channels/wechat/login/qrcode",async(e,t)=>(x(t),t.send())),w.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(x(t),t.send())),w.options("/channels/:id",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/connect",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/disconnect",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/contacts",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/bindings",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/bindings/:bindingId",async(e,t)=>(x(t),t.send())),w.options("/channels/task-message",async(e,t)=>(x(t),t.send())),w.options("/channels/group-history",async(e,t)=>(x(t),t.send())),w.get("/channels",{schema:{response:{200:ht.object({channels:ht.array(Do)}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return{channels:n.getChannels()}}),w.get("/channels/platforms",{schema:{response:{200:ht.object({platforms:ht.array(ht.enum($o))})}}},async(e,t)=>(x(t),{platforms:[...$o]})),w.get("/channels/wechat/login/qrcode",{schema:{response:{200:ht.object({qrcode:ht.string(),qrcodeContent:ht.string(),qrcodeTerminal:ht.string(),baseUrl:ht.string()}),502:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);try{return await _o.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return _e.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),w.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:ht.object({qrcode:ht.string()}),response:{200:ht.object({status:ht.string(),token:ht.string().optional(),baseUrl:ht.string().optional(),ilinkBotId:ht.string().optional(),ilinkUserId:ht.string().optional()}),502:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);try{return await _o.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return _e.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),w.post("/channels",{schema:{body:Oo,response:{200:Do,503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return n.addChannel(e.body)}),w.delete("/channels/:id",{schema:{params:ht.object({id:ht.string()}),response:{200:ht.object({success:ht.boolean()}),404:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),w.post("/channels/:id/connect",{schema:{params:ht.object({id:ht.string()}),response:{200:Do,404:ht.object({error:ht.string()}),500:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/:id/disconnect",{schema:{params:ht.object({id:ht.string()}),response:{200:Do,404:ht.object({error:ht.string()}),500:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.get("/channels/:id/contacts",{schema:{params:ht.object({id:ht.string()}),response:{200:ht.object({contacts:ht.array(jo)}),404:ht.object({error:ht.string()}),500:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.get("/channels/:id/bindings",{schema:{params:ht.object({id:ht.string()}),response:{200:ht.object({bindings:ht.array(Uo)}),404:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/task-message",{schema:{body:ht.object({taskId:ht.string(),content:ht.string().optional(),attachments:ht.array(ht.object({filePath:ht.string(),fileName:ht.string().optional(),mimeType:ht.string().optional(),kind:ht.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:ht.object({channelId:ht.string(),chatId:ht.string()}).optional()}),response:{200:ht.object({success:ht.boolean()}),404:ht.object({error:ht.string()}),503:ht.object({error:ht.string()}),500:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/group-history",{schema:{body:ht.object({taskId:ht.string(),limit:ht.number().int().positive().max(100).optional(),beforeSeq:ht.number().int().positive().optional(),afterSeq:ht.number().int().nonnegative().optional(),target:ht.object({channelId:ht.string(),chatId:ht.string(),platform:ht.string().optional(),chatType:ht.string().optional(),chatName:ht.string().optional()})}),response:{200:ht.object({historyXml:ht.string(),hasMoreBefore:ht.boolean(),hasMoreAfter:ht.boolean()}),400:ht.object({error:ht.string()}),503:ht.object({error:ht.string()}),500:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.delete("/channels/:id/bindings/:bindingId",{schema:{params:ht.object({id:ht.string(),bindingId:ht.string()}),response:{200:ht.object({success:ht.boolean()}),404:ht.object({error:ht.string()}),503:ht.object({error:ht.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/list",{schema:{response:{200:ht.object({children:ht.array(ht.object({startedBy:ht.string(),taskId:ht.string(),pid:ht.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),w.post("/stop-session",{schema:{body:ht.object({sessionId:ht.string()}),response:{200:ht.object({success:ht.boolean()})}}},async e=>{const{sessionId:t}=e.body;return _e.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),w.post("/stop",{schema:{response:{200:ht.object({status:ht.string()})}}},async()=>(_e.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{_e.debug("[CONTROL SERVER] Triggering daemon shutdown"),i()},50),{status:"stopping"})),"127.0.0.1"!==y&&_e.warn(`[CONTROL SERVER] Listening on ${y}; ensure daemon control endpoints are protected by network policy`);const I=e=>new Promise((t,n)=>{b.listen({port:e,host:y},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{e=await I(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw _e.info("[CONTROL SERVER] Failed to start:",t),t;_e.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await I(0)}const t=parseInt(e.split(":").pop());_e.info(`[CONTROL SERVER] Started on port ${t}`),f({port:t,host:y,webhookHost:v,stop:async()=>{await b.close(),_e.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw _e.info("[CONTROL SERVER] Failed to start:",e),e})})}function dc(e,t={}){const n=$e(),s=A(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw _e.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return ct(process.execPath,a,t)}const pc={".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"},uc={"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 mc(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=$(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=$(s);if(e)return e}return""}catch{return""}}(e),i=s.headers.get("content-type"),o=i?.split(";")[0].trim()||function(e){const t=e.toLowerCase();return pc[t]||"application/octet-stream"}(a),r=a||function(e){return uc[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=_(t);c=n&&$(n)?n:`${xe()}${r||".dat"}`}catch{c=`${xe()}${r||".dat"}`}else c=`${xe()}${r||".dat"}`;const d=A(t,c),p=s.body,u=l(d);return await Qe(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)}`)}}async function hc(e,t){const{attachmentsDir:n,log:s}=t;if(!Array.isArray(e.message.content))return e;const a=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","IMAGE",`Downloading image to local attachment: ${s}`);const{filePath:a,mimeType:i}=await mc(s,t,!0);return n?.("info","IMAGE",`Image saved to: ${a}`),{type:"text",text:`Image file: ${a}\nType: ${i}`}}catch(t){return n?.("error","IMAGE",`Error downloading image to file: ${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n,s):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","DOCUMENT",`Downloading document from: ${s}`);const{filePath:a,mimeType:i,filename:o}=await mc(s,t,!0);return n?.("info","DOCUMENT",`Document downloaded to: ${a}`),{type:"text",text:`Document: ${a}\nTitle: ${e.title||o}\nType: ${i}`}}catch(t){return n?.("error","DOCUMENT",`Error processing document: ${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n,s):e));return{...e,message:{...e.message,content:a}}}const gc="Agentrix-DevOps",fc="main";function yc(e){return(e.supportedFeatures??[]).includes(ee)}function vc(e){return"zh-Hans"===e.preferredLanguage||`${process.env.AGENTRIX_LANG??""} ${process.env.LANG??""}`.toLowerCase().includes("zh")?"zh-Hans":"en"}function bc(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 wc(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 xc(e,t){return A(Ae.resolveDataDir(e,t),"devops-init")}function kc(e,t){return A(xc(e,t),"original-input.json")}function Ic(e,t){return A(xc(e,t),"handoff.json")}function Sc(e){const t=xc(e.userId,e.taskId);d(t,{recursive:!0}),u(kc(e.userId,e.taskId),JSON.stringify(e,null,2))}function Tc(e,t){const n=kc(e,t);return r(n)?JSON.parse(c(n,"utf-8")):null}function Cc(e,t){const n=Ic(e,t);if(!r(n))return null;const s=JSON.parse(c(n,"utf-8"));return f(n),s}class Ec{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:z(),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 _e.warn(`[SESSION] Missing PID for task ${e}`);_e.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 Ae.getSecretKey();if(!t)return;const n=W(G(e.dataEncryptionKey),t);if(!n)return void _e.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=te(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:_e.warn("[SESSION] Failed to decrypt task message")}async persistCreateTaskStart(e){const t=Ae.resolveDataDir(e.userId,e.taskId),n=Ae.resolveAttachmentsDir(e.userId,e.taskId),s=so({dataDir:t,taskId:e.taskId});try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:t.sequence??0});let a=null;if(t.message){let e=t.message;ne(e)&&(e=await hc(e,{attachmentsDir:n,log:(e,t,n)=>_e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),a=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return a}finally{s.close()}}async persistResumeTaskStart(e){const t=Ae.resolveDataDir(e.userId,e.taskId),n=Ae.resolveAttachmentsDir(e.userId,e.taskId),s=so({dataDir:t,taskId:e.taskId}),a=e.eventData.sequence;if(null==a)throw new Error(`Missing resume sequence for task ${e.taskId}`);try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:a});let i=null;if(t.message){let e=t.message;ne(e)&&(e=await hc(e,{attachmentsDir:n,log:(e,t,n)=>_e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),i=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return i}finally{s.close()}}async processTaskMessageAttachments(e){if("task-message"!==e.event)return;const t=e.eventData;if(!t.message||!ne(t.message))return;const n=Ae.resolveAttachmentsDir(e.userId,e.taskId),s=await hc(t.message,{attachmentsDir:n,log:(e,t,n)=>_e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)});e.eventData={...t,message:s}}trackWorkerProcess(e,t){const n={startedBy:"daemon",pid:t.pid,childProcess:t,taskId:e.taskId};this.pidToTrackedSession.set(t.pid,n),t.on("exit",(n,s)=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId),this.maybeContinueAfterDevOpsInit(e).catch(t=>{_e.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=Cc(e.userId,e.taskId);t&&(_e.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=Tc(e,t);if(!n)return void _e.warn(`[DEVOPS_INIT] Missing original task input for ${t}; cannot continue original worker`);if(_e.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),Ae.writeTaskInput(n);const a={eventId:z(),status:"success",opCode:n.eventId};await this.startWorkerInternal(n,"create-task",a)}restoreOriginalWorkerAfterSlashDevOpsInit(e){const t=so({dataDir:Ae.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const n=t.pageRecentMessages(1).data[0]?.localSequence??0;t.updateAgentLastSequence(e.agentId,n),_e.info(`[DEVOPS_INIT] Restored original worker ${e.agentId} for task ${e.taskId} at sequence ${n}; waiting for the next user message`)}finally{t.close()}Ae.writeTaskInput(e)}positionOriginalWorkerHistoryCursor(e,t){if(null===t)return void _e.warn(`[DEVOPS_INIT] Original worker message for task ${e.taskId} has no local sequence; cannot isolate DevOps init history`);const n=so({dataDir:Ae.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),_e.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:z(),taskId:e.taskId,agentSessionId:e.agentSessionId,cwd:e.cwd??e.userCwd}),void _e.info(`[DEVOPS_INIT] Restored original agent session for task ${e.taskId}`);t.send("reset-task-session",{eventId:z(),taskId:e.taskId}),_e.info(`[DEVOPS_INIT] Cleared DevOps init agent session for task ${e.taskId}`)}else _e.warn(`[DEVOPS_INIT] No daemon socket client available to sync task session for ${e.taskId}`)}completeDevOpsInit(e){_e.info(`[DEVOPS_INIT] Completion received for task ${e.taskId}, action=${e.action}`),function(e,t,n){const s=xc(e,t);d(s,{recursive:!0}),u(Ic(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=>{_e.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after completion signal:`,t)})},100)}startDevOpsInit(e){this.startDevOpsInitAsync(e).catch(t=>{_e.error(`[DEVOPS_INIT] Failed to start slash-command DevOps init for task ${e.taskId}:`,t)})}async startDevOpsInitAsync(e){const t=Ae.readTaskInput(e.userId,e.taskId);Sc(t);const n=await this.buildDevOpsWorkerInput(t,!0);Ae.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:z(),status:"success",opCode:e.eventId};return void await this.startWorkerInternal(e,t,n)}_e.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 _e.info(`[DEVOPS_INIT] Original worker for task ${t} is already running with PID ${s.pid}`);if(s)continue;const a=Cc(e,t);if(!a)return void _e.info(`[DEVOPS_INIT] Handoff for task ${t} was already consumed`);if(_e.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)}_e.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:z(),status:"success",opCode:e.eventId},s=this.createWorkerGateAck(e.eventId);if(s)return _e.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)),Ae.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const a=this.taskToStartPromise.get(e.taskId);if(a)return _e.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===gc||!yc(e))return e;const t=Tc(e.userId,e.taskId);if(!t||"agentSessionId"in t)return e;_e.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(!yc(e)||e.agentId===gc)return e;if(this.isLocalDirectoryDevOpsTarget(e)){if(!function(e,t={}){const n=t.checkLocalState??!0,s=A(e,".agentrix"),a=A(s,"env"),i=A(a,"init"),o=A(i,"state","local"),c=!r(s),l=!r(A(a,"README.md")),d=!r(A(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}}(Ae.resolveProjectCWD(e.userCwd,e.userId,e.taskId),{checkLocalState:!0}).needsInit)return _e.info(`[DEVOPS_INIT] Local project init state complete for task ${e.taskId}; starting original worker`),e}else{if(!this.isCodeRepositoryDevOpsTarget(e))return _e.info(`[DEVOPS_INIT] No project directory or code repository selected for task ${e.taskId}; skipping Agentrix DevOps init`),e;_e.info(`[DEVOPS_INIT] Code repository target selected for task ${e.taskId}; starting Agentrix-DevOps without local init-state precheck`)}Sc(e);const t=await this.buildDevOpsWorkerInput(e,!1);return _e.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=A(Ae.agentrixAgentsHomeDir,gc),t=A(Ae.agentrixHomeDir,"tmp","agentrix-agent-devops-init"),n=`${e}.tmp-${Date.now()}`,s=`${e}.backup-${Date.now()}`;d(A(Ae.agentrixHomeDir,"tmp"),{recursive:!0}),r(A(t,".git"))?(kt("git",["fetch","--depth=1","origin",`${fc}:refs/remotes/origin/${fc}`],{cwd:t,stdio:"pipe"}),kt("git",["checkout",fc],{cwd:t,stdio:"pipe"}),kt("git",["reset","--hard",`origin/${fc}`],{cwd:t,stdio:"pipe"})):(h(t,{recursive:!0,force:!0}),kt("git",["clone","--depth=1","--branch",fc,"https://github.com/xmz-ai/agentrix-agent.git",t],{stdio:"pipe"}));const a=A(t,"agentrix-dev-init");if(!r(A(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}),ra(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"===vc(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?z():i.eventId,agentId:gc,agentType:"claude",agentDir:n,eventData:{...a,eventId:z(),senderType:"system",senderId:"agentrix-devops-init",senderName:"Agentrix DevOps init",message:{uuid:qt(),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 _e.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;const a=this.getAliveSessionByTaskId(e.taskId);if(a)return _e.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=Ae.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-CWSO7ijQ.mjs").then(function(e){return e.d}),{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);_e.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${r}`),l=ct(r,{shell:!0,cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),_e.info(`[SESSION] Worker started with sandbox, PID: ${l.pid}`)}catch(t){return _e.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=dc(o,{cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),_e.info(`[SESSION] Worker started without sandbox, PID: ${l.pid}`);return process.env.DEBUG&&(l.stdout?.on("data",e=>{_e.debug(`[Daemon] worker stdout: ${e.toString()}`)}),l.stderr?.on("data",e=>{_e.debug(`[Daemon] worker stderr: ${e.toString()}`)})),l.pid?(_e.info(`[SESSION] Worker started, PID: ${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"),_e.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"),_e.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){_e.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){_e.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return _e.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(){_e.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){_e.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:z(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return _e.warn(`[SESSION] Rejecting hive-publish for task ${e.taskId}: ${n.message}`),n;Ae.writeTaskInput(e);try{const n=dc(["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=>{_e.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{_e.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;_e.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:z(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return _e.warn(`[SESSION] Rejecting hive-install for task ${e.taskId}: ${n.message}`),n;Ae.writeTaskInput(e);try{const n=dc(["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=>{_e.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{_e.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;_e.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:z(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return _e.warn(`[SESSION] Rejecting deployment for task ${e.taskId}: ${n.message}`),n;Ae.writeTaskInput(e);try{const n=dc(["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=>{_e.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{_e.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;_e.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 Ac{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=ut()}async initialize(e){if(this.settings=e,!e.enabled)return _e.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!Gt(this.platform))return _e.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL(Ae.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new Ft,await this.networkManager.initialize(t),_e.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw _e.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=Ae.resolveUserWorkSpaceDir(t),a=Ae.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=ze.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new Bt(this.networkManager,c);return this.workerSandboxes.set(e,l),_e.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return _e.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 _e.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),_e.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){_e.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),_e.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,_e.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class _c{constructor(e,t){this.client=e,this.machineId=t;const n=Ae.agentrixAgentsHomeDir,s=A(n,"companion"),a=A(s,"claude");this.bootstrapPath=A(a,"BOOTSTRAP.md"),this.countPath=A(s,"BOOTSTRAP.count"),this.stateFilePath=A(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?_e.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):(_e.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):_e.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 _e.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void _e.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return _e.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),_e.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:z(),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){_e.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 $c(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function Pc(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 Rc(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 Mc(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 Nc(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 Dc(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class Oc{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:$c((t=e.credentials).appId,"appId"),appSecret:$c(t.appSecret,"appSecret")},this.client=new Wt.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:Wt.AppType.SelfBuild,domain:Wt.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 Wt.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:Wt.Domain.Feishu,loggerLevel:Wt.LoggerLevel.info,onReady:()=>{_e.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{_e.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{_e.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{_e.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new Wt.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: ${Nc(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:x(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:x(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?(_e.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return _e.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 _e.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 _e.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${Nc(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=An(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 _e.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${Nc(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 _e.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){_e.warn(`[CHANNEL][LARK] bot identity lookup failed: ${Nc(e)}`)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}resolveLarkFileType(e,t){const n=$(e).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 _e.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:Mc(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:Pc(n),fileKey:i?Dc(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?Dc(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:Rc(t.create_time??e?.create_time??e?.ts),raw:e}}}const Uc="https://api.telegram.org",jc=4e4,Lc=1e3;function Hc(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function qc(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Gc(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function Fc(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function Bc(e){return e.photo?.[e.photo.length-1]?.file_id}class Wc{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=Lc;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=qc(e.token)??qc(e.botToken)??qc(e.bot_token);return{token:t||Hc(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:jc}),this.polling=!0,this.retryDelayMs=Lc,this.pollPromise=this.pollLoop(),this.setState("connected"),_e.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:jc})}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 At(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:jc})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:jc});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||_(n.file_path);return await Pn(`${Uc}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return _e.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:jc});return t.title||Gc(t)||t.username||e}catch(t){return _e.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:jc});return Gc(t)||t.username||e}catch(t){return _e.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:jc,isPoll:!0});this.retryDelayMs=Lc,"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));_e.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(`${Uc}/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(`${Uc}/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 _e.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||xe()),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?Gc(t.from):void 0,type:Fc(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:Bc(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 zc(e){const t=Qc(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${Vc({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 Kc(e){const t=Qc(e);return t?`<msg ${Vc({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 Vc(e){return Object.entries(e).filter(([,e])=>void 0!==e&&""!==e).map(([e,t])=>`${e}="${function(e){return e.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;").replaceAll(">","&gt;")}(t)}"`).join(" ")}function Xc(e){const t=[];for(const n of e){const e=Kc(n);e&&t.push(e)}return t.join("\n")}function Jc(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 Yc(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 Qc(e){const{text:t,nonTextBlocks:n}=(s=e.message,se(s)?{text:Jc(s),nonTextBlocks:[]}:ae(s)?{text:Yc(s),nonTextBlocks:[]}:ie(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 Zc{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=A(Ae.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=A(Ae.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){_e.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}_e.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=>{_e.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),_e.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:xe(),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(),_e.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(),_e.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=>{_e.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),_e.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):(_e.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(),_e.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 Oc({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new _o({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new Wc({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){_e.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 _e.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);_e.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=>{_e.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),_e.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=Vc({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){_e.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}),so({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return A(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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}escapeXmlAttribute(e){return this.escapeXmlText(e).replace(/"/g,"&quot;").replace(/'/g,"&apos;")}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&&(_e.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(_e.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void _e.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void _e.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 _e.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:z(),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}}),_e.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=le(a,t),o=void 0}catch(e){_e.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(),_e.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:xe(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.isPendingTaskId(s)?(_e.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(),_e.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 _e.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${xe()}`;if(!this.client.connected)return _e.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${xe()}`;const s=await this.createChannelTaskEncryptionPayload();if(!s)return _e.error("[CHANNEL] Cannot create encrypted channel task: missing local machine encryption credentials"),`pending-encryption-unavailable-${xe()}`;const{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e,s.taskDataKey);try{const o=await this.client.sendWithAck("channel-task-create",{eventId:z(),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),_e.info(`[CHANNEL] Created task ${o.taskId} for chat ${e.chatId}`),o.taskId):(_e.error(`[CHANNEL] API task creation failed: ${o?.message||"unknown"}`),`pending-api-error-${xe()}`)}catch(e){return _e.error("[CHANNEL] Failed to create task via API",e),`pending-error-${xe()}`}}async resolveChatName(e){try{_e.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(_e.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if(_e.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 _e.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 Ae.readCredentials();if(!e?.secret)return _e.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 oe(e.secret),s=B();return{taskDataKey:s,dataEncryptionKey:H(ce(s,n.publicKey)),ownerEncryptedDataKey:H(re(H(s),t))}}(e);return t||(_e.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 _e.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:z(),taskId:e});if("success"===t?.status&&t.dataEncryptionKey){const n=await Ae.getSecretKey();if(!n)return _e.warn(`[CHANNEL] Missing machine secret key while decrypting task key: task=${e}`),null;const s=W(G(t.dataEncryptionKey),n);return s&&32===s.length?(this.taskDataKeyCache.set(e,s),s):(_e.warn(`[CHANNEL] Failed to decrypt valid task data key: task=${e}`),null)}_e.warn(`[CHANNEL] Failed to fetch encryption keys for task ${e}: ${t?.message||"unknown"}`)}catch(t){_e.warn(`[CHANNEL] Error fetching encryption keys for task ${e}`,t)}return null}readCompanionState(){const e=A(Ae.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return _e.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}:(_e.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return _e.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=>{_e.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),_e.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=qo.parse(e),(e.companionDataEncryptionKey||e.companionOwnerEncryptedDataKey||e.companionKeyMachineId||e.companionKeyChatId)&&this.saveState()}catch(e){_e.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=M(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 el(){try{const e=Ke($e(),"package.json"),t=JSON.parse(je(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}async function tl(){const e=el();try{const t=lt("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 nl(e,t={}){const n=function(){const e=Ke(Ve(Ae.getStatePaths().daemonStateFile),"upgrade.lock");if(Le(e))try{const t=je(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)||He(e)}catch{He(e)}try{const t=qe(e,"wx");Ge(t,JSON.stringify({pid:process.pid,createdAt:(new Date).toISOString()})),Fe(t)}catch{return null}return{release:()=>{try{const t=je(e,"utf-8");JSON.parse(t).pid===process.pid&&He(e)}catch{}}}}();if(!n)return{status:"busy",message:"CLI upgrade already in progress"};try{const n=e??await tl();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=ct("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()}}function sl(){return"true"===process.env.AGENTRIX_DISABLE_AUTO_UPGRADE}async function al(e){try{if(console.log(""),e||(console.log(L.blue("🔄 Checking for upgrades...")),e=await tl()),!e.hasUpgrade)return console.log(L.green("✓ Already on latest version")),console.log(""),!0;console.log(L.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`));const t=await nl(e,{stdio:"inherit"});if("busy"===t.status)return console.log(L.yellow(`⚠️ ${t.message}`)),!1;if("failed"===t.status)throw new Error(t.error);return console.log(L.green("✓ Upgrade complete")),console.log(""),!0}catch(e){return console.log(""),console.log(L.yellow("⚠️ Auto-upgrade failed")),console.log(L.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}class il{state="ready";machineId;workerManager;getSocketClient;requestRestartCallback;restartRequested=!1;pendingRestartReport=null;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:Pe.version,installedCliVersion:el(),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"]}}handleCommand(e,t){this.matchesTarget(e)?"ping"!==e.action?"upgrade-cli"!==e.action?t(this.failedAck(e.eventId,"unsupported_operation","Unsupported machine control operation")):this.handleUpgradeCli(e,t):t({eventId:z(),status:"success",opCode:e.eventId,data:{result:this.buildPingResult()}}):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:z(),status:"success",opCode:e.eventId}),this.runUpgrade(e).catch(t=>{_e.error("[MACHINE CONTROL] upgrade-cli failed unexpectedly:",t),this.state="ready",this.sendProgress({eventId:z(),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:z(),opCode:e.eventId,status:"running",message:"Checking and installing CLI upgrade"});const t=await nl(void 0,{stdio:"ignore"});if("busy"===t.status)return this.state="ready",void this.sendProgress({eventId:z(),opCode:e.eventId,status:"failed",errorCode:"operation_busy",errorMessage:t.message});if("already_latest"===t.status)return this.state="ready",void this.sendProgress({eventId:z(),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:z(),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:z(),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}})}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:z(),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):_e.warn(`[MACHINE CONTROL] Dropping progress ${e.opCode}; socket not connected`)}matchesTarget(e){return e.target.machineId===this.machineId}failedAck(e,t,n){return{eventId:z(),status:"failed",opCode:e,message:n,data:{errorCode:t}}}}function ol(){return A(M(Ae.getStatePaths().daemonStateFile),"daemon-restart-report.json")}function rl(e){return new Promise(t=>setTimeout(t,e))}function cl(e){try{return process.kill(e,0),!0}catch{return!1}}async function ll(){Object.assign(_e,Re({type:"daemon"}));const{requestShutdown:e,shutdownPromise:t}=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?_e.debug(`${s} Shutdown already requested; ignoring duplicate request from ${a}`):(i=!0,_e.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=>{_e.info(`${s} FATAL: Uncaught exception`,e),_e.info(`${s} Stack trace: ${e.stack}`),a("exception",e.message)}),process.on("unhandledRejection",e=>{_e.info(`${s} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);_e.info(`${s} Stack trace: ${t.stack}`),a("exception",t.message)}),process.on("exit",e=>{_e.info(`${s} Process exiting with code: ${e}`)}),{requestShutdown:a,shutdownPromise:o}}();console.log("[DAEMON RUN] Starting daemon process..."),_e.debug("[DAEMON RUN] Environment",Os()),await hn()&&(console.log("Daemon already running..."),process.exit(0));let n=await Ae.acquireDaemonLock(5,200);for(;!n;)await fn(),n=await Ae.acquireDaemonLock(5,200),n||(_e.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{(function(){if(Ae.disableCaffeinate)return _e.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return _e.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(Es&&!Es.killed)return _e.debug("[caffeinate] Caffeinate already running"),!0;try{return Es=ct("caffeinate",["-im"],{stdio:"ignore",detached:!1}),Es.on("error",e=>{_e.debug("[caffeinate] Error starting caffeinate:",e),Es=null}),Es.on("exit",(e,t)=>{_e.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),Es=null}),_e.info(`[caffeinate] Started with PID ${Es.pid}`),function(){if($s)return;$s=!0;const e=()=>{_s()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{_e.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{_e.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return _e.info("[caffeinate] Failed to start caffeinate:",e),!1}})()&&_e.debug("[DAEMON RUN] Sleep prevention enabled");const s=await xn();_e.debug("[DAEMON RUN] Auth and machine setup complete");const a=new Ac;await a.initialize(Ae.getSandboxSettings());const i=new Ec(a);let o,l,d,p,u=!1;i.setSocketClientProvider(()=>o?.client),p=new il({machineId:s.machineId,workerManager:i,getSocketClient:()=>o?.client,requestRestart:(t,n,s)=>{!function(e){try{const t=dc(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 _e.error("[DAEMON RESTART] Failed to launch restart command",e),null}}({oldPid:process.pid,expectedCliVersion:s?.toVersion??el(),reason:n,report:s})?p.rollbackGracefulRestart():(u=!0,e("agentrix-cli",n))}});const{port:m,host:h,webhookHost:g,stop:y}=await lc({getChildren:()=>i.getCurrentSessions(),stopSession:e=>i.stopSession(e),startDevOpsInit:e=>i.startDevOpsInit(e),completeDevOpsInit:e=>i.completeDevOpsInit(e),requestShutdown:()=>e("agentrix-cli"),registerSession:(e,t)=>i.registerTaskWorker(e,t),prepareGracefulRestart:e=>p.prepareGracefulRestart(e.source,e.reason),clearGracefulRestartGate:()=>p.clearGracefulRestartGate(),getSocketClient:()=>o?.client,credentials:s,get companionScheduler(){return l},get channelManager(){return d}});try{await Ls(),_e.debug("[DAEMON RUN] Openers detected")}catch(e){_e.warn("[DAEMON RUN] Failed to detect openers",e)}const v={pid:process.pid,port:m,host:h,webhookHost:g,startTime:(new Date).toLocaleString(),cliVersion:Pe.version,logPath:Me({type:"daemon"})};Ae.writeDaemonState(v),_e.debug("[DAEMON RUN] Daemon state written");const b=new Cs({machineId:s.machineId,serverUrl:Ae.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:de(s.token,s.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:z(),machineId:s.machineId,timestamp:Date.now().toString(),controlPort:m})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>_e.debug(`[DAEMON SOCKET] ${e}`,...t)},i,{requestShutdown:e,machineControl:p}),w=new Zc(b.client,s.machineId);d=w,i.setChannelManager(w),await b.connect(),o=b,_e.info("[DAEMON RUN] Machine client connected to server"),await async function(e){const t=function(){const e=ol();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=Pe.version,s={eventId:z(),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=>{_e.warn("[DAEMON RESTART] Could not confirm restart report flush",e)}),function(){try{const e=ol();r(e)&&f(e)}catch{}}(),_e.info(`[DAEMON RESTART] Flushed pending restart report for ${t.opCode}`),!0}(b.client).catch(e=>{_e.warn("[DAEMON RUN] Failed to flush pending restart report",e)});const x=new lo(b.client,s.machineId);l=x,x.start(),await w.start(),b.setCompanionInteractionCallback(e=>{x.recordInteraction(e)});const k=new _c(b.client,s.machineId);k.start(),b.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&x.setHeartbeatTaskId(e.taskId)}),b.client.onEvent("companion-memory-organization-response",e=>{e?.taskId&&x.setMemoryOrganizationTaskId(e.taskId)});const I=async(e,t)=>{await w.stop(),x.stop(),k.stop(),await b.disconnect(),await y(),await a.shutdown(),await gn(),await _s(),await Ae.releaseDaemonLock(n),u&&_e.info("[DAEMON RUN] Restart command owns replacement daemon startup"),_e.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};_e.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const S=await t;await I(S.source,S.errorMessage)}catch(e){(function(e){return e instanceof Error&&e.message.includes("Machine binding revoked")})(e)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again.")),_e.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",e),process.exit(1)}}const dl="\n\n[Tool result truncated to 1024 bytes]";function pl(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(dl,"utf8");return n>t?ml(dl,t):`${ml(e,t-n)}${dl}`}function ul(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function ml(e,t){let n="",s=0;for(const a of e){const e=Buffer.byteLength(a,"utf8");if(s+e>t)break;n+=a,s+=e}return n}const hl={senderType:"system",senderId:"system",senderName:"system"};class gl{client;context;historyDb;getPermissionMode;outbox=new Map;usageOutbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new Sn(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir,logger:t.logger},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.initHandlers()}getPermissionModeSnapshot(){return this.getPermissionMode?.()??null}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Worker connection timeout after 10 seconds"))},1e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.client.disconnect()}sendTaskMessage(e,t,n){const s=z();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:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd,...void 0!==e?.deployingAgent&&{deployingAgent:e.deployingAgent},...void 0!==e?.upgradingAgent&&{upgradingAgent:e.upgradingAgent}};this.client.send("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.client.send("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.client.send("worker-ready",n)}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.client.send("worker-running",n)}sendPermissionMode(e){const t={eventId:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.client.send("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:z(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.client.send("worker-exit",t)}async sendErrorMessageAndExit(e){await this.sendTerminalErrorResultAndWait(e),this.sendWorkerExit("error"),await this.disconnect()}async sendTerminalErrorResultAndWait(e,t){const n=this.sendTerminalErrorResult(e,t);await this.waitForEventAcks(n,2e3)}sendTerminalErrorResult(e,t){const n=this.sendSystemErrorMessage(e,t),s=this.sendTaskEvent(hl,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(hl,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(hl,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(hl,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 pl(e,t);const n=ul(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?pl(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:ul(e);var t}).join("\n"),t):pl(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??z(),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.context.dataEncryptionKey){const e=le(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,l),d&&(this.usageOutbox.set(c,d),this.client.send("task-usage-report",d)),this.client.send("task-message",l),c}waitForEventAcks(e,t){const n=e.filter(e=>this.outbox.has(e));return 0===n.length?Promise.resolve():new Promise(e=>{let s=n.length;const a=t=>{this.ackWaiters.delete(t),s-=1,s<=0&&(clearTimeout(i),e())},i=setTimeout(()=>{for(const e of n)this.ackWaiters.delete(e);e()},t);for(const e of n)this.ackWaiters.set(e,()=>a(e))})}buildTaskUsageReport(e,t){if("result"!==e.type)return null;const n=e.modelUsage;if(!n||"object"!=typeof n)return null;const s={};for(const[e,t]of Object.entries(n)){if(!e||!t||"object"!=typeof t)continue;const n=t,a={inputTokens:this.normalizeUsageCount(n.inputTokens),outputTokens:this.normalizeUsageCount(n.outputTokens),cacheReadInputTokens:this.normalizeUsageCount(n.cacheReadInputTokens),cacheCreationInputTokens:this.normalizeUsageCount(n.cacheCreationInputTokens),webSearchRequests:this.normalizeUsageCount(n.webSearchRequests)};Object.values(a).some(e=>e>0)&&(s[e]=a)}return 0===Object.keys(s).length?null:{eventId:z(),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:z(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.client.send("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:z(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.client.send("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:z(),taskId:this.context.taskId,title:e};this.client.send("change-task-title",t),_e.info(`[AGENT] Title changed to: ${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:z(),taskId:this.context.taskId,agentId:e,...t};this.client.send("update-agent-info",n),_e.info(`[AGENT] Agent info updated: ${JSON.stringify(t)}`)}async sendVisionPlanCard(e){const t={eventId:z(),taskId:this.context.taskId,issueId:e.issueId,repoRoot:e.repoRoot,createdAt:(new Date).toISOString()},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 _e.info(`[AGENT] Vision Plan card sent for issue: ${e.issueId}`),n}sendResetTaskSession(){const e={eventId:z(),taskId:this.context.taskId};this.client.send("reset-task-session",e),_e.info(`[AGENT] Session reset requested for task ${this.context.taskId}`)}async sendMergeRequest(e,t,n){const s={eventId:z(),taskId:this.context.taskId,summary:e,description:t,sourceBranch:n};_e.info(`[MERGE] Sending merge-request event for task ${this.context.taskId}`);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 _e.info(`[MERGE] Pull request created: #${a.data.pullRequestNumber}`),{pullRequestNumber:a.data.pullRequestNumber,pullRequestUrl:a.data.pullRequestUrl}}async sendMergePr(){const e={eventId:z(),taskId:this.context.taskId,mergeMethod:"squash"};return _e.info(`[MERGE-PR] Sending merge-pr event for task ${this.context.taskId}`),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:z(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};_e.info(`[REPO] Sending repository association request: ${e}/${t}/${n}`),this.client.send("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:z(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},{"cancel-task":async e=>{e.taskId===t.taskId&&(_e.info(`[WORKER] Task ${t.taskId} cancelled`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&(_e.info(`[WORKER] Task ${t.taskId} stopped: ${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;let a=e.message??null;if(!a&&e.encryptedMessage&&t.dataEncryptionKey&&(a=te(e.encryptedMessage,t.dataEncryptionKey)??null),!a)return;e.channelReplyTarget&&"object"==typeof a&&(a.__channelReplyTarget=e.channelReplyTarget);const i={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&ne(a)&&(a=await hc(a,{attachmentsDir:t.attachmentsDir,log:t.logger})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(a,i))return void _e.debug(`[WORKER] Dropping incoming task-message before persistence: eventId=${e.eventId}`);if(!n.saveMessage({eventId:e.eventId,message:a,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return _e.debug(`[WORKER] Ignoring duplicate incoming task-message: eventId=${e.eventId}`),void s(e.eventId);const o={...e,message:a,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:o,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(a,i)},"task-info-update":async e=>{e.taskId===t.taskId&&t.onTaskInfoUpdate&&await t.onTaskInfoUpdate(e)},"worker-status-request":async e=>{e.taskId===t.taskId&&t.onWorkerStatusRequest&&await t.onWorkerStatusRequest(e)},"sub-task-result-updated":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskResultUpdated&&await t.onSubTaskResultUpdated(e)},"sub-task-ask-user":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskAskUser&&await t.onSubTaskAskUser(e)}});var t,n,s;this.client.onEvent("cancel-task",e["cancel-task"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEvent("task-message",e["task-message"]),this.client.onEvent("task-info-update",e["task-info-update"]),this.client.onEvent("worker-status-request",e["worker-status-request"]),this.client.onEvent("sub-task-result-updated",e["sub-task-result-updated"]),this.client.onEvent("sub-task-ask-user",e["sub-task-ask-user"]),this.client.onEvent("event-ack",e=>{const t=e.data?.sequence;void 0!==e.opCode&&(this.outbox.delete(e.opCode),this.usageOutbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.()),void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(this.outbox.size>0){_e.info(`[WORKER] Reconnected — flushing ${this.outbox.size} outbox message(s)`);for(const[e,t]of this.outbox.entries()){const n=this.usageOutbox.get(e);n&&this.client.send("task-usage-report",n),this.client.send("task-message",t)}}}else this.hasConnectedOnce=!0})}}const fl=Rt(xt),yl="xmz-ai",vl="agentrix-hive",bl="https://github.com/xmz-ai/agentrix-hive.git",wl="github";class xl{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=z();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=le(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=le(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=le(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=Ae.resolveRepoStoreCheckoutDir(wl,yl,vl),t=Ae.resolveRepoStoreLockPath(wl,yl,vl),n=await Ae.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await pi(e)){if(!ki(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await yi(bl,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await Ri(e,"origin",Pi(bl));try{return await fl("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 Ae.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 Oe.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||Ln.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 Oe.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 kl(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=te(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 Il(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=te(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 Sl(){const e=new Set;return{filter(t){const n=t;if(!n.message||!n.message.content||"string"==typeof n.message.content)return t;const s=n.message.content.filter(t=>!("tool_result"===t.type&&e.has(t.tool_use_id)||"user"===n.type&&"tool_result"!==t.type));return 0===s.length?null:(n.message.content=s,n)},clear(){e.clear()}}}function Tl(e){return Tt("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:ht.string().describe("Concrete natural-language desktop operation to perform, including the app/document/target and desired outcome."),expectedResult:ht.string().optional().describe("Optional concise success condition the computer-use sub-task should verify before returning."),title:ht.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??Nr(void 0,t.log);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(br);if(i)return t.log?.("info","COMPUTER_USE",`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"};t.log?.("info","COMPUTER_USE",`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(br,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),log:e.log});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 Cl({workClient:e}){return Tt("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:ht.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function El(e){return Tt("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:ht.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=Z.parse({previewUrl:t}),s=await fetch(`${Ae.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 Al(e){return Tt("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:rr.shape.repoRoot,issueId:rr.shape.issueId},async t=>{const n=await cr(t,e.taskId);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 _l({agentContext:e,log:t}){return Tt("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:ht.string().describe("Sub-task ID to send the message to"),instructions:ht.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:ht.array(ht.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async n=>{try{let t;return t=n.answers&&n.answers.length>0?{type:"ask_user_response",answers:n.answers}:{type:"user",message:{role:"user",content:n.instructions??""}},await e.sendMessage({taskId:n.taskId,message:t,target:"agent"}),{content:[{type:"text",text:`${n.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${n.taskId}.`}]}}catch(e){return t("error","TASK",`Failed to send message to sub-task ${n.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function $l({historyDb:e}){return Tt("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:ht.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:ht.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=Xc(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 Pl({agentContext:e}){return Tt("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 Rl({agentContext:e,log:t}){return Tt("list_sub_task","List direct sub tasks for the current task with taskId, title, and cwd.",{},async()=>{try{const t=await e.listSubTasks();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No sub tasks found."}]}}catch(e){return t("error","TASK","Failed to list sub tasks:",e),{content:[{type:"text",text:`Failed to list sub tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Ml({agentContext:e,agentId:t,log:n,setPendingNavigateTaskId:s}){return Tt("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:ht.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:ht.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:ht.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:ht.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:ht.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:ht.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:ht.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:ht.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async a=>{try{if(a.autoNavigate&&!a.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const i=a.agentId||t;let o;return a.independent?(o=await e.startIndependentTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,autoNavigate:a.autoNavigate}),a.autoNavigate&&s(o.taskId),n("info","TASK",`Created independent task ${o.taskId} for agent ${i} (autoNavigate: ${a.autoNavigate??!1})`)):(o=await e.startSubTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}}),n("info","TASK",`Created sub-task ${o.taskId} for agent ${i}`)),{content:[{type:"text",text:`🚀 Task created: ${o.taskId}\n${a.agentId?`Agent: ${i}\n`:""}${a.independent?"Mode: Independent\n":""}Summary: ${a.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return n("error","TASK","Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Nl({agentContext:e,log:t}){return Tt("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:ht.string().min(1).max(200).describe("Task title"),instructions:ht.string().describe("Instructions for the owner agent"),briefSummary:ht.string().optional().describe("One-line summary shown to user immediately"),agentId:ht.string().describe("Target agent ID"),cwd:ht.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:ht.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:n.agentId,message:{type:"user",message:{role:"user",content:n.instructions}},title:n.title,cwd:n.cwd,forceUserCwd:!n.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","TASK","Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Dl({agentContext:e,log:t,agentId:n}){return Tt("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:ht.string().min(1).max(200).describe("Task title"),requirement:ht.string().describe("Overall requirement"),briefSummary:ht.string().optional().describe("One-line summary shown to user immediately"),todos:ht.array(ht.object({agentId:ht.string().describe("Agent ID responsible for the todo"),title:ht.string().min(1).max(200).describe("Todo title"),instructions:ht.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:n.title,todos:n.todos,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"},message:{type:"user",message:{role:"user",content:n.requirement}}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","DISPATCH","Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Ol({askUser:e,log:t}){return Tt("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:ht.array(ht.object({question:ht.string().describe("The complete question to ask the user"),header:ht.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:ht.boolean().describe("Set to true to allow multiple option selections"),options:ht.array(ht.object({label:ht.string().describe("Option label (1-5 words)"),description:ht.string().describe("Explanation of what this option means")})).min(2).max(4).describe("Available choices (2-4 options)")})).min(1).max(4).describe("Questions to ask (1-4 questions)")},async n=>{try{const t=n.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(t);return"answered"!==(s.status??"answered")?{content:[{type:"text",text:"The user did not provide an answer within the expected time. \n<system-reminder>Please abort the session, and decide whether to retry when the user provides a new message later.</system-reminder>"}],isError:!0}:{content:[{type:"text",text:`User answers:\n${s.answers.map(e=>e.startsWith("other:")?`Other: "${e.slice(6)}"`:e).join("\n")}`}]}}catch(e){return t("error","ASK_USER","Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function Ul({invokeAgent:e}){return Tt("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:ht.string().describe("Target agent ID"),hint:ht.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 jl({workClient:e,agentId:t,uploadFile:n,log:s}){return Tt("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:ht.string().optional().describe("Your display name"),avatarPath:ht.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:ht.string().optional().describe("Short status line or tagline shown under your name")},async a=>{let i;if(a.avatarPath)try{i=(await n({name:"avatar.png",path:a.avatarPath,visibility:"public"})).fileId}catch(e){return s("error","TOOL","Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:a.displayName,avatar:i,signature:a.signature});const o=[];return a.displayName&&o.push(`name → ${a.displayName}`),i&&o.push("avatar → uploaded"),a.signature&&o.push(`signature → ${a.signature}`),{content:[{type:"text",text:`Profile updated: ${o.join(", ")}`}]}})}function Ll({assign:e,log:t}){return Tt("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:ht.string().describe("Target agent ID"),instruction:ht.string().describe("Task instruction for the agent"),acknowledgment:ht.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 Hl({agentContext:e,log:t}){return Tt("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:ht.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:ht.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async n=>{try{const t=await e.listTasks({limit:n.limit??10,status:n.status??"all"});return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return t("error","TASK","Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ql({chatHistoryDb:e}){return Tt("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:ht.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:ht.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=Xc(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 Gl({agentContext:e,log:t}){return Tt("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:ht.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:ht.string().optional().describe("Path to detailed analysis file in workspace, if any")},async n=>{try{const t=e.getChatId();return await e.sendMessage({taskId:t,message:{type:"companion_reminder",content:n.content,filePath:n.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return t("error","COMPANION","Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}const Fl=ht.enum(["created","updated","deleted"]);function Bl({log:e,taskId:t}){return Tt("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:ht.string().optional().describe("Deprecated compatibility field; each change.summary is used for the JSONL record and semantic git commit title."),trigger:ht.enum(["scheduled","user_request"]).describe("What triggered this memory change."),source:ht.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:ht.boolean().describe("Whether a reminder has already been sent or will be sent immediately after this record."),changes:ht.array(ht.object({file:ht.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:Fl,summary:ht.string().describe("One-sentence summary of what changed."),reasons:ht.array(ht.string()).min(1).describe("Short reasons for this change."),deletedFiles:ht.array(ht.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 n=>{try{const s=process.env.AGENTRIX_COMPANION_HOME;if(!s)throw new Error("AGENTRIX_COMPANION_HOME is not set; memory changes can only be recorded by Companion workers.");const a=new Date,i=a.toISOString().slice(0,10),o=A(s,"memory-changes"),r=A(o,`${i}.jsonl`),c=n.changes.map(e=>({file:Fa(s,e.file).relativePath,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles?.map(e=>Fa(s,e).relativePath)??[]}));await Ba({companionHome:s,log:e});const l=new Map;for(const e of c){const t=l.get(e.file);t?t.push(e):l.set(e.file,[e])}const d=[];for(const i of l.values()){const o=i[0],r=Array.from(new Set(i.flatMap(e=>e.deletedFiles))),c=await Ka({companionHome:s,title:o.summary,body:za({trigger:n.trigger,source:n.source,action:o.action,file:o.file,reasons:i.flatMap(e=>e.reasons),deletedFiles:r,notifiedCompanion:n.notifiedCompanion,taskId:t}),paths:[o.file,...r],log:e});if(c)for(const e of i)d.push(JSON.stringify({time:a.toISOString(),trigger:n.trigger,source:n.source,taskId:t,file:e.file,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles,notifiedCompanion:n.notifiedCompanion,commit:c}));else e("warn","COMPANION",`Skipping memory change JSONL record because no semantic git commit was created: file=${o.file}`)}return d.length>0&&(await Kt(o,{recursive:!0}),await Vt(r,`${d.join("\n")}\n`,"utf-8")),e("info","COMPANION",`Memory changes recorded: path=${r}, source=${n.source??"unspecified"}, trigger=${n.trigger}, records=${d.length}, requestedChanges=${c.length}, taskId=${t}`),{content:[{type:"text",text:d.length>0?`Memory changes recorded: ${d.length} JSONL record(s) at ${r}`:"No memory change JSONL records were written because no semantic git commit was created."}]}}catch(t){return e("error","COMPANION","Failed to record memory change:",t),{content:[{type:"text",text:`Failed to record memory change: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}function Wl({uploadFile:e,log:n}){return Tt("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., ![screenshot](url)).",{filePath:ht.string().describe("Absolute path to the local file to upload"),name:ht.string().optional().describe("Display name for the file (defaults to filename)")},async s=>{try{const n=t("path"),a=s.name||n.basename(s.filePath);return{content:[{type:"text",text:(await e({name:a,path:s.filePath,visibility:"public"})).url}]}}catch(e){return n("error","TOOL","File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const zl=2147483648,Kl=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function Vl({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a,log:i}){return Tt("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:ht.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:ht.array(ht.object({filePath:ht.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:ht.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:ht.enum(["auto","image","file","audio","video"]).optional().describe("Attachment kind. Use auto unless you know the exact type.")})).optional().describe("Optional user-facing deliverable files to send with the message.")},async o=>{const r=s?.()??null;if(!r)return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel, so no channel message can be sent."}],isError:!0};a?.();try{const s=o.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await Jl(n));return t}(o.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const i=await pn(e,{content:s||void 0,attachments:a.length>0?a:void 0},r);return i?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:i.error}}),{content:[{type:"text",text:`Failed to send channel message: ${i.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,mimeType:e.mimeType,kind:e.kind}))}}),{content:[{type:"text",text:a.length>0?`Sent channel message with ${a.length} attachment(s).`:"Sent channel message."}]})}catch(e){return i("warn","CHANNEL","Channel message send rejected or failed:",e),{content:[{type:"text",text:`Failed to send channel message: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Xl({taskId:e,getChannelReplyTarget:t}){return Tt("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:ht.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:ht.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:ht.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 rn("/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 Jl(e){if(!D(e.filePath))throw new Error("filePath must be absolute");const t=await Xt(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>zl)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(Kl.test(s)||Kl.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=Ln.lookup(n)||Ln.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 Yl({agentContext:e,log:t}){return Tt("list_agents","List all available agents for the current user, including system agents and user-created agents (both published and draft).",{},async()=>{try{const{agents:t,draftAgents:n}=await e.listAgents(),s=e=>`- **${e.displayName||e.name}** (${e.id})\n Type: ${e.type}\n`+(e.developerName?` Developer: ${e.developerName}\n`:"")+` ${e.description||"No description"}\n`;let a="# Available Agents\n\n";return t.length>0&&(a+="## Published Agents\n\n",a+=t.map(s).join("\n")),n.length>0&&(a+="\n## Draft Agents\n\n",a+=n.map(s).join("\n")),0===t.length&&0===n.length&&(a+="No agents available."),{content:[{type:"text",text:a}]}}catch(e){return t("error","AGENTS","Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*Ql(e){yield e}function Zl({visionModel:e,log:t}){return Tt("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:ht.string().describe("Absolute path to the image file to analyze"),prompt:ht.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async n=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const t=(await zt(n.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[n.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=n.prompt||"Describe this image in detail.",i=St({prompt:Ql({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:t}},{type:"text",text:a}]},parent_tool_use_id:null,session_id:""}),options:{model:e,permissionMode:"bypassPermissions",maxTurns:1,tools:[]}});let o="";for await(const e of i)if("result"===e.type){o=e.result??"";break}return{content:[{type:"text",text:o||"No description returned."}]}}catch(e){return t("error","VISION","Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ed({log:e}){return Tt("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:ht.enum(["create","list","delete"]).describe("Operation to perform"),task:ht.string().optional().describe("Task description (required for create)"),type:ht.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:ht.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:ht.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:ht.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:ht.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:ht.string().optional().describe("Task ID (required for delete)")},async t=>{try{const e=await Ae.readDaemonState();if(!e?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${e.port}`;if("list"===t.action){const e=await fetch(`${n}/schedule`),t=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${t.error}`}],isError:!0};const s=t.tasks??[];return 0===s.length?{content:[{type:"text",text:"No scheduled tasks."}]}:{content:[{type:"text",text:s.map(e=>`- [${e.id}] ${"once"===e.type?`once at ${e.due}`:`recurring: ${e.cron}`} — "${e.task}"`).join("\n")}]}}if("create"===t.action){if(!t.task||!t.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const e=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:t.task,type:t.type,due:t.due,cron:t.cron,timezone:t.timezone,timeType:t.timeType})}),s=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0};const a="once"===s.type?`due=${s.due}`:`cron=${s.cron}`;return{content:[{type:"text",text:`Scheduled: id=${s.id}, ${a}`}]}}if("delete"===t.action){if(!t.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const e=await fetch(`${n}/schedule/${t.id}`,{method:"DELETE"}),s=await e.json();return e.ok?{content:[{type:"text",text:`Deleted: ${t.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${t.action}`}],isError:!0}}catch(t){return e("error","SCHEDULE","Schedule task failed:",t),{content:[{type:"text",text:`Failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}})}function td({agentContext:e,log:t}){return Tt("hive_prepare_repository","Prepare the Agentrix Hive source repository in the local global repo store.\n\nUse this before discovering community agents or skills. This tool only clones/pulls\nthe repository and returns the absolute checkout path. It does not search and does\nnot define the repository layout. After calling it, use Explore with a\ntask-specific goal to find relevant candidates; do not catalog the whole repo\nunless the user explicitly asks for a catalog. If pullSucceeded is false, inspect\nerror and continue with the existing local checkout when it is usable.",{},async()=>{try{const t=await e.prepareHiveRepository();return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Failed to prepare Hive repository:",e),{content:[{type:"text",text:`Failed to prepare Hive repository: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function nd({agentContext:e,log:t}){return Tt("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:ht.enum(["agent","skill"]),draftAgentId:ht.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:ht.string().optional().describe("Absolute local skill directory for skill publishing"),name:ht.string().optional().describe("Listing name, lowercase kebab-case"),displayName:ht.string().optional().describe("Human-readable listing name"),description:ht.string().optional(),readme:ht.string().optional(),category:ht.string().optional(),tags:ht.array(ht.string()).optional(),authorType:ht.enum(["user","agent"]).default("user"),authorId:ht.string(),machineId:ht.string().optional(),cloudId:ht.string().optional()},async n=>{try{const t=await e.publishToHive(n);return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function sd({agentContext:e,log:t}){return Tt("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:ht.string().describe("Owned HiveListing ID to update"),version:ht.string().optional().describe("Optional new version; defaults to next patch version"),changelog:ht.string().optional(),sourceDir:ht.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:ht.string().optional(),cloudId:ht.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.updateHiveListingVersion(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function ad({agentContext:e,log:t}){return Tt("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:ht.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:ht.string().describe("Absolute local directory where the agent or skill was installed"),name:ht.string().optional().describe("Optional local name for installed agent"),machineId:ht.string().optional(),cloudId:ht.string().optional(),installedVersion:ht.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.recordHiveInstall(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function id({agentContext:e,log:t}){return Tt("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:ht.string().describe("HiveListing ID"),rating:ht.number().int().min(1).max(5),comment:ht.string().optional().describe("Markdown review text")},async n=>{try{const t=await e.createHiveReview(n.listingId,{rating:n.rating,comment:n.comment??null});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function od({agentContext:e,log:t}){return Tt("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:ht.string().describe("HiveListing ID"),content:ht.string().min(1).describe("Markdown comment content"),parentId:ht.string().optional().describe("Parent comment ID for replies")},async n=>{try{const t=await e.createHiveComment(n.listingId,{content:n.content,parentId:n.parentId});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function rd(e){if(e)return e.replace(/\/+$/g,"")||"/"}function cd(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,branchName:e.branchName,branchBinding:e.branchBinding,cwd:rd(e.cwd)||"",userCwd:rd(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,initPolicies:e.initPolicies,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function ld(e){return!!e.branchName&&"none"!==e.branchBinding&&"external-observed"!==e.branchBinding}function dd(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 pd(e,t){const n=Mt(e);await n.raw(["checkout","-B",t,"HEAD"])}function ud(e){return`HEAD:refs/heads/${e}`}function md(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 hd(e){if(!e)return null;const t=await Jn();return t?es(e,t):null}async function gd(e,t){const n=Zn(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 li("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await li("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 fd(e,t,n){const s=await hd(n);s?await async function(e,t){const n=Li();try{await li("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:Hi(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await li("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,env:qi(),windowsHide:!0})}(t,e)}async function yd(e,t,n,s,a,i){const o=Pi(t),c=await pi(e);if(!ki(e)&&!c)throw new Error(`Directory ${e} exists but is not a git repository`);const l=await hd(a);return ki(e)?(l?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=M(n);r(s)||d(s,{recursive:!0});const a=Li();try{await li("git",["-c","credential.helper=","clone",t,n],{env:Hi(a,e),windowsHide:!0})}finally{f(a)}}(l,o,e),a&&await gd(e,a)):await yi(t,e),await $i(e,"origin",o),i&&await vi(e,i,s),await wi(e)):(await Ri(e,"origin",o),await fd(e,t,a),a&&await gd(e,a),i&&await vi(e,i,s),await wi(e))}async function vd(e,t,n,s={}){const a=await hd(s.gitServerId);a?await async function(e,t,n,s=!1){const a=Li();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await li("git",i,{cwd:t,env:Hi(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 li("git",a,{cwd:t,env:qi(),windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=di(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function bd(e,t,n){const s=n.trim();if(!s)return;const a=Ae.resolveDataDir(e,t),i=A(a,"patch.diff");return await Et(a,{recursive:!0}),await _t(i,`${s}\n`),i}async function wd(e,t,n){await Ae.writeLastSentArtifactVersion(e,t,n)}function xd(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 kd(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:qt()}}function Id(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:qt()}}function Sd(e){const t="```sh\n",n="\n```";return`${t}${pl(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function Td(e,t,n,s=6e4){return new Promise(a=>{const i=ct("/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=Sd(l);n.onOutput(Id(p)),n.onOutput(kd(p,i,d)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=Sd(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(Id(t)),n.onOutput(kd(t,1,!0)),n.onComplete(1),a(1)})})}class Cd{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="running";messageIdCounter=0;isStopped=!1;runStartTime=Date.now();commandRunning=!1;isDebouncing=!1;agentRunningMap=new Map;backgroundTaskMap=new Map;anonymousBackgroundTaskCount=0;lastActiveAgentsSignature=null;idleTimeoutHandle=null;idleTimeoutMs;constructor(e){this.config=e,this.idleTimeoutMs=Math.max(0,e.idleTimeoutMs??0)}parseMessage(e){if("user"!==e.type)return{type:"normal",content:"",originalMessage:e};const t=("string"==typeof e.message.content?e.message.content:"").trim();return t.startsWith("!")&&!t.startsWith("![")?{type:"bash-command",content:t.slice(1).trim(),originalMessage:e}:"![merge-request]"===t?{type:"merge-request",content:t,originalMessage:e}:"![merge-pr]"===t?{type:"merge-pr",content:t,originalMessage:e}:"![new]"===t?{type:"new-session",content:t,originalMessage:e}:"![agentrix-dev-init]"===t?{type:"agentrix-dev-init",content:t,originalMessage:e}:"![plan]"===t?{type:"plan-mode",content:t,originalMessage:e}:{type:"normal",content:t,originalMessage:e}}async enqueue(e){if(this.isStopped)return void this.log("warn","COORDINATOR","Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void this.log("warn","COORDINATOR","Ignoring malformed user message (missing content)");const t=this.parseMessage(e),n={id:"msg-"+ ++this.messageIdCounter,type:t.type,priority:"normal",content:t.content,originalMessage:e,timestamp:Date.now()};this.messageQueue.push(n),this.log("info","COORDINATOR",`Enqueued message ${n.id} (type: ${n.type}, queue: ${this.messageQueue.length})`),this.tryUpdateWorkerState(),this.tryProcessNext()}async tryProcessNext(){if(!this.isStopped)if(0!==this.messageQueue.length)try{const e=this.messageQueue.shift();this.log("info","COORDINATOR",`Processing message ${e.id} (type: ${e.type})`),await this.processMessage(e),this.log("info","COORDINATOR",`Completed message ${e.id}`)}catch(e){this.log("error","COORDINATOR",`Error processing message: ${e}`)}finally{this.tryUpdateWorkerState(),this.isStopped||this.tryProcessNext()}else this.tryUpdateWorkerState()}async processMessage(e){switch(e.type){case"normal":await this.processNormalMessage(e);break;case"bash-command":await this.processBashCommand(e);break;case"merge-request":await this.processMergeRequest(e);break;case"merge-pr":await this.processMergePr(e);break;case"new-session":await this.processNewSession(e);break;case"agentrix-dev-init":await this.processAgentrixDevInit(e);break;case"plan-mode":await this.processPlanMode(e);break;default:this.log("warn","COORDINATOR",`Unknown message type: ${e.type}`)}}async processNormalMessage(e){this.log("info","COORDINATOR","Processing normal message for SDK");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){this.log("info","COORDINATOR",`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){this.log("info","COORDINATOR","Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){this.log("info","COORDINATOR","Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){this.log("info","COORDINATOR","Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processAgentrixDevInit(e){this.log("info","COORDINATOR","Processing agentrix-dev-init command"),await this.processCommand(async()=>{await(this.config.handlers.onAgentrixDevInit?.(e.originalMessage))},e)}async processPlanMode(e){this.log("info","COORDINATOR","Processing plan-mode command"),await this.processCommand(async()=>{if(!this.config.handlers.onPlanMode)return;const t=await this.config.handlers.onPlanMode(e.originalMessage);t&&this.enqueueAgentMessage(t)},e)}async processCommand(e,t){await this.waitWorkerIdle(),this.setCommandRunning(!0),this.markCommandMessageProcessed(t);try{await e()}finally{this.setCommandRunning(!1)}}markCommandMessageProcessed(e){const t=e.originalMessage.__localSequence;void 0!==t&&this.config.onCommandMessageProcessed?.(t)}async waitWorkerIdle(){for(;"idle"!==this.getExecutionState();){if(this.isStopped)throw new Error("Coordinator stopped while waiting for idle");this.log("debug","COORDINATOR","Waiting for worker idle state"),await new Promise(e=>setTimeout(e,100))}}setWorkerState(e){if(this.workerState===e)return;const t=this.workerState;if(this.log("info","COORDINATOR",`Worker state: ${t} → ${e}`),this.workerState=e,"running"===e&&"idle"===t&&(this.runStartTime=Date.now(),this.config.workClient.sendWorkRunning(this.getActiveAgents()),this.lastActiveAgentsSignature=this.getActiveAgentsSignature(),this.clearIdleTimer()),"idle"===e&&"running"===t){let e;this.runStartTime&&(e=Date.now()-this.runStartTime,this.runStartTime=null),this.config.workClient.sendWorkerReady(e),this.lastActiveAgentsSignature=null,this.startIdleTimer(),this.config.onBecameIdle?.()}}updateAgentRunning(e){this.setAgentRunning("default","Agent",e)}setAgentRunning(e,t,n){const s="running"===this.workerState,a=this.lastActiveAgentsSignature;n?this.agentRunningMap.set(e,{agentId:e,agentName:t,startedAt:Date.now()}):this.agentRunningMap.delete(e);const i=this.getActiveAgentsSignature();this.lastActiveAgentsSignature=i,this.tryUpdateWorkerState(),s&&"running"===this.workerState&&i!==a&&this.config.workClient.sendWorkRunning(this.getActiveAgents())}setBackgroundTaskRunning(e,t){e&&(t?this.backgroundTaskMap.set(e,{taskId:e,startedAt:Date.now()}):!this.backgroundTaskMap.delete(e)&&this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,this.log("debug","COORDINATOR",`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Anonymous background task completed (count: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState()}getActiveAgents(){return Array.from(this.agentRunningMap.values()).map(({agentId:e,agentName:t})=>({agentId:e,agentName:t}))}getActiveAgentsSignature(){const e=this.getActiveAgents().slice().sort((e,t)=>e.agentId.localeCompare(t.agentId));return JSON.stringify(e)}enqueueAgentMessage(e){if(this.isStopped)this.log("warn","COORDINATOR","Ignoring agent message - coordinator is stopped");else if(this.agentMessageQueue.push(e),this.agentMessageResolver){const e=this.agentMessageResolver;this.agentMessageResolver=null,e(this.agentMessageQueue.shift())}}hasAgentMessages(){return this.agentMessageQueue.length>0}getAgentQueueLength(){return this.agentMessageQueue.length}async waitForAgentMessage(){return this.isStopped?null:this.agentMessageQueue.length>0?this.agentMessageQueue.shift():new Promise(e=>{this.agentMessageResolver=e})}cancelAgentWait(){if(!this.agentMessageResolver)return;const e=this.agentMessageResolver;this.agentMessageResolver=null,e(null)}setCommandRunning(e){this.commandRunning!==e&&(this.commandRunning=e,this.tryUpdateWorkerState())}hasExecutionWork(){return this.commandRunning||this.agentRunningMap.size>0||this.backgroundTaskMap.size>0||this.anonymousBackgroundTaskCount>0||this.isDebouncing}getExecutionState(){return this.hasExecutionWork()?"running":"idle"}setDebouncing(e){this.isDebouncing!==e&&(this.isDebouncing=e,this.tryUpdateWorkerState())}tryUpdateWorkerState(){if(this.isStopped)return;const e=this.messageQueue.length>0||this.agentMessageQueue.length>0,t=this.hasExecutionWork(),n=!e&&!t;this.setWorkerState(n?"idle":"running")}startIdleTimer(){0!==this.idleTimeoutMs&&(this.idleTimeoutHandle||(this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(this.log("info","COORDINATOR","Idle timeout reached, stopping task"),this.cancelAgentWait(),this.config.onIdleTimeout?.())},this.idleTimeoutMs)))}clearIdleTimer(){this.idleTimeoutHandle&&(clearTimeout(this.idleTimeoutHandle),this.idleTimeoutHandle=null)}getStatus(){return{state:this.workerState}}isActivelyExecuting(){return this.hasExecutionWork()}stop(){this.log("info","COORDINATOR","Stopping coordinator"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait()}log(e,t,n){this.config.logger&&this.config.logger(e,t,n)}}function Ed(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(hl,n)}async function Ad(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 _i(t),s=await bi(t),d=await async function(e,t){const n=di(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 Ed(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 vd(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===p))return void Ed(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)Ed(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 _d(e,t,n){let s=!1;const a={},i=e.updates?.repositoryId;"string"==typeof i&&i.length>0&&t.repositoryId!==i&&(t.repositoryId=i,a.taskRepositoryId=i,s=!0);const o=e.updates?.branchName;"string"==typeof o&&o.length>0&&t.branchName!==o&&(t.branchName=o,a.branchName=o,s=!0);const r=e.updates?.branchBinding;return"none"!==r&&"explicit"!==r&&"platform-managed"!==r&&"external-observed"!==r||t.branchBinding===r||(t.branchBinding=r,a.branchBinding=r,s=!0),s&&n&&await n.updateTaskMetadata(a),s}function $d(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 Pd(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:xe(),session_id:e.sessionId}}function Rd(e,t){const n=xe();return t.set(e,n),n}function Md(e,t){return t.get(e)||e}function Nd(e,t,n={}){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"error"===e.type?{type:"system",subtype:"temporary",content:e.message}:"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:Rd(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:Rd(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:Rd(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:Rd(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);default:return null}}(e.item,t):"item.completed"===e.type?function(e,t,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:xe().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:Md(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??Rd(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=Md(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=Dd(n,t.taskDataDir);if(s!==n)return[s];const a=Od(e,t.taskDataDir);return a?[n,a]:n}const a=n.map(e=>Dd(e,t.taskDataDir)),i=Od(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:Md(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"todo_list":return function(e){return{type:"assistant",message:{role:"assistant",content:`📋 Todo List:\n${e.items.map(e=>`${e.completed?"✓":"○"} ${e.text}`).join("\n")}`},parent_tool_use_id:null,session_id:""}}(e);case"error":return function(e){return{type:"assistant",message:{role:"assistant",content:`❌ Error: ${e.message}`},parent_tool_use_id:null,session_id:""}}(e)}}(e.item,t,n):null}function Dd(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:Ud(i),mimeType:a}:null}(e);if(!n)return e;try{const e=A(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=A(e,`${xe()}${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 Od(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=A(t,"attachments");d(e,{recursive:!0});const s=function(e){const t=$(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=A(e,`${xe()}${s}`);return k(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 Ud(e){const t=e.match(/^data:[^;]+;base64,(.*)$/s);return t?t[1]:e}let jd,Ld,Hd;function qd(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 Gd(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 Fd(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||A(n.homedir(),".codex");return A(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(Ld===e&&void 0!==jd)return jd;if(Ld=e,jd=null,!r(e))return jd;let t;try{t=c(e,"utf8")}catch{return jd}for(const e of t.split(/\r?\n/)){const t=qd(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=Gd(n[1])?.trim();return jd=s||null,jd}return jd}()}class Bd{createCodex(e){const t={},n=function(){if(void 0!==Hd)return Hd??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return Hd=e,e;Hd=null}();n&&(t.codexPathOverride=n),e.env&&(t.env=Ia(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(ca(`\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 ca(`\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 ca(`\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 Jt(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=Fd(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),r=await o.run("string"==typeof e?e:Ca(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});return Ea({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:r.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:r.finalResponse??"",structuredOutput:Aa(r.finalResponse??"",Boolean(t.structuredOutputSchema))})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=Fd(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),{events:r}=await o.runStreamed("string"==typeof e?e:Ca(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let c=t.agentSessionId||"",l="",d={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const p=new Map,u={get:e=>p.get(e),set:(e,t)=>{p.set(e,t)}};for await(const e of r){if("thread.started"===e.type&&(c=e.thread_id,yield Pd({sessionId:c,cwd:t.cwd,model:a??void 0})),"turn.completed"===e.type){e.usage&&(d=e.usage);break}if("turn.failed"===e.type)throw new Error(e.error.message);if("item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(l=e.item.text),"error"===e.type||"item.started"===e.type||"item.completed"===e.type){const n=Nd(e,u,{taskDataDir:t.taskDataDir});if(!n)continue;const s=Array.isArray(n)?n:[n];for(const e of s)yield e}}const m=Ea({sessionId:c,model:a??"unknown",numTurns:1,usage:d,result:l,structuredOutput:Aa(l,Boolean(t.structuredOutputSchema))});yield m}loop(e){const t=e.abortController,n=this.createCodex(e),s=Fd(e.model),a={workingDirectory:e.cwd,model:s??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let i=e.agentSessionId?n.resumeThread(e.agentSessionId,a):n.startThread(a),o=!1;const r=[];let c=null,l=e.agentSessionId??null,d=0;const p=()=>{if(!o&&(o=!0,c)){const e=c;c=null,e(null)}},u=e=>"string"==typeof e?e:Ca(e),m=async function*(){try{for(;!o&&!t.signal.aborted;){const n=r.length>0?r.shift():await new Promise(e=>{c=e});if(!n)break;let a="";const p=new Map,m={get:e=>p.get(e),set:(e,t)=>{p.set(e,t)}},{events:h}=await i.runStreamed(u(n),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of h){if(o)break;if("thread.started"!==t.type){if("turn.completed"===t.type){l&&(yield Ea({sessionId:l,model:s??"unknown",numTurns:d+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:a,structuredOutput:Aa(a,Boolean(e.structuredOutputSchema))}));break}if("turn.failed"===t.type)throw new Error(t.error.message);if("error"===t.type||"item.started"===t.type||"item.completed"===t.type){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(a=t.item.text);const n=Nd(t,m,{taskDataDir:e.taskDataDir});if(!n)continue;const s=Array.isArray(n)?n:[n];for(const e of s)yield e}}else l=t.thread_id,yield Pd({sessionId:l,cwd:e.cwd,model:s??void 0})}d+=1}}finally{p()}}();return t.signal.addEventListener("abort",p,{once:!0}),{push:e=>{if(console.log("CodexRunner.loop.push:",JSON.stringify(e,null,2)),!o){if(c){const t=c;return c=null,void t(e)}r.push(e)}},events:m,stop:p}}}const Wd=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification"];function zd(e){const t={};for(const n of Wd){const s=e[n];"function"==typeof s&&(t[n]=s,console.log(`[Hook Loader] ✓ Loaded hook: ${n}`))}const n=Object.keys(t).length;return 0===n?console.warn("[Hook Loader] No valid hooks found in module"):console.log(`[Hook Loader] Successfully loaded ${n} hook(s)`),t}class Kd{static pool=new Map;static async create(e,t,n){const s=this.pool.get(t);if(s)return s;let a;if("claude"===e||"companion"===e){const s=await async function(e){const{agentId:t,agentDir:n,logger:s}=e;if(!t||"default"===t)return{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};try{ai(s,"info",`Loading agent: ${t}`);const e=await st({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return ai(s,"warn",`No claude configuration found for agent ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};const a=e.claude,i=a.plugins.map(e=>({type:"local",path:e})),o=n||at().resolveAgentDir(t),r=a.config.sdkMcpTools?.map(e=>A(o,"claude",e)),c={customSystemPrompt:a.systemPrompt,customModel:a.config.model,customFallbackModel:a.config.fallbackModel,customMaxTurns:a.config.maxTurns,customExtraArgs:a.config.extraArgs,customPermissionMode:a.config.settings?.permissionMode,customPlugins:i,systemPromptMode:a.config.systemPrompt?.mode??"append",customPRPromptTemplate:a.prPromptTemplate,prPromptMode:a.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:r};return ai(s,"info",`Agent ${t} loaded successfully (${i.length} plugins)`),c}catch{return ai(s,"error",`Failed to load agent: ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}}}({agentId:t,agentDir:n?.agentDir,logger:n?.logger});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=pe(),a=t||s.resolveAgentDir(e),i=A(a,"claude");return await async function(e,t){const n=Ke(e,"hooks");if(!Le(n))return{};const s=[Ke(n,"dist","index.mjs"),Ke(n,"dist","index.js"),Ke(n,"index.mjs"),Ke(n,"index.js")];let a=null;for(const e of s)if(Le(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] ${Ke(n,"index.js")} or ${Ke(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${Ut(a).href}?t=${Date.now()}`,n=await import(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),zd(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return zd(n)}catch(e){throw console.error(`[Hook Loader] Failed to load hooks from ${a}:`,e),new Error(`Hook loading failed: ${e instanceof Error?e.message:String(e)}`)}}(i,n)}catch(e){return void console.warn("[AgentRunners] Failed to load hooks:",e)}}(t,n.agentDir,n.context)),n?.context&&s.customSdkMcpTools&&s.customSdkMcpTools.length>0&&(o=await async function(e,t,n){const s={};for(const a of e)try{n&&n("info","MCP",`Loading SDK MCP tools from: ${a}`);const e=await import(a),i=e.default||e;if(!i){n&&n("warn","MCP",`No default export found in ${a}`);continue}const o="function"==typeof i?i(t):i,r=o.name;s[r]=o,n&&n("info","MCP",`Loaded MCP server: ${r}`)}catch(e){n&&n("error","MCP",`Failed to load SDK MCP tools from ${a}: ${e instanceof Error?e.message:String(e)}`)}return s}(s.customSdkMcpTools,n.context,n.logger)),a=new si(t,e,s,i,o,n?.logger)}else a=new Bd;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class Vd{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=We.join(this.workingDirectory,e);return Oe.existsSync(t)?Oe.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=We.join(this.workingDirectory,e);return Oe.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=Oe.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?me.includes(o.name)||this.listFilesRecursively(We.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class Xd{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=Ae.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,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,branchName:l.branchName,branchBinding:l.branchBinding,taskRepositoryId:l.taskRepositoryId,initialCommitHash:d,initPolicies:{...i?.initPolicies,...e.initPolicies,...h}};await Ae.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 pi(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await bi(e),i=await wi(e),o=s||Ae.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await Ai(e,o),c=r?await bd(t,n,r.patch):void 0,l=await Ae.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 Di(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 Ae.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 Ai(t,n);if(!o)return{};try{await bd(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new Vd(e);return ue(t)}(t),c=await Ae.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=ld(e)?e.branchName:void 0,d=e.forceUserCwd||!1===e.useWorktree,p="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await pi(s),m=ki(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){const o=rd(e)||e,c=Pi(n),l=Ni(c);if(!l)throw new Error(`Unable to resolve repository owner/name from git URL: ${c}`);const d=Ae.resolveRepoStoreCheckoutDir(s,l.owner,l.repo),p=Ae.resolveRepoStoreLockPath(s,l.owner,l.repo),u=await Ae.acquireFileLock(p);if(!u)throw new Error(`Timed out waiting for repo store lock at ${p}`);try{await async function(e,t,n,s){const a=Pi(t);if(!await pi(e)){if(!ki(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await gi(e)}await Ri(e,"origin",a),await fd(e,t,n);const i=function(e,t){if(t&&e.includes(t))return t;if(e.includes("main"))return"main";if(e.includes("master"))return"master";if(e.length>0)return e[0];throw new Error("Cannot create worktree: repository has no remote branches to base the workspace on.")}(await Mi(e),s);return await async function(e,t,n){await li("git",["checkout","--force","-B",t,n],{cwd:e,windowsHide:!0}),await li("git",["reset","--hard",n],{cwd:e,windowsHide:!0}),await li("git",["clean","-fd"],{cwd:e,windowsHide:!0})}(e,i,`origin/${i}`),{baseBranch:i}}(d,n,s,a);const e=i,t=await ui(d);if(t.find(e=>rd(e.path)===o))return s&&await gd(o,s),{initialCommitHash:await wi(o)};const c=e?t.find(t=>t.branch===e&&rd(t.path)!==o):void 0;if(e&&c)throw new Error(`Branch ${e} is already attached to worktree ${c.path}. Remove it before retrying.`);const l=Mt(d),p=await l.branchLocal(),u=!!e&&p.all.includes(e);if(r(o)&&!ki(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{e?u?await l.raw(["worktree","add",o,e]):await mi(d,o,e,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await hi(d,o,!0)}catch{}throw e}return await gd(o,s),{initialCommitHash:await wi(o)}}finally{await Ae.releaseFileLock(p,u)}}(s,0,a,c,o,l);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 e=await yd(s,a,0,o,c,l)||await wi(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await $i(s,"origin",Pi(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=ld(e)?e.branchName:void 0;if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const e=await yd(i,o,0,c,l,d)||await wi(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await this.assertDirectGitServerRemoteMatches(i,o),{...await this.tryResolveDirtyRepo(e,t,n,{defaultBranchMismatchAction:"Keep"}),setupAction:"reuse",useWorktree:!1}}async assertDirectGitServerRemoteMatches(e,t){const n=Ni(Pi(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${Pi(t)}`);const s=await Di(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 pi(s))return this.tryResolveDirtyRepo(e,t,n);if(!ki(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(ki(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await pi(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await xi(t)||await fi(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=rd(t)||t;if(!await pi(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await xi(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 ui(i)).find(e=>rd(e.path)===o))return{initialCommitHash:await wi(o)};const l=Mt(i),d=await l.branchLocal(),p=!!c&&d.all.includes(c);if(r(o)&&!ki(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 mi(i,o,c,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await hi(i,o,!0)}catch{}throw e}return{initialCommitHash:await wi(o)}}(t,s,0,ld(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 pi(s)){await async function(e){return{initialCommitHash:await async function(e){return await gi(e),await fi(e),await wi(e)}(e)}}(s),ld(e)&&e.branchName&&await vi(s,e.branchName,e.baseBranch);const t=await wi(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 pi(e)&&await bi(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}: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=di(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 xi(e.cwd)||await fi(e.cwd),r=ld(e)?"Ignore"===a?await _i(e.cwd)===e.branchName?"none":"kept":await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch"):"none";const c=await wi(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(!ld(e)||!e.branchName)return"none";const i=e.branchName,o=await _i(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 vi(e.cwd,i,e.baseBranch),"switched")}}const Jd=ht.object({title:ht.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:ht.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:ht.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),Yd=gt(Jd,{target:"draft-07"}),Qd=gt(Jd);function Zd(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?Jd.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=ep(e),n=JSON.parse(t);return Jd.parse(n)}(t.result??"")}function ep(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class tp{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const np=[{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 sp(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function ap(e=[]){const t=[],n=new Set;for(const e of np.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(sp).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 ip=ht.object({message:ht.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),op=gt(ip,{target:"draft-07"}),rp=gt(ip);async function cp(e){if(!await bi(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await wi(e.workingDirectory),n=await async function(e){const t=e.runner.runStreamed("Generate a git commit message for the current uncommitted changes.\n\nRequirements:\n- Follow this repository's commit message conventions.\n- Keep the subject line specific and concise.\n- Add a body only if it materially improves clarity.\n- Return only the commit message.",{cwd:e.workingDirectory,model:e.model,abortController:e.abortController,modeConfig:e.modeConfig,disableClaudePlanModeTools:e.disableClaudePlanModeTools,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?op:rp}});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?ip.parse(t.structured_output):ip.parse(JSON.parse(ep(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=di(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 wi(e)}(e.workingDirectory,n);if(await bi(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 lp(e){if(e)return{type:"json_schema",schema:e}}async function dp(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=E.join(e,s.name),a=E.join(t,s.name);s.isDirectory()?await dp(n,a):await o.promises.copyFile(n,a)}}function pp(e){return"oneshot"===function(e){return e.workerExecutionMode??he}(e)}async function up(e){const t=A(e,".agentrix"),n=A(t,"prompt.md"),s=A(t,"plugins"),[a,i]=await Promise.all([mp(n),hp(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function mp(e){try{if(!(await I.stat(e)).isFile())return;const t=(await I.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(gp(e))return;throw e}}async function hp(e){let t;try{t=await I.readdir(e,{withFileTypes:!0})}catch(e){if(gp(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=A(e,s.name),a=A(t,".claude-plugin","plugin.json");try{(await I.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(gp(e))continue;throw e}}return n}function gp(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}function fp(e){const t=e,n=ge({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 yp(e){if(!e)return!1;const t=A(e,".agentrix","vision");try{return r(t)&&p(t).isDirectory()}catch{return!1}}const vp=Symbol("companionHeartbeatContext"),bp=Symbol("companionMemoryOrganizationContext");class wp{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=Re({type:"worker",taskId:a}),this.currentAgentSessionId="agentSessionId"in s?s.agentSessionId:void 0;const o=s.taskAgents||[];this.taskAgentsMap=new Map(o.map(e=>[e.id,e]));const r=this.taskAgentsMap.size>1;this.primaryAgentId=r?"planner":s.agentId,this.primaryAgentName=r?"planner":this.taskAgentsMap.get(s.agentId)?.name??"unknown";const c=this.createWorkerClientConfig(i,a,n),l=Ae.resolveDataDir(i,a);this.historyDb=so({dataDir:l,taskId:a}),this.workClient=new gl(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new xl({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:Ae.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:Ae.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const d={...cd(this.options.input),cwd:this.workingDirectory};this.workspace=new Xd({options:d,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=Sl();logger;workClient;workspace;coordinator;agentContext;runner;agentQueues=new Map;currentAgentSessionId;currentGroupId=null;historyDb;chatHistoryDb=null;agentrixTools;pendingNavigateTaskId=null;pendingPermissions=new Map;grantedPermissions=new Set;loopPermissionModeSetter=null;configuredPermissionMode="bypassPermissions";desiredPermissionMode=null;activePermissionMode=null;lastBroadcastPermissionMode=null;taskAgentsMap;messageSavedListener=null;messageDebounceHandle=null;messageDebounceMs=1e4;lastProcessedSequence=0;primarySessionReady=!1;pendingPrimaryLastSequence=null;primaryAgentId;primaryAgentName;exitReason="completed";pendingChannelReplies=[];channelMessageInvocationCount=0;projectAgentrixGuidance={claudePlugins:[]};newMessageGroupId(){return`group-${crypto.randomUUID()}`}refreshGroupId(){this.currentGroupId=this.newMessageGroupId()}getConfiguredPermissionMode(){if(this.isOneShotExecution())return"bypassPermissions";const e=this.runner?.getAgentConfiguration()?.customPermissionMode;return e??"bypassPermissions"}isOneShotExecution(){return pp(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=ae(t);return!!fe(t)||!!ye(t)||!!ve(t)||!(!ie(t)&&!a)&&"agent"!==e.senderType&&(s?e.senderId!==this.primaryAgentId:!!a||"system"===e.senderType&&"user"===t.type||"user"===t.type)}shouldDropHeartbeatWhileBusy(){return this.coordinator.isActivelyExecuting()}async processPendingMessages(){const e=this.historyDb.pageMessagesAfter(this.lastProcessedSequence,100),t=this.getRunnerMode(),n="group_chat"===t||"group_work"===t,s=[];for(const t of e.data)if(this.lastProcessedSequence=t.localSequence,this.shouldProcessMessage(t)){if(n&&this.isUnsupportedGroupPlanCommand(t)){this.log("info","PLAN","Ignoring unsupported ![plan] command in group mode");continue}s.push(t)}if(s.length>0){this.deduplicateHeartbeats(s);const e=this.mergeConsecutiveHumanMessages(s);n?await this.processMessagesAsGroup(e):await this.processMessagesIndividually(e)}e.hasMore&&await this.processPendingMessages()}isUnsupportedGroupPlanCommand(e){const t=e.message;return!(!ie(t)||"user"!==t.type)&&"![plan]"===Ca(t).trim()}deduplicateHeartbeats(e){let t=-1;for(let n=e.length-1;n>=0;n--)fe(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(!ie(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=zc(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(fe(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionHeartbeatPrompt(e)},parent_tool_use_id:null,session_id:""};return n[vp]=e,n}if(ve(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(ye(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionMemoryOrganizationPrompt(e)},parent_tool_use_id:null,session_id:""};return n[bp]=e,n}return ie(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 this.log("info","COMPANION",`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[bp];return t?(delete e[bp],{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[vp]?(delete e[vp],{COMPANION_SHADOW_TASK:"heartbeat"}):void 0}async prepareMessageForRunner(e){return hc(e,{attachmentsDir:Ae.resolveAttachmentsDir(this.options.input.userId,this.taskId),log:(e,t,n,...s)=>{this.log(e,t,n,...s)}})}setupMessageSavedListener(){this.messageSavedListener=()=>{this.triggerMessageProcessing()},this.historyDb.on("message-saved",this.messageSavedListener)}triggerMessageProcessing(){const e=this.getRunnerMode();"group_chat"===e||"group_work"===e?this.scheduleProcessPendingMessages():this.processPendingMessages()}scheduleProcessPendingMessages(){this.coordinator?.setDebouncing(!0),this.messageDebounceHandle&&clearTimeout(this.messageDebounceHandle),this.messageDebounceHandle=setTimeout(async()=>{this.messageDebounceHandle=null,await this.processPendingMessages(),this.coordinator?.setDebouncing(!1)},this.messageDebounceMs)}async start(){let e="completed";try{if(await this.initialize(),!await this.maybeConfirmAgentrixDevOpsInit())return;await this.handleEvent(),await this.runClaude()}catch(t){if(!(t instanceof Ct)){e="error",this.log("warn","AGENT","Fatal error:",t);const n=t instanceof Error?t.message:String(t);await this.reportFatalError(n)}}finally{await this.exitWorker("error"===e?"error":this.exitReason)}}async autoInstallAgent(e){const t=this.options.input,n=t.agentGitUrl,s=t.agentGitSubDir;if(n)try{this.log("info","AGENT",`Auto-installing agent ${e} from git`),await oa({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){this.log("warn","AGENT",`Auto-install failed for agent ${e}: ${t}`)}else this.log("warn","AGENT",`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=Ae.agentrixAgentsHomeDir,a=A(s,`${e}.new`),i=A(s,`${e}-bak`);try{this.log("info","AGENT",`Applying upgrade for ${e}`),ra(n),m(n,a),await dp(t,i),h(t,{recursive:!0,force:!0}),m(a,t),Le(i)&&h(i,{recursive:!0,force:!0}),this.log("info","AGENT",`Upgrade applied for ${e}`)}catch(n){this.log("warn","AGENT",`Upgrade failed for ${e}: ${n}`),!Le(t)&&Le(i)&&m(i,t),Le(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??Ae.resolveAgentDir(e.agentId,this.workingDirectory);Boolean(t&&"git-server"===e.repositorySourceType&&!e.agentDir&&!Le(A(s,"agent.json")))&&(n=await this.workspace.setup());const a=e.agentDir??Ae.resolveAgentDir(e.agentId,this.workingDirectory),i=A(a,"upgrade"),o=Boolean(a)&&Boolean(e.agentGitUrl)&&!t,r=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&o&&!Le(a)),c=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!t&&!r&&Le(i));if(await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:r,upgradingAgent:c}),r&&await this.autoInstallAgent(e.agentId),t&&"default"!==e.agentId&&!Le(A(a,"agent.json")))throw new Error(`Filesystem agent not found: ${e.agentId} (${a})`);c&&await this.applyAgentUpgrade(e.agentId,a,i),this.log("info","AGENT",`Resolved agent ${e.agentId}: ${a}`);const l=await Kd.create(e.agentType,e.agentId,{agentDir:a,logger:this.log.bind(this),context:this.agentContext});this.runner=l,this.initializePermissionModeState(),n??=await this.workspace.setup(),this.projectAgentrixGuidance=await up(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${n.setupAction} at ${this.workingDirectory} (${n.initialCommitHash||"none"})`),this.setEnvironmentVariables(),this.lastProcessedSequence=this.historyDb.getAgentLastSequences().get(this.primaryAgentId)??0,this.log("info","HISTORY",`Starting from sequence ${this.lastProcessedSequence} (tracking: ${this.primaryAgentId})`),this.currentAgentSessionId&&(this.historyDb.upsertAgentSession(this.primaryAgentId,this.currentAgentSessionId),this.primarySessionReady=!0),this.setupMessageSavedListener(),this.workClient.sendWorkerInitialized(),this.workClient.sendTaskSlashCommandsUpdate(ap())}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 cn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}setEnvironmentVariables(){this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.ANTHROPIC_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.ANTHROPIC_AUTH_TOKEN=this.options.input.api_key)}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new Cd({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 dn(this.taskId,this.options.input.userId),this.stopTask("event")},onPlanMode:async()=>this.isOneShotExecution()?(this.workClient.sendSystemErrorMessage("![plan] is not supported in oneshot execution mode",{groupId:this.currentGroupId??void 0}),null):(await this.requestPermissionMode("plan"),null)},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=kl(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=Il(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}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&&ye(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(){this.log("info","MERGE","Executing merge-request command");const e=this.getRunnerMode(),t="group_chat"===e||"group_work"===e;try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await bi(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await wi(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Si(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=ld(o),c=r?dd(this.options.input.taskId,o.branchName):void 0;if(r&&c){const e=await _i(this.workingDirectory);if(e!==c){const t=md(e,c);return this.log("warn","MERGE",t),void this.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}const l=this.runner?.getAgentConfiguration(),d=xd(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);this.log("debug","MERGE",`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(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:Yd}});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=Zd(u),g=dd(this.options.input.taskId,c,h.title);r||await pd(this.workingDirectory,g);const f=ud(g);this.log("info","MERGE",`Pushing HEAD to remote branch ${g}`),await vd(this.workingDirectory,f,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","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}`,b={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(),Ea({sessionId:u.session_id,model:this.options.input.model??"unknown",numTurns:u.num_turns,usage:b,result:v}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.workClient.sendSystemErrorMessage(`❌ Merge-request failed: ${t}\n\nPlease check git status and try again, or create the PR manually.`,{groupId:this.currentGroupId??void 0})}var n,s}async executeBashCommand(e){if(!Ae.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await Td(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await Ad({workingDirectory:this.workingDirectory,workClient:this.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.logger,askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(){this.log("info","MERGE","Generating commit message with agent"),await cp({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),schemaTarget:"claude",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.taskAgentsMap.size>1?e:this.messageFilter.filter(e);null!==t&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}isAgentrixDevOpsInitWorker(){return this.options.input.agentId===gc}async maybeConfirmAgentrixDevOpsInit(){if(!this.isAgentrixDevOpsInitWorker())return!0;const e=vc(this.options.input),t=(await this.askUser([bc(e)],{onTimeout:"abort_task"})).answers[0]??"";return("zh-Hans"===e?"先初始化"===t:"Initialize first"===t)||(await ln(this.taskId,this.options.input.userId,"continue"),!1)}getAgentrixExtraTools(){if(this.isAgentrixDevOpsInitWorker())return[Tt("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:ht.string().describe("Short user-visible summary of what initialization completed")},async e=>{const t=vc(this.options.input),n=await this.askUser([wc(t)],{onTimeout:"abort_task"}),s=function(e,t){const n=e.trim();return"zh-Hans"===t?"继续实现需求"===n||"继续"===n?"continue":"输入修改建议"===n||"修改建议"===n?"modify":"停止任务"===n||"停止"===n?"stop":null:"Continue request"===n||"Continue"===n?"continue":"Provide changes"===n||"Modify"===n?"modify":"Stop task"===n||"Stop"===n?"stop":null}(n.answers[0]??"",t);if(this.log("info","DEVOPS_INIT",`Post-init user decision: ${s??"unrecognized"} (answer=${JSON.stringify(n.answers[0]??"")})`),!s)return{content:[{type:"text",text:"The platform could not recognize the user post-init choice. Ask the user again or call complete_devops_init again after confirming the next action. Do not stop this DevOps init session yet."}]};if("modify"===s){const e=n.details?.[0]?.trim();return{content:[{type:"text",text:e?`The user wants additional Agentrix DevOps init changes before completion:\n${e}`:"The user wants additional Agentrix DevOps init changes before completion. Continue the same initialization session."}]}}return await ln(this.taskId,this.options.input.userId,"continue"===s?"continue":"stop"),setImmediate(()=>this.stopTask("event")),{content:[{type:"text",text:"continue"===s?`Agentrix DevOps initialization completed: ${e.summary}. The platform is switching back to the original development agent.`:`Agentrix DevOps initialization completed: ${e.summary}. The task will stop without starting the development agent.`}]}})]}async runClaude(){if(this.log("info","AGENT",`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void this.log("info","AGENT",`Skipping Claude run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runClaudeOneShot();const e=this.currentAgentSessionId,t=this.runner,n=this.getRunnerModeConfig(),s="group_chat"===n.mode||"group_work"===n.mode,a=this.createPermissionHandler(),i=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.initializePermissionModeState();const o=t.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:e,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:n,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(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.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){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of o.events)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,s);this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude agent finished for task ${this.taskId}`)}async runClaudeOneShot(){const e=this.runner,t=this.getRunnerModeConfig(),n="group_chat"===t.mode||"group_work"===t.mode,s=this.createPermissionHandler(),a=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.loopPermissionModeSetter=null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.initializePermissionModeState(),this.broadcastPermissionMode(this.getPermissionModeSnapshot());const i=await this.coordinator.waitForAgentMessage();if(!i)return this.isStopping||this.stopTask("oneshot_complete"),this.resetPrimaryPermissionState(),void this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&this.markPrimaryMessageProcessed(o),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=>{this.log("debug","SDK",e)},modeConfig:t,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(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(),this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e,t){if("system"===e.type&&"init"===e.subtype)return this.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.workClient.sendTaskSlashCommandsUpdate(ap(e.slash_commands??[]),e.session_id),this.currentAgentSessionId=e.session_id,this.historyDb.upsertAgentSession(this.primaryAgentId,e.session_id),this.primarySessionReady=!0,null!==this.pendingPrimaryLastSequence&&(this.historyDb.updateAgentLastSequence(this.primaryAgentId,this.pendingPrimaryLastSequence),this.pendingPrimaryLastSequence=null),this.refreshGroupId(),void this.updateAgentRunning(!0);if("result"===e.type)return await this.handleSdkResultMessage(e),this.refreshGroupId(),void this.updateAgentRunning(!1);"system"===e.type&&"task_notification"===e.subtype&&this.handleBackgroundTaskNotification(e);const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}resetPrimaryPermissionState(){this.loopPermissionModeSetter=null,this.activePermissionMode=null}updateAgentRunning(e){this.coordinator?.setAgentRunning(this.primaryAgentId,this.primaryAgentName,e)}markPrimaryMessageProcessed(e){this.historyDb.updateAgentLastSequence(this.primaryAgentId,e),this.primarySessionReady||(this.pendingPrimaryLastSequence=null===this.pendingPrimaryLastSequence?e:Math.max(this.pendingPrimaryLastSequence,e))}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}async handleAskUserQuestionPermission(e){const t=e,n=Array.isArray(t.questions)?t.questions:[];if(0===n.length)return this.log("warn","PERMISSION","AskUserQuestion missing questions"),{behavior:"deny",message:"AskUserQuestion missing questions"};const s=n.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]}));try{const e=await this.askUser(s),a={};for(let t=0;t<n.length;t+=1){const s=n[t]?.question;if(!s)continue;const i=e.answers?.[t];"string"==typeof i&&(a[s]=i)}return{behavior:"allow",updatedInput:{...t,answers:a}}}catch(e){return this.log("warn","PERMISSION",`AskUserQuestion failed: ${e}`),{behavior:"deny",message:"AskUserQuestion failed"}}}createPermissionHandler(){return async(e,t)=>{if("AskUserQuestion"===e)return this.handleAskUserQuestionPermission(t);if("ExitPlanMode"===e)return this.handleExitPlanModePermission(t);if(this.grantedPermissions.has(e))return this.log("info","PERMISSION",`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return this.log("info","PERMISSION",`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;this.log("info","PERMISSION",`Requesting permission for "${e}"`);const a=new Promise(e=>{s=e});this.pendingPermissions.set(e,a);try{const n=await this.requestToolPermission(e);return s(n),"allow"===n?(this.grantedPermissions.add(e),{behavior:"allow",updatedInput:t}):{behavior:"deny",message:"Permission denied by user"}}catch(e){return s("deny"),{behavior:"deny",message:"Permission request failed"}}finally{this.pendingPermissions.delete(e)}}}async handleExitPlanModePermission(e){const t=e.planFilePath??e.filePath;let n,s;if(t){const e=this.workspace.getCwd(),a=e.endsWith("/")?e:e+"/";n=t.startsWith(a)?t.slice(a.length):void 0;try{const e=await Be.readFile(t,"utf-8");s=e.length>8e3?e.slice(0,8e3)+"\n\n…(truncated)":e}catch{}}!s&&"string"==typeof e.plan&&e.plan&&(s=e.plan);const a=[{question:"Review the plan and choose how to proceed.",header:"Plan Review",multiSelect:!1,options:[{label:"Approve",description:"Approve the plan and start implementation"},{label:"Revise",description:"Need to revise the plan",additionalInput:{enabled:!0,required:!1,placeholder:"Describe what should change."}},{label:"Cancel",description:"Cancel this plan"}],planFilePath:n,planContent:s}];try{const t=await this.askUser(a,{onTimeout:"abort_task"}),n=t.answers[0],s=t.details?.[0]?.trim();return"Approve"===n?{behavior:"allow",updatedInput:e}:"Revise"===n?{behavior:"deny",message:s?`The user wants to revise the plan. Revision notes: ${s}. Please reconsider and update the plan, then call ExitPlanMode again when ready.`:"The user wants to revise the plan. Please reconsider and update the plan, then call ExitPlanMode again when ready."}:(await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"User cancelled plan review",interrupt:!0})}catch{return await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"Plan review failed or was interrupted"}}}async requestToolPermission(e){const t=[{question:`Tool "${e}" is requesting permission to execute. Allow this operation?`,header:"Permission",multiSelect:!1,options:[{label:"Allow",description:"Allow this tool to execute"},{label:"Deny",description:"Deny this tool execution"}]}];try{return"Allow"===(await this.askUser(t,{onTimeout:"abort_task"})).answers[0]?"allow":"deny"}catch(e){return this.log("warn","PERMISSION",`Permission request failed: ${e}`),"deny"}}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.workClient;return $d(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>n.sendAssistantMessage(e,{groupId:this.currentGroupId??void 0}),stopTask:e=>this.stopTask(e)},t)}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}getRunnerMode(){const e=this.taskAgentsMap.size>1,t=this.options.input.taskType,n=!(!process.env.AGENTRIX_COMPANION_HOME&&!process.env.AGENTRIX_COMPANION_WORKSPACE);return"shadow"===t?"companion_shadow":n&&"chat"===t?"companion_chat":e?"chat"===t?"group_chat":"group_work":"chat"===t?"chat":"work"}getGroupAgents(){if(!(this.taskAgentsMap.size<=1))return Array.from(this.taskAgentsMap.values()).map(e=>({id:e.id,name:e.name,description:e.description}))}getRunnerModeConfig(){return{mode:this.getRunnerMode(),supportChangeTitle:this.supportChangeTitle,groupAgents:this.getGroupAgents()}}shouldDisableClaudePlanModeTools(){const e=this.options.input.taskType;return"chat"===e||"shadow"===e||this.isChannelBoundTask()||Boolean(this.options.input.parentTaskId)}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}getStructuredOutputSchema(){return lp(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=Ae.resolveDataDir(t,e);this.chatHistoryDb=so({dataDir:n,taskId:e})}return{createTask:Ml(t={agentContext:this.agentContext,workClient:this.workClient,uploadFile:e=>this.agentContext.uploadFile(e),credentials:this.credentials,taskId:this.taskId,chatId:this.options.input.chatId,agentId:this.primaryAgentId,isGroup:e,historyDb:this.historyDb,chatHistoryDb:this.chatHistoryDb??void 0,askUser:e=>this.askUser(e),log:this.log.bind(this),onChannelMessageInvoked:()=>{this.channelMessageInvocationCount+=1},invokeAgent:(e,t)=>this.invokeAgent(e,t),assign:(e,t,n)=>this.assignWork(e,t,n),setPendingNavigateTaskId:e=>{this.pendingNavigateTaskId=e},getChannelReplyTarget:()=>this.getInjectedChannelReplyTarget(),supportedFeatures:this.options.input.supportedFeatures,visionModel:this.options.input.visionModel,workingDirectory:this.workingDirectory}),createSoloTask:Nl(t),createGroupTask:Dl(t),replyToSubTask:_l(t),changeTaskTitle:Cl(t),publishTaskPreviewUrl:El(t),sendVisionArtifact:Al(t),askUser:Ol(t),getTaskHistory:$l(t),getTaskAgents:Pl(t),listSubTask:Rl(t),invoke:Ul(t),assign:Ll(t),updateAgentInfo:jl(t),sendReminder:Gl(t),recordMemoryChange:Bl(t),listTasks:Hl(t),readConversation:ql(t),uploadFile:Wl(t),sendChannelMessage:Vl(t),getChannelGroupHistory:Xl(t),listAgents:Yl(t),analyzeImage:Zl(t),scheduleTask:ed(t),prepareHiveRepository:td(t),publishToHive:nd(t),updateHiveListingVersion:sd(t),recordHiveInstall:ad(t),createHiveReview:id(t),createHiveComment:od(t),computerUse:Tl(t)};var t}isComputerUseEnabled(){try{return Nr(void 0,this.log.bind(this)).enabled}catch(e){return this.log("warn","COMPUTER_USE",`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 tp,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 Kd.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),d=this.buildSystemHooks({trackBackgroundTasks:!1}),p=Sl(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(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=[ka(e,i),"=== CONVERSATION STREAM START FROM HERE ===",Ca(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){this.log("error","INVOKE",`Invoke failed for ${e}:`,t)}finally{this.coordinator?.setAgentRunning(e,o,!1)}}),!0}async assignWork(e,t,n){const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new tp,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 Kd.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),d=Sl(),p=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(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){this.log("error","RUN_TASK",`Run task failed for ${e}:`,t);const n=t instanceof Error?t.message:String(t);this.sendAgentErrorMessage(e,o,`I meet some error: ${n}`,{groupId:s})}finally{this.coordinator?.setAgentRunning(e,o,!1)}})}buildSubAgentHistoryContext(e,t){const n=this.historyDb;if(!n)return this.log("warn","HISTORY","Task history DB unavailable; delegate cannot build context."),null;const s=n.getAgentSessions().get(e),a=n.getAgentLastSequences().get(e)??0,i=n.pageRecentMessagesAfter(a,20);if(0===i.data.length&&!t)return null;const o=this.mergeConsecutiveHumanMessages(i.data),r=this.buildHistoryMessages(o,t);return r?{message:r,sessionId:s,lastSequence:i.data.length>0?i.data[i.data.length-1].localSequence:a}:null}buildHistoryMessages(e,t){const n=[];for(const t of e){const e=Kc(t);e&&n.push(e)}if(0===n.length&&!t)return null;let s=n.join("\n");return t&&(s=`<hint>\n${t}\n</hint>\n\n${s}`),{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}buildSystemHooks(e){const t=e?.trackBackgroundTasks??!0,n=e?.trackPrimaryAgentStop??!1,s={};return t&&(s.PostToolUse=async e=>(this.syncPermissionModeFromPostToolUse(e),this.trackBackgroundTaskFromPostToolUse(e),{})),n&&(s.Stop=async()=>(this.updateAgentRunning(!1),{})),s}trackBackgroundTaskFromPostToolUse(e){if(!e||"object"!=typeof e)return void this.log("debug","TASK","PostToolUse hook input is not an object");const t=e,n=t.tool_input;if(!n||!0!==n.run_in_background)return;const s=this.extractBackgroundTaskId(t.tool_response);if(!s)return this.log("debug","TASK",`PostToolUse(${t.tool_name}) run_in_background=true but no task_id found, using anonymous tracking`),void this.coordinator?.setAnonymousBackgroundTaskRunning(!0);this.coordinator?.setBackgroundTaskRunning(s,!0),this.log("info","TASK",`Background task started: ${s} (tool: ${t.tool_name})`)}syncPermissionModeFromPostToolUse(e){if(!e||"object"!=typeof e)return;const t=(n=e.tool_name,s=this.configuredPermissionMode,"EnterPlanMode"===n?"plan":"ExitPlanMode"===n?s:null);var n,s;t&&this.confirmPermissionModeApplied(t)}handleBackgroundTaskNotification(e){this.updateAgentRunning(!0),this.coordinator?.setBackgroundTaskRunning(e.task_id,!1),this.log("info","TASK",`Background task ${e.task_id} ${e.status}`)}extractBackgroundTaskId(e){const t=new Set,n=new Set,s=e=>{if("string"!=typeof e)return;const n=e.trim();n&&t.add(n)},a=e=>{if(null==e)return;if("string"==typeof e)return void(e=>{const t=/(task[_-]?id|agent[_-]?id|shell[_-]?id)["'\s:=]+([A-Za-z0-9._:-]+)/gi;let n;for(;null!==(n=t.exec(e));)s(n[2])})(e);if("object"!=typeof e)return;if(n.has(e))return;if(n.add(e),Array.isArray(e)){for(const t of e)a(t);return}const t=e;"string"==typeof t.task_id&&s(t.task_id),"string"==typeof t.taskId&&s(t.taskId),"string"==typeof t.agent_id&&s(t.agent_id),"string"==typeof t.agentId&&s(t.agentId),"string"==typeof t.shell_id&&s(t.shell_id),"string"==typeof t.shellId&&s(t.shellId);for(const e of Object.values(t))a(e)};a(e);const i=[...t];return i.length>1&&this.log("warn","TASK",`Multiple background task ids extracted (${i.join(", ")}), using first id ${i[0]}`),i[0]}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.taskAgentsMap.get(s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:Ae.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:be(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:z(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString(),activeAgents:this.coordinator?.getActiveAgents(),permissionMode:this.getPermissionModeSnapshot()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>this.logger.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:Ae.resolveAttachmentsDir(e,t),logger:(e,t,n,...s)=>{this.log(e,t,n,...s)},stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!fe(e)||!this.shouldDropHeartbeatWhileBusy()||(this.log("debug","WORKER","Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(ae(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{await _d(e,this.options.input,this.workspace)},onWorkerStatusRequest:async()=>{const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning():"idle"===e&&this.workClient.sendWorkerReady()},onSubTaskResultUpdated:async e=>{const t=kl(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=Il(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`),this.coordinator&&this.coordinator.stop(),this.workClient&&(this.workClient.sendWorkerExit(e),await this.workClient.disconnect()),this.historyDb&&this.historyDb.close(),this.chatHistoryDb&&this.chatHistoryDb.close(),process.exit(0)}async reportFatalError(e){await this.workClient.sendTerminalErrorResultAndWait(e,{groupId:this.currentGroupId??void 0})}log(e,t,n,...s){this.logger&&this.logger[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}const s=this.getRunnerMode(),a="group_chat"===s||"group_work"===s,i=this.pendingNavigateTaskId;if(this.pendingNavigateTaskId=null,a?this.workClient.sendTaskEvent(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}):this.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}),n)try{await wd(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}await this.forwardResultToChannelIfNeeded(e)}async forwardResultToChannelIfNeeded(e){if("result"!==e.type)return;const t=this.pendingChannelReplies.shift(),n=void 0===t?this.getInjectedChannelReplyTarget():t.target??this.getInjectedChannelReplyTarget();if(void 0===t&&!n)return;const s="success"===e.subtype,a=t?this.channelMessageInvocationCount>t.channelMessageInvocationCountAtStart:this.channelMessageInvocationCount>0;if(s&&a)return;const i=this.extractResultTextForChannel(e);if(!i)return;const o=await pn(this.taskId,i,n),r=s;this.historyDb.saveTaskEvent({taskId:this.taskId,chatId:this.options.input.chatId,eventType:"channel-message-send",sequence:null,eventData:{status:o?.error?"error":"sent",delivery:r?"fallback":"error-forward",reason:r?"send_channel_message_not_invoked":"task_failed",channelId:n?.channelId,hasContent:!0,attachments:[],...o?.error?{error:o.error}:{}}}),o?.error&&this.log("debug","CHANNEL",`Claude reply was not sent to channel: ${o.error}`)}getInjectedChannelReplyTarget(){const e=process.env.AGENTRIX_CHANNEL_REPLY_TARGET;if(!e)return null;try{const t=JSON.parse(e);if("string"==typeof t.channelId&&"string"==typeof t.chatId)return{channelId:t.channelId,chatId:t.chatId,..."string"==typeof t.platform?{platform:t.platform}:{},..."string"==typeof t.chatType?{chatType:t.chatType}:{},..."string"==typeof t.chatName?{chatName:t.chatName}:{}}}catch(e){this.log("debug","CHANNEL","Ignoring invalid channel reply target:",e)}return null}isChannelBoundTask(){return null!==this.getInjectedChannelReplyTarget()}isChannelGroupBoundTask(){return"group"===this.getInjectedChannelReplyTarget()?.chatType?.toLowerCase()}getExternalChannelPromptContext(){const e=this.getInjectedChannelReplyTarget();if(e)return{platform:e.platform,chatType:e.chatType,chatName:e.chatName,chatId:e.chatId}}isChannelReplyTarget(e){return Boolean(e&&"object"==typeof e&&"string"==typeof e.channelId&&"string"==typeof e.chatId)}extractResultTextForChannel(e){if("success"===e.subtype){const t=e.result;if("string"!=typeof t)return null;const n=t.trim();return n.length>0?n:null}const t=e.errors,n=Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0).join("\n").trim():"",s=e.subtype;return`Task failed: ${n||("string"==typeof s?s:"Unknown error")}`}}class xp{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>rd(e)||e;if(n)return l(n);const d=Ae.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.shouldUseWorktree(e)?l(d):e}return l(d)}static async shouldUseWorktree(e){try{return!ki(e)&&await pi(e)}catch{return!1}}}var kp=Mn(Ne);class Ip{constructor(e,t){this.credentials=e,this.options=t}context;threadId=null;isStopping=!1;filteredToolUseIds=new Set;currentModel=null;dataEncryptionKey=null;abortController=new AbortController;coordinator;logger;askUserAwaiter=new Map;workClient;workspace;historyDb=null;currentGroupId=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return pp(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${xe()}`}async start(){try{await this.initialize(),await this.handleEvent(),await this.runCodex(),await this.exitWorker(this.exitReason)}catch(e){if(!this.isStopping){this.isStopping=!0,this.askUserAwaiter.clear(),this.coordinator?.stop(),this.log("warn","AGENT","Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}this.log("info","AGENT",`Task ${this.taskId} stopped gracefully`),await this.exitWorker(this.exitReason)}finally{process.exit(0)}}async initialize(){const e=this.options.input.taskId,t=this.options.input.userId;this.logger=this.createLogger({type:"worker",taskId:e}),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const n=cd(this.options.input),s=await xp.calculateFinalCwd(n),a={...n,cwd:s};this.log("info","INIT",`Phase 1: Working directory: ${s}`);const i=this.createWorkerClientConfig(t,e,s),o=Ae.resolveDataDir(t,e);this.historyDb=so({dataDir:o,taskId:e});const r=new gl(i.config,{...i.handlers,historyDb:this.historyDb});this.workClient=r,this.log("info","INIT","Phase 2: WorkerClient created");const c=1e3*Math.max(0,this.options.idleTimeoutSecond??0);this.coordinator=this.createMessageCoordinator(r,c),this.log("info","INIT","Phase 3: Coordinator created"),await r.connect(),r.sendWorkerInitializing(),this.log("info","INIT","Phase 4: Connected to server"),this.log("info","INIT","Phase 5: Skipped (no AgentContext for Codex)"),this.log("info","INIT","Phase 6: Skipped (no custom resources for Codex)");const l=new Xd({options:a,handlers:this.createWorkspaceHandlers(r,s)}),{initialCommitHash:d,gitStateResult:p,setupAction:u}=await l.setup();this.workspace=l,this.projectAgentrixGuidance=await up(s),this.log("info","INIT","Phase 7: Workspace setup complete"),r.sendWorkerInitialized(),r.sendTaskSlashCommandsUpdate(ap()),this.log("info","INIT","Phase 8: Initialization finalized"),await this.registerWithDaemon(s),this.log("info","INIT","Phase 9: Registered with daemon"),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${u} at ${s} (${d||"none"})`),this.context={credentials:this.credentials,options:this.options,workClient:r,workingDirectory:s,dataDir:o,initialCommitHash:d,logger:this.logger},process.env.AGENTRIX_WORKING_DIR=s,process.env.AGENTRIX_WORKING_USER=t,process.env.AGENTRIX_WORKING_TASK=e,this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.OPENAI_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.CODEX_API_KEY=this.options.input.api_key),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,this.log("info","AGENT",`Resuming thread: ${this.threadId}`))}createWorkspaceHandlers(e,t){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await cn(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new Cd({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 dn(this.taskId,this.options.input.userId),this.stopTask("event")}},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){if("task-message"===this.options.input.event){const{eventId:e,message:t}=this.options.input.eventData;t&&ie(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e&&this.workClient?.sendEventAck(e))}}async executeMergeRequest(){this.refreshGroupId(),this.log("info","MERGE","Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await bi(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await wi(this.context.workingDirectory),t=this.context.initialCommitHash,n=this.workspace.getState(),s=n.branchName?{branchName:n.branchName,branchBinding:n.branchBinding}:this.options.input,a=ld(s),i=a?dd(this.options.input.taskId,s.branchName):void 0;if(a&&i){const e=await _i(this.context.workingDirectory);if(e!==i){const t=md(e,i);return this.log("warn","MERGE",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 this.log("error","MERGE",e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Si(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=xd(t);this.log("debug","MERGE",`PR prompt: ${o.substring(0,200)}...`);const r=this.options.input.agentId??"default",c=await Kd.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,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:Qd}});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=Zd(p),m=dd(this.options.input.taskId,i,u.title);a||await pd(this.context.workingDirectory,m);const h=ud(m);this.log("info","MERGE",`Pushing HEAD to remote branch ${m}`),await vd(this.context.workingDirectory,h,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","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);this.log("error","MERGE","Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){this.log("info","WORKER",`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!Ae.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.context.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t=await Td(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await Ad({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 Kd.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");this.log("info","MERGE","Generating commit message with agent"),await cp({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},schemaTarget:"openai",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.filterMessages(e);null!==t&&this.getActiveWorkClient().sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return lp(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 Ae.readDaemonState();if(!e?.port)return this.log("debug","MCP","Agentrix event MCP broker unavailable: daemon state not found"),null;const t=fp(this.options.input),n=yp(this.context?.workingDirectory),s=function(e,t){const n={taskId:t.taskId,userId:t.userId,machineId:t.machineId??e.machineId,nonce:we(16).toString("base64url"),taskPreviewEnabled:t.taskPreviewEnabled,visionPlanEnabled:t.visionPlanEnabled},s=(a=JSON.stringify(n),Buffer.from(a,"utf8").toString("base64url"));var a;return`${s}.${ir(s,ar(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId,taskPreviewEnabled:t,visionPlanEnabled:n});return{serverName:lr,url:on(e,dr),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:pr,previewToolName:t?ur:void 0,sendVisionArtifactToolName:n?mr:void 0,token:s}}buildCodexRunEnvironment(){if(this.codexAgentrixEventMcp)return{...process.env,[this.codexAgentrixEventMcp.tokenEnvVar]:this.codexAgentrixEventMcp.token}}async runCodex(){this.log("info","AGENT",`Starting Codex agent for task ${this.taskId}`),this.currentModel=Fd(this.options.input.model),this.currentModel?this.log("info","AGENT",`Using model: ${this.currentModel}`):this.log("info","AGENT","Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await Kd.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void this.log("info","AGENT",`Skipping Codex run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runCodexOneShot(t,n);const s=t.loop({cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(e)this.refreshGroupId(),this.updateAgentRunning(!0),s.push(e);else if(this.isStopping)break}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.log("info","AGENT",`Codex agent finished for task ${this.taskId}`)}async runCodexOneShot(e,t){const n=await this.coordinator.waitForAgentMessage();if(!n)return this.isStopping||this.stopTask("oneshot_complete"),void this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId();const s=e.runStreamed(n,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:t,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:fp(this.options.input),enableVisionPlan:yp(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.isStopping||this.stopTask("oneshot_complete")}finally{this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e){if("system"===e.type&&"init"===e.subtype)return this.threadId=e.session_id,this.context.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.context.workClient.sendTaskSlashCommandsUpdate(ap(e.slash_commands??[]),e.session_id),this.log("info","AGENT",`Thread started: ${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);null!==t&&("result"===e.type?await this.handleSdkResultMessage(t):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"!==e.type?this.updateAgentRunning(!0):this.updateAgentRunning(!1)}filterMessages(e){const t=e,n=t?.message?.content;if(!n||"string"==typeof n)return e;const s=n.filter(e=>{return"tool_use"!==e.type||"agentrix"!==(n=e.server_name)&&n!==lr?!("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:xe().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:xe().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 $d(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>this.sendMessage(e),stopTask:e=>this.stopTask(e)},t)}getActiveWorkClient(){const e=this.context?.workClient??this.workClient;if(!e)throw new Error("[WORKER] WorkerClient not available");return e}resolveTaskAgentName(e){const t=this.options.input.taskAgents??[];return t.find(t=>t.id===e)?.name||""}getChatSenderMeta(){const e=this.options.input.agentId;return{senderType:"agent",senderId:e,senderName:this.resolveTaskAgentName(e)??""}}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t,n){this.log("info","MERGE",`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=Ae.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 mc(t,n,!1);this.log("info","IMAGE",`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){this.log("error","IMAGE",`Failed to download image from ${t}:`,e)}}else if("document"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:a,mimeType:i,filename:o}=await mc(t,n,!0);this.log("info","DOCUMENT",`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){this.log("error","DOCUMENT",`Failed to download document from ${t}:`,e)}}const s=e.map(e=>e.trim()).filter(Boolean).join("\n\n").trim();if(s)return s}return""}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}updateAgentRunning(e){this.coordinator?.updateAgentRunning(e)}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.options.input.taskAgents?.find(e=>e.id===s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:Ae.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:be(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:z(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>(this.context?.logger??this.logger)?.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:Ae.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(ae(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}ie(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{await _d(e,this.options.input,this.workspace)},onWorkerStatusRequest:async()=>{if(!this.context?.workClient)return;if(!this.coordinator)return;const{state:e}=this.coordinator.getStatus();"running"===e?this.context.workClient.sendWorkRunning():"idle"===e&&this.context.workClient.sendWorkerReady()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`);const n=this.context?.workClient??this.workClient;n&&("error"===e&&t?await n.sendErrorMessageAndExit(t):(n.sendWorkerExit(e),await n.disconnect()),this.historyDb&&this.historyDb.close())}createLogger(e){const{createLogger:t}=kp;return t(e)}log(e,t,n,...s){const a=this.context?.logger??this.logger;a&&a[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}getCurrentModel(){return this.currentModel||"unknown"}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}if(this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0}),n)try{await wd(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}}}function Sp(){const e=process.env.AGENTRIX_CLAUDE_PATH?.trim();if(!e)return;if(e.includes("/")||e.includes("\\")||e.startsWith(".")){const t=E.isAbsolute(e)?e:E.resolve(e);return o.existsSync(t)?t:void 0}const t="win32"===process.platform?"where":"which",n=vt(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 Tp(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 Cp(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(...Cp(E.join(e,a.name),n)):s.push(n))}return s}async function Ep(e,t,n){const s=Cp(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)},Tt("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:ht.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:ht.array(ht.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:ht.array(ht.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:Tp(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=It({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=St({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:Sp(),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 Ap=Rt(xt);function _p(e,t,n){const s=Ae.serverUrl.replace(/^http/,"ws");return Je(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function $p(e,...t){const{stdout:n}=await Ap("git",t,{cwd:e});return n.trim()}function Pp(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const Rp=Rt(xt);function Mp(e,t,n){const s=Ae.serverUrl.replace(/^http/,"ws");return Je(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const Np=["claude","codex","deployment","companion","hive-publish","hive-install"],Dp={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Ae.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=cd(t.input),s=await xp.calculateFinalCwd(n),a=new wp(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Ae.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 Ip(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:Ae.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=E.join(Ae.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await dp(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=Ae.serverUrl.replace(/^http/,"ws");return Je(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:z(),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:z(),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:Ae.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(E.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=E.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:Pp(r),displayName:r,description:c,readme:n,repoDirName:Pp(r)}}(r);m=e.name,h=e.displayName,g=e.description,f=e.readme,u=E.posix.join(u,e.repoDirName),console.log(`[HivePublish] Parsed skill metadata name=${m}, displayName=${h}`)}v=E.join(Ae.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(v,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await $p(v,"clone","--depth","1",c,".");const t=E.join(v,u);if(o.mkdirSync(E.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 dp(r,t),o.writeFileSync(E.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await $p(v,"add",".");const i=await async function(e){try{return await Ap("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 Ep(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 $p(v,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await $p(v,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const b=await $p(v,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${b}`),y=_p(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:z(),taskId:s,listingId:a,success:!0,gitCommitHash:b,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??_p(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{y.emit("hive-publish-complete",{eventId:z(),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:Ae.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=E.join(Ae.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 Rp("git",t,{cwd:e});return n.trim()}(u,"clone","--depth","1",r,".");const t=E.join(u,i);if(!o.existsSync(t))throw new Error(`Source directory not found in hive repo: ${i}`);if("skill"===l&&!o.existsSync(E.join(t,"SKILL.md")))throw new Error(`Skill directory must contain SKILL.md: ${i}`);const n=(m=d).startsWith("~/")?E.join(process.env.HOME||"",m.slice(2)):E.isAbsolute(m)?m:E.join(Ae.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 dp(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),ra(n)}catch(e){try{o.rmSync(n,{recursive:!0,force:!0})}catch{}throw e}const a=E.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=Mp(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:z(),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??Mp(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{p.emit("hive-install-complete",{eventId:z(),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=Ae.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 to();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=cd(t.input),i=await xp.calculateFinalCwd(a),o=new wp(e,t,i);await o.start()}(e,r)}}};async function Op(e,t){const n=`${Ae.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function Up(e){try{const t=c(A(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function jp(e,t){const n=e=>e.split(".").map(e=>parseInt(e,10)||0),s=n(e),a=n(t);for(let e=0;e<Math.max(s.length,a.length);e++){const t=s[e]??0,n=a[e]??0;if(t>n)return!0;if(t<n)return!1}return!1}async function Lp(e){const t=Ae.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>p(A(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=A(t,s),a=A(n,"upgrade");if(r(a))continue;const i=Up(n);_e.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await Op(s,e);if(!t||!t.gitUrl){_e.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];wt(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?A(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=Up(o);if(!c||i&&!jp(c,i)){_e.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}_e.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),_e.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){_e.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}let Hp=null;function qp(){const e=Ae.getStatePaths();return ze.join(ze.dirname(e.daemonStateFile),"upgrade-daemon.state.json")}function Gp(){try{const e=qp();if(!Ue.existsSync(e))return null;const t=Ue.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function Fp(e){try{const t=qp();if(Ue.existsSync(t)){if("number"==typeof e){const t=Gp();if(!t||t.pid!==e)return}Ue.unlinkSync(t)}}catch{}}function Bp(e){try{return process.kill(e,0),!0}catch{return!1}}async function Wp(e){return(await un(e)).error?await async function(){try{return await fn(),dc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),!0}catch{return!1}}()?(Hp=null,!0):(Hp=e,!1):(Hp=null,!0)}async function zp(){if(Hp)return await Wp(Hp)?"upgraded":"no-upgrade";if(sl())return"no-upgrade";const e=await tl();if(e.hasUpgrade&&await al(e)){const e="Automatic CLI upgrade installed";return Hp=e,await Wp(e)?"upgraded":"no-upgrade"}try{const e=await Ae.readCredentials();e&&await Lp(e)}catch{}return"no-upgrade"}function Kp(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 Vp(e,t){if(!Yt.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=Zt({input:Yt,output:Qt});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}async function Xp(){const e=await Jn();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}function Jp(e){return"string"==typeof e&&e.trim()?e.trim():void 0}async function Yp(e){const t=await Xp(),n=Kp(Jp(e["base-url"])??await Vp("GitLab base URL"),"baseUrl"),s=Kp(Jp(e["api-url"])??await Vp("GitLab API URL",function(e){return`${Kp(e,"baseUrl")}/api/v4`}(n)),"apiUrl"),a=(Jp(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()}(Jp(e["pat-file"])):void 0)??await async function(e){return Yt.isTTY&&Qt.isTTY&&"function"==typeof Yt.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{Yt.setRawMode(!1),Yt.pause(),Yt.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Qt.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Qt.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Qt.write(`${e}: `),Yt.setRawMode(!0),Yt.resume(),Yt.on("data",i)}):Vp(e)}("GitLab PAT");if(!a)throw new Error("GitLab PAT is required");let i;const o=await async function(e,t){const{result:n,user:s}=await et(e,t);return{valid:n.valid,username:n.username,scopes:n.scopes,meta:n.valid&&s?{username:s.username,email:s.email||"",lastValidatedAt:(new Date).toISOString(),expiresAt:n.expiresAt}:void 0}}(s,a);if(!o.valid)throw new Error(`PAT validation failed for ${s}/user`);i=o.meta;const l=await async function(e){const t=await async function(e){return await rn("/git-server/register",e)}({name:new URL(e.baseUrl).hostname,baseUrl:e.baseUrl,apiUrl:e.apiUrl});if(t.error||!t.gitServer)throw new Error(`Backend Git server registration failed: ${t.error||"Daemon did not return a registered Git server"}`);return{id:t.gitServer.id,baseUrl:t.gitServer.baseUrl,apiUrl:t.gitServer.apiUrl}}({baseUrl:n,apiUrl:s});var d,p;i&&(d=l.id,p=i,Xn.savePatMeta(d,p)),function(e,t){Xn.saveGitServerConfig(e,t)}(l.id,{baseUrl:l.baseUrl,apiUrl:l.apiUrl}),function(e,t,n){Xn.savePat(e,t,n)}(l.id,a,t);const u=function(e,t){return Xn.ensureGitLabWebhookSecret(e,t)}(l.id,t),m=await async function(e){return await rn("/git-server/complete",{gitServerId:e})}(l.id);if(m.error||!m.success)throw new Error(`Backend Git server completion failed: ${m.error||"Daemon did not confirm completion"}`);console.log(JSON.stringify({id:l.id,type:"gitlab",baseUrl:l.baseUrl,apiUrl:l.apiUrl,webhookEndpointPath:ot(l.id),webhookUrl:it(l.id,await Ae.readDaemonState()),backendRegistered:!0,patConfigured:!0,patMeta:Zn(l.id),webhookSecret:u},null,2))}function Qp(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function Zp(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||Ae.serverUrl}function eu(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return S(A(t,e),T.X_OK),!0}catch{return!1}})}function tu(e,t,n){return new Promise((s,a)=>{const i=bt(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 nu(e){try{return await Pt(e),!0}catch{return!1}}function su(e){return e.filter(e=>e.required&&!e.installed)}async function au(e,t){eu(e)?console.log(L.green(`✓ ${e} is installed`)):eu("npm")?(console.log(L.blue(`Installing ${e} with npm...`)),await tu("npm",["install","-g",t])):console.log(L.yellow(`npm is not available. Install ${t} manually.`))}async function iu(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function ou(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 ru(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(L.yellow("Invalid selection"))}}function cu(e){return JSON.stringify(e)}async function lu(e,t){const n=await async function(e){try{return(await Ee.get(`${Ae.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||Zp()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(L.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),Zp()}}(t),s=Zt({input:Yt,output:Qt});try{await async function(e,t,n){const s=A(Ae.claudeConfigDir,"settings.json");if(!t&&await nu(s)&&!await ou(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(L.gray("Skipped Claude config"));const a=await ru(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(L.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await iu(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await iu(e,"Agentrix API key for Claude");else{const t=await iu(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await iu(e,"Anthropic auth token")}const o=await iu(e,"Claude primary model","claude-sonnet-4-6"),r=await iu(e,"Claude fast model","claude-haiku-4-5"),c=await iu(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 Et(Ae.claudeConfigDir,{recursive:!0}),await _t(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(L.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=A(Ae.codexHomeDir,"config.toml");if(!t&&await nu(s)&&!await ou(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(L.gray("Skipped Codex config"));const a=await ru(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(L.gray("Skipped Codex config"));const i=await iu(e,"Codex model","gpt-5.5"),o=await ru(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 iu(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await iu(e,"OpenAI API key")):(c=await iu(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await iu(e,"Custom API key")),await Et(Ae.codexHomeDir,{recursive:!0}),await _t(s,function(e){const t=e.provider,n=[`model = ${cu(e.model)}`,`model_provider = ${cu(t)}`,"",`[model_providers.${t}]`,`name = ${cu("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${cu(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${cu(s)}`)}return e.envKey&&n.push(`env_key = ${cu(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=Ae.readOrInitSettings({sandbox:Ae.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};Ae.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(L.green(`✓ Wrote Codex config: ${s}`)),console.log(L.green(`✓ Wrote Codex env vars to ${Ae.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function du(e={}){console.log(L.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=Ns(),t=[...su(e.cli.filter(e=>"claude"!==e.name)),...su(e.sandbox)];"linux"!==process.platform||eu("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(L.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(L.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(L.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=>eu(e.name))||null;if(!t){console.log(L.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(L.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(L.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await tu(s.join(" "),[],{shell:!0}):await tu(s[0],s.slice(1))}(t),await au("claude","@anthropic-ai/claude-code@latest"),await au("codex","@openai/codex@latest");const n=Ds();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await xn();await lu(Boolean(e.force),t),e.skipDaemon||await async function(){if(await hn())console.log(L.green("✓ Daemon is already running"));else{console.log(L.blue("Starting Agentrix daemon...")),dc(["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 mn())return void console.log(L.green("✓ Daemon started successfully"));console.log(L.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(L.green("\n✓ Agentrix CLI initialization complete"))}function pu(e,t){const n=e[t]?.trim();return n||void 0}function uu(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function mu(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 hu(e){const t=pu(e,"AGENTRIX_API_KEY");if(t)return t;const n=pu(e,"AGENTRIX_API_KEY_FILE");if(!n)return;const s=(await async function(e){try{return(await At(uu(e),"utf-8")).replace(/[\r\n]/g,"")}catch{throw new Error(`AGENTRIX_API_KEY_FILE is set but is not readable: ${e}`)}}(n)).trim();return s||void 0}function gu(e){return JSON.stringify(e)}function fu(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 yu(e){var t;return`${[`model = ${gu(e.codexModel)}`,'model_provider = "agentrix"',"","[model_providers.agentrix]",'name = "Agentrix"','wire_api = "responses"',`base_url = ${gu((t=e.baseUrl,`${t.replace(/\/+$/,"")}/v1`))}`,'env_key = "AGENTRIX_API_KEY"'].join("\n")}\n`}function vu(e,t){return`${JSON.stringify({connectionMode:"gemini-compatible",baseUrl:e.baseUrl,apiKey:t,imageModel:e.geminiImageModel},null,2)}\n`}function bu(e,t){return"skip"===e?"skip":t?"would write":"write"}const wu=U(j(process.argv)).scriptName("agentrix").version(Pe.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 xu(e){try{return process.kill(e,0),!0}catch{return!1}}async function ku(e){let t;if("string"==typeof e["report-json"])try{t=JSON.parse(e["report-json"])}catch{console.error(L.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 Ae.readDaemonState():null,n=e.oldPid??(t&&cl(t.pid)?t.pid:void 0),s=e.expectedCliVersion??el();var a;if(e.report&&(a={...e.report,oldPid:n,expectedCliVersion:s,reason:e.reason,createdAt:(new Date).toISOString()},u(ol(),JSON.stringify(a,null,2),"utf-8")),e.stopExistingDaemon&&void 0!==n&&cl(n)&&await fn(),void 0!==n){const t=await async function(e,t){const n=Date.now()+t;for(;Date.now()<n;){if(!cl(e))return!0;await rl(100)}return!cl(e)}(n,e.oldDaemonExitTimeoutMs??12e4);if(!t)return{success:!1,error:`Old daemon PID ${n} did not exit before timeout`}}try{dc(["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 Ae.readDaemonState();if(n&&n.pid!==e&&n.cliVersion===t&&cl(n.pid))return n;await rl(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(L.red("Error:"),a.error??"Daemon restart failed"),process.exit(1))}Ae.getStatePaths,wu.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(L.dim(`Current version: ${Pe.version}`));const t=await mn(),n=t?await Ae.readDaemonState():null;await al()||process.exit(1);try{const e=await Ae.readCredentials();e&&(console.log(L.dim("Checking agent updates...")),await Lp(e))}catch{}if(t){console.log(L.blue("Preparing daemon restart..."));const e=await un("CLI upgrade installed");let t=!0;const s=el();e.error?(console.log(L.yellow(`⚠️ Could not prepare graceful restart: ${e.error}`)),console.log(L.blue("Restarting daemon directly...")),await fn(),dc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()):"pending_restart"===e.state&&(console.log(L.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&&!a){if(xu(e.pid)){await new Promise(e=>setTimeout(e,100));continue}a=!0}const n=await Ae.readDaemonState();if(n&&n.pid!==e?.pid&&n.cliVersion===t&&xu(n.pid))return!0;await new Promise(e=>setTimeout(e,100))}return!1}(n,s),a?console.log(L.green("✓ Daemon restarted successfully")):console.log(L.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check.")))}const s=el();"0.0.0"!==s?console.log(L.green(`\n✓ Now running version: ${s}`)):console.log(L.dim("\nRun 'agentrix --version' to see the new version")),process.exit(0)}),wu.command("doctor","System diagnostics & troubleshooting",{},async e=>{await Us(),process.exit(0)}),wu.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await Ae.readCredentials())return void console.log(L.yellow("Not currently authenticated"));console.log(L.blue("This will log you out of Agentrix")),console.log(L.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=De({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(L.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await fn(),console.log(L.gray("Stopped daemon"))}catch{}await Ae.clearCredentials(),console.log(L.gray("Removed credentials")),console.log(L.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(L.blue("Logout cancelled"))}()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),wu.command("stop","Stop the daemon",{},async e=>{!function(){const e=Gp();if(e)try{Bp(e.pid)&&process.kill(e.pid,"SIGTERM")}catch{}finally{Fp()}}(),await fn(),process.exit(0)}),wu.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 ku(e),console.log(L.green("✓ Daemon restarted successfully")),process.exit(0)}),wu.command("status","Show daemon and authentication status",{},async e=>{await Us("daemon"),console.log(""),await async function(){const e=await Ae.readCredentials();if(console.log(L.bold("\nAuthentication Status\n")),!e)return void console.log(L.red("✗ Not authenticated"));console.log(L.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(L.gray(` Token: ${t}`)),e.machineId?(console.log(L.green("✓ Machine registered")),console.log(L.gray(` Machine ID: ${e.machineId}`)),console.log(L.gray(` Host: ${n.hostname()}`))):console.log(L.yellow("⚠️ Machine not registered")),console.log(L.gray(`\n Data directory: ${Ae.agentrixHomeDir}`));try{await mn()?console.log(L.green("✓ Daemon running")):console.log(L.gray("✗ Daemon not running"))}catch{console.log(L.gray("✗ Daemon not running"))}}(),process.exit(0)}),wu.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await rn("/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)}),wu.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await Rs()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===e.type||"upgrade-daemon"===e.type)).map(e=>({pid:e.pid,command:e.command}))}(),t=[];let n=0;for(const{pid:s,command:a}of e)try{if(console.log(`Killing runaway process PID ${s}: ${a}`),"win32"===process.platform){const e=pt.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 dt()).find(e=>e.pid===s)&&(console.log(`Process PID ${s} ignored SIGTERM, using SIGKILL`),process.kill(s,"SIGKILL"));console.log(`Successfully killed runaway process PID ${s}`),n++}catch(e){const n=e.message;t.push({pid:s,error:n}),console.log(`Failed to kill process PID ${s}: ${n}`)}return{killed:n,errors:t}}();console.log(`Cleaned up ${e.killed} runaway processes`),e.errors.length>0&&console.log("Errors:",e.errors),process.exit(0)}),function(e){e.command("git-server","Manage local private GitLab server config",e=>e.command("add","Add a private GitLab server to local daemon config",e=>e.option("base-url",{type:"string",describe:"GitLab base URL, for example https://gitlab.example.com"}).option("api-url",{type:"string",describe:"GitLab API URL, defaults to <base-url>/api/v4"}).option("pat-file",{type:"string",nargs:1,describe:"Read GitLab PAT from a file, or - for stdin"}),async e=>{try{await Yp(e),process.exit(0)}catch(e){Qp(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await Xp(),t=await Ae.readDaemonState(),n=await async function(){return await rn("/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=Yn(e.id)??{},a=Qn(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:ot(e.id),webhookUrl:it(e.id,n),patConfigured:(i=e.id,Xn.hasPat(i)),patMeta:Zn(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){Qp(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(wu),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 du({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(wu),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 async function(e={}){const t=e.env||process.env,s=!0===e.force,a=!0===e.dryRun,i=await async function(e){const t=uu(pu(e,"AGENTRIX_HOME_DIR")||pu(e,"AGENTRIX_DIR")||A(n.homedir(),".agentrix")),s=uu(pu(e,"AGENTRIX_CLAUDE_HOME")||A(t,"config","claude")),a=uu(pu(e,"AGENTRIX_CODEX_HOME")||A(t,"config","codex")),i=uu(pu(e,"AGENTRIX_GEMINI_HOME")||A(t,"config","gemini")),o=pu(e,"AGENTRIX_CLAUDE_MODEL")||"claude-sonnet-4-6";return{agentrixHomeDir:t,claudeConfigDir:s,codexHomeDir:a,geminiConfigDir:i,baseUrl:mu(pu(e,"AGENTRIX_BASE_URL")||"https://api.xmz.ai"),apiKey:await hu(e),codexModel:pu(e,"AGENTRIX_CODEX_MODEL")||"gpt-5.5",claudeModel:o,claudeFastModel:pu(e,"AGENTRIX_CLAUDE_FAST_MODEL")||"claude-haiku-4-5",claudeSubagentModel:pu(e,"AGENTRIX_CLAUDE_SUBAGENT_MODEL")||o,geminiImageModel:pu(e,"AGENTRIX_GEMINI_IMAGE_MODEL")||"gemini-2.5-flash-image"}}(t);if(function(e,t){return!(!t&&r(A(e.claudeConfigDir,"settings.json"))&&r(A(e.codexHomeDir,"config.toml"))&&r(A(e.geminiConfigDir,"settings.json")))}(i,s)&&!i.apiKey)throw new Error("AGENTRIX_API_KEY 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:A(e.claudeConfigDir,"settings.json"),content:fu(e,t)},{kind:"codex",path:A(e.codexHomeDir,"config.toml"),content:yu(e)},{kind:"gemini",path:A(e.geminiConfigDir,"settings.json"),content:vu(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 Et(M(e.path),{recursive:!0}),await _t(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}:{}}}({force:!0===e.force,dryRun:!0===e.dryRun,env:process.env}),s=t.files.filter(e=>"write"===e.action).length,a=t.files.filter(e=>"skip"===e.action).length,i=t.dryRun?"LLM config dry run":"LLM config applied";if(console.log(L.green(`✓ ${i}: ${s} write(s), ${a} skipped`)),!0===e.verbose||t.dryRun)for(const e of t.files)console.log(`${bu(e.action,t.dryRun)} ${e.kind}: ${e.path}`);t.env.AGENTRIX_API_KEY&&console.log(L.gray("AGENTRIX_API_KEY prepared for this process.")),process.exit(0)}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(wu),wu.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 rn("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?L.green("✓ Session stopped"):L.red("Failed to stop session"))}catch(e){console.log(L.red("No daemon running"))}process.exit(0)}),wu.command("daemon",!1,{},async e=>{try{await xn()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await ll(),process.exit(0)}),wu.command("worker",!1,e=>e.option("type",{type:"string",choices:Np,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=Dp[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=await xn(),i=e["user-id"],o=e["task-id"],r=e["idle-timeout"];await n.run({credentials:a,startedBy:s,userId:i,taskId:o,idleTimeoutSecond:r})}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),wu.command("upgrade-daemon",!1,{},async e=>{await async function(){await async function(){!function(e){const t=qp();Ue.writeFileSync(t,JSON.stringify(e,null,2))}({pid:process.pid,startedAt:(new Date).toISOString()}),process.on("SIGTERM",()=>{Fp(process.pid),process.exit(0)}),process.on("SIGINT",()=>{Fp(process.pid),process.exit(0)});try{"upgraded"===await zp()&&(dc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}for(;;){await new Promise(e=>setTimeout(e,216e5));try{"upgraded"===await zp()&&(dc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}}}()}(),process.exit(0)}),wu.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 ku(e),process.exit(0)}),wu.command("start","Start daemon (if not running) and show status",{},async e=>{try{await xn()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=Ds();if(t.ok||(console.log(L.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(L.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(L.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await hn()){console.log("Starting Agentrix background service..."),dc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await mn()){e=!0;break}e?(await new Promise(e=>setTimeout(e,1200)),await mn()?console.log(L.green("✓ Daemon started successfully")):await async function(){const e=await async function(){const e=A(Ae.getStatePaths().logsDir,"daemon.log");try{return(await At(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(L.red("✗ Daemon exited shortly after startup")),!e)return;const t=e.split("\n").reverse().find(e=>e.includes("Machine binding revoked")||e.includes("Run `agentrix logout` and bind again"));t?console.log(L.yellow(t)):(console.log(L.gray("Recent daemon log:")),console.log(e))}()):console.log(L.yellow("⚠️ Daemon may still be starting..."))}if(sl()){const e=await tl();e.hasUpgrade&&(n=e).hasUpgrade&&n.latestVersion&&(console.log(""),console.log(L.yellow("┌────────────────────────────────────────────────────┐")),console.log(L.yellow("│")+" "+L.bold("Upgrade Available")+" "+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+` Current: ${L.dim(n.currentVersion)} → Latest: ${L.green.bold(n.latestVersion)} `+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+" Run "+L.cyan.bold("agentrix upgrade")+" to upgrade "+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+" To enable auto-upgrade, set: "+L.yellow("│")),console.log(L.yellow("│")+" "+L.dim("AGENTRIX_DISABLE_AUTO_UPGRADE=false")+" "+L.yellow("│")),console.log(L.yellow("└────────────────────────────────────────────────────┘")),console.log(""))}else(function(){const e=Gp();return!(!e||!Bp(e.pid)&&(Fp(),1))})()||dc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();var n;await Us("daemon"),process.exit(0)}),wu.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 v,lstatSync as y,symlinkSync as b,readlinkSync as w,createReadStream as x,copyFileSync as k,promises as I,accessSync as S,constants as T}from"node:fs";import*as E from"node:path";import A,{join as _,basename as C,extname as $,resolve as N,sep as R,dirname as P,relative as M,isAbsolute as D,normalize as O}from"node:path";import U from"yargs";import{hideBin as j}from"yargs/helpers";import L from"chalk";import{encodeBase64 as q,encryptMachineEncryptionKey as H,decodeBase64 as G,createKeyPairWithUit8Array as B,generateAESKey as F,decryptWithEphemeralKey as W,SocketAuthErrorDataSchema as z,createEventId as K,encryptFileContent as V,VisionPlanReviewWriteEventSchema as X,splitRtcChunkFrame as J,RtcChunkFlags as Y,buildRtcChunkFrame as Q,decodeGitPath as Z,UpdateTaskPreviewUrlRequestSchema as ee,AGENTRIX_DEV_INIT_FEATURE as te,decryptSdkMessage as ne,isSDKUserMessage as se,isAskUserMessage as ae,isAskUserResponseMessage as ie,isSDKMessage as oe,createKeyPair as re,encryptAES as ce,encryptWithEphemeralKey as le,encryptSdkMessage as de,machineAuth as pe,getAgentContext as ue,detectPreview as me,IGNORED_DIRECTORIES as he,DEFAULT_WORKER_EXECUTION_MODE as ge,getTaskExecutionMode as fe,isCompanionHeartbeatMessage as ve,isCompanionMemoryOrganizationMessage as ye,isCompanionReminderMessage as be,workerAuth as we}from"@agentrix/shared";import{randomBytes as xe,randomUUID as ke,createHash as Ie,createDecipheriv as Se,createCipheriv as Te,createHmac as Ee,timingSafeEqual as Ae}from"node:crypto";import _e from"axios";import{m as Ce,l as $e,p as Ne,a as Re,c as Pe,g as Me,b as De}from"./logger-x_FEOhbQ.mjs";import{createInterface as Oe}from"node:readline";import*as Ue from"fs";import je,{readFileSync as Le,existsSync as qe,unlinkSync as He,openSync as Ge,writeFileSync as Be,closeSync as Fe,promises as We}from"fs";import*as ze from"path";import Ke,{join as Ve,dirname as Xe}from"path";import Je from"open";import{io as Ye}from"socket.io-client";import{EventEmitter as Qe}from"node:events";import{pipeline as Ze}from"node:stream/promises";import{createRequire as et}from"node:module";import{spawn as tt,execSync as nt}from"child_process";import st from"ps-list";import at from"cross-spawn";import{getPlatform as it}from"@xmz-ai/sandbox-runtime/dist/utils/platform.js";import ot from"fastify";import{z as rt,toJSONSchema as ct}from"zod";import{validatorCompiler as lt,serializerCompiler as dt}from"fastify-type-provider-zod";import{spawnSync as pt,spawn as ut,execSync as mt,execFile as ht,execFileSync as gt}from"node:child_process";import{createSdkMcpServer as ft,query as vt,tool as yt,AbortError as bt}from"@anthropic-ai/claude-agent-sdk";import{replacePromptPlaceholders as wt,loadAgentConfig as xt,getAgentContext as kt,GitServerLocalStore as It,deriveLocalGitServerEncryptionKey as St,validateGitLabPatToken as Tt,buildGitLabWebhookUrl as Et,buildGitLabWebhookEndpointPath as At}from"@agentrix/shared/node";import{mkdir as _t,readFile as Ct,writeFile as $t,readdir as Nt,access as Rt}from"node:fs/promises";import{promisify as Pt}from"node:util";import Mt from"simple-git";import{EventEmitter as Dt}from"events";import Ot from"better-sqlite3";import{fileURLToPath as Ut,pathToFileURL as jt}from"url";import{Cron as Lt}from"croner";import{McpServer as qt}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Ht}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Gt}from"crypto";import{isSupportedPlatform as Bt,NetworkManager as Ft,SandboxManager as Wt}from"@xmz-ai/sandbox-runtime";import*as zt from"@larksuiteoapi/node-sdk";import{readFile as Kt,mkdir as Vt,appendFile as Xt,stat as Jt}from"fs/promises";import{Codex as Yt}from"@openai/codex-sdk";import{stdin as Qt,stdout as Zt}from"node:process";import{createInterface as en}from"node:readline/promises";import"winston";import"os";const tn=new Set(["AGENTRIX_CLAUDE_HOME","AGENTRIX_CODEX_HOME","AGENTRIX_GEMINI_HOME","AGENTRIX_CLAUDE_PATH","AGENTRIX_CODEX_PATH"]);function nn(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function sn(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 an(e,t,n){const s=n.trim();s&&("AGENTRIX_CLAUDE_HOME"===t?e.CLAUDE_CONFIG_DIR=nn(s):"AGENTRIX_CODEX_HOME"===t&&(e.CODEX_HOME=nn(s)))}async function on(e){return new Promise(t=>setTimeout(t,e))}function rn(e,t){return`http://${"::1"===e.host?"[::1]":"127.0.0.1"}:${e.port}${t}`}async function cn(e,t){const n=await Ce.readDaemonState();if(!n?.port){const e="No daemon running, no state file found";return $e.debug(`[CONTROL CLIENT] ${e}`),{error:e}}try{const s=process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT?parseInt(process.env.AGENTRIX_DAEMON_HTTP_TIMEOUT):1e4,a=rn(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 $e.debug(`[CONTROL CLIENT] ${n}`),{error:n}}return await i.json()}catch(t){const s=`Request failed: ${e} at ${rn(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 $e.debug(`[CONTROL CLIENT] ${s}`),{error:s}}}async function ln(e,t){return await cn("/session-started",{sessionId:e,metadata:t})}async function dn(e,t,n){return await cn("/devops-init-complete",{taskId:e,userId:t,action:n})}async function pn(e,t){return await cn("/devops-init-start",{taskId:e,userId:t})}async function un(e,t,n){const s="string"==typeof t?{content:t}:t;return await cn("/channels/task-message",{taskId:e,...s,...n?{target:n}:{}})}async function mn(e){return await cn("/prepare-graceful-restart",{source:"agentrix-cli",reason:e})}async function hn(){const e=await Ce.readDaemonState();if(!e)return!1;try{return process.kill(e.pid,0),!0}catch{return $e.debug("[DAEMON RUN] Daemon PID not running, cleaning up state"),await fn(),!1}}async function gn(){if($e.debug("[DAEMON CONTROL] Checking if daemon is running same version"),!await hn())return $e.debug("[DAEMON CONTROL] No daemon running, returning false"),!1;const e=await Ce.readDaemonState();if(!e)return $e.debug("[DAEMON CONTROL] No daemon state found, returning false"),!1;try{const t=Ve(Ne(),"package.json"),n=JSON.parse(Le(t,"utf-8")).version;return $e.debug(`[DAEMON CONTROL] Current CLI version: ${n}, Daemon started with version: ${e.cliVersion}`),n===e.cliVersion}catch(e){return $e.debug("[DAEMON CONTROL] Error checking daemon version",e),!1}}async function fn(){try{await Ce.clearDaemonState(),$e.debug("[DAEMON RUN] Daemon state file removed")}catch(e){$e.debug("[DAEMON RUN] Error cleaning up daemon metadata",e)}}async function vn(){try{const e=await Ce.readDaemonState();if(!e)return void $e.debug("No daemon state found");$e.debug(`Stopping daemon with PID ${e.pid}`);try{return await async function(){await cn("/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){$e.debug("HTTP stop failed, will force kill",e)}process.kill(e.pid,"SIGKILL")}catch(e){$e.debug("Error stopping daemon",e)}}function yn(e){return`${e}\nRun \`agentrix logout\` and bind this machine again.`}function bn(e,t){if(_e.isAxiosError(e)){const n=e.response?.data?.message;return"string"==typeof n&&n.length>0?n.includes("Machine binding revoked")?yn(n):`${t}: ${n}`:"string"==typeof e.message&&e.message.includes("Machine binding revoked")?yn(e.message):`${t}: ${e.message}`}return e instanceof Error&&e.message.includes("Machine binding revoked")?yn(e.message):e instanceof Error?`${t}: ${e.message}`:t}function wn(){return q(new Uint8Array(xe(32)))}async function xn(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=F();return e.machineAesKey=q(n),n}(e);a.dataEncryptionKey=H(s.publicKey,t,G(n))}await _e.post(`${Ce.serverUrl}/v1/machines/sync`,a,{headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},timeout:6e4})}catch(e){throw new Error(bn(e,"Failed to sync machine data"))}}async function kn(){const e=await Ce.readCredentials();if(e){await async function(e){try{await _e.get(`${Ce.serverUrl}/v1/machines/validate`,{headers:{Authorization:`Bearer ${e.token}`},timeout:15e3})}catch(e){throw new Error(bn(e,"Stored machine credentials are no longer valid"))}}(e);let t=e;e.secret||(t={...e,secret:wn()},await Ce.writeCredentials(t),$e.info("[AUTH] Generated missing local auth secret"));try{await xn(t,Ce.metadata()),$e.info("[AUTH] Machine metadata synced")}catch(e){$e.warn("[AUTH] Failed to sync machine metadata",e)}return $e.info("[AUTH] Using existing credentials"),t}const t=process.env.CLOUD_AUTH_TOKEN;let n,s,a;if(t){const e=Ce.generateMachineId();n={token:t,secret:wn(),machineId:e},$e.info(`[AUTH] Cloud mode detected, generated machine ID: ${e}`)}else{const e=await async function(){console.clear();const e=Ce.generateMachineId(),t=new Uint8Array(xe(32)),n=await B(t);try{console.log(`[AUTH] Sending auth request to: ${Ce.serverUrl}/v1/auth/machine`),console.log(`[AUTH] Public key: ${q(n.publicKey).substring(0,20)}...`);const t={machineId:e};await _e.post(`${Ce.serverUrl}/v1/auth/machine`,t),console.log("[AUTH] Auth request sent successfully")}catch(e){return console.log(bn(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:q(e,"base64"),machineId:t},s=JSON.stringify(n),a=q((new TextEncoder).encode(s),"base64url");return`${Ce.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?($e.debug("[browser] Headless environment detected, skipping browser open"),!1):($e.debug(`[browser] Attempting to open URL: ${e}`),await Je(e),$e.debug("[browser] Browser opened successfully"),!0)}catch(e){return $e.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(`${Ce.serverUrl}/v1/auth/machine?machineId=${t}`);if("authorized"===n.data.state){const t=n.data.token,s=n.data.content,a=W(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${bn(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 on(1e3)}}finally{process.off("SIGINT",a)}return{token:null,userPublicKey:null}}(e,t)}(n,e);return s.token?{credentials:{token:s.token,secret:q(t),machineId:e},userPublicKey:s?.userPublicKey,keypair:n}:{credentials:null,userPublicKey:null,keypair:n}}();if(!e.credentials||!e.userPublicKey)throw new Error("Authentication failed or was cancelled");n=e.credentials,s=e.keypair,a=e.userPublicKey}return await xn(n,Ce.metadata(),a,s),await Ce.writeCredentials(n),$e.info("[AUTH] Machine setup completed"),n}!function(e=process.env){!function(e=process.env,t){if(!t?.variables)return e;const n=!0===t.enabled;for(const[s,a]of Object.entries(t.variables)){const t=s.trim();if(!t)continue;const i=String(a),o=tn.has(t);(n||o)&&(e[t]=i,sn(e,t,i),an(e,t,i))}}(e,function(e=process.env){const t=_(function(e=process.env){const t=e.AGENTRIX_HOME_DIR||e.AGENTRIX_DIR;return t?nn(t):_(n.homedir(),".agentrix")}(e),"settings.json");if(!r(t))return null;try{const e=c(t,"utf-8"),n=JSON.parse(e);return n?.daemonEnv||null}catch{return null}}(e))}();const In=new Set(["authorization","apikey","accesstoken","refreshtoken","machineaeskey","key","password","pat","secret","token"]);class Sn{interval=null;socket=null;config;constructor(e){this.config=e}start(e){this.interval&&this.stop(),this.socket=e,this.interval=setInterval(()=>{if(!this.socket)return void this.stop();const e=this.config.payloadGenerator?this.config.payloadGenerator():{};this.socket.emit(this.config.event,e)},this.config.intervalMs)}stop(){this.interval&&(clearInterval(this.interval),this.interval=null),this.socket=null}isRunning(){return null!==this.interval}}function Tn(e){if(!e||"object"!=typeof e)return{message:String(e??"unknown error")};const t=e,n=function(e){const t=z.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 En(e){if(!e||"object"!=typeof e)return String(e??"unknown error");const t=e,n=Tn(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=${JSON.stringify(t.description)}`),void 0!==t.data&&s.push(`data=${JSON.stringify(t.data)}`),void 0!==t.context&&s.push(`context=${JSON.stringify(t.context)}`),s.filter(Boolean).join(" ")||"unknown socket error"}function An(e,t=0){if(t>8)return"[MaxDepth]";if(Array.isArray(e))return e.map(e=>An(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]=In.has(e)?"[REDACTED]":An(a,t+1)}return n}function _n(e){try{return JSON.stringify(An(e))}catch{return"[Unserializable]"}}class Cn{socket=null;config;eventHandlers=new Map;eventEmitter=new Qe;KeepAliveManager=null;healthCheckInterval=null;constructor(e){this.config=e,e.keepAliveConfig&&(this.KeepAliveManager=new Sn(e.keepAliveConfig))}connect(){if(this.socket)return void this.log("Already connected or connecting");const{serverUrl:e,path:t,auth:n={},options:s={}}=this.config,a={path:t,auth:n,transports:["websocket"],reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:5e3,reconnectionAttempts:1/0,...s};this.socket=Ye(e,a),this.setupSocketHandlers(),this.log(`Connecting to ${e}`)}disconnect(){this.socket&&(this.log("Disconnecting"),this.stopHealthCheck(),this.socket.close(),this.socket=null)}get connected(){return this.socket?.connected??!1}replaceSocketHandler(e,t,n){this.socket&&(t&&this.socket.off(e,t),this.socket.on(e,n))}onEvent(e,t){const n=async n=>(this.log(`received event ${e}, data: ${_n(n)}`),t(n)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}onEventWithAck(e,t){const n=async(n,s)=>(this.log(`received event with ack ${e}, data: ${_n(n)}`),t(n,s)),s=this.eventHandlers.get(e);this.eventHandlers.set(e,n),this.replaceSocketHandler(e,s,n)}unregisterHandler(e){this.eventHandlers.delete(e),this.socket&&this.socket.off(e)}send(e,t){this.socket?(this.log(`send event ${e}`),void 0!==t?this.socket.emit(e,t):this.socket.emit(e)):this.log("Cannot send - socket not connected")}async sendWithAck(e,t){if(!this.socket)throw new Error("Cannot send - socket not connected");return this.log(`send event ${e}, data: ${_n(t)}`),this.socket.emitWithAck(e,t)}sendVolatile(e,t){this.socket&&(void 0!==t?this.socket.volatile.emit(e,t):this.socket.volatile.emit(e))}async flush(e=1e4){if(this.connected)return new Promise(t=>{const n=setTimeout(()=>t(),e);this.socket.emit("ping",()=>{clearTimeout(n),t()})})}updateAuth(e){this.socket&&(this.socket.auth=e),this.config.auth=e}onLifecycle(e,t){this.eventEmitter.on(`lifecycle:${e}`,t)}offLifecycle(e){this.eventEmitter.removeAllListeners(`lifecycle:${e}`)}setupSocketHandlers(){this.socket&&(this.socket.on("connect",()=>{this.log("Connected"),this.eventEmitter.emit("lifecycle:connect",this.socket);for(const[e,t]of this.eventHandlers.entries())this.socket.off(e,t),this.socket.on(e,t);this.KeepAliveManager?.start(this.socket),this.startHealthCheck()}),this.socket.on("disconnect",e=>{this.log(`Disconnected: ${e||"unknown"}`),this.eventEmitter.emit("lifecycle:disconnect",e),this.KeepAliveManager?.stop(),this.stopHealthCheck()}),this.socket.on("connect_error",e=>{this.log(`Connection error: ${En(e)}`),this.eventEmitter.emit("lifecycle:connect_error",e),setTimeout(()=>this.socket?.connect(),5e3)}),this.socket.on("error",e=>{this.log(`Socket error: ${En(e)}`),this.eventEmitter.emit("lifecycle:error",e)}))}startHealthCheck(){const e=this.config.healthCheckConfig;if(!1===e?.enabled)return;const t=e?.intervalMs??3e4,n=e?.timeoutMs??5e3;this.stopHealthCheck(),this.healthCheckInterval=setInterval(()=>{if(!this.socket||!this.connected)return;const e=setTimeout(()=>{this.log("Health check timeout - forcing reconnect"),this.socket&&(this.socket.disconnect(),this.socket.connect())},n);this.socket.once("pong",()=>{clearTimeout(e)}),this.socket.emit("ping")},t)}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null)}log(e,...t){this.config.logger&&this.config.logger(`[SocketClient] ${e}`,...t)}}const $n="attachment",Nn={"image/jpeg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/heic":".heic","application/pdf":".pdf"};function Rn(){const e=_(Ce.agentrixHomeDir,"tmp","channel-files");return r(e)||d(e,{recursive:!0}),e}function Pn(e){const t=function(e){if(!e)return;return C(e).replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").trim()||void 0}(e)||$n;return _(Rn(),`${ke()}-${t}`)}function Mn(e){const t=N(Rn()),n=N(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 Dn(e,t){if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);if(!e.body)throw new Error("Response body is null");const n=function(e,t){if(!e){const e=Un(t);return e?`${$n}${e}`:void 0}if($(e))return e;const n=Un(t);return n?`${e}${n}`:e}(t||function(e){if(!e)return;const t=e.match(/filename\*=UTF-8''([^;]+)/i);if(t?.[1])return decodeURIComponent(t[1]);const n=e.match(/filename="?([^";]+)"?/i);return n?.[1]}(e.headers.get("content-disposition")),e.headers.get("content-type")),s=Pn(n),a=l(s);return await Ze(e.body,a),s}async function On(e,t,n){const s=await fetch(e,n),a=function(e){try{const t=C(new URL(e).pathname);return $(t)?t:void 0}catch{return}}(e);return Dn(s,t||a)}function Un(e){const t=e?.split(";")[0]?.trim().toLowerCase();return t?Nn[t]:void 0}function jn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var n=function e(){var n=!1;try{n=this instanceof e}catch{}return n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}),n}var Ln,qn,Hn,Gn={},Bn={"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}},Fn=(Hn||(Hn=1,function(e){var t,n,s,a=qn?Ln:(qn=1,Ln=Bn),i=Ke.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}}})}(Gn)),Gn);function Wn(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return Mn(decodeURIComponent(e))}return Ce.resolveWorkspaceFilePath(e,t,n)}function zn(e,t){e?e.send("workspace-file-response",t):$e.error("[WORKSPACE] Cannot send workspace-file-response: client not available")}function Kn(e,t){e?e.send("workspace-file-mutation-response",t):$e.error("[WORKSPACE] Cannot send workspace-file-mutation-response: client not available")}function Vn(e,t,n,s){return{eventId:K(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function Xn(e,t,n,s){return{eventId:K(),requestId:e,taskId:t,success:!1,error:{code:n,message:s}}}function Jn(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,operation:r,content:c,createOnly:l}=t;$e.debug(`[WORKSPACE] File mutation request: taskId=${n}, userId=${s}, relativePath=${a}, operation=${r}, createOnly=${!!l}`);try{if(a.startsWith("channel-attachment/"))return void Kn(e.client,Xn(o,n,"permission_denied","Channel attachments are read-only"));const t=Wn(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=E.normalize(Ce.resolveWorkspaceFilePath(e,t,i)),r=E.normalize(s);return r===o||r.startsWith(o+E.sep)}(s,n,a,t))return void Kn(e.client,Xn(o,n,"permission_denied","Path escapes workspace"));if("delete"===r)return await i.promises.rm(t,{force:!1}),void Kn(e.client,{eventId:K(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r}});if(void 0===c)return void Kn(e.client,Xn(o,n,"bad_request","File content is required"));await i.promises.mkdir(E.dirname(t),{recursive:!0});try{await i.promises.writeFile(t,c,l?{flag:"wx"}:void 0)}catch(t){if("EEXIST"===t.code)return void Kn(e.client,Xn(o,n,"file_exists","File already exists"));throw t}const d=await i.promises.stat(t);Kn(e.client,{eventId:K(),requestId:o,taskId:n,success:!0,data:{relativePath:a,operation:r,modifiedAt:d.mtime.toISOString()}})}catch(t){$e.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";Kn(e.client,Xn(o,n,s,t.message))}}}function Yn(e){return async t=>{const{taskId:n,userId:s,relativePath:a,requestId:o,maxFileSizeMB:r,ifModifiedSince:c,dataEncryptionKey:l}=t;$e.debug(`[WORKSPACE] File request: taskId=${n}, userId=${s}, relativePath=${a}, maxFileSizeMB=${r}, ifModifiedSince=${c}, hasEncryptionKey=${!!l}`);try{const t=1024*(r||10)*1024,d=Wn(s,n,a);if(!i.existsSync(d))return $e.warn(`[WORKSPACE] File not found: ${d}`),void zn(e.client,Vn(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){$e.debug(`[WORKSPACE] File not modified: ${s}`),zn(e,{eventId:K(),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=E.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}}));zn(e,{eventId:K(),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=Fn.lookup(d)||"application/octet-stream";return p.size>t?void function(e,t,n,s,a,i,o){$e.warn(`[WORKSPACE] File too large (${a.size} bytes > ${o} bytes): ${s}`),zn(e,{eventId:K(),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=Fn.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 Ce.getSecretKey();if(!t)return $e.warn("[WORKSPACE] Machine secret key not available"),null;const n=G(e);return W(n,t)||($e.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey"),null)}catch(e){return $e.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=V(c,l):d.content=c,zn(e,{eventId:K(),requestId:t,taskId:n,success:!0,data:d})}(e.client,o,n,d,p,l)}}catch(t){$e.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";zn(e.client,Vn(o,n,s,t.message))}}}function Qn(e,t){return{eventId:K(),status:"failed",opCode:e,message:t}}function Zn(e,t){const n=E.relative(t,e);if(n.startsWith("..")||E.isAbsolute(n))throw new Error("Vision Plan review path is outside the bound issue directory")}const es=100,ts=[{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 ns{apiUrl;pat;requestId;gitServerId;constructor(e,t,n){this.apiUrl=e,this.pat=t,this.requestId=n?.requestId,this.gitServerId=n?.gitServerId}logPrefix(){return`[GITLAB EXECUTOR] reqId=${this.requestId??"-"}, gitServer=${this.gitServerId??"-"}`}summarizeResult(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"id"in n&&"status"in n?`id=${String(n.id??"-")}, status=${String(n.status??"-")}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}truncateText(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}async requestWithResponse(e,t="GET",n){const s=`${this.apiUrl}${e}`,a={Authorization:`Bearer ${this.pat}`,"Content-Type":"application/json"},i=Date.now();$e.debug(`${this.logPrefix()} request start: ${t} ${e}`);try{const o=await fetch(s,{method:t,headers:a,body:n?JSON.stringify(n):void 0}),r=Date.now()-i;if(!o.ok){const n=await o.text().catch(()=>"Unknown error"),s=this.truncateText(n);throw $e.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 $e.debug(`${this.logPrefix()} request success: ${t} ${e}, elapsedMs=${r}`),{data:await o.json(),headers:o.headers}}catch(n){if("object"==typeof n&&null!==n&&"status"in n)throw n;const s=n instanceof Error?n.message:"Unknown network error";throw $e.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();$e.debug(`${this.logPrefix()} form request start: POST ${e}`);try{const i=await fetch(n,{method:"POST",headers:s,body:t}),o=Date.now()-a;if(!i.ok){const t=await i.text().catch(()=>"Unknown error"),n=this.truncateText(t);throw $e.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 $e.debug(`${this.logPrefix()} form request success: POST ${e}, elapsedMs=${o}`),await i.json()}catch(t){if("object"==typeof t&&null!==t&&"status"in t)throw t;const n=t instanceof Error?t.message:"Unknown network error";throw $e.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:es,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:es,page:t});return this.request(n)});return s.push(...t),s}if(!a&&n.data.length===es){let t=2;for(;;){const n=this.withQueryParams(e,{per_page:es,page:t}),a=await this.request(n);if(0===a.length)break;if(s.push(...a),a.length<es)break;t+=1}}return s}async executeOperation(e,t){$e.info(`${this.logPrefix()} execute operation: op=${e}, payloadKeys=${Object.keys(t||{}).join(",")||"-"}`);try{let n;switch(e){case"listRepos":n=await this.listRepos();break;case"listBranches":n=await this.listBranches(t.owner,t.name);break;case"createMergeRequest":n=await this.createMergeRequest(t);break;case"getMergeRequest":n=await this.getMergeRequest(t.owner,t.name,t.iid);break;case"listMergeRequests":n=await this.listMergeRequests(t.owner,t.name);break;case"triggerPipeline":n=await this.triggerPipeline(t);break;case"ensurePipelineTriggerToken":n=await this.ensurePipelineTriggerToken(t);break;case"requestGitlabApi":n=await this.requestGitlabApi(t);break;case"resolveGitAuthContext":n={authMode:"local_pat",hasPat:!0};break;default:throw{status:400,message:`Unknown operation: ${e}`}}return $e.info(`${this.logPrefix()} operation success: op=${e}, summary=${this.summarizeResult(e,n)}`),n}catch(t){const n=t instanceof Error?t.message:"object"==typeof t&&null!==t&&"message"in t?String(t.message):"Unknown error";throw $e.error(`${this.logPrefix()} operation failed: op=${e}, message=${n}`),t}}async listRepos(){return(await this.requestPaginated("/projects?membership=true&order_by=updated_at&sort=desc")).map(e=>({id:e.id,owner:e.path_with_namespace.split("/").slice(0,-1).join("/")||e.namespace.path,name:e.path,fullName:e.path_with_namespace,defaultBranch:e.default_branch,isPrivate:"private"===e.visibility,description:e.description,url:e.web_url,createdAt:e.created_at,updatedAt:e.updated_at}))}async listBranches(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.requestPaginated(`/projects/${n}/repository/branches`)).map(e=>({name:e.name,commit:{sha:e.commit.id,url:""},protected:e.protected}))}async createMergeRequest(e){const t=encodeURIComponent(`${e.owner}/${e.repo}`),n=await this.request(`/projects/${t}/merge_requests`,"POST",{source_branch:e.head,target_branch:e.base,title:e.title,description:e.body||""});return{number:n.iid,title:n.title,body:n.description,state:"opened"===n.state?"open":n.state,url:n.web_url,head:n.source_branch,base:n.target_branch,createdAt:n.created_at,updatedAt:n.updated_at}}async getMergeRequest(e,t,n){const s=encodeURIComponent(`${e}/${t}`),a=await this.request(`/projects/${s}/merge_requests/${n}`);return{number:a.iid,title:a.title,body:a.description,state:"opened"===a.state?"open":a.state,url:a.web_url,head:a.source_branch,base:a.target_branch,createdAt:a.created_at,updatedAt:a.updated_at}}async listMergeRequests(e,t){const n=encodeURIComponent(`${e}/${t}`);return(await this.request(`/projects/${n}/merge_requests?state=opened&per_page=20`)).map(e=>({number:e.iid,title:e.title,body:e.description,state:"opened"===e.state?"open":e.state,url:e.web_url,head:e.source_branch,base:e.target_branch,createdAt:e.created_at,updatedAt:e.updated_at}))}parseNonEmptyString(e,t){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} is required`};return e.trim()}parseOptionalString(e,t){if(null!=e){if("string"!=typeof e||0===e.trim().length)throw{status:400,message:`${t} must be a non-empty string`};return e.trim()}}resolveProjectPath(e){if("number"==typeof e.projectId||"string"==typeof e.projectId){const t=String(e.projectId).trim();if(t.length>0)return encodeURIComponent(t)}const t=this.parseOptionalString(e.projectPath,"projectPath");if(t)return encodeURIComponent(t);const n=this.parseOptionalString(e.owner,"owner"),s=this.parseOptionalString(e.repo??e.name,"repo");if(!n||!s)throw{status:400,message:"projectId, projectPath, or owner + repo is required"};return encodeURIComponent(`${n}/${s}`)}parsePipelineVariables(e){if(null==e)return{};if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Pipeline variables must be an object"};const t={};for(const[n,s]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw{status:400,message:`Pipeline variable name is invalid: ${n}`};if(null!=s){if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Pipeline variable value for "${n}" is invalid`};t[n]=String(s)}}return t}isUsableTriggerToken(e){return"string"==typeof e&&e.length>=20&&!e.includes("*")}async resolvePipelineTriggerToken(e,t){const n=this.parseOptionalString(t.triggerToken,"triggerToken");if(n)return n;if(!0!==t.createTriggerIfMissing)throw{status:400,message:"triggerToken is required unless createTriggerIfMissing is true"};const s=this.parseOptionalString(t.triggerDescription,"triggerDescription")??"Agentrix webhook bridge",a=(await this.requestPaginated(`/projects/${e}/triggers`)).find(e=>e.description===s&&this.isUsableTriggerToken(e.token));if(a?.token)return a.token;const i=new URLSearchParams;i.set("description",s);const o=await this.requestForm(`/projects/${e}/triggers`,i);if(!this.isUsableTriggerToken(o.token))throw{status:502,message:"GitLab did not return a usable pipeline trigger token"};return o.token}async ensurePipelineTriggerToken(e){const t=this.resolveProjectPath(e);return{token:await this.resolvePipelineTriggerToken(t,{...e,createTriggerIfMissing:!0})}}async triggerPipeline(e){const t=this.resolveProjectPath(e),n=this.parseNonEmptyString(e.ref,"ref"),s=this.parsePipelineVariables(e.variables),a=await this.resolvePipelineTriggerToken(t,e),i=new URLSearchParams;i.set("token",a),i.set("ref",n);for(const[e,t]of Object.entries(s))i.set(`variables[${e}]`,t);const o=await this.requestForm(`/projects/${t}/trigger/pipeline`,i);return{id:o.id,iid:o.iid,projectId:o.project_id,ref:o.ref,sha:o.sha,status:o.status,source:o.source,url:o.web_url,createdAt:o.created_at,updatedAt:o.updated_at}}parseProxyMethod(e){const t="string"==typeof e?e.toUpperCase():"GET";if("GET"===t||"POST"===t||"PUT"===t||"PATCH"===t||"DELETE"===t)return t;throw{status:400,message:`Unsupported proxy method: ${String(e)}`}}parseProxyPath(e){if("string"!=typeof e||0===e.length)throw{status:400,message:"Proxy path is required"};if(!e.startsWith("/"))throw{status:400,message:'Proxy path must start with "/"'};if(e.includes("://")||e.includes(".."))throw{status:400,message:"Proxy path contains invalid segments"};if(e.includes("?"))throw{status:400,message:"Proxy path must not contain query string; use payload.query"};return e}buildProxyQueryString(e){if(null==e)return"";if("object"!=typeof e||Array.isArray(e))throw{status:400,message:"Proxy query must be an object"};const t=new URLSearchParams;for(const[n,s]of Object.entries(e))if(null!=s)if(Array.isArray(s))for(const e of s){if("string"!=typeof e&&"number"!=typeof e&&"boolean"!=typeof e)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(e))}else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw{status:400,message:`Proxy query value for "${n}" is invalid`};t.append(n,String(s))}return t.toString()}isProxyAllowed(e,t){return ts.some(n=>n.method===e&&n.pattern.test(t))}async requestGitlabApi(e){const t=this.parseProxyMethod(e.method),n=this.parseProxyPath(e.path),s=this.buildProxyQueryString(e.query),a=s.length>0?`${n}?${s}`:n;if(!this.isProxyAllowed(t,n))throw{status:403,message:`Proxy path not allowed: ${t} ${n}`};return"GET"===t?await this.request(a,t):await this.request(a,t,e.body)}}function ss(e){const t=e.replace(/\/+$/,"");return t.endsWith("/v1")?`${t}/models`:`${t}/v1/models`}function as(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname.replace(/\/+$/,"")}`}catch{return e}}function is(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 os(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(ss(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 rs(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){$e.info(`[MODELS] Requesting models: source=${e.source}, protocol=${a}, url=${as(ss(e.baseUrl))}, officialProtocol=${t??"none"}`);try{const t=await os(e,a);return $e.info(`[MODELS] Models request succeeded: source=${e.source}, protocol=${a}, count=${t.length}`),t}catch(t){s=t;const n=is(t);$e.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 cs(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 ls(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}}(_(Ce.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:cs(e,t)}:null}();e&&t.push(e)}if(!e||"codex"===e){const e=function(){const e=_(Ce.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)}$e.info(`[MODELS] Listing available models: agentType=${e??"all"}, endpointCount=${t.length}, endpoints=${t.map(e=>`${e.source}:${as(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 rs(e))n.add(t)}catch(t){const n=is(t);s.push({source:e.source,baseUrl:as(e.baseUrl),message:n.message,status:n.status,code:n.code})}const i=Array.from(n).sort();return 0===i.length?$e.warn(`[MODELS] No models available: endpointCount=${t.length}, failures=${JSON.stringify(s)}`):$e.info(`[MODELS] Listed available models: count=${i.length}`),{models:i,defaultModel:a}}function ds(e,t){return{eventId:K(),status:"failed",opCode:e,message:t}}function ps(e){return async(t,n)=>{if($e.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 $e.error(`[EVENT HANDLER] create-task expects task-message, got ${t.event} for task ${t.taskId}`),void n(ds(t.eventId,`create-task expects task-message, got ${t.event}`));try{const s=await e.workerManager.startWorker(t,"create-task");"success"!==s.status&&$e.error(`[EVENT HANDLER] create-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){$e.error(`[EVENT HANDLER] create-task startup threw for task ${t.taskId}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"create-task startup failed"))}}}function us(e){return async(t,n)=>{$e.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&&$e.error(`[EVENT HANDLER] resume-task startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){$e.error(`[EVENT HANDLER] resume-task startup threw for task ${t.taskId}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"resume-task startup failed"))}}}function ms(e){return async(t,n)=>{if($e.info(`[EVENT HANDLER] list-models received: machineId=${t.machineId}, agentType=${t.agentType??"all"}, eventId=${t.eventId}`),t.machineId!==e.machineId)return $e.warn(`[EVENT HANDLER] list-models target mismatch: requested=${t.machineId}, current=${e.machineId}`),void n(ds(t.eventId,"list-models target machine mismatch"));try{const{models:e,defaultModel:s}=await ls(t.agentType);if(0===e.length&&!s)return $e.warn(`[EVENT HANDLER] list-models found no models and no default model: machineId=${t.machineId}, agentType=${t.agentType??"all"}`),void n(ds(t.eventId,"No models available from configured endpoints"));$e.info(`[EVENT HANDLER] list-models success: machineId=${t.machineId}, count=${e.length}, defaultModel=${s??"-"}`),n({eventId:K(),status:"success",opCode:t.eventId,data:{models:e,defaultModel:s}})}catch(e){$e.error(`[EVENT HANDLER] list-models failed: machineId=${t.machineId}, agentType=${t.agentType??"all"}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"Failed to list models"))}}}function hs(e){return async t=>{$e.info("[EVENT HANDLER] shutdown-machine received",t),e.requestShutdown("agentrix-app",t.reason)}}function gs(e){return async(t,n)=>{$e.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&&$e.error(`[EVENT HANDLER] deploy-agent startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){$e.error(`[EVENT HANDLER] deploy-agent startup threw for task ${t.taskId}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"deploy-agent startup failed"))}}}function fs(e){return async(t,n)=>{$e.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&&$e.error(`[EVENT HANDLER] hive-publish startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){$e.error(`[EVENT HANDLER] hive-publish startup threw for task ${t.taskId}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"hive-publish startup failed"))}}}function vs(e){return async(t,n)=>{$e.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&&$e.error(`[EVENT HANDLER] hive-install startup failed for task ${t.taskId}: ${s.message||"unknown error"}`),n(s)}catch(e){$e.error(`[EVENT HANDLER] hive-install startup threw for task ${t.taskId}:`,e),n(ds(t.eventId,e instanceof Error?e.message:"hive-install startup failed"))}}}function ys(e){return async t=>{$e.info(`[EVENT HANDLER] stop-task: ${t.taskId}, reason=${t.reason||"n/a"}`),e.workerManager.stopSession(t.taskId)||$e.warn(`[EVENT HANDLER] stop-task failed, task not found: ${t.taskId}`)}}function bs(e){return async t=>{$e.info(`[GITLAB PROXY] request received: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, ttlMs=${t.ttlMs}, payloadKeys=${function(e){const t=Object.keys(e||{});return t.length>0?t.join(","):"-"}(t.payload)}`);const n=Date.now(),s=n=>{const s={eventId:t.requestId,requestId:t.requestId,machineId:e.machineId,...n};e.client?(e.client.send("daemon-gitlab-response",s),$e.info(`[GITLAB PROXY] response sent: reqId=${t.requestId}, op=${t.operation}, success=${n.success}, executionMs=${n.executionTimeMs}`)):$e.error(`[GITLAB PROXY] response dropped: reqId=${t.requestId}, op=${t.operation}, reason=socket-client-unavailable`)};try{const e=t.accessToken?.trim();if(!e)return $e.warn(`[GITLAB PROXY] access token missing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:`No access token provided for git server ${t.gitServerId}`,executionTimeMs:Date.now()-n});const a=t.payload.apiUrl;if(!a)return $e.warn(`[GITLAB PROXY] apiUrl missing in payload: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}`),void s({success:!1,errorCode:"PAT_MISSING",errorMessage:"GitLab API URL not provided in request",executionTimeMs:Date.now()-n});$e.info(`[GITLAB PROXY] executing: reqId=${t.requestId}, op=${t.operation}, gitServer=${t.gitServerId}, apiHost=${function(e){try{return new URL(e).host}catch{return"invalid-url"}}(a)}`);const i=new ns(a,e,{requestId:t.requestId,gitServerId:t.gitServerId}),o=await i.executeOperation(t.operation,t.payload);$e.info(`[GITLAB PROXY] execution succeeded: reqId=${t.requestId}, op=${t.operation}, summary=${function(e,t){if(Array.isArray(t))return`items=${t.length}`;if(t&&"object"==typeof t){const n=t;return"resolveGitAuthContext"===e?`authMode=${String(n.authMode??"unknown")}, hasPat=${Boolean(n.hasPat)}`:"number"in n||"state"in n?`number=${String(n.number??"-")}, state=${String(n.state??"-")}`:`keys=${Object.keys(n).join(",")||"-"}`}return"type="+typeof t}(t.operation,o)}`),s({success:!0,data:o,executionTimeMs:Date.now()-n})}catch(e){const a=e;let i="GITLAB_CONNECTIVITY_FAILED";401===a.status?i="PAT_INVALID":403===a.status?i="PAT_SCOPE_INSUFFICIENT":404===a.status&&(i="RESOURCE_NOT_FOUND");const o="string"==typeof a.message?a.message:"Unknown error",r="string"==typeof a.detail?function(e,t=300){return e.length<=t?e:`${e.slice(0,t)}...`}(a.detail):void 0,c="number"==typeof a.status?String(a.status):"unknown";$e.error(`[GITLAB PROXY] execution failed: reqId=${t.requestId}, op=${t.operation}, errorCode=${i}, status=${c}, message=${o}${r?`, detail=${r}`:""}`),s({success:!1,errorCode:i,errorMessage:o,executionTimeMs:Date.now()-n})}}}function ws(e){return async(t,n)=>{e.machineControl?e.machineControl.handleCommand(t,n):n(ds(t.eventId,"Machine control is not available"))}}const xs=parseInt(process.env.MAX_WORKSPACE_FILE_SIZE_MB||"100",10);function ks(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)}function Is(e,t,n){if(n.startsWith("channel-attachment/")){const e=n.slice(19);return Mn(decodeURIComponent(e))}return Ce.resolveWorkspaceFilePath(e,t,n)}class Ss{client;machineId;iceServers=[];sessions=new Map;rtcModule={};peerConstructor;constructor(e,t){this.client=e,this.machineId=t;const n=et(import.meta.url);try{this.rtcModule=n("node-datachannel"),this.peerConstructor=(s=this.rtcModule).RTCPeerConnection||s.PeerConnection||s.RTCConnection||s.PeerConnection,this.rtcModule.setDebugLevel?.("warning")}catch(e){const t=e instanceof Error?e.message:String(e);$e.warn(`[RTC] node-datachannel unavailable; RTC support disabled: ${t}`)}var s}registerHandlers(){this.peerConstructor?(this.client.onLifecycle("connect",()=>{this.requestIceServers()}),this.client.onEvent("rtc-ice-servers-response",e=>this.handleIceServersResponse(e)),this.client.onEvent("machine-rtc-request",e=>this.handleRtcRequest(e)),this.client.onEvent("rtc-signal",e=>this.handleRtcSignal(e))):$e.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:K()})}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),$e.info(`[RTC] Loaded ${this.iceServers.length} ICE servers`)}handleRtcRequest(e){if(!this.peerConstructor)return;const t=e.userId;if(!t)return void $e.warn("[RTC] machine-rtc-request missing userId");const n=e.workspaceUserId||t,s=e.taskId;if(this.sessions.has(e.sessionId))return void this.sendMachineRtcResponse(e.sessionId,t,!0);const a=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers}),i={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:a,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]};this.sessions.set(e.sessionId,i),this.registerPeerHandlers(i),this.sendMachineRtcResponse(e.sessionId,t,!0)}sendMachineRtcResponse(e,t,n,s){this.client.send("machine-rtc-response",{eventId:K(),machineId:this.machineId,sessionId:e,accepted:n,reason:s,userId:t,capabilities:{dataChannel:!0}})}handleRtcSignal(e){if(!this.peerConstructor)return;if("app"!==e.from)return;const t=e.userId;if(!t)return void $e.warn("[RTC] rtc-signal missing userId");const n=e.workspaceUserId||t,s=e.taskId;let a=this.sessions.get(e.sessionId);if(!a){const i=new this.peerConstructor(e.sessionId,{iceServers:this.iceServers});a={sessionId:e.sessionId,userId:t,workspaceUserId:n,allowedTaskId:s||void 0,peerConnection:i,lastActivity:Date.now(),remoteDescriptionSet:!1,pendingCandidates:[]},this.sessions.set(e.sessionId,a),this.registerPeerHandlers(a)}try{this.applyRemoteSignal(a,e.signal)}catch(e){$e.warn("[RTC] Failed to apply remote signal",e)}}registerPeerHandlers(e){const{peerConnection:t}=e;t.onStateChange?.(t=>{$e.info(`[RTC] Peer state (${e.sessionId}): ${t}`)}),t.onGatheringStateChange?.(t=>{$e.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:K(),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:K(),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?.(()=>{$e.info(`[RTC] Data channel open (${e.sessionId})`),e.lastActivity=Date.now(),ks(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?.(()=>{$e.warn(`[RTC] Data channel closed (${e.sessionId})`),e.peerConnection.close?.(),this.sessions.delete(e.sessionId)}),t.onError?.(t=>{$e.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{J(new Uint8Array(t))}catch(e){$e.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 $e.warn("[RTC] Non-JSON message",n)}s&&"string"==typeof s.type&&("file.request"!==s.type?"file.mutate"===s.type&&this.handleFileMutation(e,s).catch(e=>{$e.error("[RTC] Failed to handle file mutation",e)}):this.handleFileRequest(e,s).catch(e=>{$e.error("[RTC] Failed to handle file request",e)}))}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=Is(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=E.normalize(Ce.resolveWorkspaceFilePath(e,t,i)),r=E.normalize(s);return r===o||r.startsWith(o+E.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=Is(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=E.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??xs)*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=Fn.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(E.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=Y.Binary|(0===o?Y.Start:0),a=Buffer.isBuffer(e)?e:Buffer.from(e),i=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),r=Q({streamId:t,seq:o,flags:n,payloadLength:i.length},i);ks(s,r),o+=1}),a.on("end",()=>{if(o>0){const e=Q({streamId:t,seq:o,flags:Y.End|Y.Binary,payloadLength:0},new Uint8Array);ks(s,e)}e()}),a.on("error",e=>n(e))})}sendControl(e,t){const n=e.dataChannel;n&&ks(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){$e.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 Ts{client;context;rtcManager;constructor(e,t,n){const{machineId:s,...a}=e;this.client=new Cn(a),this.context={machineId:s,workerManager:t,requestShutdown:n.requestShutdown,client:this.client,machineControl:n.machineControl},this.rtcManager=new Ss(this.client,s),this.initHandlers(),this.rtcManager.registerHandlers()}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Machine connection timeout after 30 seconds"))},3e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.rtcManager.shutdown(),this.client.disconnect()}setCompanionInteractionCallback(e){this.context.onCompanionInteraction=e}initHandlers(){const e={"create-task":ps(t=this.context),"resume-task":us(t),"list-models":ms(t),"stop-task":ys(t),"deploy-agent":gs(t),"hive-publish":fs(t),"hive-install":vs(t),"shutdown-machine":hs(t),"workspace-file-request":Yn({client:t.client}),"workspace-file-mutation-request":Jn({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=X.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(Qn(n,"Vision Plan review write path does not match the bound issue"));const o=Ce.resolveWorkspaceFilePath(s.userId,s.taskId,a);Zn(o,Ce.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=E.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);Zn(r,o),await i.promises.writeFile(r,s.content.endsWith("\n")?s.content:`${s.content}\n`,"utf8");const c=E.posix.join(a,E.basename(r)).replace(/^project\//,"");t({eventId:K(),status:"success",opCode:s.eventId,data:{relativePath:c}})}catch(e){$e.error("[VisionPlanReviewWrite] Failed to write review:",e),t(Qn(n,e instanceof Error?e.message:"Failed to write Vision Plan review"))}},"daemon-gitlab-request":bs(t),"machine-control-command":ws(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.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"])}}let Es=null;let As=!1;async function _s(){if(As)$e.info("[caffeinate] Already stopping, skipping");else if(Es&&!Es.killed){As=!0,$e.info(`[caffeinate] Stopping caffeinate process PID ${Es.pid}`);try{Es.kill("SIGTERM"),await new Promise(e=>setTimeout(e,1e3)),Es&&!Es.killed&&Es.kill("SIGKILL"),Es=null,As=!1}catch(e){$e.info("[caffeinate] Error stopping caffeinate:",e),As=!1}}}let Cs=!1;function $s(e){const{pid:t,name:n,cmd:s}=e;if(t===process.pid||t===process.ppid)return null;if(!(n.includes("agentrix")||"node"===n&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("dist\\index.mjs"))||("MainThread"===n||n.includes("MainThread"))&&(s.includes("agentrix-cli")||s.includes("dist/index.mjs")||s.includes("agentrix.mjs"))||s.includes("agentrix.mjs")||s.includes("agentrix-cli")||s.includes("tsx")&&s.includes("src/index.ts")&&s.includes("agentrix-cli")))return null;let a="unknown";const i=s.toLowerCase();return i.includes(" worker")?a="worker":i.includes(" upgrade-daemon")?a="upgrade-daemon":i.includes(" daemon")?a="daemon":i.includes("doctor")&&(a="doctor"),{pid:t,command:s||n,type:a}}async function Ns(){try{let e;e="win32"===process.platform?await async function(){try{const e=nt("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 st()).map(e=>({pid:e.pid,name:e.name||"",cmd:e.cmd||""}));const t=[];for(const n of e){const e=$s(n);e&&t.push(e)}return t}catch(e){return[]}}function Rs(e){try{const t="win32"===process.platform?"where":"which";return{available:!0,path:nt(`${t} ${e}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()}}catch{return{available:!1}}}function Ps(){const e=it(),t=function(){const e=Rs("git"),t=Rs("claude"),n=Rs("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=Rs("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=Rs("bwrap"),t=Rs("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 Ms(){const e=Ps(),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 Ds(){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:Ce.agentrixHomeDir,serverUrl:Ce.serverUrl,logsDir:Ce.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 Os(e){if(e||(e="all"),console.log(L.bold.cyan("\n🩺 Agentrix CLI Doctor\n")),"all"===e){console.log(L.bold("📋 Basic Information")),console.log(`Agentrix CLI Version: ${L.green(Re.version)}`),console.log(`Platform: ${L.green(process.platform)} ${process.arch}`),console.log(`Node.js Version: ${L.green(process.version)}`),console.log(""),console.log(L.bold("🔧 Daemon Spawn Diagnostics"));const e=Ne(),t=_(e,"bin","agentrix.mjs"),n=_(e,"dist","index.mjs");console.log(`Project Root: ${L.blue(e)}`),console.log(`Wrapper Script: ${L.blue(t)}`),console.log(`CLI Entrypoint: ${L.blue(n)}`),console.log(`Wrapper Exists: ${r(t)?L.green("✓ Yes"):L.red("❌ No")}`),console.log(`CLI Exists: ${r(n)?L.green("✓ Yes"):L.red("❌ No")}`),console.log(""),console.log(L.bold("⚙️ Configuration")),console.log(`Agentrix Home: ${L.blue(Ce.agentrixHomeDir)}`),console.log(`Server URL: ${L.blue(Ce.serverUrl)}`),console.log(`Logs Dir: ${L.blue(Ce.getStatePaths().logsDir)}`),console.log(L.bold("\n🌍 Environment Variables"));const s=Ds();console.log(`AGENTRIX_HOME_DIR: ${s.AGENTRIX_HOME_DIR?L.green(s.AGENTRIX_HOME_DIR):L.gray("not set")}`),console.log(`AGENTRIX_SERVER_URL: ${s.AGENTRIX_SERVER_URL?L.green(s.AGENTRIX_SERVER_URL):L.gray("not set")}`),console.log(`DANGEROUSLY_LOG_TO_SERVER: ${s.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING?L.yellow("ENABLED"):L.gray("not set")}`),console.log(`DEBUG: ${s.DEBUG?L.green(s.DEBUG):L.gray("not set")}`),console.log(`NODE_ENV: ${s.NODE_ENV?L.green(s.NODE_ENV):L.gray("not set")}`),console.log(L.bold("\n🔐 Authentication"));try{await Ce.readCredentials()?console.log(L.green("✓ Authenticated (credentials found)")):console.log(L.yellow("⚠️ Not authenticated (no credentials)"))}catch(e){console.log(L.red("❌ Error reading credentials"))}!function(e=!1){const t=Ps(),n=it();console.log(L.bold("\n🔧 CLI Dependencies"));for(const n of t.cli)if(n.installed)console.log(L.green(`✓ ${n.name}`),L.gray(`- ${n.description}`)),e&&n.path&&console.log(L.gray(` Location: ${n.path}`));else{const e=n.required?L.red("❌"):L.yellow("⚠️");console.log(`${e} ${n.name}`,L.gray(`- ${n.description}`)),n.installCommand&&console.log(L.blue(` Install: ${n.installCommand}`))}if(t.sandbox.length>0){console.log(L.bold("\n🔒 Sandbox Dependencies")),console.log(L.gray(`Platform: ${n}`));for(const n of t.sandbox)n.installed?(console.log(L.green(`✓ ${n.name}`),L.gray(`- ${n.description}`)),e&&n.path&&console.log(L.gray(` Location: ${n.path}`))):(console.log(L.red(`❌ ${n.name}`),L.gray(`- ${n.description}`)),n.installCommand&&console.log(L.blue(` Install: ${n.installCommand}`)))}else console.log(L.bold("\n🔒 Sandbox Dependencies")),console.log(L.yellow(`⚠️ Platform ${n} not supported - sandbox will be disabled`));if(t.allSatisfied)return console.log(L.bold.green("\n✓ All required dependencies are installed")),!0;{console.log(L.bold.red("\n⚠️ Missing Required Dependencies"));const e=[...t.missingCli,...t.missingSandbox];for(const t of e)console.log(L.red(` • ${t.name}`));console.log(L.yellow("\nPlease install missing dependencies before starting the daemon."))}}(!0)}console.log(L.bold("\n🤖 Daemon Status"));try{const t=await hn(),n=await Ce.readDaemonState();if(t&&n?(console.log(L.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(L.yellow("⚠️ Daemon state exists but process not running (stale)")):console.log(L.red("❌ Daemon is not running")),n){console.log(L.bold("\n📄 Daemon State:"));const e=Ce.getStatePaths();console.log(L.blue(`Location: ${e.daemonStateFile}`)),console.log(L.gray(JSON.stringify(n,null,2)))}const s=await Ns();if(s.length>0){console.log(L.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(L.blue(`\n${{daemon:"🤖 Daemon","upgrade-daemon":"🔄 Upgrade Daemon",worker:"🔗 Workers",doctor:"🩺 Doctor",unknown:"❓ Unknown"}[e]||e}:`)),t.forEach(({pid:t,command:n})=>{const s=e.startsWith("dev")?L.cyan:e.includes("daemon")?L.blue:L.gray;console.log(` ${s(`PID ${t}`)}: ${L.gray(n)}`)})})}else console.log(L.red("❌ No agentrix processes found"));"all"===e&&s.length>1&&(console.log(L.bold("\n💡 Process Management")),console.log(L.gray("To clean up runaway processes: agentrix killall")))}catch(e){console.log(L.red("❌ Error checking daemon status"))}}let Us=null;async function js(){const e=Fs(),t=function(e){try{return JSON.stringify(e)}catch{return""}}(e);if(Us&&Us.expiresAt>Date.now()&&Us.overridesSignature===t)return Us.openers;const n=qs(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 Us={expiresAt:Date.now()+6048e5,openers:s,overridesSignature:t},s}function Ls(e){const t=process.platform;if("darwin"===t)return function(e){const t=Hs(e),n=[];if(t){const e=Ys(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"),Gs(Vs("osascript",n,{captureOutput:!0}))}(e);if("win32"===t)return function(e){const t=Ks("powershell")?"powershell":Ks("pwsh")?"pwsh":null;if(!t)throw new Error("PowerShell is required to pick a directory");const n=Hs(e),s=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;",n?`$dialog.SelectedPath = '${Js(n)}';`:"","$null = $dialog.ShowDialog();","$dialog.SelectedPath;"].filter(Boolean).join(" ");return Gs(Vs(t,"powershell"===t?["-NoProfile","-STA","-Command",s]:["-NoProfile","-Sta","-Command",s],{captureOutput:!0}))}(e);if("linux"===t)return function(e){const t=Hs(e);if(Ks("zenity")){const e=["--file-selection","--directory","--title=Select Folder"];if(t){const n=t.endsWith("/")?t:`${t}/`;e.push(`--filename=${n}`)}return Gs(Vs("zenity",e,{captureOutput:!0}))}if(Ks("kdialog")){const e=["--getexistingdirectory"];return t&&e.push(t),Gs(Vs("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 qs(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:()=>Ws("vscode",t,n)},{id:"cursor",label:"Cursor",kind:"editor",method:"scheme",urlTemplate:"cursor://file/{path}?windowId=_blank",scheme:"cursor",macAppNames:s,isSupported:()=>Ws("cursor",t,s)},{id:"idea",label:"IntelliJ IDEA",kind:"ide",method:"scheme",urlTemplate:"idea://open?file={path}&newWindow=true",scheme:"idea",macAppNames:a,isSupported:()=>Ws("idea",t,a)},{id:"pycharm",label:"PyCharm",kind:"ide",method:"scheme",urlTemplate:"pycharm://open?file={path}&newWindow=true",scheme:"pycharm",macAppNames:o,isSupported:()=>Ws("pycharm",t,o)},{id:"webstorm",label:"WebStorm",kind:"ide",method:"scheme",urlTemplate:"webstorm://open?file={path}&newWindow=true",scheme:"webstorm",macAppNames:i,isSupported:()=>Ws("webstorm",t,i)},{id:"terminal",label:"Terminal",kind:"terminal",method:"cli",isSupported:()=>function(e){return"darwin"===e?Ks("osascript")&&zs("Terminal"):"win32"===e?Ks("wt")||Ks("powershell")||Ks("pwsh")||Ks("cmd"):"linux"===e&&Boolean(Bs())}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"===t){if(Ks("wt"))return void Xs("wt",["-d",e]);const t=Ks("powershell")?"powershell":Ks("pwsh")?"pwsh":null;return t?void Xs(t,["-NoExit","-Command",`Set-Location -LiteralPath '${Js(e)}'`]):void Xs("cmd",["/K",`cd /d "${e.replace(/"/g,'""')}"`])}if("linux"===t){const t=Bs();if(!t)throw new Error("No supported terminal is available");return void Xs(t.command,t.args(e))}throw new Error("Terminal open is not supported on this platform")}if(!Vs("osascript",["-e",'tell application "Terminal"',"-e",`do script "${Ys(`cd ${Qs(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?Ks("open"):"win32"===e||"linux"===e&&(Ks("xdg-open")||Ks("gio"))}(t),open:e=>function(e,t){if("darwin"!==t){if("win32"!==t){if("linux"===t)return Ks("xdg-open")?void Vs("xdg-open",[e]):void Vs("gio",["open",e]);throw new Error("File manager open is not supported on this platform")}Vs("explorer",[e])}else Vs("open",[e])}(e,t)},{id:"open-with",label:"Open With...",kind:"system",method:"cli",isSupported:()=>function(e){return"darwin"===e?Ks("osascript"):"win32"===e?Ks("powershell")||Ks("pwsh"):"linux"===e&&Ks("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");Vs("gio",["open","--ask",e])}else Vs(Ks("powershell")?"powershell":"pwsh",["-NoProfile","-Command",`Start-Process -Verb OpenAs -FilePath '${Js(e)}'`]);else if(null===Vs("osascript",["-e",`set targetPath to POSIX file "${Ys(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??Fs();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=>zs(e)):A.isAbsolute(e)||e.includes(A.sep)?r(e):Ks(e)}(n.command,s,t),a.open=e=>function(e,t,n){if(!Vs(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 Hs(e){if(!e)return;const t=e.replace(/^~(?=$|[\\/])/,n.homedir());if(r(t)){try{if(!p(t).isDirectory())return}catch{return}return t}}function Gs(e){if(!e)return null;return e.trim()||null}function Bs(){const e=Qs(process.env.SHELL||"/bin/sh"),t=process.env.TERMINAL;return t&&/^[A-Za-z0-9_./+-]+$/.test(t)&&Ks(t)?{command:t,args:t=>["-e","sh","-lc",`cd ${Qs(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 ${Qs(t)} && exec ${e}`]},{command:"x-terminal-emulator",args:t=>["-e","sh","-lc",`cd ${Qs(t)} && exec ${e}`]}].find(e=>Ks(e.command))??null}function Fs(){try{const e=Ce.readSettings();if(!e||"object"!=typeof e)return{};const t=e.openersOverrides;return t&&"object"==typeof t?t:{}}catch(e){return $e.warn("[OPENERS] Failed to read opener overrides",e),{}}}function Ws(e,t,s){return"darwin"===t?function(e,t){if(Ks("mdfind")){const t=Vs("mdfind",[`kMDItemCFBundleURLSchemes == '${e}'`],{captureOutput:!0});if(t&&t.trim())return!0}if(Ks("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=Vs("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){$e.debug("[OPENERS] Failed to parse LaunchServices handlers",e)}}}return!!(t&&t.length>0)&&t.some(e=>zs(e))}(e,s):"win32"===t?function(e){return Ks("reg")&&(Boolean(Vs("reg",["query",`HKCU\\Software\\Classes\\${e}`]))||Boolean(Vs("reg",["query",`HKCR\\${e}`])))}(e):"linux"===t&&function(e){if(Ks("xdg-settings")){const t=Vs("xdg-settings",["get","default-url-scheme-handler",e],{captureOutput:!0});if(t&&t.trim()&&"null"!==t.trim())return!0}if(Ks("gio")){const t=Vs("gio",["mime",`x-scheme-handler/${e}`],{captureOutput:!0});if(t&&/Default application/.test(t))return!0}return!1}(e)}function zs(e){return"darwin"===process.platform&&Boolean(Vs("open",["-Ra",e]))}function Ks(e){return"win32"===process.platform?Boolean(Vs("where",[e])):Boolean(Vs("sh",["-c",`command -v ${e}`]))}function Vs(e,t,n){const s=pt(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&&$e.warn(`[OPENERS] Command failed: ${e} ${t.join(" ")}: ${n}`)}return null}return n?.captureOutput?s.stdout:"ok"}function Xs(e,t){ut(e,t,{detached:!0,stdio:"ignore",windowsHide:!1}).unref()}function Js(e){return e.replace(/'/g,"''")}function Ys(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Qs(e){return`'${e.replace(/'/g,"'\\''")}'`}function Zs(e,t){if(t){const n=M(t,e),s=!n||n.startsWith("..")||D(n)?C(e):n;return _(t,"versions",s)}let n=P(e),s=0;for(;s<10;){if(r(_(n,"agent.json"))){const t=e.slice(n.length).replace(/^\//,"");return _(n,"versions",t)}const t=P(n);if(t===n)break;n=t,s++}const a=P(e),i=C(e);return _(a,`.${i}.version`)}function ea(e,t){const n=Zs(e,t);if(!r(n))return"0.0.0";try{return c(n,"utf-8").trim()}catch(e){return"0.0.0"}}function ta(e,t,n){try{const s=Zs(e,n),a=P(s);r(a)||d(a,{recursive:!0}),u(s,t,"utf-8")}catch(e){}}function na(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 sa(e,t,n){const s=ea(e,n),a=na(t.metadata.version,s);if(!r(e)){const s=P(e);return r(s)||d(s,{recursive:!0}),u(e,t.content,"utf-8"),ta(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"),ta(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 aa(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 ia(e){const{agentId:t,gitUrl:n,branch:s,subDir:a}=e,i=_(Ce.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),mt(e.join(" "),{stdio:"pipe"}),a){const 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 oa(i),{agentDir:i}}catch(e){throw r(o)&&h(o,{recursive:!0,force:!0}),r(i)&&h(i,{recursive:!0,force:!0}),e}}function oa(e){const t=[],n=_(e,"claude","plugins");if(r(n))for(const e of g(n)){const s=_(n,e);p(s).isDirectory()&&r(_(s,"package.json"))&&t.push(s)}const s=_(e,"claude","hooks");r(s)&&r(_(s,"package.json"))&&t.push(s);for(const e of t)mt("yarn install --frozen-lockfile",{cwd:e,stdio:"pipe"}),mt("yarn build",{cwd:e,stdio:"pipe"})}function ra(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 ca=ra("\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 la(e){return ra(`\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 da(e){return ra(`\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 pa(e){return ra(`\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 ua=ra("\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 ma(e){const t="group"===e?.chatType?.toLowerCase();return ra(`\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 ra(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?ra("\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`)}ma();const ha=ra('\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'),ga=ra('\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'),fa=ra('\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'),va=ra("\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"),ya=ra(`\n ${fa}\n\n ${ha}\n\n ${ga}\n`),ba=ra('\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 wa(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 xa(e,t){const n=t.find(t=>t.id===e);if(!n)return wa(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(ba),a.join("\n")}function ka(e){const t={};for(const[n,s]of Object.entries(e))"string"==typeof s&&(t[n]=s);return t}function Ia(e){if("object"!=typeof e||null===e)return!1;const t=e;return"text"===t.type&&"string"==typeof t.text}function Sa(e){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:""}}function Ta(e){const t=e.message?.content;return"string"==typeof t?t:Array.isArray(t)?t.filter(Ia).map(e=>e.text).join("\n").trim():""}function Ea(e){const t=e.usage.input_tokens-e.usage.cached_input_tokens,n={input_tokens:e.usage.input_tokens,output_tokens:e.usage.output_tokens,cache_creation:{ephemeral_1h_input_tokens:0,ephemeral_5m_input_tokens:0},cache_creation_input_tokens:0,cache_read_input_tokens:e.usage.cached_input_tokens,inference_geo:"",iterations:[],server_tool_use:{web_fetch_requests:0,web_search_requests:0},service_tier:"standard",speed:"standard"};return{type:"result",subtype:"success",duration_ms:0,duration_api_ms:0,is_error:!1,num_turns:e.numTurns,result:e.result??"",stop_reason:null,total_cost_usd:0,usage:n,modelUsage:{[e.model]:{inputTokens:t>0?t:0,outputTokens:e.usage.output_tokens,cacheReadInputTokens:e.usage.cached_input_tokens,cacheCreationInputTokens:0,webSearchRequests:0,costUSD:0,contextWindow:0,maxOutputTokens:0}},permission_denials:[],uuid:crypto.randomUUID(),session_id:e.sessionId,structured_output:e.structuredOutput}}function Aa(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 _a="agentrix",Ca="1.0.0",$a=Pt(ht),Na=["*","","!.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"),Ra=new Set(["MEMORY.md","USER.md","SOUL.md","IDENTITY.md","SKILLS.md","system_prompt.md","HEARTBEAT.md","MEMORY_ORGANIZATION.md","UPGRADES.md"]),Pa=["memory","memory-changes","plugins","versions"],Ma={GIT_AUTHOR_NAME:"Agentrix Companion",GIT_AUTHOR_EMAIL:"companion@agentrix.local",GIT_COMMITTER_NAME:"Agentrix Companion",GIT_COMMITTER_EMAIL:"companion@agentrix.local"};function Da(e){return function(e){return e.split(R).join("/")}(O(e)).replace(/^\.\//,"")}function Oa(e,t,n){e?e("warn","COMPANION_GIT",t,n):console.warn(`[COMPANION GIT] ${t}`,n)}async function Ua(e,t){const{stdout:n}=await $a("git",t,{cwd:e,encoding:"utf-8",windowsHide:!0,env:{...process.env,...Ma}});return n}async function ja(e){try{return await Ua(e,["diff","--cached","--quiet","--exit-code"]),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}async function La(e,t,n){const s=["commit","-m",t];return n?.trim()&&s.push("-m",n.trim()),await Ua(e,s),(await Ua(e,["rev-parse","HEAD"])).trim()}async function qa(e){return(await Ua(e,["ls-files"])).split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).filter(Ha)}function Ha(e){const t=Da(e);return!(!t||"."===t||t.startsWith("../")||t.includes("/../"))&&(!!Ra.has(t)||!(t.includes("/")||!t.endsWith(".upgrade"))||Pa.some(e=>t===e||t.startsWith(`${e}/`)))}function Ga(e,t){const n=O(e),s=O(t),a=D(s)?s:O(_(n,s)),i=Da(M(n,a));if(!i.startsWith("../")&&!D(i)&&Ha(i))return{absolutePath:a,relativePath:i};if(!D(s)){const e=O(_(n,"memory",s)),t=Da(M(n,e));if(!t.startsWith("../")&&!D(t)&&Ha(t))return{absolutePath:e,relativePath:t}}throw new Error(`Companion self-evolution path is not allowlisted: ${t}`)}async function Ba(e){const{companionHome:t,log:n}=e;if(!t)return n?.("warn","COMPANION_GIT","Skipping self-evolution git repo ensure: companion home is not set"),!1;if(!r(t))return n?.("warn","COMPANION_GIT",`Skipping self-evolution git repo ensure: companion home does not exist (${t})`),!1;try{await _t(t,{recursive:!0});const e=r(_(t,".git"));return e||await Ua(t,["init"]),await async function(e){const t=_(e,".gitignore");await Ct(t,"utf-8").catch(()=>{})!==Na&&await $t(t,Na,"utf-8")}(t),e||(await Fa(t),await ja(t)&&await La(t,"Initialize Companion self-evolution history","Initial snapshot before automatic Companion run checkpoints.")),!0}catch(e){return Oa(n,"Failed to ensure Companion self-evolution git repo",e),!1}}async function Fa(e){const t=await async function(e){const t=new Set;r(_(e,".gitignore"))&&t.add(".gitignore");for(const n of Ra)r(_(e,n))&&t.add(n);const n=await Nt(e).catch(()=>[]);for(const s of n)!s.includes("/")&&s.endsWith(".upgrade")&&r(_(e,s))&&t.add(s);for(const n of Pa)r(_(e,n))&&t.add(n);for(const n of await qa(e))t.add(n);return Array.from(t)}(e);0!==t.length&&await Ua(e,["add","-A","--",...t])}function Wa(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 za(e){const{companionHome:t,title:n,body:s,paths:a,log:i}=e;try{const e=await async function(e,t){const n=new Set(await qa(e)),s=Array.from(new Set(t.map(Da))).filter(Ha).filter(t=>r(_(e,t))||n.has(t));return 0===s.length?[]:(await Ua(e,["add","-A","--",...s]),s)}(t,a);return 0===e.length?(i?.("warn","COMPANION_GIT","Skipping Companion memory change commit: no allowlisted paths to stage"),null):await ja(t)?await La(t,n,s):null}catch(e){return Oa(i,"Failed to create Companion memory change semantic commit",e),null}}async function*Ka(e){yield e}let Va;const Xa=["Bash","Glob","Grep","ExitPlanMode","Read","Skill","SlashCommand","EnterPlanMode"],Ja=["EnterPlanMode","ExitPlanMode"],Ya=new Set(Ja),Qa=["Glob","Grep","Read","Skill"],Za=["Read","Glob","Grep"],ei=["Read","Glob","Grep","TodoWrite"];function ti(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,v=a.systemPromptMode??"append",y=function(e,t){const{mode:n,supportChangeTitle:s}=e,a=t?.enableTaskPreviewUrl??!0,i=[ua];switch(n){case"work":s&&i.unshift(ca),a&&i.push(la("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(da("mcp__agentrix__send_vision_artifact")),t?.enableAgentrixComputerUse&&i.push(pa("mcp__agentrix__agentrix_computer_use"));break;case"companion_shadow":case"companion_chat":case"reply":case"group_chat":break;case"chat":i.unshift(va),t?.enableAgentrixComputerUse&&i.push(pa("mcp__agentrix__agentrix_computer_use"));break;case"group_work":s&&i.unshift(ca),a&&i.push(la("mcp__agentrix__publish_task_preview_url")),t?.enableVisionPlan&&i.push(da("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=[ya];return g&&g.length>0&&e.push(wa(g)),y&&e.push(y),i&&e.push(ma(o)),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const b="reply"===h&&g&&g.length>0?xa(t,g):void 0,w={},x=process.env.AGENTRIX_COMPANION_HOME||process.env.AGENTRIX_COMPANION_WORKSPACE,k="companion_shadow"===h?function(e){return"memory_organization"===e?.COMPANION_SHADOW_TASK?"memory_organization":"heartbeat"}(d):void 0;x&&(w.COMPANION_HOME=x,w.COMPANION_MODE="companion_shadow"===h?"shadow":"chat","companion_shadow"===h&&(w.COMPANION_SHADOW_TASK=k??"heartbeat")),Object.assign(w,d);const I=Object.keys(w).length>0?w:void 0,S=f?wt(f,s,I):void 0,T="companion_shadow"===h?function(e,t){if(!e||!t)return;const n=_(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}(x,k):void 0;if("replace"===v&&S){const e=[S];return b&&e.push(b),y&&e.push(y),i&&e.push(ma(o)),T&&e.push(T),l?.systemPromptAppend&&e.push(l.systemPromptAppend),e.join("\n\n")}const E=[];return b&&E.push(b),y&&E.push(y),i&&E.push(ma(o)),S&&E.push(S),T&&E.push(T),l?.systemPromptAppend&&E.push(l.systemPromptAppend),{type:"preset",preset:"claude_code",append:E.length>0?E.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[...Xa];case"reply":return[...Qa];case"group_chat":return[...Za];case"group_work":return[...ei]}}(n.modeConfig.mode),Boolean(n.disableClaudePlanModeTools)&&u?u.filter(e=>!Ya.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!==Va)return Va??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=D(t)?t:N(t);return r(e)?e:void 0}return function(e){const t="win32"===process.platform?"where":"which",n=pt(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 Va=t,t}Va=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=_a,serverVersion:h=Ca}=e,{mode:g,supportChangeTitle:f}=t,v=[];switch(g){case"work":p&&v.push(n.computerUse),i?.includes("sub-task")&&(v.push(n.createTask),v.push(n.replyToSubTask),v.push(n.listSubTask)),f&&v.push(n.changeTaskTitle),a&&v.push(n.askUser),l&&v.push(n.publishTaskPreviewUrl),d&&v.push(n.sendVisionArtifact),v.push(n.getTaskHistory);break;case"chat":p&&v.push(n.computerUse),v.push(n.createTask),v.push(n.replyToSubTask),a&&v.push(n.askUser),v.push(n.getTaskHistory),v.push(n.listSubTask);break;case"group_chat":v.push(n.invoke),v.push(n.createSoloTask),v.push(n.createGroupTask),v.push(n.replyToSubTask),v.push(n.getTaskAgents),v.push(n.getTaskHistory);break;case"group_work":v.push(n.invoke),v.push(n.assign),f&&v.push(n.changeTaskTitle),l&&v.push(n.publishTaskPreviewUrl),d&&v.push(n.sendVisionArtifact),v.push(n.getTaskAgents),v.push(n.getTaskHistory);break;case"reply":v.push(n.getTaskHistory),a&&v.push(n.askUser);break;case"companion_chat":v.push(n.createTask),v.push(n.replyToSubTask),a&&v.push(n.askUser),v.push(n.getTaskHistory),v.push(n.uploadFile),v.push(n.listAgents),v.push(n.scheduleTask);break;case"companion_shadow":v.push(n.getTaskHistory),v.push(n.readConversation),v.push(n.listAgents),v.push(n.scheduleTask)}("companion_chat"===g||"companion_shadow"===g)&&(v.push(n.listTasks),v.push(n.sendReminder),v.push(n.recordMemoryChange),v.push(n.prepareHiveRepository),v.push(n.publishToHive),v.push(n.updateHiveListingVersion),v.push(n.recordHiveInstall),v.push(n.createHiveReview),v.push(n.createHiveComment)),"companion"===s&&v.push(n.updateAgentInfo),o&&"companion_shadow"!==g&&v.push(n.sendChannelMessage),r&&"companion_shadow"!==g&&v.push(n.getChannelGroupHistory),c&&"companion_shadow"!==g&&"reply"!==g&&v.push(n.analyzeImage),v.push(...u);const y=ft({name:m,version:h,tools:v}),b=v.map(e=>((e,t)=>`mcp__${e}__${t}`)(m,e.name));return{server:y,toolNames:b}}({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:[...Ja]}:{},mcpServers:f,plugins:[...s.customPlugins,...n.projectAgentrixGuidance?.claudePlugins??[]],abortController:n.abortController,env:n.env?ka(n.env):void 0,pathToClaudeCodeExecutable:h,maxTurns:s.customMaxTurns??n.maxTurns??l,extraArgs:s.customExtraArgs,canUseTool:n.canUseTool,hooks:m,outputFormat:n.structuredOutputSchema}}class ni{constructor(e,t,n,s,a,i){this.agentId=e,this.agentType=t,this.agentConfig=n,this.agentHooks=s,this.agentMcpServers=a,this.logger=i}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?Sa(e):e;let a=null;await this.checkpointCompanionRun(t,"before_run");try{const e=vt({prompt:Ka(s),options:ti(this.agentId,this.agentType,t,n,this.agentHooks,this.agentMcpServers,t.agentrixTools)});for await(const t of e)if(console.log("ClaudeRunner.run: received message",JSON.stringify(t)),"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?Sa(e):e;await this.checkpointCompanionRun(t,"before_run");try{const e=vt({prompt:Ka(s),options:ti(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=ti(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=vt({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(console.log("ClaudeRunner.loop.push:",JSON.stringify(e,null,2)),i)return;const t="string"==typeof e?Sa(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)}}}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,log:a}=e;if("companion_chat"!==n&&"companion_shadow"!==n)return{committed:!1};try{if(!await Ba({companionHome:t,log:a})||!t)return{committed:!1};if(await Fa(t),!await ja(t))return{committed:!1};const i="companion_shadow"===n?e.shadowTask??"unknown":"unknown",o=await La(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,i,s),function(e,t,n){return[`mode: ${e}`,`shadow_task: ${"companion_shadow"===e?t:"unknown"}`,`phase: ${n}`].join("\n")}(n,i,s));return a?.("info","COMPANION_GIT",`Created Companion self-evolution ${s} checkpoint ${o}`),{committed:!0,commit:o}}catch(e){return Oa(a,`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,log:this.logger})}}function si(e,t,n){e&&e(t,"AGENT",n)}function ai(){return`Companion probe timed out after ${Math.round(45)}s`}function ii(e){return e instanceof Error&&e.message?e.message:String(e)}function oi(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 ri(){const e=_(Ce.agentrixHomeDir,"tmp","companion-probe");d(e,{recursive:!0});const t=new ni("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?ai():oi(a)}:{success:!0}}catch(e){return{success:!1,error:s?ai():ii(e)}}finally{clearTimeout(a)}}const ci=Pt(ht);function li(e){const t={baseDir:e,binary:"git",maxConcurrentProcesses:6,trimmed:!1};return"win32"===process.platform&&(t.spawnOptions={windowsHide:!0}),Mt(t)}async function di(e){try{const t=li(e);return await t.checkIsRepo()}catch{return!1}}async function pi(e){const t=li(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 ui(e,t,n,s="HEAD"){const a=P(t);if(r(a)||d(a,{recursive:!0}),r(t)&&!xi(t))throw new Error(`Worktree directory already exists at ${t}`);const i=li(e);await i.raw(["worktree","add","-b",n,t,s])}async function mi(e,t,n=!1){const s=li(e),a=["worktree","remove"];n&&a.push("--force"),a.push(t),await s.raw(a)}async function hi(e){const t=li(e);await t.init()}async function gi(e){const t=li(e);await t.add("."),await t.commit("Initial commit",{"--allow-empty":null})}async function fi(e,t){const n=P(t);r(n)||d(n,{recursive:!0});const s=li();await s.clone(e,t)}async function vi(e,t,n){const s=li(e);(await s.branchLocal()).all.includes(t)?await s.checkout(t):(await Ri(e).catch(()=>[])).includes(t)?await ci("git",["checkout","-B",t,`origin/${t}`],{cwd:e,windowsHide:!0}):n?await ci("git",["checkout","-b",t,n],{cwd:e,windowsHide:!0}):await s.checkoutLocalBranch(t)}async function yi(e){const t=li(e);return!(await t.status()).isClean()}async function bi(e){const t=li(e),n=await t.log({maxCount:1});if(!n.latest)throw new Error("No commits found in repository");return n.latest.hash}async function wi(e){try{const t=li(e);return null!==(await t.log({maxCount:1})).latest}catch{return!1}}function xi(e){if(!r(e))return!0;const t=g(e);return 0===t.length||1===t.length&&".git"===t[0]}function ki(e){const t=e.match(/^(.*)?\{([^}]*) => ([^}]*)\}(.*)$/);if(!t)return e;const[,n="",,s,a=""]=t;return`${n}${s}${a}`}async function Ii(e,t,n){const s=li(e),a=await s.diffSummary([`${t}..${n}`]);return{totalInsertions:a.insertions,totalDeletions:a.deletions,files:a.files.map(e=>({path:ki(Z(e.file)),insertions:"insertions"in e?e.insertions:0,deletions:"deletions"in e?e.deletions:0}))}}async function Si(e,t){try{const{stdout:n}=await ci("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 Ti(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:ki(Z(o)),insertions:a,deletions:i}}(e)).filter(e=>null!==e)}function Ei(e,t){return Ie("sha256").update(`${e}\n${t}`).digest("hex")}async function Ai(e,t){const n=await Si(e,["diff","--binary","--find-renames",t,"--"]),s=Ti(await Si(e,["diff","--numstat","--find-renames",t,"--"])),a=await async function(e){const{stdout:t}=await ci("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=>Si(e,["diff","--no-index","--binary","--","/dev/null",t]))),o=Ti((await Promise.all(a.map(t=>Si(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:Ei(t,r)}:null;var c}async function _i(e){const t=li(e);return(await t.revparse(["--abbrev-ref","HEAD"])).trim()}async function Ci(e,t,n){const s=li(e);await s.remote(["set-url",t,n])}function $i(e){try{const t=new URL(e);return t.username="",t.password="",t.toString()}catch{return e}}async function Ni(e,t,n){const s=li(e),a=(await s.getRemotes(!0)).find(e=>e.name===t);a?a.refs.fetch!==n&&await Ci(e,t,n):await s.addRemote(t,n)}async function Ri(e,t="origin"){const{stdout:n}=await ci("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 Pi(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 Mi(e){try{const t=li(e),n=(await t.getRemotes(!0)).find(e=>"origin"===e.name);return n?.refs?.fetch?Pi(n.refs.fetch):null}catch(e){return console.error("[GIT] Failed to get remote info:",e),null}}const Di="oauth2",Oi="AGENTRIX_GIT_USERNAME",Ui="AGENTRIX_GIT_PASSWORD";function ji(){const e=_(s(),`git-askpass-${ke()}.sh`);return u(e,`#!/bin/sh\ncase "$1" in\n *Username*|*username*) printf '%s\\n' "\${${Oi}:-${Di}}" ;;\n *) printf '%s\\n' "\${${Ui}:-}" ;;\nesac\n`,{mode:448}),e}function Li(e,t,n=Di){return{...process.env,GIT_ASKPASS:e,GIT_TERMINAL_PROMPT:"0",[Oi]:n,[Ui]:t}}function qi(){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 Hi=Pt(ht),Gi="github",Bi="xmz-ai",Fi="agentrix-agent",Wi="https://github.com/xmz-ai/agentrix-agent.git",zi="main";async function Ki(e,t,n){await Hi("git",["clone","--depth=1","--branch",t,e,n]),await Ni(n,"origin",$i(e))}async function Vi(e){const t=Ce.resolveRepoStoreCheckoutDir(Gi,Bi,Fi),n=_(t,"companion"),s=Ce.resolveRepoStoreLockPath(Gi,Bi,Fi),a=await Ce.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=`${Ce.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||zi}}return{gitUrl:Wi,branch:zi}}(e);if(!await di(t)){if(!xi(t))return{path:t,companionDir:n,pullSucceeded:!1,error:`Companion template checkout exists but is not a git repository: ${t}`};try{return await Ki(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 Hi("git",["fetch","--depth=1",e,t],{cwd:n}),await Hi("git",["merge","--ff-only","FETCH_HEAD"],{cwd:n}),await Ni(n,"origin",$i(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=_(P(n),`.agentrix-agent.tmp-${process.pid}-${Date.now()}`);try{await Ki(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 Ce.releaseFileLock(s,a)}}function Xi(e){r(e)||d(e,{recursive:!0})}function Ji(e){return e.split("\\").join("/")}function Yi(e,t){const n=_(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 Qi(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 Zi(e){return _(e,"versions/.companion-template-language.json")}async function eo(e){const t=Ce.agentrixAgentsHomeDir,n=_(t,"companion"),s=_(n,"claude"),a=!r(_(n,"agent.json")),i=await Vi(e?.credentials);let o=r(_(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 ri();if(!e.success)throw new Error(`Companion probe failed: ${e.error||"Unknown error"}`);if(r(_(o,"agent.json")))v(o,n,{recursive:!0}),oa(n),console.log("[Companion] Installed from template repository");else try{await ia({agentId:"companion",gitUrl:Wi,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(_(n,"agent.json"))||(console.log("[Companion] Falling back to public repo install..."),await ia({agentId:"companion",gitUrl:Wi,branch:"main",subDir:"companion"})),o=r(_(i.companionDir,"agent.json"))?i.companionDir:n}Xi(_(s,"memory"));const l=Qi(e?.preferredLanguage),d=function(e,t,n){if(n)return{language:t,source:"initial-install",verified:!0};const s=function(e){const t=Zi(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,"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=Qi(e),a=Yi("common",t),i=Yi(s,t),o=[],l={version:"1.0.0",updateStrategy:"create-only"};for(const[e,n]of Object.entries(a)){const s=_(t,e);r(s)&&o.push({relativePath:e,content:c(s,"utf-8"),metadata:n,language:"common",sourcePath:s})}const d=_(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=_(s,i);if(p(a).isDirectory()){n(a);continue}if("versions.json"===i)continue;const o=Ji(M(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:_(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=Zi(e);Xi(P(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=sa(_(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/")))&&(oa(n),console.log("[Companion] Rebuilt plugins after template updates"));const{pendingUpgrades:y,blockedUpgrades:b}=function(e,t,n={}){const s=[],a=[];for(const i of e){if("notify-user"!==i.metadata.updateStrategy)continue;const e=_(t,i.relativePath);if(!r(e))continue;const o=ea(e,t);if(na(i.metadata.version,o)>0){const r={template:i,targetPath:e,upgradePath:`${e}.upgrade`,versionPath:Zs(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(y.length>0||b.length>0)try{const 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:y,blockedUpgrades:b,agentDir:n,language:m,languageSource:d.source});u(e,t,"utf-8");for(const e of y)u(e.upgradePath,aa(e),"utf-8");console.log(`[Companion] Created UPGRADES.md with ${y.length} pending upgrade(s) and ${b.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 to=[{version:1,fileName:"001_init.sql"}];function no(e){var t;return function(e,t){const n=new Ot(e),s=new Dt;n.pragma("journal_mode = WAL"),function(e){const t=function(){const e=Xe(Ut(import.meta.url)),t=[Ve(e,"migrations"),Ve(process.cwd(),"dist","migrations"),Ve(process.cwd(),"src","worker","history","migrations")];for(const e of t)if(qe(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=Ve(e,t);return Le(n,"utf8")}(t,to[0].fileName);e.exec(s),n<to[0].version&&e.pragma(`user_version = ${to[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 "),v=n.prepare("\n SELECT agent_id, session_id, last_sequence\n FROM task_agent_session\n "),y=n.prepare("\n INSERT INTO task_agent_session (agent_id, task_id, session_id, last_sequence, updated_at)\n VALUES (?, ?, ?, NULL, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n task_id = excluded.task_id,\n session_id = excluded.session_id,\n updated_at = excluded.updated_at\n "),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??K(),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??K(),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(ao),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(ao).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?ao(s):null},pageRecentMessages:e=>{const t=p.all(e).map(so).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(so),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(so).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(so).reverse(),s=n[0]?.localSequence??null;return{data:n,hasMore:!!s&&Boolean(h.get(s))}},getAgentSessions:()=>{const e=v.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.session_id);return t},getAgentLastSequences:()=>{const e=v.all(),t=new Map;for(const n of e)t.set(n.agent_id,n.last_sequence);return t},upsertAgentSession:(e,n)=>{y.run(e,t,n,(new Date).toISOString())},updateAgentLastSequence:(e,n)=>{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,Ve(t,"data.bin")),e.taskId)}function so(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 ao(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 io=[1,2,4,6,8,12,24];function oo(e){return"number"==typeof e&&io.includes(e)}function ro(e){return oo(e)?e:4}class co{constructor(e,t,n={}){this.client=e,this.machineId=t;const s=Ce.agentrixAgentsHomeDir,a=_(s,"companion","claude");this.stateFilePath=n.stateFilePath??_(a,"state.json"),this.initialDelayMs=n.initialDelayMs??6e4}timer=null;initialDelay=null;intervalMs=9e5;enabled=!1;heartbeatTaskId=null;memoryOrganizationEnabled=!1;memoryOrganizationIntervalHours=4;memoryOrganizationTaskId=null;companionState=null;stateFilePath;initialDelayMs;started=!1;cronJobs=new Map;start(){this.started?this.reloadStateAndReschedule():(this.started=!0,this.loadState(),this.companionState?($e.info(`[COMPANION SCHEDULER] Ready: agent=${this.companionState.agentId}, chatId=${this.companionState.chatId}`),this.restoreScheduledTasks()):$e.warn("[COMPANION SCHEDULER] No state.json found (companion not registered yet), will keep checking"),$e.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(),$e.debug(`[COMPANION SCHEDULER] Stopped cron job: ${e}`);this.cronJobs.clear(),$e.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(),$e.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),$e.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),$e.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),$e.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&&($e.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=ro(this.companionState?.memoryOrganizationIntervalHours),this.memoryOrganizationTaskId=this.companionState?.memoryOrganizationTaskId??null,$e.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){$e.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=P(this.stateFilePath);r(s)||d(s,{recursive:!0}),u(this.stateFilePath,JSON.stringify(n,null,2),"utf-8"),$e.debug(`[COMPANION SCHEDULER] Saved state field: ${e}=${t??"removed"}`)}catch(t){$e.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 $e.debug(`[COMPANION SCHEDULER] Sending memory organization to existing task ${this.memoryOrganizationTaskId}`),void this.client.send("task-message",{eventId:K(),taskId:this.memoryOrganizationTaskId,chatId:e.chatId,from:"machine",message:a,senderType:"system",senderId:"system",senderName:"system"});$e.debug("[COMPANION SCHEDULER] Requesting initial memory organization task"),this.client.send("request-companion-memory-organization",{eventId:K(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n,trigger:"scheduled",triggerTime:s,intervalHours:this.memoryOrganizationIntervalHours})}addScheduledTask(e){const t={id:ke(),...e,createdAt:(new Date).toISOString()};this.loadState();const n=this.companionState?.scheduledTasks??[];return n.push(t),this.saveStateField("scheduledTasks",n),this.startCronJob(t),$e.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)),$e.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 $e.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 $e.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 Lt(s,t,()=>{this.onScheduledTaskFired(e)});this.cronJobs.set(e.id,a),$e.debug(`[COMPANION SCHEDULER] Started cron job: id=${e.id}, pattern="${s}"`)}catch(t){$e.warn(`[COMPANION SCHEDULER] Failed to start cron job for task ${e.id}`,t)}}onScheduledTaskFired(e){$e.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:K(),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()?$e.debug(`[COMPANION SCHEDULER] Skipping expired one-time task: ${n.id}`):(this.startCronJob(n),t++);$e.info(`[COMPANION SCHEDULER] Restored ${t}/${e.length} scheduled tasks`)}tick(){if(this.loadState(),!this.companionState)return void $e.debug("[COMPANION SCHEDULER] Still no state.json, skipping heartbeat");const e=this.companionState,t=[],n=new Date;if(this.isMemoryOrganizationDue(e,n)&&($e.info("[COMPANION SCHEDULER] Memory organization triggered"),this.triggerMemoryOrganization(e,n)),!this.enabled)return void $e.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)return void $e.debug("[COMPANION SCHEDULER] No trigger conditions met, skipping heartbeat");$e.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?($e.debug(`[COMPANION SCHEDULER] Sending heartbeat to existing task ${this.heartbeatTaskId}`),this.client.send("task-message",{eventId:K(),taskId:this.heartbeatTaskId,chatId:e.chatId,from:"machine",message:o,senderType:"system",senderId:"system",senderName:"system"})):($e.debug("[COMPANION SCHEDULER] Requesting new heartbeat task"),this.client.send("request-companion-heartbeat",{eventId:K(),machineId:e.machineId,agentId:e.agentId,chatId:e.chatId,userId:e.userId,timestamp:n.toISOString(),triggerTime:i,triggerReasons:t,heartbeatTriggerCount:a}))}}const lo=new It({credentialsDir:_(Ce.agentrixHomeDir,"credentials")});async function po(){const e=await Ce.readCredentials();return e?.secret?St(e.secret):null}function uo(e){return lo.loadGitServerConfig(e)}function mo(e,t){return lo.loadGitLabWebhookBridgeSecrets(e,t)}function ho(e){return lo.loadPatMeta(e)}function go(e,t){return lo.loadPat(e,t)}const fo="https://ilinkai.weixin.qq.com",vo="https://novac2c.cdn.weixin.qq.com/c2c",yo=1e3,bo=et(import.meta.url)("qrcode-terminal");function wo(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`WeChat credential "${t}" is required`);return e.trim()}function xo(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function ko(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 Io(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 So(e,t){for(const n of t){const t=e[n];if("string"==typeof t&&t.trim())return t}}function To(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 Eo(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 Ao(e){if(e.image_item?.media?.full_url)return _o(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 _o(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 _o(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 Co(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 $o(e){return e.retcode??e.ret??e.errcode}function No(e,t){const n=$o(e);return[void 0===n?void 0:`ret=${n}`,e.errmsg||t].filter(Boolean).join(", ")}function Ro(e,t){const n=e.replace(/\/+$/,"");return n.endsWith("/ilink/bot")?`${n}/${t}`:`${n}/ilink/bot/${t}`}function Po(e){let t="";return bo.generate(e,{small:!0},e=>{t=e}),t}class Mo{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=yo;contextTokens=new Map;clientId=xe(8).toString("hex");constructor(e){this.id=e.id,this.credentials=function(e){const t=xo(e.token)??xo(e.botToken)??xo(e.bot_token)??xo(e.apiKey)??xo(e.api_key);return{baseUrl:xo(e.baseUrl)??xo(e.base_url)??fo,token:t||wo(t,"token"),routeTag:xo(e.routeTag)??xo(e.route_tag),getUpdatesBuf:xo(e.getUpdatesBuf)??xo(e.get_updates_buf)??"",channelVersion:xo(e.channelVersion)??xo(e.channel_version)??"1.0.0",pollTimeoutMs:ko(e.pollTimeoutMs??e.poll_timeout_ms,3e4),requestTimeoutMs:ko(e.requestTimeoutMs??e.request_timeout_ms,4e4),fileDownloadEndpoint:xo(e.fileDownloadEndpoint)??xo(e.file_download_endpoint)??xo(e.downloadEndpoint)??xo(e.download_endpoint)??"downloadfile"}}(e.credentials)}static async createLoginQRCode(e={}){const t=e.baseUrl?.trim()||fo,n={};e.routeTag?.trim()&&(n.SKRouteTag=e.routeTag.trim());const s=await fetch(`${Ro(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=$o(a);if(i&&0!==i)throw new Error(No(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:Po(a.qrcode_img_content),baseUrl:t}}static async getLoginStatus(e,t={}){const n=t.baseUrl?.trim()||fo,s=await fetch(`${Ro(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=$o(a);if(i&&0!==i)throw new Error(No(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=yo,this.setState("connecting"),this.pollPromise=this.pollLoop(),this.setState("connected"),$e.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=$o(s);if(a&&0!==a)throw new Error(No(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()||C(t.filePath),a=await Ct(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=$o(p);if(u&&0!==u)throw new Error(No(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=Ie("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=$o(c);if(l&&0!==l)throw new Error(No(c,"WeChat getuploadurl failed"));const d=this.extractUploadParam(c),p=await fetch(`${vo}/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:`${vo}/download?encrypted_query_param=${encodeURIComponent(u)}`,aesKey:Buffer.from(i,"utf-8").toString("base64"),aesKeyHex:i,encryptQueryParam:u,md5:r,encryptedSize:o.length}}extractUploadParam(e){const t=e.upload_param;if("string"==typeof t&&t.trim())return t.trim();const n=e.data;if(n&&"object"==typeof n){const e=n.upload_param;if("string"==typeof e&&e.trim())return e.trim()}throw new Error("WeChat getuploadurl response missing upload_param")}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=function(e){if(!e.startsWith("wechat-media:"))return null;try{const t=JSON.parse(Buffer.from(e.slice(13),"base64url").toString("utf-8"));return"string"==typeof t?.url&&t.url?{url:t.url,aesKey:"string"==typeof t.aesKey?t.aesKey:void 0,fileName:"string"==typeof t.fileName?t.fileName:void 0}:null}catch{return null}}(e);if(n)return await this.downloadEncryptedMedia(n,t.fileName);if(/^https?:\/\//i.test(e))return await On(e,t.fileName);const s=await this.requestDownloadFile(e);return await Dn(s,t.fileName||e)}catch(t){return $e.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=$o(e);if(t&&0!==t)throw new Error(No(e,"WeChat getupdates failed"));const n=e.data??e;this.credentials.getUpdatesBuf=n.get_updates_buf??this.credentials.getUpdatesBuf,this.retryDelayMs=yo,"connected"!==this.connectionState&&this.setState("connected");for(const e of Co(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));$e.warn(`[CHANNEL][WECHAT] Poll failed: channel=${this.id}, message=${t.message}`),this.setState("error",t),await this.sleepWithCancel(this.retryDelayMs),this.retryDelayMs=Math.min(2*this.retryDelayMs,3e4),this.polling&&this.setState("connecting")}}async request(e,t,n){const s=new AbortController;"getupdates"===e&&(this.pollController=s);const a=setTimeout(()=>s.abort(),n.timeoutMs);try{const n=this.buildHeaders(),a=await fetch(this.apiUrl(e),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,...t}),signal:s.signal}),i=await a.json().catch(()=>({}));if(!a.ok)throw new Error(`HTTP ${a.status}: ${JSON.stringify(i)}`);return i}finally{clearTimeout(a),"getupdates"===e&&this.pollController===s&&(this.pollController=null)}}async requestDownloadFile(e){const t=new AbortController,n=setTimeout(()=>t.abort(),this.credentials.requestTimeoutMs);try{const n=this.buildHeaders(),s=await fetch(this.apiUrl(this.credentials.fileDownloadEndpoint),{method:"POST",headers:n,body:JSON.stringify({base_info:{channel_version:this.credentials.channelVersion},client_id:this.clientId,file_id:e,file_key:e,image_key:e}),signal:t.signal});if(!s.ok){const e=await s.text().catch(()=>"");throw new Error(`HTTP ${s.status}: ${e||s.statusText}`)}return s}finally{clearTimeout(n)}}async downloadEncryptedMedia(e,t){const n=await fetch(e.url);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=Buffer.from(await n.arrayBuffer()),a=e.aesKey?this.decryptWechatMedia(s,e.aesKey):s,i=Pn(t||e.fileName||"attachment");return await $t(i,a),i}decryptWechatMedia(e,t){const n=this.decodeWechatAesKey(t);try{const t=Se("aes-128-ecb",n,null);return Buffer.concat([t.update(e),t.final()])}catch{const t=Se("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=Te("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 Ro(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 $e.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?_o(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?_o(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??ke()),channelId:this.id,platform:"wechat",chatId:t,chatType:e.room_id||String(t).endsWith("@chatroom")?"group":"p2p",senderId:a,senderName:So(n,["sender_name","nickname","user_name"]),type:Eo(e),text:To(e),fileKey:s.fileKey,fileName:s.fileName,imageKey:Ao(e),mentionedBot:i,replyToBot:o,triggered:i||o,rawContent:e.content??e.item_list,timestamp:Io(e.timestamp??e.create_time),raw:e}}}const Do=["telegram","wechat","lark"],Oo=rt.enum(Do),Uo=rt.enum(["connecting","connected","disconnected","error"]),jo=rt.enum(["text","image","file","voice"]),Lo=rt.record(rt.string(),rt.unknown()),qo=rt.object({id:rt.string(),platform:Oo,name:rt.string().optional(),credentials:Lo,enabled:rt.boolean(),connectionState:Uo,lastConnectedAt:rt.string().optional(),lastDisconnectedAt:rt.string().optional(),lastError:rt.string().optional(),createdAt:rt.string(),updatedAt:rt.string()}),Ho=rt.object({platform:Oo,name:rt.string().optional(),credentials:Lo,enabled:rt.boolean().optional()}),Go=rt.object({id:rt.string(),channelId:rt.string(),chatId:rt.string(),taskId:rt.string(),chatName:rt.string().optional(),createdAt:rt.string(),updatedAt:rt.string()});rt.object({id:rt.string(),channelId:rt.string(),platform:Oo,chatId:rt.string(),chatType:rt.string().optional(),senderId:rt.string().optional(),senderType:rt.string().optional(),senderName:rt.string().optional(),type:jo,text:rt.string().optional(),fileKey:rt.string().optional(),fileName:rt.string().optional(),imageKey:rt.string().optional(),attachmentPaths:rt.array(rt.string()).optional(),mentionedBot:rt.boolean().optional(),replyToBot:rt.boolean().optional(),triggered:rt.boolean().optional(),rawContent:rt.unknown().optional(),timestamp:rt.string(),raw:rt.unknown().optional()});const Bo=rt.object({id:rt.string(),name:rt.string(),avatar:rt.string().optional(),description:rt.string().optional(),chatStatus:rt.string().optional(),external:rt.boolean().optional()}),Fo=rt.enum(["auto","image","file","audio","video"]),Wo=rt.object({filePath:rt.string(),fileName:rt.string().optional(),mimeType:rt.string().optional(),kind:Fo.optional()});rt.object({content:rt.string().optional(),attachments:rt.array(Wo).optional()});const zo=rt.object({version:rt.literal(1),channels:rt.array(qo),bindings:rt.array(Go)}),Ko=new Map;function Vo(e){return!e||"object"!=typeof e||Array.isArray(e)?null:e}function Xo(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function Jo(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function Yo(e){if("boolean"==typeof e)return e;if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"true"===t||"1"===t||"yes"===t||"false"!==t&&"0"!==t&&"no"!==t&&void 0}function Qo(e){const t=Vo(e.project);return t?{id:Jo(t.id),path:Xo(t.path),path_with_namespace:Xo(t.path_with_namespace),default_branch:Xo(t.default_branch),web_url:Xo(t.web_url)}:null}function Zo(e){const t=Vo(e.object_attributes);return t?{iid:Jo(t.iid),title:Xo(t.title),url:Xo(t.url),action:Xo(t.action),state:Xo(t.state)}:null}function er(e){const t=Vo(e.object_attributes);if(!t)return null;const n=Vo(t.last_commit),s=hr(t.labels);return{iid:Jo(t.iid),title:Xo(t.title),description:Xo(t.description),url:Xo(t.url),action:Xo(t.action),state:Xo(t.state),source_branch:Xo(t.source_branch),target_branch:Xo(t.target_branch),oldrev:Xo(t.oldrev)??Xo(e.oldrev),last_commit_sha:Xo(n?.id)??Xo(n?.sha),labels:s.length>0?s:hr(t.label_names)}}function tr(e){const t=Vo(e.object_attributes);return t?{id:Jo(t.id),note:Xo(t.note),noteable_type:Xo(t.noteable_type),url:Xo(t.url),action:Xo(t.action),system:Yo(t.system),isDiffNote:Boolean(t.position||t.diff_refs||t.line_code)}:null}function nr(e){const t=Vo(e.object_attributes);return t?{id:Jo(t.id),iid:Jo(t.iid),status:Xo(t.status),source:Xo(t.source),ref:Xo(t.ref),sha:Xo(t.sha),url:Xo(t.url)}:null}function sr(e){return Xo(e.event_type)||Xo(e.object_kind)||"unknown"}function ar(e){const t=e;return{message:"string"==typeof t?.message?t.message:e instanceof Error?e.message:"Failed to trigger GitLab pipeline",detail:"string"==typeof t?.detail?t.detail:void 0,upstreamStatus:"number"==typeof t?.status?t.status:void 0}}function ir(e,t){return`gitlab-webhook-trigger:${e}:${t}:pipeline`}function or(e,t,n){!function(e){for(const[t,n]of Ko.entries())n<=e&&Ko.delete(t)}(n);const s=ir(e,t),a=Ko.get(s);return"number"==typeof a&&a>n}function rr(e,t,n){const s=ir(e,t);Ko.set(s,n+18e5)}function cr(e){return Vo(e.changes)??{}}function lr(e,t){if(!(t in e))return null;const n=e[t];if(Array.isArray(n)&&n.length>=2)return{previous:n[0],current:n[1]};const s=Vo(n);return s?{previous:s.previous,current:s.current}:null}function dr(e,t){for(const n of t){const t=lr(e,n);if(t)return t}return null}function pr(e){return Array.isArray(e)?e:[]}function ur(e){return Array.from(new Set(e))}function mr(e){if("string"==typeof e)return Xo(e);const t=Vo(e);return Xo(t?.title)??Xo(t?.name)}function hr(e){return ur(pr(e).map(mr).filter(e=>Boolean(e)))}function gr(e){const t=Vo(e);return Xo(t?.username)??Xo(t?.name)??("number"==typeof t?.id?String(t.id):void 0)}function fr(e){if("string"==typeof e)return Xo(e);const t=Vo(e);return Xo(t?.id)??Xo(t?.sha)}function vr(e,t,n){const s=ur(pr(e).map(n).filter(e=>Boolean(e))),a=ur(pr(t).map(n).filter(e=>Boolean(e)));return{added:a.filter(e=>!s.includes(e)),removed:s.filter(e=>!a.includes(e)),current:a,previous:s}}function yr(e){return null==e||""===e}function br(e){if(!e)return null;const t=Yo(e.previous),n=Yo(e.current);return void 0===t||void 0===n||t===n?null:{previous:t,current:n}}function wr(e,t){return t.some(t=>t in e)}function xr(e){if(Array.isArray(e))return`[${e.map(xr).join(",")}]`;const t=Vo(e);return t?`{${Object.keys(t).sort().map(e=>`${JSON.stringify(e)}:${xr(t[e])}`).join(",")}}`:JSON.stringify(e)}function kr(e,t){const n=Xo(t);return n||`payload-${Ie("sha256").update(xr(e)).digest("hex")}`}function Ir(e){return encodeURIComponent(String(e??"unknown"))}function Sr(e,t,n){null!=n&&(e[t]=String(n))}function Tr(e,t,n){e[t]=JSON.stringify(n)}function Er(e,t){0!==t.length&&(Sr(e,"AGENTRIX_LABELS",t.join(",")),Tr(e,"AGENTRIX_LABELS_JSON",t))}function Ar(e){const{owner:t,name:n}=function(e){const t=e.split("/").filter(Boolean);if(t.length<2)return{owner:"",name:e};const n=t[t.length-1];return{owner:t.slice(0,-1).join("/"),name:n}}(e.project.path_with_namespace??""),s={AGENTRIX_EVENT_NAME:e.eventName,AGENTRIX_EVENT_ACTION:e.eventAction,AGENTRIX_GIT_SERVER_ID:e.gitServerId,AGENTRIX_PROVIDER:"gitlab",AGENTRIX_REPOSITORY_OWNER:t,AGENTRIX_REPOSITORY_NAME:n,AGENTRIX_TRIGGER_SOURCE:"agentrix_daemon_webhook",AGENTRIX_COMPAT_KIND:e.compatKind,AGENTRIX_PROVIDER_EVENT_NAME:e.providerEventName,AGENTRIX_GITLAB_EVENT_NAME:e.providerEventName,AGENTRIX_GITLAB_CHANGED_KEYS:e.changedKeys.join(",")};return Sr(s,"AGENTRIX_PROVIDER_EVENT_ACTION",e.providerEventAction),Sr(s,"AGENTRIX_GITLAB_EVENT_ACTION",e.providerEventAction),Sr(s,"AGENTRIX_SUBJECT_KIND",e.subjectKind),s}function _r(e,t,n,s){const a={ref:t,variables:n};return e.id?a.projectId=e.id:e.path_with_namespace&&(a.projectPath=e.path_with_namespace),s.triggerToken&&(a.triggerToken=s.triggerToken),void 0!==s.createTriggerIfMissing&&(a.createTriggerIfMissing=s.createTriggerIfMissing),a}function Cr(e){const t={...Ar(e),...e.variables??{}};return{project:e.project,ref:e.ref,normalizedEventIdParts:e.normalizedEventIdParts,eventName:e.eventName,eventAction:e.eventAction,providerEventName:e.providerEventName,providerEventAction:e.providerEventAction,compatKind:e.compatKind,subjectKind:e.subjectKind,changedKeys:e.changedKeys,variables:t}}function $r(e,t,n){const s=kr(t,n.deliveryId),a=sr(t);return function(e,t,n){return e.map((s,a)=>{const i=function(e,t){return[e,...t].map(Ir).join(":")}(n,s.normalizedEventIdParts),o={...s.variables,AGENTRIX_NORMALIZED_EVENT_ID:i,AGENTRIX_NORMALIZED_EVENT_INDEX:String(a),AGENTRIX_NORMALIZED_EVENT_COUNT:String(e.length)};return{normalizedEventId:i,eventName:s.eventName,eventAction:s.eventAction,providerEventName:s.providerEventName,providerEventAction:s.providerEventAction,compatKind:s.compatKind,operationPayload:_r(s.project,s.ref,o,t),action:s.eventAction}})}((()=>{switch(a){case"issue":return function(e,t,n){const s=Qo(t),a=Zo(t);if(!s?.path_with_namespace||!a?.iid)return[];const i=n.ref||s.default_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes project.default_branch"};const o=a.action,r=Object.keys(cr(t)),c={gitServerId:e,project:s,ref:i,providerEventName:"issue",providerEventAction:o,subjectKind:"issue",changedKeys:r},l=()=>{const e={};return function(e,t,n){Sr(e,"AGENTRIX_ISSUE_NUMBER",n.iid),Sr(e,"AGENTRIX_ISSUE_TITLE",n.title),Sr(e,"AGENTRIX_ISSUE_URL",function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/issues/${t.iid}`:void 0}(t,n))}(e,s,a),e};if("open"===o||"opened"===o||!o&&"opened"===a.state)return[Cr({...c,eventName:"issues",eventAction:"opened",compatKind:"exact",normalizedEventIdParts:["issues","opened",`issue-${a.iid}`],variables:l()})];if("close"===o||"closed"===o||!o&&"closed"===a.state)return[Cr({...c,eventName:"issues",eventAction:"closed",compatKind:"exact",normalizedEventIdParts:["issues","closed",`issue-${a.iid}`],variables:l()})];if("reopen"===o||"reopened"===o)return[Cr({...c,eventName:"issues",eventAction:"reopened",compatKind:"exact",normalizedEventIdParts:["issues","reopened",`issue-${a.iid}`],variables:l()})];const d=cr(t),p=[],u=lr(d,"labels");if(u){const e=vr(u.previous,u.current,mr);for(const t of e.added){const n=l();n.AGENTRIX_LABEL_NAME=t,Er(n,e.current),Tr(n,"AGENTRIX_LABEL_CHANGES_JSON",e),p.push(Cr({...c,eventName:"issues",eventAction:"labeled",compatKind:"exact",normalizedEventIdParts:["issues","labeled",`issue-${a.iid}`,`label-${t}`],variables:n}))}for(const t of e.removed){const n=l();n.AGENTRIX_LABEL_NAME=t,Er(n,e.current),Tr(n,"AGENTRIX_LABEL_CHANGES_JSON",e),p.push(Cr({...c,eventName:"issues",eventAction:"unlabeled",compatKind:"exact",normalizedEventIdParts:["issues","unlabeled",`issue-${a.iid}`,`label-${t}`],variables:n}))}}const m=lr(d,"assignees");if(m){const e=vr(m.previous,m.current,gr);for(const t of e.added){const n=l();n.AGENTRIX_ASSIGNEE_LOGIN=t,Tr(n,"AGENTRIX_ASSIGNEE_CHANGES_JSON",e),p.push(Cr({...c,eventName:"issues",eventAction:"assigned",compatKind:"exact",normalizedEventIdParts:["issues","assigned",`issue-${a.iid}`,`assignee-${t}`],variables:n}))}for(const t of e.removed){const n=l();n.AGENTRIX_ASSIGNEE_LOGIN=t,Tr(n,"AGENTRIX_ASSIGNEE_CHANGES_JSON",e),p.push(Cr({...c,eventName:"issues",eventAction:"unassigned",compatKind:"exact",normalizedEventIdParts:["issues","unassigned",`issue-${a.iid}`,`assignee-${t}`],variables:n}))}}const h=dr(d,["milestone","milestone_id"]);if(h&&yr(h.previous)!==yr(h.current)){const e=yr(h.previous)?"milestoned":"demilestoned",t=l();p.push(Cr({...c,eventName:"issues",eventAction:e,compatKind:"exact",normalizedEventIdParts:["issues",e,`issue-${a.iid}`],variables:t}))}const g=br(lr(d,"discussion_locked"));if(g){const e=g.current?"locked":"unlocked",t=l();p.push(Cr({...c,eventName:"issues",eventAction:e,compatKind:"exact",normalizedEventIdParts:["issues",e,`issue-${a.iid}`],variables:t}))}return wr(d,["title","description"])&&p.push(Cr({...c,eventName:"issues",eventAction:"edited",compatKind:"exact",normalizedEventIdParts:["issues","edited",`issue-${a.iid}`],variables:l()})),p}(e,t,n);case"note":return function(e,t,n){const s=Qo(t),a=tr(t);if(!s?.path_with_namespace||!a||!0===a.system)return[];const i=function(e){const t=e?.trim().toLowerCase();return"issue"===t?"issue":"mergerequest"===t||"merge_request"===t?"merge_request":void 0}(a.noteable_type);if(!i)return[];const o=Vo("issue"===i?t.issue:t.merge_request),r=Jo(o?.iid);if(!r)return[];const c=(()=>{switch(a.action){case void 0:case"create":case"created":return"created";case"update":case"updated":return"edited";case"delete":case"deleted":return"deleted";default:return null}})();if(!c)return[];const l="merge_request"===i?Xo(o?.source_branch):void 0,d="merge_request"===i?Xo(o?.target_branch):void 0,p=n.ref||d||s.default_branch||l;if(!p)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes a usable ref"};const u="merge_request"===i&&a.isDiffNote?"pull_request_review_comment":"issue_comment",m="merge_request"===i?"pull_request":"issue",h=Object.keys(cr(t)),g={AGENTRIX_COMMENT_COMMAND:(f=a.note,f&&/(?:^|[^A-Za-z0-9._-])(?:@agentrix|\/agentrix)(?=$|[^A-Za-z0-9._-])/i.test(f)?"true":"false"),AGENTRIX_GITLAB_NOTEABLE_TYPE:a.noteable_type??i};var f;return Sr(g,"AGENTRIX_COMMENT_BODY",a.note),Sr(g,"AGENTRIX_COMMENT_ID",a.id),Sr(g,"AGENTRIX_COMMENT_URL",a.url),"issue"===i?Sr(g,"AGENTRIX_ISSUE_NUMBER",r):(Sr(g,"AGENTRIX_PR_NUMBER",r),Sr(g,"AGENTRIX_HEAD_REF",l),Sr(g,"AGENTRIX_BASE_REF",d)),[Cr({gitServerId:e,project:s,ref:p,eventName:u,eventAction:c,providerEventName:"note",providerEventAction:a.action,compatKind:"issue"===i?"exact":"derived",subjectKind:m,changedKeys:h,normalizedEventIdParts:[u,c,`${m}-${r}`,`comment-${a.id??"unknown"}`],variables:g})]}(e,t,n);case"merge_request":return function(e,t,n){const s=Qo(t),a=er(t);if(!s?.path_with_namespace||!a?.iid)return[];const i=n.ref||a.target_branch||s.default_branch||a.source_branch;if(!i)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes target_branch or project.default_branch"};const o=a.action,r=Object.keys(cr(t)),c={gitServerId:e,project:s,ref:i,providerEventName:"merge_request",providerEventAction:o,subjectKind:"pull_request",changedKeys:r},l=()=>{const e={};return function(e,t,n){Sr(e,"AGENTRIX_PR_NUMBER",n.iid),Sr(e,"AGENTRIX_HEAD_REF",n.source_branch),Sr(e,"AGENTRIX_BASE_REF",n.target_branch),Sr(e,"AGENTRIX_MR_TITLE",n.title),Sr(e,"AGENTRIX_PR_BODY",n.description),Sr(e,"AGENTRIX_MR_DESCRIPTION",n.description),Sr(e,"AGENTRIX_MR_URL",function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.iid?`${e.web_url}/-/merge_requests/${t.iid}`:void 0}(t,n)),Er(e,n.labels)}(e,s,a),e};if("open"===o||"opened"===o)return[Cr({...c,eventName:"pull_request",eventAction:"opened",compatKind:"exact",normalizedEventIdParts:["pull_request","opened",`mr-${a.iid}`],variables:l()})];if("reopen"===o||"reopened"===o)return[Cr({...c,eventName:"pull_request",eventAction:"reopened",compatKind:"exact",normalizedEventIdParts:["pull_request","reopened",`mr-${a.iid}`],variables:l()})];if("merge"===o||"merged"===o||"merged"===a.state){const e=l();return e.AGENTRIX_PULL_REQUEST_MERGED="true",[Cr({...c,eventName:"pull_request",eventAction:"closed",compatKind:"derived",normalizedEventIdParts:["pull_request","closed",`mr-${a.iid}`,"merged"],variables:e})]}if("close"===o||"closed"===o){const e=l();return e.AGENTRIX_PULL_REQUEST_MERGED="false",[Cr({...c,eventName:"pull_request",eventAction:"closed",compatKind:"exact",normalizedEventIdParts:["pull_request","closed",`mr-${a.iid}`],variables:e})]}if("approved"===o||"approval"===o){const e=l();return e.AGENTRIX_REVIEW_STATE="approved",[Cr({...c,eventName:"pull_request_review",eventAction:"submitted",compatKind:"derived",normalizedEventIdParts:["pull_request_review","submitted",`mr-${a.iid}`,"approved"],variables:e})]}if("unapproved"===o||"unapproval"===o){const e=l();return e.AGENTRIX_REVIEW_STATE="approved_removed",[Cr({...c,eventName:"pull_request_review",eventAction:"dismissed",compatKind:"derived",normalizedEventIdParts:["pull_request_review","dismissed",`mr-${a.iid}`,"approved_removed"],variables:e})]}const d=cr(t),p=[],u=function(e){const t=dr(e,["last_commit","head_sha","source_branch_sha","sha"]);if(!t)return null;const n=fr(t.previous),s=fr(t.current);return n||s?n===s?null:{previous:n,current:s}:null}(d),m=a.oldrev??u?.current??a.last_commit_sha??"unknown";if(a.oldrev||u){const e=l();Sr(e,"AGENTRIX_GITLAB_OLDREV",a.oldrev??u?.previous),Sr(e,"AGENTRIX_HEAD_SHA",u?.current??a.last_commit_sha),p.push(Cr({...c,eventName:"pull_request",eventAction:"synchronize",compatKind:"derived",normalizedEventIdParts:["pull_request","synchronize",`mr-${a.iid}`,m],variables:e}))}const h=lr(d,"labels");if(h){const e=vr(h.previous,h.current,mr);for(const t of e.added){const n=l();n.AGENTRIX_LABEL_NAME=t,Er(n,e.current),Tr(n,"AGENTRIX_LABEL_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"labeled",compatKind:"exact",normalizedEventIdParts:["pull_request","labeled",`mr-${a.iid}`,`label-${t}`],variables:n}))}for(const t of e.removed){const n=l();n.AGENTRIX_LABEL_NAME=t,Er(n,e.current),Tr(n,"AGENTRIX_LABEL_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"unlabeled",compatKind:"exact",normalizedEventIdParts:["pull_request","unlabeled",`mr-${a.iid}`,`label-${t}`],variables:n}))}}const g=lr(d,"assignees");if(g){const e=vr(g.previous,g.current,gr);for(const t of e.added){const n=l();n.AGENTRIX_ASSIGNEE_LOGIN=t,Tr(n,"AGENTRIX_ASSIGNEE_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"assigned",compatKind:"exact",normalizedEventIdParts:["pull_request","assigned",`mr-${a.iid}`,`assignee-${t}`],variables:n}))}for(const t of e.removed){const n=l();n.AGENTRIX_ASSIGNEE_LOGIN=t,Tr(n,"AGENTRIX_ASSIGNEE_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"unassigned",compatKind:"exact",normalizedEventIdParts:["pull_request","unassigned",`mr-${a.iid}`,`assignee-${t}`],variables:n}))}}const f=lr(d,"reviewers");if(f){const e=vr(f.previous,f.current,gr);for(const t of e.added){const n=l();n.AGENTRIX_REQUESTED_REVIEWER_LOGIN=t,Tr(n,"AGENTRIX_REVIEWER_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"review_requested",compatKind:"exact",normalizedEventIdParts:["pull_request","review_requested",`mr-${a.iid}`,`reviewer-${t}`],variables:n}))}for(const t of e.removed){const n=l();n.AGENTRIX_REQUESTED_REVIEWER_LOGIN=t,Tr(n,"AGENTRIX_REVIEWER_CHANGES_JSON",e),p.push(Cr({...c,eventName:"pull_request",eventAction:"review_request_removed",compatKind:"exact",normalizedEventIdParts:["pull_request","review_request_removed",`mr-${a.iid}`,`reviewer-${t}`],variables:n}))}}const v=br(dr(d,["draft","work_in_progress"]));if(v){const e=v.current?"converted_to_draft":"ready_for_review";p.push(Cr({...c,eventName:"pull_request",eventAction:e,compatKind:"derived",normalizedEventIdParts:["pull_request",e,`mr-${a.iid}`],variables:l()}))}return wr(d,["title","description","target_branch"])&&p.push(Cr({...c,eventName:"pull_request",eventAction:"edited",compatKind:"exact",normalizedEventIdParts:["pull_request","edited",`mr-${a.iid}`],variables:l()})),p}(e,t,n);case"pipeline":return function(e,t,n){const s=Qo(t),a=nr(t);if(!s?.path_with_namespace||!a?.status||"trigger"===a.source)return[];const i=function(e){switch(e){case"created":case"pending":return{eventAction:"requested",workflowStatus:"pending"};case"running":return{eventAction:"in_progress",workflowStatus:e};case"success":return{eventAction:"completed",workflowStatus:"completed",conclusion:"success"};case"failed":return{eventAction:"completed",workflowStatus:"completed",conclusion:"failure"};case"canceled":case"cancelled":return{eventAction:"completed",workflowStatus:"completed",conclusion:"cancelled"};case"skipped":return{eventAction:"completed",workflowStatus:"completed",conclusion:"skipped"};default:return null}}(a.status);if(!i)return[];const o=n.ref||a.ref||s.default_branch;if(!o)throw{status:400,message:"Pipeline ref is required; pass ref or ensure GitLab payload includes object_attributes.ref or project.default_branch"};const r={AGENTRIX_WORKFLOW_RUN_STATUS:i.workflowStatus,AGENTRIX_PIPELINE_STATUS:a.status,AGENTRIX_REF:o};return Sr(r,"AGENTRIX_WORKFLOW_RUN_CONCLUSION",i.conclusion),Sr(r,"AGENTRIX_PIPELINE_SOURCE",a.source),Sr(r,"AGENTRIX_PIPELINE_ID",a.id),Sr(r,"AGENTRIX_PIPELINE_IID",a.iid),Sr(r,"AGENTRIX_SHA",a.sha),Sr(r,"AGENTRIX_PIPELINE_URL",function(e,t){return t.url?t.url:e.web_url&&"number"==typeof t.id?`${e.web_url}/-/pipelines/${t.id}`:void 0}(s,a)),Sr(r,"AGENTRIX_PR_NUMBER",function(e){const t=Vo(e.merge_request);return Jo(t?.iid)}(t)),[Cr({gitServerId:e,project:s,ref:o,eventName:"workflow_run",eventAction:i.eventAction,providerEventName:"pipeline",providerEventAction:a.status,compatKind:"derived",subjectKind:"workflow_run",changedKeys:[],normalizedEventIdParts:["workflow_run",i.eventAction,`pipeline-${a.id??a.iid??"unknown"}`],variables:r})]}(e,t,n);default:return[]}})(),n,s)}function Nr(e){const t=sr(e);if("note"===t){const t=tr(e);return!0===t?.system?"system_note":t?"unsupported_provider_specific_event":"missing_required_payload"}if("pipeline"===t){const t=nr(e);return"trigger"===t?.source?"pipeline_source_trigger_ignored":"unsupported_provider_specific_event"}if("issue"===t||"merge_request"===t){const n=Qo(e),s="issue"===t?Zo(e):er(e);return n?.path_with_namespace&&s?.iid?"unsupported_provider_specific_event":"missing_required_payload"}return"unsupported_provider_specific_event"}async function Rr({gitServerId:e,payload:t,config:n,pat:s}){const a=sr(t),i=$r(e,t,n);if(0===i.length)return{status:"ignored",eventType:a,reason:Nr(t),triggeredCount:0,failedCount:0,events:[]};if(!n.apiUrl)throw{status:400,message:"GitLab API URL is required"};const o=new ns(n.apiUrl,s,{gitServerId:e}),r=[];for(const t of i){const n=Date.now();if(or(e,t.normalizedEventId,n))r.push({status:"ignored",normalizedEventId:t.normalizedEventId,eventName:t.eventName,eventAction:t.eventAction,action:t.action,reason:"duplicate_delivery_event"});else try{const n=await o.executeOperation("triggerPipeline",t.operationPayload);rr(e,t.normalizedEventId,Date.now()),r.push({status:"triggered",normalizedEventId:t.normalizedEventId,eventName:t.eventName,eventAction:t.eventAction,action:t.action,pipeline:n})}catch(e){const n=ar(e);r.push({status:"failed",normalizedEventId:t.normalizedEventId,eventName:t.eventName,eventAction:t.eventAction,action:t.action,reason:"pipeline_trigger_failed",errorMessage:n.message,errorDetail:n.detail,upstreamStatus:n.upstreamStatus})}}const c=r.filter(e=>"failed"===e.status),l=r.filter(e=>"triggered"===e.status),d=r.filter(e=>"ignored"===e.status),p=r[0],u=c[0];return u?{status:"failed",eventType:a,eventName:p?.eventName,eventAction:p?.eventAction,action:p?.action,reason:u.reason,errorMessage:u.errorMessage,errorDetail:u.errorDetail,upstreamStatus:u.upstreamStatus,triggeredCount:l.length,failedCount:c.length,events:r}:0===l.length&&d.length>0?{status:"ignored",eventType:a,eventName:p?.eventName,eventAction:p?.eventAction,action:p?.action,reason:p?.reason,triggeredCount:0,failedCount:0,events:r}:{status:"triggered",eventType:a,eventName:p?.eventName,eventAction:p?.eventAction,action:p?.action,pipeline:1===r.length?p?.pipeline:void 0,triggeredCount:l.length,failedCount:0,events:r}}function Pr(e){return e.secret||e.token}function Mr(e,t){return Ee("sha256",t).update(e).digest("base64url")}function Dr(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&&Ae(n,s)}(s,Mr(n,Pr(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 Or=rt.object({repoRoot:rt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:rt.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 Ur(e,t){return{issueId:Or.parse(e).issueId}}const jr="agentrix_event_broker",Lr="/mcp/agentrix-event-broker",qr="change_title",Hr="publish_task_preview_url",Gr="send_vision_artifact";function Br(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:K(),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(`${Ce.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 Ur(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:K(),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 qt({name:"agentrix-event-broker",version:"1.0.0"});return t.registerTool(qr,{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:rt.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(Hr,{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:rt.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=ee.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(Gr,{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:rt.string().min(1).describe("Absolute repository root containing .agentrix/issues"),issueId:rt.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=Or.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:Dr(n.credentials,s),dispatcher:n.dispatcher}),i=new Ht({sessionIdGenerator:void 0});try{await a.connect(i),t.hijack(),await i.handleRequest(e.raw,t.raw,e.body)}catch(e){$e.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 Wr extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="MachineAesKeyUpdateError"}}function zr(e){if(!e)return null;try{const t=G(e);return 32===t.length?t:null}catch{return null}}function Kr(e){return!!zr(e.machineAesKey)}const Vr="agentrix-computer-use";function Xr(){const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return r(e)?{available:!0,path:e}:{available:!1,path:e};const t=pt("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 Jr(e,t){const s=t?.trim();if(s)return r(s)?{available:!0,path:s}:{available:!1,path:s};const a=pt("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[_(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 Yr(e){try{return p(e).isDirectory()}catch{return!1}}function Qr(e){return"boolean"==typeof e?e:void 0}function Zr(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function ec(e){return[_(e,"skills","cua-driver"),_(n.homedir(),".agents","skills","cua-driver")]}function tc(){const e=process.env.AGENTRIX_CUA_DRIVER_SKILL_SOURCE?.trim();if(e){const t=Zr(e);return r(_(t,"SKILL.md"))?t:null}const t=[_(n.homedir(),".agents","skills","cua-driver"),_(n.homedir(),".claude","skills","cua-driver"),_(n.homedir(),".openclaw","skills","cua-driver")].filter(e=>Boolean(e));for(const e of t){const t=N(Zr(e));if(r(_(t,"SKILL.md")))return t}return null}function nc(e=Ce.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()):_(n.homedir(),".codex")}(),s=_(Ce.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=Xr(),o=Jr("cua-driver",process.env.AGENTRIX_CUA_DRIVER_PATH),l=_(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);_(t,"skills","cua-driver");const m=null!==function(e){for(const t of ec(e))if(Yr(t)&&r(_(t,"SKILL.md")))return t;return null}(t),h=tc()??void 0,g=function(e){if(!e||"darwin"!==process.platform)return{};const t=pt(e,["doctor","--json"],{encoding:"utf8",timeout:1e4});try{const e=JSON.parse(t.stdout);return{accessibilityGranted:Qr(e.ax_granted),screenRecordingGranted:Qr(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 ${ec(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 sc(e){const t=Jr("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=Xr();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=pt(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=pt(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 ac(e){const t=tc(),n=_(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(_(n,"SKILL.md")))return null;try{return y(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(P(n),{recursive:!0}),b(t,n,"dir"),null}catch(e){return`Failed to create Cua Driver skill symlink ${n} -> ${t}: ${e instanceof Error?e.message:String(e)}`}}function ic(e){try{return(r(e)||y(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 oc(e){try{return y(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 rc(e){try{if(!y(e).isSymbolicLink())return null;const t=w(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 cc(){const e=nc(),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=Ce.readSettings()??{};return Ce.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&&(pt(a,["stop"],{encoding:"utf8",timeout:1e4}),t.push("Stopped Cua Driver daemon if it was running."));const i=["/Applications/CuaDriver.app","/Applications/CuaDriverRs.app",_(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_updater.plist"),_(n.homedir(),"Library","LaunchAgents","com.trycua.cua_driver_daemon.plist"),_(n.homedir(),"Library","LaunchAgents","com.trycua.cua-driver-rs.plist"),_(n.homedir(),"Library","Application Support","Cua Driver"),_(n.homedir(),"Library","Caches","cua-driver"),_(n.homedir(),".cua-driver-rs")];for(const e of i){const n=ic(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const e of[_(n.homedir(),".local","bin","cua-driver"),"/usr/local/bin/cua-driver"]){const n=oc(e);n?s.push(n):t.push(`Removed ${e}.`)}for(const a of[_(e.codexHome,"skills","cua-driver"),_(n.homedir(),".agents","skills","cua-driver")]){const e=rc(a);e?s.push(e):t.push(`Removed ${a}.`)}const o=function(e){const t=_(e,"config.toml");try{const n=Xr();if(n.available&&n.path&&pt(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=nc();"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 lc(e=Ce.readSettings(),t){const n=nc(e);if(!n.enabled)return n;const s=[];if(!n.cuaDriverMcpConfigured){t?.("info","COMPUTER_USE","Configuring Cua Driver MCP for Codex");const e=sc(n.codexHome);e&&s.push(e)}if(!n.cuaDriverSkillPresent){t?.("info","COMPUTER_USE","Configuring Cua Driver skill for Codex");const e=ac(n.codexHome);e&&s.push(e)}const a=nc(e);return 0===s.length?a:{...a,missing:[...a.missing,...s.map(e=>`Automatic Cua Driver configuration failed: ${e}`)]}}function dc(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 pc(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 uc(e,t,n){const s=await Tt(n.apiUrl,n.pat,{log:{warn:(e,t)=>$e.warn(e,t),error:(e,t)=>$e.warn(e,t)}});if(!s.result.valid||!s.user)throw new Error(s.result.error||`PAT validation failed for ${n.apiUrl}/user`);const a=await po();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:K(),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){lo.saveGitServerConfig(e,t)}(o.id,{baseUrl:o.baseUrl,apiUrl:o.apiUrl}),function(e,t,n){lo.savePat(e,t,n)}(o.id,n.pat,a),c=o.id,l=r,lo.savePatMeta(c,l);const d=function(e,t){return lo.ensureGitLabWebhookSecret(e,t)}(o.id,a);return{success:!0,gitServer:o,machineId:i.machineId,proxyRegistered:i.proxyRegistered,webhookEndpointPath:At(o.id),webhookUrl:Et(o.id,await Ce.readDaemonState()),patConfigured:!0,patMeta:r,webhookSecret:d}}function mc(e,t){const n=[],s=g(e,{withFileTypes:!0});for(const a of s){if(".gitkeep"===a.name)continue;const s=_(e,a.name),i=p(s),o=M(t,s);n.push({name:a.name,path:o,size:i.size,modifiedAt:i.mtimeMs,isDirectory:a.isDirectory()}),a.isDirectory()&&n.push(...mc(s,t))}return n}function hc(){return _(Ce.agentrixAgentsHomeDir,"companion","claude")}function gc(e,t){const n=O(_(e,t));return n.startsWith(e)?{absolutePath:n,relativePath:M(e,n)}:null}function fc(e,t,n){const s=_(e,"memory-changes"),a=_(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 vc(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 yc(e,t){if(!r(_(e,".git")))return"";try{return gt("git",["-C",e,...t],{encoding:"utf8",timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return""}}function bc(e,t,n){const s=n.replace(/[^0-9a-f]/gi,"");return s?yc(e,["show","--format=","--no-ext-diff",s,"--",t]):""}function wc(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=wc(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=wc(n);if(e)return e}}return""}function xc(e){if("string"==typeof e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{const e=wc(JSON.parse(t));if(e)return e}catch{}return e}if(!e||"object"!=typeof e)return"";const t=wc(e);if(t)return t;const n=e.content;return"string"==typeof n?xc(n):Array.isArray(n)?n.map(e=>xc(e)).filter(Boolean).join("\n"):""}function kc(e,t){return xc(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 Ec(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=no({dataDir:Ce.resolveDataDir(e,t),taskId:t});try{return[...s.pageRecentMessages(50).data].reverse().filter(e=>"system"!==e.senderType&&xc(e.message).trim()).slice(0,n).map(e=>({summary:kc(xc(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 Cc(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 qc(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,"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=kc(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 Nc(e,t){const n=[],s=no({dataDir:Ce.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?Ec(i):"";o&&(n.push({time:a.createdAt,summary:kc(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(...Nc(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=no({dataDir:Ce.resolveDataDir(s,e),taskId:e});try{for(const e of a.pageRecentMessages(160).data){if("agent"!==e.senderType)continue;const s=xc(e.message);if(!s.trim())continue;if(!n&&!r.some(e=>s.toLowerCase().includes(e.toLowerCase())))continue;const a=kc(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 Mc(e){return"127.0.0.1"===e||"::1"===e||"::ffff:127.0.0.1"===e}const Dc=rt.object({id:rt.string(),type:rt.string(),name:rt.string(),baseUrl:rt.string(),apiUrl:rt.string(),oauthServerId:rt.string().nullable().optional(),ownerId:rt.string().nullable().optional(),authModeDefault:rt.string().optional(),executionMode:rt.string().optional(),syncMode:rt.string().optional(),networkMode:rt.string().optional(),githubAppName:rt.string().nullable().optional(),enabled:rt.boolean().optional(),createdAt:rt.string().optional(),updatedAt:rt.string().optional()}).passthrough(),Oc=rt.object({platform:rt.string(),enabled:rt.boolean(),enabledBy:rt.enum(["env","settings","marker"]).nullable(),codexHome:rt.string(),codexAvailable:rt.boolean(),codexPath:rt.string().optional(),codexConfigPresent:rt.boolean(),cuaDriverAvailable:rt.boolean(),cuaDriverPath:rt.string().optional(),cuaDriverAccessibilityGranted:rt.boolean().optional(),cuaDriverScreenRecordingGranted:rt.boolean().optional(),cuaDriverMcpConfigured:rt.boolean(),cuaDriverSkillPresent:rt.boolean(),cuaDriverSkillSource:rt.string().optional(),markerPath:rt.string(),missing:rt.array(rt.string())});async function Uc(e,t,n){let s;try{return await Promise.race([e,new Promise((e,a)=>{s=setTimeout(()=>a(new Error(n)),t)})])}finally{s&&clearTimeout(s)}}function jc(e){return Array.isArray(e)?e[0]:e}function Lc(e){return e instanceof Error?e.message:"Unknown error"}async function qc(e,t,n,s,a=15e3){if(!e?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:K(),method:t,path:n,body:s},o=await Uc(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 Hc(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 v=Ce.getDaemonControlHost(),y=Ce.getDaemonWebhookHost(),b=ot({logger:!1});b.removeContentTypeParser("application/json"),b.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,{})}),b.setValidatorCompiler(lt),b.setSerializerCompiler(dt);const w=b.withTypeProvider();!function(e,t){const n=t.getSocketClient??(()=>{}),s={credentials:t.credentials,getSocketClient:n,dispatcher:t.dispatcher??Br(t.credentials,n)};e.post(Lr,async(e,t)=>{try{await Fr(e,t,s)}catch(e){const n=e instanceof Error?e.message:"Unauthorized Agentrix event MCP request";return $e.warn(`[EVENT MCP] ${n}`),t.status(401).send({jsonrpc:"2.0",error:{code:-32001,message:n},id:null})}}),e.get(Lr,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null})),e.delete(Lr,async(e,t)=>t.status(405).send({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}(b,{credentials:l,getSocketClient:m});const x=e=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),e.header("Access-Control-Allow-Private-Network","true")};w.post("/session-started",{schema:{body:rt.object({sessionId:rt.string(),metadata:rt.any()}),response:{200:rt.object({status:rt.literal("ok")})}}},async e=>{const{sessionId:t,metadata:n}=e.body;return $e.debug(`[CONTROL SERVER] Session started: ${t}`),o(t,n),{status:"ok"}}),w.post("/devops-init-complete",{schema:{body:rt.object({taskId:rt.string(),userId:rt.string(),action:rt.enum(["continue","stop"])}),response:{200:rt.object({status:rt.literal("ok")})}}},async e=>{const{taskId:t,userId:n,action:s}=e.body;return $e.info(`[CONTROL SERVER] Agentrix DevOps init complete for task ${t}, action=${s}`),a?.({taskId:t,userId:n,action:s}),{status:"ok"}}),w.post("/devops-init-start",{schema:{body:rt.object({taskId:rt.string(),userId:rt.string()}),response:{200:rt.object({status:rt.literal("ok")})}}},async e=>{const{taskId:t,userId:n}=e.body;return $e.info(`[CONTROL SERVER] Starting Agentrix DevOps init for existing task ${t}`),s?.({taskId:t,userId:n}),{status:"ok"}}),w.post("/prepare-graceful-restart",{schema:{body:rt.object({source:rt.string().optional(),reason:rt.string().optional()}).optional(),response:{200:rt.object({state:rt.enum(["pending_restart","restarting"]),activeSessions:rt.number()}),503:rt.object({error:rt.string()}),403:rt.object({error:rt.string()})}}},async(e,t)=>Mc(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"})),w.post("/clear-graceful-restart-gate",{schema:{response:{200:rt.object({success:rt.literal(!0)}),403:rt.object({error:rt.string()})}}},async(e,t)=>Mc(e.ip)?(g?.(),{success:!0}):t.code(403).send({error:"Graceful restart control is only allowed from loopback"})),w.options("/ping",async(e,t)=>(x(t),t.send())),w.get("/ping",{schema:{response:{200:rt.object({status:rt.literal("ok"),machineId:rt.string(),timestamp:rt.string(),controlHost:rt.string(),webhookHost:rt.string(),hasMachineAesKey:rt.boolean()})}}},async(e,t)=>(x(t),{status:"ok",machineId:l.machineId,timestamp:(new Date).toISOString(),controlHost:v,webhookHost:y,hasMachineAesKey:Kr(l)})),w.get("/computer-use/status",{schema:{response:{200:rt.object({status:Oc}),403:rt.object({error:rt.string()})}}},async(e,t)=>Mc(e.ip)?{status:nc()}:t.code(403).send({error:"Computer Use status is only allowed from loopback"})),w.post("/computer-use/install",{schema:{response:{200:rt.object({success:rt.boolean(),status:Oc,actions:rt.array(rt.string()),error:rt.string().optional()}),403:rt.object({error:rt.string()})}}},async(e,t)=>{if(!Mc(e.ip))return t.code(403).send({error:"Computer Use installation is only allowed from loopback"});try{return function(){let e=nc();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=pt(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=sc(e.codexHome);s?n.push(s):t.push("Configured Cua Driver MCP for Agentrix Computer Use.")}if(e=nc(),e.cuaDriverSkillPresent)t.push("Cua Driver skill is already available to Agentrix Computer Use.");else{const s=ac(e.codexHome);s?n.push(s):t.push("Linked Cua Driver skill for Agentrix Computer Use.")}const s=function(e){try{return d(P(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=Ce.readSettings()??{};return Ce.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=nc(),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:nc(),actions:[],error:Lc(e)}}}),w.post("/computer-use/uninstall",{schema:{response:{200:rt.object({success:rt.boolean(),status:Oc,actions:rt.array(rt.string()),error:rt.string().optional()}),403:rt.object({error:rt.string()})}}},async(e,t)=>{if(!Mc(e.ip))return t.code(403).send({error:"Computer Use uninstall is only allowed from loopback"});try{return cc()}catch(e){return{success:!1,status:nc(),actions:[],error:Lc(e)}}}),w.post("/machine/aes-key",{schema:{body:rt.object({machineId:rt.string(),machineAesKey:rt.string()}),response:{200:rt.object({success:rt.literal(!0),updated:rt.boolean(),hasMachineAesKey:rt.literal(!0)}),400:rt.object({error:rt.string()}),403:rt.object({error:rt.string()}),409:rt.object({error:rt.string()}),500:rt.object({error:rt.string()})}}},async(e,t)=>{if(!Mc(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=Ce){if(t.machineId!==e.machineId)throw new Wr("machineId does not match daemon credentials",409);if(!zr(t.machineAesKey))throw new Wr("machineAesKey must decode to a 32-byte key",400);const s=await n.readCredentials()??e;if(s.machineId!==e.machineId)throw new Wr("stored credentials machineId does not match daemon credentials",409);if(Kr(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 $e.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 Wr?e.statusCode:500,s=400===n||409===n?n:500,a=e instanceof Error?e.message:"Failed to store machine AES key";return $e.warn(`[CONTROL SERVER] Failed to store recovered machine AES key: ${a}`),t.code(s).send({error:a})}}),w.options("/openers",async(e,t)=>(x(t),t.send())),w.get("/openers",{schema:{response:{200:rt.object({openers:rt.array(rt.object({id:rt.string(),label:rt.string(),kind:rt.enum(["system","file-manager","terminal","editor","ide"]),method:rt.enum(["scheme","cli"]),urlTemplate:rt.string().optional(),supported:rt.boolean()}))})}}},async(e,t)=>(x(t),{openers:await js()})),w.options("/open",async(e,t)=>(x(t),t.send())),w.options("/pick-directory",async(e,t)=>(x(t),t.send())),w.post("/open",{schema:{body:rt.object({path:rt.string(),openerId:rt.string(),userId:rt.string().optional(),taskId:rt.string().optional()}),response:{200:rt.object({success:rt.boolean(),error:rt.string().optional()})}}},async(e,t)=>{x(t);const{path:n,openerId:s,userId:a,taskId:i}=e.body;return await async function({openerId:e,targetPath:t,userId:n,taskId:s}){const a=qs(Fs()).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=Ce.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 $e.warn(`[OPENERS] Failed to open path: ${t}`),{success:!1,error:t}}}({openerId:s,targetPath:n,userId:a,taskId:i})}),w.post("/pick-directory",{schema:{body:rt.object({defaultPath:rt.string().optional()}),response:{200:rt.object({path:rt.string().nullable(),error:rt.string().optional()})}}},async(e,t)=>{x(t);try{return{path:Ls(e.body.defaultPath)??null}}catch(e){return{path:null,error:e instanceof Error?e.message:"Failed to pick directory"}}}),w.post("/companion/ensure",{schema:{body:rt.object({preferredLanguage:rt.enum(["en","zh-Hans"]).nullable().optional()}).optional(),response:{200:rt.object({agentDir:rt.string()})}}},async e=>await eo({preferredLanguage:e.body?.preferredLanguage,credentials:l})),w.post("/companion/probe",{schema:{response:{200:rt.object({success:rt.boolean(),error:rt.string().optional()})}}},async()=>await ri()),w.get("/companion/workspace/status",{schema:{response:{200:rt.object({exists:rt.boolean()})}}},async()=>{const e=hc();return{exists:r(e)}}),w.get("/companion/workspace",{schema:{response:{200:rt.object({files:rt.array(rt.object({name:rt.string(),path:rt.string(),size:rt.number(),modifiedAt:rt.number(),isDirectory:rt.boolean()}))})}}},async()=>{const e=hc();return r(e)?{files:mc(e,e)}:{files:[]}}),w.get("/companion/file",{schema:{querystring:rt.object({path:rt.string()}),response:{200:rt.object({content:rt.string()}),404:rt.object({error:rt.string()})}}},async(e,t)=>{const n=hc(),s=O(_(n,e.query.path));return s.startsWith(n)&&r(s)?{content:c(s,"utf-8")}:t.code(404).send({error:"File not found"})}),w.put("/companion/file",{schema:{body:rt.object({path:rt.string(),content:rt.string()}),response:{200:rt.object({success:rt.boolean()}),400:rt.object({error:rt.string()})}}},async(e,t)=>{const n=hc(),s=O(_(n,e.body.path));return s.startsWith(n)?(d(P(s),{recursive:!0}),u(s,e.body.content,"utf-8"),{success:!0}):t.code(400).send({error:"Invalid path"})}),w.get("/companion/file/versions",{schema:{querystring:rt.object({path:rt.string(),limit:rt.coerce.number().int().positive().max(50).optional(),skip:rt.coerce.number().int().min(0).optional()}),response:{200:rt.object({versions:rt.array(rt.object({commit:rt.string(),shortCommit:rt.string(),subject:rt.string(),body:rt.string(),authoredAt:rt.string()})),hasMore:rt.boolean(),nextSkip:rt.number()}),404:rt.object({error:rt.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=yc(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"})}),w.get("/companion/file/diff",{schema:{querystring:rt.object({path:rt.string(),commit:rt.string()}),response:{200:rt.object({commit:rt.string(),path:rt.string(),diff:rt.string()}),404:rt.object({error:rt.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:bc(n,s.relativePath,e.query.commit)}:t.code(404).send({error:"File not found"})}),w.get("/companion/memory-events",{schema:{querystring:rt.object({after:rt.string().optional(),date:rt.string().optional()}),response:{200:rt.object({after:rt.string().optional(),date:rt.string().optional(),nextAfter:rt.string(),events:rt.array(rt.object({id:rt.string(),createdAt:rt.union([rt.string(),rt.number()]),title:rt.string(),summary:rt.string(),files:rt.array(rt.string()),actions:rt.array(rt.string()).optional(),source:rt.string().optional(),trigger:rt.string().optional(),commit:rt.string().optional()})),hasMore:rt.boolean()}),400:rt.object({error:rt.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 vc(n,e.query)||t.code(400).send({error:"Invalid after or date"})}),w.get("/companion/recent-activity",{schema:{querystring:rt.object({limit:rt.coerce.number().int().positive().max(50).optional()}),response:{200:rt.object({chats:rt.array(rt.object({type:rt.literal("chat"),title:rt.string(),summary:rt.string(),time:rt.string(),status:rt.string().optional()})),tasks:rt.array(rt.object({type:rt.literal("task"),title:rt.string(),summary:rt.string(),time:rt.string(),status:rt.string().optional()})),memories:rt.array(rt.object({type:rt.literal("memory"),title:rt.string(),summary:rt.string(),time:rt.string(),status:rt.string().optional()}))})}}},async e=>{const t=hc(),n=e.query.limit??1,s=_(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([Cc(a,m?.(),n),Promise.resolve(_c(a,n)),Promise.resolve($c(t,n))]);return{chats:o,tasks:i,memories:l}}),w.get("/companion/config",{schema:{querystring:rt.object({recentLimit:rt.coerce.number().int().positive().max(50).optional()}),response:{200:rt.object({heartbeatIntervalMs:rt.number(),heartbeatEnabled:rt.boolean(),lastHeartbeatTimestamp:rt.string().nullable(),lastHeartbeatDate:rt.string().nullable(),lastMaintenanceHeartbeatTimestamp:rt.string().nullable(),heartbeatTriggerCount:rt.number(),lastInteractionTimestamp:rt.string().nullable(),memoryOrganizationEnabled:rt.boolean(),memoryOrganizationIntervalHours:rt.number(),allowedMemoryOrganizationIntervalHours:rt.array(rt.number()),lastMemoryOrganizationTimestamp:rt.string().nullable(),memoryOrganizationTaskId:rt.string().nullable(),heartbeatRecentRecords:rt.array(rt.object({time:rt.string(),summary:rt.string(),updated:rt.boolean()})),memoryOrganizationRecentRecords:rt.array(rt.object({time:rt.string(),summary:rt.string(),updated:rt.boolean()}))})}}},async e=>{const t=hc(),n=e.query.recentLimit??1,s=_(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,v={};if(r(s))try{v=JSON.parse(c(s,"utf-8")),"number"==typeof v.heartbeatIntervalMs&&(a=v.heartbeatIntervalMs),"boolean"==typeof v.heartbeatEnabled&&(i=v.heartbeatEnabled),"string"==typeof v.lastHeartbeatTimestamp&&(o=v.lastHeartbeatTimestamp),"string"==typeof v.lastHeartbeatDate&&(l=v.lastHeartbeatDate),"string"==typeof v.lastMaintenanceHeartbeatTimestamp&&(d=v.lastMaintenanceHeartbeatTimestamp),"number"==typeof v.heartbeatTriggerCount&&(p=v.heartbeatTriggerCount),"string"==typeof v.lastInteractionTimestamp&&(u=v.lastInteractionTimestamp),"boolean"==typeof v.memoryOrganizationEnabled&&(m=v.memoryOrganizationEnabled),h=ro(v.memoryOrganizationIntervalHours),"string"==typeof v.lastMemoryOrganizationTimestamp&&(g=v.lastMemoryOrganizationTimestamp),"string"==typeof v.memoryOrganizationTaskId&&(f=v.memoryOrganizationTaskId)}catch{}const y=Rc(v,"heartbeat",n),b=Rc(v,"memory-organization",n);return{heartbeatIntervalMs:a,heartbeatEnabled:i,lastHeartbeatTimestamp:o,lastHeartbeatDate:l,lastMaintenanceHeartbeatTimestamp:d,heartbeatTriggerCount:p,lastInteractionTimestamp:u,memoryOrganizationEnabled:m,memoryOrganizationIntervalHours:h,allowedMemoryOrganizationIntervalHours:[...io],lastMemoryOrganizationTimestamp:g,memoryOrganizationTaskId:f,heartbeatRecentRecords:y,memoryOrganizationRecentRecords:b}}),w.put("/companion/config",{schema:{body:rt.object({heartbeatIntervalMs:rt.number().optional(),heartbeatEnabled:rt.boolean().optional(),memoryOrganizationEnabled:rt.boolean().optional(),memoryOrganizationIntervalHours:rt.number().optional()}),response:{200:rt.object({success:rt.boolean()}),400:rt.object({error:rt.string()})}}},async(t,n)=>{const s=hc(),a=_(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(!oo(m))return n.code(400).send({error:`memoryOrganizationIntervalHours must be one of: ${io.join(", ")}`});i.memoryOrganizationIntervalHours=m}return d(P(a),{recursive:!0}),u(a,JSON.stringify(i,null,2),"utf-8"),e.companionScheduler?.reloadStateAndReschedule(),{success:!0}}),w.post("/agent/install",{schema:{body:rt.object({agentId:rt.string(),gitUrl:rt.string(),branch:rt.string().optional(),subDir:rt.string().optional()}),response:{200:rt.object({agentDir:rt.string()}),500:rt.object({error:rt.string()})}}},async(e,t)=>{try{return await ia(e.body)}catch(e){const n=e instanceof Error?e.message:String(e);return t.code(500).send({error:n})}}),w.post("/git-server/bind",{schema:{body:rt.object({name:rt.string().min(1),baseUrl:rt.string().url(),apiUrl:rt.string().url(),pat:rt.string().min(1),useAsProxy:rt.boolean().optional().default(!0)}),response:{200:rt.object({success:rt.literal(!0),gitServer:Dc,machineId:rt.string(),proxyRegistered:rt.boolean(),webhookEndpointPath:rt.string(),webhookUrl:rt.string().optional(),patConfigured:rt.literal(!0),patMeta:rt.object({username:rt.string(),email:rt.string(),lastValidatedAt:rt.string(),expiresAt:rt.string().nullable().optional()}),webhookSecret:rt.string()}),502:rt.object({error:rt.string()})}}},async(e,t)=>{try{const n=m?.();if(!n)throw new Error("Machine WebSocket is not connected");const s=await uc(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=Lc(n);return $e.warn(`[GIT SERVER] bind failed: baseUrl=${e.body.baseUrl}, message=${s}`),t.code(502).send({error:s})}}),w.post("/git-server/list",{schema:{response:{200:rt.object({gitServers:rt.array(Dc)}),502:rt.object({error:rt.string()})}}},async(e,t)=>{try{const e=await qc(m?.(),"POST","/v1/git-servers/machine-list",{machineId:l.machineId});return t.send({gitServers:Array.isArray(e)?e:[]})}catch(e){const n=Lc(e);return $e.warn(`[GIT SERVER] list failed: message=${n}`),t.code(502).send({error:n})}}),w.post("/git-server/delete",{schema:{body:rt.object({gitServerId:rt.string().min(1)}),response:{200:rt.object({success:rt.boolean(),machineId:rt.string()}),502:rt.object({error:rt.string()})}}},async(e,t)=>{try{const n=await qc(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=Lc(n);return $e.warn(`[GIT SERVER] delete failed: gitServerId=${e.body.gitServerId}, message=${s}`),t.code(502).send({error:s})}}),w.post("/webhooks/gitlab/:gitServerId",{schema:{params:rt.object({gitServerId:rt.string()}),body:rt.record(rt.string(),rt.unknown()),response:{200:rt.object({status:rt.enum(["triggered","ignored","failed"]),eventType:rt.string(),eventName:rt.string().optional(),eventAction:rt.string().optional(),action:rt.string().optional(),pipeline:rt.unknown().optional(),reason:rt.string().optional(),errorMessage:rt.string().optional(),errorDetail:rt.string().optional(),upstreamStatus:rt.number().optional(),triggeredCount:rt.number().optional(),failedCount:rt.number().optional(),events:rt.array(rt.object({status:rt.enum(["triggered","failed","ignored"]),normalizedEventId:rt.string(),eventName:rt.string(),eventAction:rt.string(),action:rt.string(),pipeline:rt.unknown().optional(),reason:rt.string().optional(),errorMessage:rt.string().optional(),errorDetail:rt.string().optional(),upstreamStatus:rt.number().optional()})).optional()}),400:rt.object({error:rt.string()}),401:rt.object({error:rt.string()}),403:rt.object({error:rt.string()}),404:rt.object({error:rt.string()}),502:rt.object({error:rt.string()}),500:rt.object({error:rt.string()})}}},async(e,t)=>{const n=ke(),s=Date.now(),a=function(e){const t=e.event_type??e.object_kind;return"string"==typeof t?t:"unknown"}(e.body),i=function(e){const t=function(e){const t=Qo(e);return t?.id?String(t.id):t?.path_with_namespace??null}(e);if(!t)return null;try{return $r("__probe__",e,{ref:"__probe__"}).length>0?t:null}catch{return t}}(e.body),o=e.ip||"-",r="string"==typeof e.headers["user-agent"]?e.headers["user-agent"]:"-",c=(a,i)=>{const o=Date.now()-s,r=function(e){if(!e||"object"!=typeof e)return"type="+typeof e;const t=e;if("string"==typeof t.error)return`error=${t.error}`;const n=String(t.status??"-"),s=String(t.eventType??"-"),a=String(t.eventName??"-"),i=String(t.action??"-"),o=String(t.reason??"-"),r=String(t.upstreamStatus??"-"),c=String(t.errorMessage??"-"),l=String(t.triggeredCount??"-"),d=String(t.failedCount??"-"),p=function(e){if(!e||"object"!=typeof e)return"-";const t=e,n=t.id??t.iid??"-",s=t.status??"-",a=t.ref??"-",i=t.web_url??t.webUrl??"-";return`id=${String(n)}, status=${String(s)}, ref=${String(a)}, webUrl=${String(i)}`}(t.pipeline);return`status=${n}, eventType=${s}, eventName=${a}, action=${i}, reason=${o}, triggeredCount=${l}, failedCount=${d}, upstreamStatus=${r}, errorMessage=${c}, pipeline=${p}`}(i);return $e[a>=400?"warn":"info"](`[GITLAB WEBHOOK] response: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, elapsedMs=${o}, ${r}`),t.code(a).send(i)};$e.info(`[GITLAB WEBHOOK] request received: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}, remote=${o}, userAgent=${r}`);const l=await po();if(!l)return c(500,{error:"Git server encryption key not available"});const d=mo(e.params.gitServerId,l),p=d?.webhookSecret;if(!p)return c(403,{error:`GitLab webhook bridge is not configured for git server ${e.params.gitServerId}`});if(!function(e,t){if("string"!=typeof e)return!1;const n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&Ae(n,s)}(e.headers["x-gitlab-token"],p))return c(401,{error:"Invalid GitLab webhook token"});const u=kr(e.body,jc((h=e.headers)["webhook-id"])??jc(h["idempotency-key"])??jc(h["x-gitlab-webhook-uuid"])??jc(h["x-gitlab-event-uuid"])??jc(h["x-gitlab-delivery"]));var h;const g=a;if(async function(e,t,n,s,a){if(!a?.connected)throw new Error("Machine WebSocket is not connected");const i={eventId:K(),provider:"gitlab",gitServerId:e,deliveryId:n,eventType:s,payload:t},o=await Uc(a.sendWithAck("repository-inbox-webhook",i),5e3,"Timed out waiting for repository inbox webhook ack");if("success"!==o.status)throw new Error(o.message||"API failed to process repository inbox webhook")}(e.params.gitServerId,e.body,u,g,m?.()).catch(t=>{const s=t instanceof Error?t.message:String(t);$e.warn(`[GITLAB WEBHOOK] inbox side-channel failed: hookId=${n}, gitServer=${e.params.gitServerId}, message=${s}`)}),!i)return c(200,await Rr({gitServerId:e.params.gitServerId,payload:e.body,pat:"",config:{deliveryId:u}}));const f=go(e.params.gitServerId,l);if(!f)return c(403,{error:`No PAT configured for git server ${e.params.gitServerId}`});try{const t=uo(e.params.gitServerId),s=t?.apiUrl;if(!s)return c(400,{error:`GitLab API URL is not configured for git server ${e.params.gitServerId}`});let o;if(i)if(o=d.projectTriggerTokens?.[i],o)$e.info(`[GITLAB WEBHOOK] pipeline trigger token reused: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`);else{const t=function(e){const t=Qo(e);return t?.path_with_namespace?t.id?{projectId:t.id}:{projectPath:t.path_with_namespace}:null}(e.body);if(!t)return c(400,{error:"GitLab webhook payload is missing project information"});$e.info(`[GITLAB WEBHOOK] ensuring pipeline trigger token: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}, mode=create_or_reuse`);const a=new ns(s,f,{gitServerId:e.params.gitServerId}),r=await a.executeOperation("ensurePipelineTriggerToken",t);if(!r||"object"!=typeof r||"string"!=typeof r.token)return c(502,{error:"Failed to create GitLab pipeline trigger token"});o=r.token,function(e,t,n){lo.saveGitLabWebhookBridgeSecrets(e,t,n)}(e.params.gitServerId,{webhookSecret:p,projectTriggerTokens:{...d.projectTriggerTokens??{},[i]:o}},l),$e.info(`[GITLAB WEBHOOK] pipeline trigger token stored: hookId=${n}, gitServer=${e.params.gitServerId}, projectKey=${i}`)}return $e.info(`[GITLAB WEBHOOK] triggering pipeline: hookId=${n}, gitServer=${e.params.gitServerId}, eventType=${a}, projectKey=${i??"-"}`),c(200,await Rr({gitServerId:e.params.gitServerId,payload:e.body,pat:f,config:{apiUrl:s,triggerToken:o,deliveryId:u}}))}catch(t){const s=t,a="number"==typeof s.status&&s.status>=400&&s.status<600?s.status:500,i="string"==typeof s.message?s.message:t instanceof Error?t.message:"Failed to process GitLab webhook";return $e.warn(`[GITLAB WEBHOOK] failed: hookId=${n}, gitServer=${e.params.gitServerId}, statusCode=${a}, message=${i}`),c(a,{error:i})}}),w.post("/schedule",{schema:{body:rt.object({task:rt.string(),type:rt.enum(["once","recurring"]),due:rt.string().optional(),cron:rt.string().optional(),timezone:rt.string().optional(),timeType:rt.enum(["utc","local"]).optional()}),response:{200:rt.object({id:rt.string(),task:rt.string(),type:rt.enum(["once","recurring"]),due:rt.string().optional(),cron:rt.string().optional(),timezone:rt.string().optional(),timeType:rt.enum(["utc","local"]).optional(),createdAt:rt.string()}),400:rt.object({error:rt.string()}),503:rt.object({error:rt.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'})}),w.get("/schedule",{schema:{response:{200:rt.object({tasks:rt.array(rt.object({id:rt.string(),task:rt.string(),type:rt.enum(["once","recurring"]),due:rt.string().optional(),cron:rt.string().optional(),timezone:rt.string().optional(),timeType:rt.enum(["utc","local"]).optional(),createdAt:rt.string()}))}),503:rt.object({error:rt.string()})}}},async(t,n)=>{const s=e.companionScheduler;return s?{tasks:s.listScheduledTasks()}:n.code(503).send({error:"Companion scheduler not available"})}),w.delete("/schedule/:id",{schema:{params:rt.object({id:rt.string()}),response:{200:rt.object({success:rt.boolean()}),404:rt.object({error:rt.string()}),503:rt.object({error:rt.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 k=t=>e.channelManager||(t.code(503).send({error:"Channel manager not available"}),null);w.options("/channels",async(e,t)=>(x(t),t.send())),w.options("/channels/platforms",async(e,t)=>(x(t),t.send())),w.options("/channels/wechat/login/qrcode",async(e,t)=>(x(t),t.send())),w.options("/channels/wechat/login/qrcode/:qrcode/status",async(e,t)=>(x(t),t.send())),w.options("/channels/:id",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/connect",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/disconnect",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/contacts",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/bindings",async(e,t)=>(x(t),t.send())),w.options("/channels/:id/bindings/:bindingId",async(e,t)=>(x(t),t.send())),w.options("/channels/task-message",async(e,t)=>(x(t),t.send())),w.options("/channels/group-history",async(e,t)=>(x(t),t.send())),w.get("/channels",{schema:{response:{200:rt.object({channels:rt.array(qo)}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return{channels:n.getChannels()}}),w.get("/channels/platforms",{schema:{response:{200:rt.object({platforms:rt.array(rt.enum(Do))})}}},async(e,t)=>(x(t),{platforms:[...Do]})),w.get("/channels/wechat/login/qrcode",{schema:{response:{200:rt.object({qrcode:rt.string(),qrcodeContent:rt.string(),qrcodeTerminal:rt.string(),baseUrl:rt.string()}),502:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);try{return await Mo.createLoginQRCode()}catch(e){const n=e instanceof Error?e.message:String(e);return $e.warn(`[CHANNEL][WECHAT] Failed to create login QR code: ${n}`),t.code(502).send({error:n})}}),w.get("/channels/wechat/login/qrcode/:qrcode/status",{schema:{params:rt.object({qrcode:rt.string()}),response:{200:rt.object({status:rt.string(),token:rt.string().optional(),baseUrl:rt.string().optional(),ilinkBotId:rt.string().optional(),ilinkUserId:rt.string().optional()}),502:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);try{return await Mo.getLoginStatus(e.params.qrcode)}catch(e){const n=e instanceof Error?e.message:String(e);return $e.warn(`[CHANNEL][WECHAT] Failed to get login QR status: ${n}`),t.code(502).send({error:n})}}),w.post("/channels",{schema:{body:Ho,response:{200:qo,503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return n.addChannel(e.body)}),w.delete("/channels/:id",{schema:{params:rt.object({id:rt.string()}),response:{200:rt.object({success:rt.boolean()}),404:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(t);if(n)return await n.removeChannel(e.params.id)?{success:!0}:t.code(404).send({error:`Channel ${e.params.id} not found`})}),w.post("/channels/:id/connect",{schema:{params:rt.object({id:rt.string()}),response:{200:qo,404:rt.object({error:rt.string()}),500:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/:id/disconnect",{schema:{params:rt.object({id:rt.string()}),response:{200:qo,404:rt.object({error:rt.string()}),500:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.get("/channels/:id/contacts",{schema:{params:rt.object({id:rt.string()}),response:{200:rt.object({contacts:rt.array(Bo)}),404:rt.object({error:rt.string()}),500:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.get("/channels/:id/bindings",{schema:{params:rt.object({id:rt.string()}),response:{200:rt.object({bindings:rt.array(Go)}),404:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/task-message",{schema:{body:rt.object({taskId:rt.string(),content:rt.string().optional(),attachments:rt.array(rt.object({filePath:rt.string(),fileName:rt.string().optional(),mimeType:rt.string().optional(),kind:rt.enum(["auto","image","file","audio","video"]).optional()})).optional(),target:rt.object({channelId:rt.string(),chatId:rt.string()}).optional()}),response:{200:rt.object({success:rt.boolean()}),404:rt.object({error:rt.string()}),503:rt.object({error:rt.string()}),500:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/channels/group-history",{schema:{body:rt.object({taskId:rt.string(),limit:rt.number().int().positive().max(100).optional(),beforeSeq:rt.number().int().positive().optional(),afterSeq:rt.number().int().nonnegative().optional(),target:rt.object({channelId:rt.string(),chatId:rt.string(),platform:rt.string().optional(),chatType:rt.string().optional(),chatName:rt.string().optional()})}),response:{200:rt.object({historyXml:rt.string(),hasMoreBefore:rt.boolean(),hasMoreAfter:rt.boolean()}),400:rt.object({error:rt.string()}),503:rt.object({error:rt.string()}),500:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.delete("/channels/:id/bindings/:bindingId",{schema:{params:rt.object({id:rt.string(),bindingId:rt.string()}),response:{200:rt.object({success:rt.boolean()}),404:rt.object({error:rt.string()}),503:rt.object({error:rt.string()})}}},async(e,t)=>{x(t);const n=k(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})}}),w.post("/list",{schema:{response:{200:rt.object({children:rt.array(rt.object({startedBy:rt.string(),taskId:rt.string(),pid:rt.number()}))})}}},async()=>({children:t().filter(e=>void 0!==e.taskId).map(e=>({startedBy:e.startedBy,taskId:e.taskId,pid:e.pid}))})),w.post("/stop-session",{schema:{body:rt.object({sessionId:rt.string()}),response:{200:rt.object({success:rt.boolean()})}}},async e=>{const{sessionId:t}=e.body;return $e.debug(`[CONTROL SERVER] Stop session request: ${t}`),{success:n(t)}}),w.post("/stop",{schema:{response:{200:rt.object({status:rt.string()})}}},async()=>($e.debug("[CONTROL SERVER] Stop daemon request received"),setTimeout(()=>{$e.debug("[CONTROL SERVER] Triggering daemon shutdown"),i()},50),{status:"stopping"})),"127.0.0.1"!==v&&$e.warn(`[CONTROL SERVER] Listening on ${v}; ensure daemon control endpoints are protected by network policy`);const I=e=>new Promise((t,n)=>{b.listen({port:e,host:v},(e,s)=>{e?n(e):t(s)})});(async()=>{let e;try{e=await I(30624)}catch(t){const n=t?.code;if("EADDRINUSE"!==n&&"EACCES"!==n)throw $e.info("[CONTROL SERVER] Failed to start:",t),t;$e.info(`[CONTROL SERVER] Port 30624 unavailable (${n??"error"}), falling back to dynamic port`),e=await I(0)}const t=parseInt(e.split(":").pop());$e.info(`[CONTROL SERVER] Started on port ${t}`),f({port:t,host:v,webhookHost:y,stop:async()=>{await b.close(),$e.info("[CONTROL SERVER] Server stopped")}})})().catch(e=>{throw $e.info("[CONTROL SERVER] Failed to start:",e),e})})}function Gc(e,t={}){const n=Ne(),s=_(n,"dist","index.mjs"),a=["--no-warnings","--no-deprecation",s,...e];if(!r(s)){const e=`Entrypoint ${s} does not exist`;throw $e.debug(`[SPAWN Agentrix CLI] ${e}`),new Error(e)}return tt(process.execPath,a,t)}const Bc={".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"},Fc={"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 Wc(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=$(t.pathname);if(n)return n;const s=t.searchParams.get("filename")||t.searchParams.get("name")||t.searchParams.get("file");if(s){const e=$(s);if(e)return e}return""}catch{return""}}(e),i=s.headers.get("content-type"),o=i?.split(";")[0].trim()||function(e){const t=e.toLowerCase();return Bc[t]||"application/octet-stream"}(a),r=a||function(e){return Fc[e]||""}(o);let c;if(n)try{const t=new URL(e).pathname,n=C(t);c=n&&$(n)?n:`${ke()}${r||".dat"}`}catch{c=`${ke()}${r||".dat"}`}else c=`${ke()}${r||".dat"}`;const d=_(t,c),p=s.body,u=l(d);return await Ze(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)}`)}}async function zc(e,t){const{attachmentsDir:n,log:s}=t;if(!Array.isArray(e.message.content))return e;const a=await Promise.all(e.message.content.map(async e=>"image"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","IMAGE",`Downloading image to local attachment: ${s}`);const{filePath:a,mimeType:i}=await Wc(s,t,!0);return n?.("info","IMAGE",`Image saved to: ${a}`),{type:"text",text:`Image file: ${a}\nType: ${i}`}}catch(t){return n?.("error","IMAGE",`Error downloading image to file: ${t}`),{type:"text",text:`[Image unavailable: failed to download from ${e.source.url}]`}}}(e,n,s):"document"===e.type&&"url"===e.source?.type&&e.source?.url?async function(e,t,n){try{const s=e.source.url;n?.("info","DOCUMENT",`Downloading document from: ${s}`);const{filePath:a,mimeType:i,filename:o}=await Wc(s,t,!0);return n?.("info","DOCUMENT",`Document downloaded to: ${a}`),{type:"text",text:`Document: ${a}\nTitle: ${e.title||o}\nType: ${i}`}}catch(t){return n?.("error","DOCUMENT",`Error processing document: ${t}`),{type:"text",text:`[Document unavailable: failed to download from ${e.source?.url}]`}}}(e,n,s):e));return{...e,message:{...e.message,content:a}}}const Kc="Agentrix-DevOps",Vc="main";function Xc(e){return(e.supportedFeatures??[]).includes(te)}function Jc(e){return"zh-Hans"===e.preferredLanguage||`${process.env.AGENTRIX_LANG??""} ${process.env.LANG??""}`.toLowerCase().includes("zh")?"zh-Hans":"en"}function Yc(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 Qc(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 Zc(e,t){return _(Ce.resolveDataDir(e,t),"devops-init")}function el(e,t){return _(Zc(e,t),"original-input.json")}function tl(e,t){return _(Zc(e,t),"handoff.json")}function nl(e){const t=Zc(e.userId,e.taskId);d(t,{recursive:!0}),u(el(e.userId,e.taskId),JSON.stringify(e,null,2))}function sl(e,t){const n=el(e,t);return r(n)?JSON.parse(c(n,"utf-8")):null}function al(e,t){const n=tl(e,t);if(!r(n))return null;const s=JSON.parse(c(n,"utf-8"));return f(n),s}class il{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:K(),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 $e.warn(`[SESSION] Missing PID for task ${e}`);$e.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 Ce.getSecretKey();if(!t)return;const n=W(G(e.dataEncryptionKey),t);if(!n)return void $e.warn("[SESSION] Failed to decrypt data encryption key");if(e.dataEncryptionKey=q(n),"task-message"!==e.event)return;const s=e.eventData;if(!s.encryptedMessage)return;const a=ne(s.encryptedMessage,n);a?e.eventData={...s,message:a,encryptedMessage:void 0}:$e.warn("[SESSION] Failed to decrypt task message")}async persistCreateTaskStart(e){const t=Ce.resolveDataDir(e.userId,e.taskId),n=Ce.resolveAttachmentsDir(e.userId,e.taskId),s=no({dataDir:t,taskId:e.taskId});try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:t.sequence??0});let a=null;if(t.message){let e=t.message;se(e)&&(e=await zc(e,{attachmentsDir:n,log:(e,t,n)=>$e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),a=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return a}finally{s.close()}}async persistResumeTaskStart(e){const t=Ce.resolveDataDir(e.userId,e.taskId),n=Ce.resolveAttachmentsDir(e.userId,e.taskId),s=no({dataDir:t,taskId:e.taskId}),a=e.eventData.sequence;if(null==a)throw new Error(`Missing resume sequence for task ${e.taskId}`);try{const t=e.eventData;s.saveTaskEvent({eventType:e.event,eventId:t.eventId,eventData:t,taskId:e.taskId,chatId:e.chatId,sequence:a});let i=null;if(t.message){let e=t.message;se(e)&&(e=await zc(e,{attachmentsDir:n,log:(e,t,n)=>$e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)})),i=s.saveMessage({eventId:t.eventId,message:e,senderType:t.senderType,senderId:t.senderId,senderName:t.senderName}).localSequence}return i}finally{s.close()}}async processTaskMessageAttachments(e){if("task-message"!==e.event)return;const t=e.eventData;if(!t.message||!se(t.message))return;const n=Ce.resolveAttachmentsDir(e.userId,e.taskId),s=await zc(t.message,{attachmentsDir:n,log:(e,t,n)=>$e["debug"===e?"info":e](`[ATTACH:${t}] ${n}`)});e.eventData={...t,message:s}}trackWorkerProcess(e,t){const n={startedBy:"daemon",pid:t.pid,childProcess:t,taskId:e.taskId};this.pidToTrackedSession.set(t.pid,n),t.on("exit",(n,s)=>{this.pidToTrackedSession.delete(t.pid),this.sandboxPool&&this.sandboxPool.disposeWorkerSandbox(e.taskId),this.maybeContinueAfterDevOpsInit(e).catch(t=>{$e.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=al(e.userId,e.taskId);t&&($e.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=sl(e,t);if(!n)return void $e.warn(`[DEVOPS_INIT] Missing original task input for ${t}; cannot continue original worker`);if($e.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),Ce.writeTaskInput(n);const a={eventId:K(),status:"success",opCode:n.eventId};await this.startWorkerInternal(n,"create-task",a)}restoreOriginalWorkerAfterSlashDevOpsInit(e){const t=no({dataDir:Ce.resolveDataDir(e.userId,e.taskId),taskId:e.taskId});try{const n=t.pageRecentMessages(1).data[0]?.localSequence??0;t.updateAgentLastSequence(e.agentId,n),$e.info(`[DEVOPS_INIT] Restored original worker ${e.agentId} for task ${e.taskId} at sequence ${n}; waiting for the next user message`)}finally{t.close()}Ce.writeTaskInput(e)}positionOriginalWorkerHistoryCursor(e,t){if(null===t)return void $e.warn(`[DEVOPS_INIT] Original worker message for task ${e.taskId} has no local sequence; cannot isolate DevOps init history`);const n=no({dataDir:Ce.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),$e.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:K(),taskId:e.taskId,agentSessionId:e.agentSessionId,cwd:e.cwd??e.userCwd}),void $e.info(`[DEVOPS_INIT] Restored original agent session for task ${e.taskId}`);t.send("reset-task-session",{eventId:K(),taskId:e.taskId}),$e.info(`[DEVOPS_INIT] Cleared DevOps init agent session for task ${e.taskId}`)}else $e.warn(`[DEVOPS_INIT] No daemon socket client available to sync task session for ${e.taskId}`)}completeDevOpsInit(e){$e.info(`[DEVOPS_INIT] Completion received for task ${e.taskId}, action=${e.action}`),function(e,t,n){const s=Zc(e,t);d(s,{recursive:!0}),u(tl(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=>{$e.error(`[DEVOPS_INIT] Failed to continue original worker for task ${e.taskId} after completion signal:`,t)})},100)}startDevOpsInit(e){this.startDevOpsInitAsync(e).catch(t=>{$e.error(`[DEVOPS_INIT] Failed to start slash-command DevOps init for task ${e.taskId}:`,t)})}async startDevOpsInitAsync(e){const t=Ce.readTaskInput(e.userId,e.taskId);nl(t);const n=await this.buildDevOpsWorkerInput(t,!0);Ce.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:K(),status:"success",opCode:e.eventId};return void await this.startWorkerInternal(e,t,n)}$e.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 $e.info(`[DEVOPS_INIT] Original worker for task ${t} is already running with PID ${s.pid}`);if(s)continue;const a=al(e,t);if(!a)return void $e.info(`[DEVOPS_INIT] Handoff for task ${t} was already consumed`);if($e.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)}$e.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:K(),status:"success",opCode:e.eventId},s=this.createWorkerGateAck(e.eventId);if(s)return $e.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)),Ce.writeTaskInput(e),"create-task"===t?await this.persistCreateTaskStart(e):await this.persistResumeTaskStart(e);const a=this.taskToStartPromise.get(e.taskId);if(a)return $e.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===Kc||!Xc(e))return e;const t=sl(e.userId,e.taskId);if(!t||"agentSessionId"in t)return e;$e.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(!Xc(e)||e.agentId===Kc)return e;if(this.isLocalDirectoryDevOpsTarget(e)){if(!function(e,t={}){const n=t.checkLocalState??!0,s=_(e,".agentrix"),a=_(s,"env"),i=_(a,"init"),o=_(i,"state","local"),c=!r(s),l=!r(_(a,"README.md")),d=!r(_(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}}(Ce.resolveProjectCWD(e.userCwd,e.userId,e.taskId),{checkLocalState:!0}).needsInit)return $e.info(`[DEVOPS_INIT] Local project init state complete for task ${e.taskId}; starting original worker`),e}else{if(!this.isCodeRepositoryDevOpsTarget(e))return $e.info(`[DEVOPS_INIT] No project directory or code repository selected for task ${e.taskId}; skipping Agentrix DevOps init`),e;$e.info(`[DEVOPS_INIT] Code repository target selected for task ${e.taskId}; starting Agentrix-DevOps without local init-state precheck`)}nl(e);const t=await this.buildDevOpsWorkerInput(e,!1);return $e.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=_(Ce.agentrixAgentsHomeDir,Kc),t=_(Ce.agentrixHomeDir,"tmp","agentrix-agent-devops-init"),n=`${e}.tmp-${Date.now()}`,s=`${e}.backup-${Date.now()}`;d(_(Ce.agentrixHomeDir,"tmp"),{recursive:!0}),r(_(t,".git"))?(gt("git",["fetch","--depth=1","origin",`${Vc}:refs/remotes/origin/${Vc}`],{cwd:t,stdio:"pipe"}),gt("git",["checkout",Vc],{cwd:t,stdio:"pipe"}),gt("git",["reset","--hard",`origin/${Vc}`],{cwd:t,stdio:"pipe"})):(h(t,{recursive:!0,force:!0}),gt("git",["clone","--depth=1","--branch",Vc,"https://github.com/xmz-ai/agentrix-agent.git",t],{stdio:"pipe"}));const a=_(t,"agentrix-dev-init");if(!r(_(a,"agent.json")))throw new Error(`Agentrix DevOps agent definition not found at ${a}`);h(n,{recursive:!0,force:!0}),v(a,n,{recursive:!0}),oa(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"===Jc(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?K():i.eventId,agentId:Kc,agentType:"claude",agentDir:n,eventData:{...a,eventId:K(),senderType:"system",senderId:"agentrix-devops-init",senderName:"Agentrix DevOps init",message:{uuid:Gt(),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 $e.warn(`[SESSION] Rejecting ${t} for task ${e.taskId}: ${s.message}`),s;const a=this.getAliveSessionByTaskId(e.taskId);if(a)return $e.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=Ce.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-x_FEOhbQ.mjs").then(function(e){return e.d}),{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);$e.debug(`[SESSION] Sandboxed command for task ${e.taskId}: ${r}`),l=tt(r,{shell:!0,cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),$e.info(`[SESSION] Worker started with sandbox, PID: ${l.pid}`)}catch(t){return $e.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=Gc(o,{cwd:i,detached:!0,stdio:["ignore","pipe","pipe"],env:c}),$e.info(`[SESSION] Worker started without sandbox, PID: ${l.pid}`);return process.env.DEBUG&&(l.stdout?.on("data",e=>{$e.debug(`[Daemon] worker stdout: ${e.toString()}`)}),l.stderr?.on("data",e=>{$e.debug(`[Daemon] worker stderr: ${e.toString()}`)})),l.pid?($e.info(`[SESSION] Worker started, PID: ${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"),$e.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"),$e.warn(`[SESSION] Task ${e} did not exit after SIGTERM, sent SIGKILL to PID ${t}`)}catch(n){$e.warn(`[SESSION] Failed to force kill task ${e} (PID ${t}):`,n)}},3e3);s.unref?.()}catch(n){$e.warn(`[SESSION] Failed to stop task ${e}:`,n),this.isProcessAlive(t)||this.pidToTrackedSession.delete(t)}return!0}return $e.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(){$e.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){$e.warn(`[SESSION] Failed to stop PID ${e}:`,t)}this.pidToTrackedSession.clear()}async startHivePublishWorker(e){const t={eventId:K(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return $e.warn(`[SESSION] Rejecting hive-publish for task ${e.taskId}: ${n.message}`),n;Ce.writeTaskInput(e);try{const n=Gc(["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=>{$e.debug(`[HivePublish] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{$e.debug(`[HivePublish] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-publish worker - no PID",t;$e.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:K(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return $e.warn(`[SESSION] Rejecting hive-install for task ${e.taskId}: ${n.message}`),n;Ce.writeTaskInput(e);try{const n=Gc(["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=>{$e.debug(`[HiveInstall] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{$e.debug(`[HiveInstall] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start hive-install worker - no PID",t;$e.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:K(),status:"success",opCode:e.eventId},n=this.createWorkerGateAck(e.eventId);if(n)return $e.warn(`[SESSION] Rejecting deployment for task ${e.taskId}: ${n.message}`),n;Ce.writeTaskInput(e);try{const n=Gc(["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=>{$e.debug(`[Deployment] worker stdout: ${e.toString()}`)}),n.stderr?.on("data",e=>{$e.debug(`[Deployment] worker stderr: ${e.toString()}`)})),!n.pid)return t.status="failed",t.message="Failed to start deployment worker - no PID",t;$e.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 ol{networkManager=null;workerSandboxes=new Map;settings=null;platform;constructor(){this.platform=it()}async initialize(e){if(this.settings=e,!e.enabled)return $e.info("[SANDBOX] Sandbox disabled via settings"),!1;if(!Bt(this.platform))return $e.warn("[SANDBOX] Platform not supported, sandbox disabled"),!1;try{const t={allowedDomains:[new URL(Ce.serverUrl).hostname,...e.network.allowedDomains],deniedDomains:e.network.deniedDomains,allowLocalBinding:!1};return this.networkManager=new Ft,await this.networkManager.initialize(t),$e.info("[SANDBOX] Sandbox pool initialized successfully"),!0}catch(e){throw $e.error("[SANDBOX] Failed to initialize:",e),e}}async createWorkerSandbox(e,t,n){if(!this.networkManager||!this.settings?.enabled)return null;try{const s=Ce.resolveUserWorkSpaceDir(t),a=Ce.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=Ke.dirname(process.execPath);r.allowRead=[...i.allowRead,e]}const c={filesystem:r,env:o},l=new Wt(this.networkManager,c);return this.workerSandboxes.set(e,l),$e.info(`[SANDBOX] Created sandbox for task ${e}`),l}catch(t){return $e.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 $e.debug(`[SANDBOX] Wrapped command for task ${e}`),s}disposeWorkerSandbox(e){const t=this.workerSandboxes.get(e);t&&(t.dispose(),this.workerSandboxes.delete(e),$e.debug(`[SANDBOX] Disposed sandbox for task ${e}`))}async shutdown(){$e.info("[SANDBOX] Shutting down sandbox pool");for(const[e,t]of this.workerSandboxes.entries())t.dispose(),$e.debug(`[SANDBOX] Disposed sandbox for task ${e}`);this.workerSandboxes.clear(),this.networkManager&&(await this.networkManager.shutdown(),this.networkManager=null,$e.info("[SANDBOX] Network manager shutdown complete"))}isEnabled(){return!0===this.settings?.enabled}}class rl{constructor(e,t){this.client=e,this.machineId=t;const n=Ce.agentrixAgentsHomeDir,s=_(n,"companion"),a=_(s,"claude");this.bootstrapPath=_(a,"BOOTSTRAP.md"),this.countPath=_(s,"BOOTSTRAP.count"),this.stateFilePath=_(a,"state.json")}timer=null;intervalMs=18e4;maxAttempts=10;bootstrapPath;countPath;stateFilePath;start(){r(this.bootstrapPath)?this.readCount()>=this.maxAttempts?$e.warn(`[COMPANION BOOTSTRAP] Already reached max attempts (${this.maxAttempts}), not starting watcher`):($e.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md exists, starting watcher"),this.scheduleNext()):$e.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 $e.info("[COMPANION BOOTSTRAP] BOOTSTRAP.md removed, companion init complete");const e=this.readCount();if(e>=this.maxAttempts)return void $e.warn(`[COMPANION BOOTSTRAP] Max attempts (${this.maxAttempts}) reached, giving up`);const t=this.loadState();if(!t)return $e.warn("[COMPANION BOOTSTRAP] No state.json available, will retry next interval"),void this.scheduleNext();this.writeCount(e+1),$e.info(`[COMPANION BOOTSTRAP] Sending init request (attempt ${e+1}/${this.maxAttempts})`),this.client.send("request-companion-init",{eventId:K(),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){$e.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 cl(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Lark credential "${t}" is required`);return e}function ll(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 dl(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 pl(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 ul(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 ml(e,t,n){return[e,t,n].map(encodeURIComponent).join(":")}class hl{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:cl((t=e.credentials).appId,"appId"),appSecret:cl(t.appSecret,"appSecret")},this.client=new zt.Client({appId:this.credentials.appId,appSecret:this.credentials.appSecret,appType:zt.AppType.SelfBuild,domain:zt.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 zt.WSClient({appId:this.credentials.appId,appSecret:this.credentials.appSecret,domain:zt.Domain.Feishu,loggerLevel:zt.LoggerLevel.info,onReady:()=>{$e.info(`[CHANNEL][LARK] Connected: channel=${this.id}`),this.setState("connected")},onError:e=>{$e.warn(`[CHANNEL][LARK] Connection error: channel=${this.id}, message=${e.message}`),this.setState("error",e)},onReconnecting:()=>{$e.warn(`[CHANNEL][LARK] Reconnecting: channel=${this.id}`),this.setState("connecting")},onReconnected:()=>{$e.info(`[CHANNEL][LARK] Reconnected: channel=${this.id}`),this.setState("connected")}});const e=new zt.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: ${ul(e)}`)}}async sendAttachment(e,t){if("image"===this.resolveOutgoingKind(t)){const n=await this.client.im.image.create({data:{image_type:"message",image:x(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||C(t.filePath),s=await this.client.im.file.create({data:{file_type:this.resolveLarkFileType(n,t.mimeType),file_name:n,file:x(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?($e.warn(`[CHANNEL][LARK] getChatName failed: code=${t.code}, msg=${t.msg}`),e):t.data?.name?t.data.name:e}catch(t){return $e.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 $e.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 $e.warn(`[CHANNEL][LARK] contact.user.basic_batch failed for ${e}: ${ul(t)}`),e}}async getContacts(){const e=[];for await(const t of await this.client.im.chat.listWithIterator({params:{page_size:50,sort_type:"ByActiveTimeDesc"}}))for(const n of t?.items??[])n.chat_id&&e.push({id:n.chat_id,name:n.name||n.chat_id,avatar:n.avatar,description:n.description,chatStatus:n.chat_status,external:n.external});return e}async downloadFile(e,t={}){try{const n=function(e){const[t,n,s]=e.split(":").map(decodeURIComponent);if(!t||!n||!s)throw new Error("Invalid Lark resource key");return{messageId:t,resourceType:n,fileKey:s}}(e),s=Pn(t.fileName||n.fileKey),a=await this.client.im.messageResource.get({path:{message_id:n.messageId,file_key:n.fileKey},params:{type:n.resourceType}});return await a.writeFile(s),s}catch(e){return $e.warn(`[CHANNEL][LARK] Failed to download file: channel=${this.id}, ${ul(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 $e.warn(`[CHANNEL][LARK] bot identity lookup failed: code=${e.code}, msg=${e.msg}`);this.botOpenId=e.bot?.open_id}catch(e){$e.warn(`[CHANNEL][LARK] bot identity lookup failed: ${ul(e)}`)}}resolveOutgoingKind(e){return"image"===e.kind?"image":"auto"!==e.kind&&e.kind?"file":e.mimeType?.startsWith("image/")?"image":"file"}resolveLarkFileType(e,t){const n=$(e).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 $e.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:pl(e?.sender),type:"image"===a?"image":"file"===a?"file":"audio"===a?"voice":"text",text:ll(n),fileKey:i?ml(t.message_id,"audio"===a?"audio":"file",i):void 0,fileName:"string"==typeof s.file_name?s.file_name:void 0,imageKey:o?ml(t.message_id,"image",o):void 0,mentionedBot:r,replyToBot:!1,triggered:r,rawContent:n,timestamp:dl(t.create_time??e?.create_time??e?.ts),raw:e}}}const gl="https://api.telegram.org",fl=4e4,vl=1e3;function yl(e,t){if("string"!=typeof e||0===e.trim().length)throw new Error(`Telegram credential "${t}" is required`);return e.trim()}function bl(e){return"string"==typeof e&&e.trim().length>0?e.trim():void 0}function wl(e){return[e.first_name,e.last_name].filter(Boolean).join(" ").trim()||(e.username?`@${e.username}`:void 0)}function xl(e){return e.photo?.length?"image":e.document?"file":e.voice?"voice":"text"}function kl(e){return e.photo?.[e.photo.length-1]?.file_id}class Il{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=vl;offset;botUser=null;constructor(e){this.id=e.id,this.credentials=function(e){const t=bl(e.token)??bl(e.botToken)??bl(e.bot_token);return{token:t||yl(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:fl}),this.polling=!0,this.retryDelayMs=vl,this.pollPromise=this.pollLoop(),this.setState("connected"),$e.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:fl})}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||C(t.filePath),r=await Ct(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:fl})}async getContacts(){return[]}async downloadFile(e,t={}){try{const n=await this.request("getFile",{file_id:e},{timeoutMs:fl});if(!n.file_path)throw new Error("Telegram getFile response is missing file_path");const s=t.fileName||C(n.file_path);return await On(`${gl}/file/bot${this.credentials.token}/${n.file_path}`,s)}catch(t){return $e.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:fl});return t.title||wl(t)||t.username||e}catch(t){return $e.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:fl});return wl(t)||t.username||e}catch(t){return $e.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:fl,isPoll:!0});this.retryDelayMs=vl,"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));$e.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(`${gl}/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(`${gl}/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 $e.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||ke()),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?wl(t.from):void 0,type:xl(t),text:t.text??t.caption,fileKey:t.document?.file_id??t.voice?.file_id,fileName:t.document?.file_name,imageKey:kl(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 Sl(e){const t=$l(e);return t?{type:"user",message:{role:"user",content:[{type:"text",text:`<msg ${El({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 Tl(e){const t=$l(e);return t?`<msg ${El({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 El(e){return Object.entries(e).filter(([,e])=>void 0!==e&&""!==e).map(([e,t])=>`${e}="${function(e){return e.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;").replaceAll(">","&gt;")}(t)}"`).join(" ")}function Al(e){const t=[];for(const n of e){const e=Tl(n);e&&t.push(e)}return t.join("\n")}function _l(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 Cl(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 $l(e){const{text:t,nonTextBlocks:n}=(s=e.message,ae(s)?{text:_l(s),nonTextBlocks:[]}:ie(s)?{text:Cl(s),nonTextBlocks:[]}:oe(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 Nl{constructor(e,t){this.client=e,this.machineId=t,this.stateFilePath=_(Ce.agentrixHomeDir,"channels","state.json"),this.groupHistoryFilePath=_(Ce.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){$e.warn(`[CHANNEL] Failed to auto-connect channel ${t.id}`,e)}$e.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=>{$e.warn(`[CHANNEL] Failed to disconnect channel ${e.id}`,t)});this.adapters.clear(),$e.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:ke(),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(),$e.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(),$e.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=>{$e.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),$e.info(`[CHANNEL] Sent task ${e} reply to ${n.channelId}/${n.chatId}`),!0):($e.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(),$e.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 hl({id:e.id,credentials:e.credentials});if("wechat"===e.platform)return new Mo({id:e.id,credentials:e.credentials});if("telegram"===e.platform)return new Il({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){$e.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 $e.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);$e.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=>{$e.warn(`[CHANNEL] Failed to flush pending attachment messages: key=${e}`,t)})},5e3);this.pendingMessages.set(e,{messages:[...n?.messages??[],t],timer:s}),$e.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=El({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){$e.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}),no({dataDir:t,taskId:this.getGroupHistoryTaskId(e)})}getGroupHistoryDataDir(e){return _(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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}escapeXmlAttribute(e){return this.escapeXmlText(e).replace(/"/g,"&quot;").replace(/'/g,"&apos;")}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&&($e.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($e.info(`[CHANNEL] Message from ${e.platform} chat ${e.chatId} → task ${t.taskId}`),!this.client.connected)return void $e.debug(`[CHANNEL] Socket not connected, cannot forward message to task ${t.taskId}`);if(t.taskId.startsWith("pending-"))return void $e.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 $e.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:K(),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}}),$e.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=de(a,t),o=void 0}catch(e){$e.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(),$e.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:ke(),channelId:e.channelId,chatId:e.chatId,taskId:s,chatName:n,createdAt:a,updatedAt:a};return this.isPendingTaskId(s)?($e.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(),$e.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 $e.error("[CHANNEL] Cannot create task: companion not registered"),`pending-no-companion-${ke()}`;if(!this.client.connected)return $e.warn("[CHANNEL] Socket not connected, cannot create task via API"),`pending-offline-${ke()}`;const s=await this.createChannelTaskEncryptionPayload();if(!s)return $e.error("[CHANNEL] Cannot create encrypted channel task: missing local machine encryption credentials"),`pending-encryption-unavailable-${ke()}`;const{plainMessage:a,encryptedMessage:i}=await this.buildEncryptedMessage(e,s.taskDataKey);try{const o=await this.client.sendWithAck("channel-task-create",{eventId:K(),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),$e.info(`[CHANNEL] Created task ${o.taskId} for chat ${e.chatId}`),o.taskId):($e.error(`[CHANNEL] API task creation failed: ${o?.message||"unknown"}`),`pending-api-error-${ke()}`)}catch(e){return $e.error("[CHANNEL] Failed to create task via API",e),`pending-error-${ke()}`}}async resolveChatName(e){try{$e.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($e.info(`[CHANNEL] resolveChatName: getUserName returned "${n}"`),n&&n!==e.senderId)return n}}if(t?.getChatName){const n=await t.getChatName(e.chatId);if($e.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 $e.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 Ce.readCredentials();if(!e?.secret)return $e.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 re(e.secret),s=F();return{taskDataKey:s,dataEncryptionKey:q(le(s,n.publicKey)),ownerEncryptedDataKey:q(ce(q(s),t))}}(e);return t||($e.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 $e.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:K(),taskId:e});if("success"===t?.status&&t.dataEncryptionKey){const n=await Ce.getSecretKey();if(!n)return $e.warn(`[CHANNEL] Missing machine secret key while decrypting task key: task=${e}`),null;const s=W(G(t.dataEncryptionKey),n);return s&&32===s.length?(this.taskDataKeyCache.set(e,s),s):($e.warn(`[CHANNEL] Failed to decrypt valid task data key: task=${e}`),null)}$e.warn(`[CHANNEL] Failed to fetch encryption keys for task ${e}: ${t?.message||"unknown"}`)}catch(t){$e.warn(`[CHANNEL] Error fetching encryption keys for task ${e}`,t)}return null}readCompanionState(){const e=_(Ce.agentrixAgentsHomeDir,"companion","claude","state.json");if(!r(e))return $e.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}:($e.warn("[CHANNEL] Companion state.json missing required fields"),null)}catch(e){return $e.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=>{$e.warn(`[CHANNEL] Reconnect failed: channel=${e}`,t),this.scheduleReconnect(e)})},3e4);this.reconnectTimers.set(e,t),$e.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=zo.parse(e),(e.companionDataEncryptionKey||e.companionOwnerEncryptedDataKey||e.companionKeyMachineId||e.companionKeyChatId)&&this.saveState()}catch(e){$e.warn("[CHANNEL] Failed to load channel state; using empty state",e),this.store={version:1,channels:[],bindings:[]}}}saveState(){const e=P(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 Rl(){try{const e=Ve(Ne(),"package.json"),t=JSON.parse(Le(e,"utf-8"));if("string"==typeof t.version&&t.version.trim().length>0)return t.version}catch{}return"0.0.0"}async function Pl(){const e=Rl();try{const t=nt("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 Ml(e,t={}){const n=function(){const e=Ve(Xe(Ce.getStatePaths().daemonStateFile),"upgrade.lock");if(qe(e))try{const t=Le(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)||He(e)}catch{He(e)}try{const t=Ge(e,"wx");Be(t,JSON.stringify({pid:process.pid,createdAt:(new Date).toISOString()})),Fe(t)}catch{return null}return{release:()=>{try{const t=Le(e,"utf-8");JSON.parse(t).pid===process.pid&&He(e)}catch{}}}}();if(!n)return{status:"busy",message:"CLI upgrade already in progress"};try{const n=e??await Pl();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=tt("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()}}function Dl(){return"true"===process.env.AGENTRIX_DISABLE_AUTO_UPGRADE}async function Ol(e){try{if(console.log(""),e||(console.log(L.blue("🔄 Checking for upgrades...")),e=await Pl()),!e.hasUpgrade)return console.log(L.green("✓ Already on latest version")),console.log(""),!0;console.log(L.blue(`🔄 Upgrading from ${e.currentVersion} to ${e.latestVersion}...`));const t=await Ml(e,{stdio:"inherit"});if("busy"===t.status)return console.log(L.yellow(`⚠️ ${t.message}`)),!1;if("failed"===t.status)throw new Error(t.error);return console.log(L.green("✓ Upgrade complete")),console.log(""),!0}catch(e){return console.log(""),console.log(L.yellow("⚠️ Auto-upgrade failed")),console.log(L.dim(" You can upgrade manually with: npm install -g @agentrix/cli@latest")),console.log(""),!1}}class Ul{state="ready";machineId;workerManager;getSocketClient;requestRestartCallback;restartRequested=!1;pendingRestartReport=null;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:Re.version,installedCliVersion:Rl(),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"]}}handleCommand(e,t){this.matchesTarget(e)?"ping"!==e.action?"upgrade-cli"!==e.action?t(this.failedAck(e.eventId,"unsupported_operation","Unsupported machine control operation")):this.handleUpgradeCli(e,t):t({eventId:K(),status:"success",opCode:e.eventId,data:{result:this.buildPingResult()}}):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:K(),status:"success",opCode:e.eventId}),this.runUpgrade(e).catch(t=>{$e.error("[MACHINE CONTROL] upgrade-cli failed unexpectedly:",t),this.state="ready",this.sendProgress({eventId:K(),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:K(),opCode:e.eventId,status:"running",message:"Checking and installing CLI upgrade"});const t=await Ml(void 0,{stdio:"ignore"});if("busy"===t.status)return this.state="ready",void this.sendProgress({eventId:K(),opCode:e.eventId,status:"failed",errorCode:"operation_busy",errorMessage:t.message});if("already_latest"===t.status)return this.state="ready",void this.sendProgress({eventId:K(),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:K(),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:K(),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}})}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:K(),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):$e.warn(`[MACHINE CONTROL] Dropping progress ${e.opCode}; socket not connected`)}matchesTarget(e){return e.target.machineId===this.machineId}failedAck(e,t,n){return{eventId:K(),status:"failed",opCode:e,message:n,data:{errorCode:t}}}}function jl(){return _(P(Ce.getStatePaths().daemonStateFile),"daemon-restart-report.json")}function Ll(e){return new Promise(t=>setTimeout(t,e))}function ql(e){try{return process.kill(e,0),!0}catch{return!1}}async function Hl(){Object.assign($e,Pe({type:"daemon"}));const{requestShutdown:e,shutdownPromise:t}=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?$e.debug(`${s} Shutdown already requested; ignoring duplicate request from ${a}`):(i=!0,$e.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=>{$e.info(`${s} FATAL: Uncaught exception`,e),$e.info(`${s} Stack trace: ${e.stack}`),a("exception",e.message)}),process.on("unhandledRejection",e=>{$e.info(`${s} FATAL: Unhandled promise rejection`,e);const t=e instanceof Error?e:new Error(`Unhandled promise rejection: ${e}`);$e.info(`${s} Stack trace: ${t.stack}`),a("exception",t.message)}),process.on("exit",e=>{$e.info(`${s} Process exiting with code: ${e}`)}),{requestShutdown:a,shutdownPromise:o}}();console.log("[DAEMON RUN] Starting daemon process..."),$e.debug("[DAEMON RUN] Environment",Ds()),await gn()&&(console.log("Daemon already running..."),process.exit(0));let n=await Ce.acquireDaemonLock(5,200);for(;!n;)await vn(),n=await Ce.acquireDaemonLock(5,200),n||($e.debug("[DAEMON RUN] cannot acquire daemon lock..."),process.exit(1));try{(function(){if(Ce.disableCaffeinate)return $e.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable"),!1;if("darwin"!==process.platform)return $e.debug("[caffeinate] Not on macOS, skipping caffeinate"),!1;if(Es&&!Es.killed)return $e.debug("[caffeinate] Caffeinate already running"),!0;try{return Es=tt("caffeinate",["-im"],{stdio:"ignore",detached:!1}),Es.on("error",e=>{$e.debug("[caffeinate] Error starting caffeinate:",e),Es=null}),Es.on("exit",(e,t)=>{$e.debug(`[caffeinate] Process exited with code ${e}, signal ${t}`),Es=null}),$e.info(`[caffeinate] Started with PID ${Es.pid}`),function(){if(Cs)return;Cs=!0;const e=()=>{_s()};process.on("exit",e),process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGUSR1",e),process.on("SIGUSR2",e),process.on("uncaughtException",t=>{$e.debug("[caffeinate] Uncaught exception, cleaning up:",t),e()}),process.on("unhandledRejection",(t,n)=>{$e.debug("[caffeinate] Unhandled rejection, cleaning up:",t),e()})}(),!0}catch(e){return $e.info("[caffeinate] Failed to start caffeinate:",e),!1}})()&&$e.debug("[DAEMON RUN] Sleep prevention enabled");const s=await kn();$e.debug("[DAEMON RUN] Auth and machine setup complete");const a=new ol;await a.initialize(Ce.getSandboxSettings());const i=new il(a);let o,l,d,p,u=!1;i.setSocketClientProvider(()=>o?.client),p=new Ul({machineId:s.machineId,workerManager:i,getSocketClient:()=>o?.client,requestRestart:(t,n,s)=>{!function(e){try{const t=Gc(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 $e.error("[DAEMON RESTART] Failed to launch restart command",e),null}}({oldPid:process.pid,expectedCliVersion:s?.toVersion??Rl(),reason:n,report:s})?p.rollbackGracefulRestart():(u=!0,e("agentrix-cli",n))}});const{port:m,host:h,webhookHost:g,stop:v}=await Hc({getChildren:()=>i.getCurrentSessions(),stopSession:e=>i.stopSession(e),startDevOpsInit:e=>i.startDevOpsInit(e),completeDevOpsInit:e=>i.completeDevOpsInit(e),requestShutdown:()=>e("agentrix-cli"),registerSession:(e,t)=>i.registerTaskWorker(e,t),prepareGracefulRestart:e=>p.prepareGracefulRestart(e.source,e.reason),clearGracefulRestartGate:()=>p.clearGracefulRestartGate(),getSocketClient:()=>o?.client,credentials:s,get companionScheduler(){return l},get channelManager(){return d}});try{await js(),$e.debug("[DAEMON RUN] Openers detected")}catch(e){$e.warn("[DAEMON RUN] Failed to detect openers",e)}const y={pid:process.pid,port:m,host:h,webhookHost:g,startTime:(new Date).toLocaleString(),cliVersion:Re.version,logPath:Me({type:"daemon"})};Ce.writeDaemonState(y),$e.debug("[DAEMON RUN] Daemon state written");const b=new Ts({machineId:s.machineId,serverUrl:Ce.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:pe(s.token,s.machineId),keepAliveConfig:{intervalMs:2e4,event:"machine-alive",payloadGenerator:()=>({eventId:K(),machineId:s.machineId,timestamp:Date.now().toString(),controlPort:m})},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>$e.debug(`[DAEMON SOCKET] ${e}`,...t)},i,{requestShutdown:e,machineControl:p}),w=new Nl(b.client,s.machineId);d=w,i.setChannelManager(w),await b.connect(),o=b,$e.info("[DAEMON RUN] Machine client connected to server"),await async function(e){const t=function(){const e=jl();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=Re.version,s={eventId:K(),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=>{$e.warn("[DAEMON RESTART] Could not confirm restart report flush",e)}),function(){try{const e=jl();r(e)&&f(e)}catch{}}(),$e.info(`[DAEMON RESTART] Flushed pending restart report for ${t.opCode}`),!0}(b.client).catch(e=>{$e.warn("[DAEMON RUN] Failed to flush pending restart report",e)}),await async function(e,t){const n=function(e=process.env){if(!pc(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=dc(t,"GITLAB_BASE_URL"),a=dc(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:pc(e.AGENTRIX_GITLAB_USE_AS_PROXY,!0)}}();if(!n)return null;const s=await uc(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 $e.info(`[GIT SERVER] auto-configured from environment: gitServer=${i.gitServerId}, proxyRegistered=${i.proxyRegistered}`),i}(b.client,s);const x=new co(b.client,s.machineId);l=x,x.start(),await w.start(),b.setCompanionInteractionCallback(e=>{x.recordInteraction(e)});const k=new rl(b.client,s.machineId);k.start(),b.client.onEvent("companion-heartbeat-response",e=>{e?.taskId&&x.setHeartbeatTaskId(e.taskId)}),b.client.onEvent("companion-memory-organization-response",e=>{e?.taskId&&x.setMemoryOrganizationTaskId(e.taskId)});const I=async(e,t)=>{await w.stop(),x.stop(),k.stop(),await b.disconnect(),await v(),await a.shutdown(),await fn(),await _s(),await Ce.releaseDaemonLock(n),u&&$e.info("[DAEMON RUN] Restart command owns replacement daemon startup"),$e.info("[DAEMON RUN] Cleanup completed, exiting process"),process.exit(0)};$e.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");const S=await t;await I(S.source,S.errorMessage)}catch(e){const t=function(e){const t=Tn(e);return t.code||t.action?t:null}(e);t?(console.error(t.message),t.action&&console.error(t.action)):function(e){const t=Tn(e);return"machine_binding_revoked"===t.code||t.message.includes("Machine binding revoked")}(e)&&(console.error("Machine binding is no longer valid."),console.error("Run `agentrix logout` and bind this machine again.")),$e.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1",e),process.exit(1)}}const Gl="\n\n[Tool result truncated to 1024 bytes]";function Bl(e,t=1024){if(Buffer.byteLength(e,"utf8")<=t)return e;const n=Buffer.byteLength(Gl,"utf8");return n>t?Wl(Gl,t):`${Wl(e,t-n)}${Gl}`}function Fl(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Wl(e,t){let n="",s=0;for(const a of e){const e=Buffer.byteLength(a,"utf8");if(s+e>t)break;n+=a,s+=e}return n}const zl={senderType:"system",senderId:"system",senderName:"system"};class Kl{client;context;historyDb;getPermissionMode;outbox=new Map;usageOutbox=new Map;ackWaiters=new Map;hasConnectedOnce=!1;constructor(e,t){const{taskId:n,userId:s,machineId:a,cwd:i,chatId:o,...r}=e,c=i.endsWith("/")?i:`${i}/`;this.client=new Cn(r),this.context={taskId:n,chatId:o,userId:s,machineId:a,cwd:c,stopTask:t.stopTask,shouldPersistTaskMessage:t.shouldPersistTaskMessage,onTaskMessage:t.onTaskMessage,onTaskInfoUpdate:t.onTaskInfoUpdate,onWorkerStatusRequest:t.onWorkerStatusRequest,onSubTaskResultUpdated:t.onSubTaskResultUpdated,onSubTaskAskUser:t.onSubTaskAskUser,onGitPush:t.onGitPush,dataEncryptionKey:e.dataEncryptionKey,attachmentsDir:t.attachmentsDir,logger:t.logger},this.historyDb=t.historyDb,this.getPermissionMode=t.getPermissionMode,this.initHandlers()}getPermissionModeSnapshot(){return this.getPermissionMode?.()??null}connect(){return new Promise((e,t)=>{const n=setTimeout(()=>{t(new Error("Worker connection timeout after 10 seconds"))},1e4);this.client.onLifecycle("connect",()=>{clearTimeout(n),e()}),this.client.onLifecycle("connect_error",e=>{clearTimeout(n),t(e)}),this.client.connect()})}async disconnect(){this.client.connected&&await this.client.flush(5e3).catch(()=>{}),this.client.disconnect()}sendTaskMessage(e,t,n){const s=K();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:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd,...void 0!==e?.deployingAgent&&{deployingAgent:e.deployingAgent},...void 0!==e?.upgradingAgent&&{upgradingAgent:e.upgradingAgent}};this.client.send("worker-initializing",t)}sendWorkerInitialized(){const e={eventId:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),cwd:this.context.cwd};this.client.send("worker-initialized",e)}sendWorkerReady(e){const t=this.getPermissionModeSnapshot(),n={eventId:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),...void 0!==e&&{duration:e},...null!==t&&{permissionMode:t}};this.client.send("worker-ready",n)}sendWorkRunning(e){const t=this.getPermissionModeSnapshot(),n={eventId:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),activeAgents:e,...null!==t&&{permissionMode:t}};this.client.send("worker-running",n)}sendPermissionMode(e){const t={eventId:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),permissionMode:e};this.client.send("worker-permission-mode",t)}sendWorkerExit(e){const t={eventId:K(),taskId:this.context.taskId,machineId:this.context.machineId,timestamp:(new Date).toISOString(),reason:e};this.client.send("worker-exit",t)}async sendErrorMessageAndExit(e){await this.sendTerminalErrorResultAndWait(e),this.sendWorkerExit("error"),await this.disconnect()}async sendTerminalErrorResultAndWait(e,t){const n=this.sendTerminalErrorResult(e,t);await this.waitForEventAcks(n,2e3)}sendTerminalErrorResult(e,t){const n=this.sendSystemErrorMessage(e,t),s=this.sendTaskEvent(zl,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(zl,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(zl,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(zl,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 Bl(e,t);const n=Fl(e);return Buffer.byteLength(n,"utf8")<=t?e:Array.isArray(e)?Bl(e.map(e=>{return"object"==typeof(t=e)&&null!==t&&"text"in t&&"string"==typeof t.text?e.text:Fl(e);var t}).join("\n"),t):Bl(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??K(),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.context.dataEncryptionKey){const e=de(s,this.context.dataEncryptionKey);l.message=void 0,l.encryptedMessage=e}return this.outbox.set(c,l),d&&(this.usageOutbox.set(c,d),this.client.send("task-usage-report",d)),this.client.send("task-message",l),c}waitForEventAcks(e,t){const n=e.filter(e=>this.outbox.has(e));return 0===n.length?Promise.resolve():new Promise(e=>{let s=n.length;const a=t=>{this.ackWaiters.delete(t),s-=1,s<=0&&(clearTimeout(i),e())},i=setTimeout(()=>{for(const e of n)this.ackWaiters.delete(e);e()},t);for(const e of n)this.ackWaiters.set(e,()=>a(e))})}buildTaskUsageReport(e,t){if("result"!==e.type)return null;const n=e.modelUsage;if(!n||"object"!=typeof n)return null;const s={};for(const[e,t]of Object.entries(n)){if(!e||!t||"object"!=typeof t)continue;const n=t,a={inputTokens:this.normalizeUsageCount(n.inputTokens),outputTokens:this.normalizeUsageCount(n.outputTokens),cacheReadInputTokens:this.normalizeUsageCount(n.cacheReadInputTokens),cacheCreationInputTokens:this.normalizeUsageCount(n.cacheCreationInputTokens),webSearchRequests:this.normalizeUsageCount(n.webSearchRequests)};Object.values(a).some(e=>e>0)&&(s[e]=a)}return 0===Object.keys(s).length?null:{eventId:K(),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:K(),taskId:this.context.taskId,agentSessionId:e,cwd:this.context.cwd};this.client.send("update-task-agent-session-id",t)}sendTaskSlashCommandsUpdate(e,t){const n={eventId:K(),taskId:this.context.taskId,commands:e,version:t,updatedAt:(new Date).toISOString()};this.client.send("task-slash-commands-update",n)}sendChangeTaskTitle(e){const t={eventId:K(),taskId:this.context.taskId,title:e};this.client.send("change-task-title",t),$e.info(`[AGENT] Title changed to: ${e}`)}sendUpdateAgentInfo(e,t){const n={eventId:K(),taskId:this.context.taskId,agentId:e,...t};this.client.send("update-agent-info",n),$e.info(`[AGENT] Agent info updated: ${JSON.stringify(t)}`)}async sendVisionPlanCard(e){const t={eventId:K(),taskId:this.context.taskId,issueId:e.issueId,repoRoot:e.repoRoot,createdAt:(new Date).toISOString()},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 $e.info(`[AGENT] Vision Plan card sent for issue: ${e.issueId}`),n}sendResetTaskSession(){const e={eventId:K(),taskId:this.context.taskId};this.client.send("reset-task-session",e),$e.info(`[AGENT] Session reset requested for task ${this.context.taskId}`)}async sendMergeRequest(e,t,n){const s={eventId:K(),taskId:this.context.taskId,summary:e,description:t,sourceBranch:n};$e.info(`[MERGE] Sending merge-request event for task ${this.context.taskId}`);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 $e.info(`[MERGE] Pull request created: #${a.data.pullRequestNumber}`),{pullRequestNumber:a.data.pullRequestNumber,pullRequestUrl:a.data.pullRequestUrl}}async sendMergePr(){const e={eventId:K(),taskId:this.context.taskId,mergeMethod:"squash"};return $e.info(`[MERGE-PR] Sending merge-pr event for task ${this.context.taskId}`),await this.client.sendWithAck("merge-pr",e)}associateRepository(e,t,n,s){const a={eventId:K(),taskId:this.context.taskId,gitServerHost:e,owner:t,repo:n,remoteUrl:s};$e.info(`[REPO] Sending repository association request: ${e}/${t}/${n}`),this.client.send("associate-repo",a)}async dispatchTaskMessage(e){await this.context.onTaskMessage(e)}sendEventAck(e){this.client.send("event-ack",{eventId:K(),status:"success",opCode:e})}initHandlers(){const e=(t=this.context,n=this.historyDb,s=e=>{this.sendEventAck(e)},{"cancel-task":async e=>{e.taskId===t.taskId&&($e.info(`[WORKER] Task ${t.taskId} cancelled`),await t.stopTask())},"stop-task":async e=>{e.taskId===t.taskId&&($e.info(`[WORKER] Task ${t.taskId} stopped: ${e.reason||"no reason"}`),await t.stopTask())},"task-message":async e=>{if(e.taskId!==t.taskId)return;let a=e.message??null;if(!a&&e.encryptedMessage&&t.dataEncryptionKey&&(a=ne(e.encryptedMessage,t.dataEncryptionKey)??null),!a)return;e.channelReplyTarget&&"object"==typeof a&&(a.__channelReplyTarget=e.channelReplyTarget);const i={senderType:e.senderType,senderId:e.senderId,senderName:e.senderName};if(t.attachmentsDir&&se(a)&&(a=await zc(a,{attachmentsDir:t.attachmentsDir,log:t.logger})),t.shouldPersistTaskMessage&&!await t.shouldPersistTaskMessage(a,i))return void $e.debug(`[WORKER] Dropping incoming task-message before persistence: eventId=${e.eventId}`);if(!n.saveMessage({eventId:e.eventId,message:a,senderType:e.senderType,senderId:e.senderId,senderName:e.senderName}).inserted)return $e.debug(`[WORKER] Ignoring duplicate incoming task-message: eventId=${e.eventId}`),void s(e.eventId);const o={...e,message:a,encryptedMessage:void 0,chatId:e.chatId??t.chatId};n.saveTaskEvent({eventType:"task-message",eventId:e.eventId,eventData:o,taskId:t.taskId,chatId:e.chatId??t.chatId,sequence:e.sequence??null}),s(e.eventId),t.onTaskMessage&&await t.onTaskMessage(a,i)},"task-info-update":async e=>{e.taskId===t.taskId&&t.onTaskInfoUpdate&&await t.onTaskInfoUpdate(e)},"worker-status-request":async e=>{e.taskId===t.taskId&&t.onWorkerStatusRequest&&await t.onWorkerStatusRequest(e)},"sub-task-result-updated":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskResultUpdated&&await t.onSubTaskResultUpdated(e)},"sub-task-ask-user":async e=>{e.parentTaskId===t.taskId&&t.onSubTaskAskUser&&await t.onSubTaskAskUser(e)}});var t,n,s;this.client.onEvent("cancel-task",e["cancel-task"]),this.client.onEvent("stop-task",e["stop-task"]),this.client.onEvent("task-message",e["task-message"]),this.client.onEvent("task-info-update",e["task-info-update"]),this.client.onEvent("worker-status-request",e["worker-status-request"]),this.client.onEvent("sub-task-result-updated",e["sub-task-result-updated"]),this.client.onEvent("sub-task-ask-user",e["sub-task-ask-user"]),this.client.onEvent("event-ack",e=>{const t=e.data?.sequence;void 0!==e.opCode&&(this.outbox.delete(e.opCode),this.usageOutbox.delete(e.opCode),this.ackWaiters.get(e.opCode)?.()),void 0!==e.opCode&&"number"==typeof t&&this.historyDb.updateTaskEventSequence(e.opCode,t)}),this.client.onLifecycle("connect",()=>{if(this.hasConnectedOnce){if(this.outbox.size>0){$e.info(`[WORKER] Reconnected — flushing ${this.outbox.size} outbox message(s)`);for(const[e,t]of this.outbox.entries()){const n=this.usageOutbox.get(e);n&&this.client.send("task-usage-report",n),this.client.send("task-message",t)}}}else this.hasConnectedOnce=!0})}}const Vl=Pt(ht),Xl="xmz-ai",Jl="agentrix-hive",Yl="https://github.com/xmz-ai/agentrix-hive.git",Ql="github";class Zl{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=K();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=de(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=de(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=de(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=Ce.resolveRepoStoreCheckoutDir(Ql,Xl,Jl),t=Ce.resolveRepoStoreLockPath(Ql,Xl,Jl),n=await Ce.acquireFileLock(t);if(!n)throw new Error(`Timed out waiting for Hive repository lock at ${t}`);try{if(!await di(e)){if(!xi(e))return{path:e,pullSucceeded:!1,error:`Hive repository checkout exists but is not a git repository: ${e}`};try{await fi(Yl,e)}catch(t){return{path:e,pullSucceeded:!1,error:t instanceof Error?t.message:String(t)}}return{path:e,pullSucceeded:!0}}await Ni(e,"origin",$i(Yl));try{return await Vl("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 Ce.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 Ue.promises.stat(e.path);this.logger.info("[Agent-Context] file stats");const n=t.size,s=e.contentType||Fn.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 Ue.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 ed(e,t){let n=e.resultMessage;if(0===n.result.trim().length&&e.encryptedResultMessage&&t){const s=ne(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 td(e,t){let n=e.message;if(!n&&e.encryptedMessage&&t){const s=ne(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 nd(){const e=new Set;return{filter(t){const n=t;if(!n.message||!n.message.content||"string"==typeof n.message.content)return t;const s=n.message.content.filter(t=>!("tool_result"===t.type&&e.has(t.tool_use_id)||"user"===n.type&&"tool_result"!==t.type));return 0===s.length?null:(n.message.content=s,n)},clear(){e.clear()}}}function sd(e){return yt("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:rt.string().describe("Concrete natural-language desktop operation to perform, including the app/document/target and desired outcome."),expectedResult:rt.string().optional().describe("Optional concise success condition the computer-use sub-task should verify before returning."),title:rt.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??lc(void 0,t.log);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(Vr);if(i)return t.log?.("info","COMPUTER_USE",`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"};t.log?.("info","COMPUTER_USE",`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(Vr,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),log:e.log});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 ad({workClient:e}){return yt("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:rt.string().describe("New title for the task")},async t=>(e.sendChangeTaskTitle(t.title),{content:[{type:"text",text:`Task title updated to: ${t.title}`}]}))}function id(e){return yt("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:rt.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=ee.parse({previewUrl:t}),s=await fetch(`${Ce.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 od(e){return yt("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:Or.shape.repoRoot,issueId:Or.shape.issueId},async t=>{const n=await Ur(t,e.taskId);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 rd({agentContext:e,log:t}){return yt("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:rt.string().describe("Sub-task ID to send the message to"),instructions:rt.string().optional().describe("Follow-up instructions for the sub-task (used when not answering ask_user)"),answers:rt.array(rt.string()).optional().describe("Answers to the sub-task ask_user questions, one per question. When provided, sends as ask_user_response.")},async n=>{try{let t;return t=n.answers&&n.answers.length>0?{type:"ask_user_response",answers:n.answers}:{type:"user",message:{role:"user",content:n.instructions??""}},await e.sendMessage({taskId:n.taskId,message:t,target:"agent"}),{content:[{type:"text",text:`${n.answers?"Sent ask_user response":"Sent follow-up instructions"} to sub-task ${n.taskId}.`}]}}catch(e){return t("error","TASK",`Failed to send message to sub-task ${n.taskId}:`,e),{content:[{type:"text",text:`Failed to send message to sub-task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function cd({historyDb:e}){return yt("get_task_history","Retrieve task history stored locally. Omit sequence to read the latest messages; only pass sequence when paginating to older messages.",{sequence:rt.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:rt.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=Al(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 ld({agentContext:e}){return yt("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 dd({agentContext:e,log:t}){return yt("list_sub_task","List direct sub tasks for the current task with taskId, title, and cwd.",{},async()=>{try{const t=await e.listSubTasks();return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No sub tasks found."}]}}catch(e){return t("error","TASK","Failed to list sub tasks:",e),{content:[{type:"text",text:`Failed to list sub tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function pd({agentContext:e,agentId:t,log:n,setPendingNavigateTaskId:s}){return yt("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:rt.string().optional().describe('Target agent ID (e.g., "agent-poster-generator"). If not provided, uses current agent.'),title:rt.string().min(1).max(200).describe("Task title for the agent to use (required)"),instructions:rt.string().describe("Detailed instructions for the agent. Be specific about what needs to be done."),briefSummary:rt.string().describe('One-line summary shown to user immediately (e.g., "Creating login page")'),cwd:rt.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:rt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place)."),independent:rt.boolean().optional().describe("Create as independent top-level task (no parent). Defaults to false (sub-task mode)."),autoNavigate:rt.boolean().optional().describe("Auto-switch App UI to this task after creation. Only works with independent=true. Defaults to false.")},async a=>{try{if(a.autoNavigate&&!a.independent)return{content:[{type:"text",text:"Error: autoNavigate can only be used with independent=true"}],isError:!0};const i=a.agentId||t;let o;return a.independent?(o=await e.startIndependentTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,autoNavigate:a.autoNavigate}),a.autoNavigate&&s(o.taskId),n("info","TASK",`Created independent task ${o.taskId} for agent ${i} (autoNavigate: ${a.autoNavigate??!1})`)):(o=await e.startSubTask({agentId:i,message:{type:"user",message:{role:"user",content:a.instructions}},title:a.title,cwd:a.cwd,forceUserCwd:!a.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}}),n("info","TASK",`Created sub-task ${o.taskId} for agent ${i}`)),{content:[{type:"text",text:`🚀 Task created: ${o.taskId}\n${a.agentId?`Agent: ${i}\n`:""}${a.independent?"Mode: Independent\n":""}Summary: ${a.briefSummary}\n\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return n("error","TASK","Failed to create task:",e),{content:[{type:"text",text:`Failed to create task: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function ud({agentContext:e,log:t}){return yt("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:rt.string().min(1).max(200).describe("Task title"),instructions:rt.string().describe("Instructions for the owner agent"),briefSummary:rt.string().optional().describe("One-line summary shown to user immediately"),agentId:rt.string().describe("Target agent ID"),cwd:rt.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:rt.boolean().optional().describe("Whether to create a git worktree for isolation. Defaults to false (work in-place).")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startSubTask({agentId:n.agentId,message:{type:"user",message:{role:"user",content:n.instructions}},title:n.title,cwd:n.cwd,forceUserCwd:!n.useWorktree,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","TASK","Create solo task failed:",e),{content:[{type:"text",text:`Create solo task failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function md({agentContext:e,log:t,agentId:n}){return yt("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:rt.string().min(1).max(200).describe("Task title"),requirement:rt.string().describe("Overall requirement"),briefSummary:rt.string().optional().describe("One-line summary shown to user immediately"),todos:rt.array(rt.object({agentId:rt.string().describe("Agent ID responsible for the todo"),title:rt.string().min(1).max(200).describe("Todo title"),instructions:rt.string().describe("Detailed instructions for this todo")})).min(1).describe("Todo list for agents")},async n=>{try{return{content:[{type:"text",text:`🚀 Task created: ${(await e.startGroupTask({title:n.title,todos:n.todos,initPolicies:{uncommittedChanges:"Ignore",branchMismatch:"Keep"},message:{type:"user",message:{role:"user",content:n.requirement}}})).taskId}\n${n.briefSummary?`Summary: ${n.briefSummary}\n`:""}\nYou'll receive a <sub-task-result-updated> notification when the task completes. Continue responding to the user.`}]}}catch(e){return t("error","DISPATCH","Dispatch failed:",e),{content:[{type:"text",text:`Dispatch failed: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function hd({askUser:e,log:t}){return yt("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:rt.array(rt.object({question:rt.string().describe("The complete question to ask the user"),header:rt.string().max(12).describe("Short label displayed as a chip/tag (max 12 chars)"),multiSelect:rt.boolean().describe("Set to true to allow multiple option selections"),options:rt.array(rt.object({label:rt.string().describe("Option label (1-5 words)"),description:rt.string().describe("Explanation of what this option means")})).min(2).max(4).describe("Available choices (2-4 options)")})).min(1).max(4).describe("Questions to ask (1-4 questions)")},async n=>{try{const t=n.questions.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]})),s=await e(t);return"answered"!==(s.status??"answered")?{content:[{type:"text",text:"The user did not provide an answer within the expected time. \n<system-reminder>Please abort the session, and decide whether to retry when the user provides a new message later.</system-reminder>"}],isError:!0}:{content:[{type:"text",text:`User answers:\n${s.answers.map(e=>e.startsWith("other:")?`Other: "${e.slice(6)}"`:e).join("\n")}`}]}}catch(e){return t("error","ASK_USER","Failed to get user response:",e),{content:[{type:"text",text:`Failed to get user response: ${e instanceof Error?e.message:"Unknown error"}`}]}}})}function gd({invokeAgent:e}){return yt("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:rt.string().describe("Target agent ID"),hint:rt.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 fd({workClient:e,agentId:t,uploadFile:n,log:s}){return yt("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:rt.string().optional().describe("Your display name"),avatarPath:rt.string().optional().describe("Local path to avatar image file (png/jpg/svg)"),signature:rt.string().optional().describe("Short status line or tagline shown under your name")},async a=>{let i;if(a.avatarPath)try{i=(await n({name:"avatar.png",path:a.avatarPath,visibility:"public"})).fileId}catch(e){return s("error","TOOL","Avatar upload failed:",e),{content:[{type:"text",text:`Avatar upload failed: ${e}`}],isError:!0}}e.sendUpdateAgentInfo(t,{displayName:a.displayName,avatar:i,signature:a.signature});const o=[];return a.displayName&&o.push(`name → ${a.displayName}`),i&&o.push("avatar → uploaded"),a.signature&&o.push(`signature → ${a.signature}`),{content:[{type:"text",text:`Profile updated: ${o.join(", ")}`}]}})}function vd({assign:e,log:t}){return yt("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:rt.string().describe("Target agent ID"),instruction:rt.string().describe("Task instruction for the agent"),acknowledgment:rt.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 yd({agentContext:e,log:t}){return yt("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:rt.number().int().min(1).max(50).default(10).optional().describe("Maximum number of tasks to return (default 10)."),status:rt.enum(["all","active","completed"]).default("all").optional().describe("Filter by task status: all, active, or completed.")},async n=>{try{const t=await e.listTasks({limit:n.limit??10,status:n.status??"all"});return t.length?{content:[{type:"text",text:JSON.stringify(t,null,2)}]}:{content:[{type:"text",text:"No tasks found."}]}}catch(e){return t("error","TASK","Failed to list tasks:",e),{content:[{type:"text",text:`Failed to list tasks: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function bd({chatHistoryDb:e}){return yt("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:rt.number().int().min(1).max(200).default(50).optional().describe("Number of recent messages to return (default 50)."),before:rt.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=Al(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 wd({agentContext:e,log:t}){return yt("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:rt.string().describe('Brief reminder message (one sentence, e.g., "Heartbeat architecture discussion pending for 2 days, consider following up")'),filePath:rt.string().optional().describe("Path to detailed analysis file in workspace, if any")},async n=>{try{const t=e.getChatId();return await e.sendMessage({taskId:t,message:{type:"companion_reminder",content:n.content,filePath:n.filePath,timestamp:(new Date).toISOString()},target:"agent"}),{content:[{type:"text",text:"Reminder sent to main companion."}]}}catch(e){return t("error","COMPANION","Failed to send reminder:",e),{content:[{type:"text",text:`Failed to send reminder: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}const xd=rt.enum(["created","updated","deleted"]);function kd({log:e,taskId:t}){return yt("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:rt.string().optional().describe("Deprecated compatibility field; each change.summary is used for the JSONL record and semantic git commit title."),trigger:rt.enum(["scheduled","user_request"]).describe("What triggered this memory change."),source:rt.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:rt.boolean().describe("Whether a reminder has already been sent or will be sent immediately after this record."),changes:rt.array(rt.object({file:rt.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:xd,summary:rt.string().describe("One-sentence summary of what changed."),reasons:rt.array(rt.string()).min(1).describe("Short reasons for this change."),deletedFiles:rt.array(rt.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 n=>{try{const s=process.env.AGENTRIX_COMPANION_HOME;if(!s)throw new Error("AGENTRIX_COMPANION_HOME is not set; memory changes can only be recorded by Companion workers.");const a=new Date,i=a.toISOString().slice(0,10),o=_(s,"memory-changes"),r=_(o,`${i}.jsonl`),c=n.changes.map(e=>({file:Ga(s,e.file).relativePath,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles?.map(e=>Ga(s,e).relativePath)??[]}));await Ba({companionHome:s,log:e});const l=new Map;for(const e of c){const t=l.get(e.file);t?t.push(e):l.set(e.file,[e])}const d=[];for(const i of l.values()){const o=i[0],r=Array.from(new Set(i.flatMap(e=>e.deletedFiles))),c=await za({companionHome:s,title:o.summary,body:Wa({trigger:n.trigger,source:n.source,action:o.action,file:o.file,reasons:i.flatMap(e=>e.reasons),deletedFiles:r,notifiedCompanion:n.notifiedCompanion,taskId:t}),paths:[o.file,...r],log:e});if(c)for(const e of i)d.push(JSON.stringify({time:a.toISOString(),trigger:n.trigger,source:n.source,taskId:t,file:e.file,action:e.action,summary:e.summary,reasons:e.reasons,deletedFiles:e.deletedFiles,notifiedCompanion:n.notifiedCompanion,commit:c}));else e("warn","COMPANION",`Skipping memory change JSONL record because no semantic git commit was created: file=${o.file}`)}return d.length>0&&(await Vt(o,{recursive:!0}),await Xt(r,`${d.join("\n")}\n`,"utf-8")),e("info","COMPANION",`Memory changes recorded: path=${r}, source=${n.source??"unspecified"}, trigger=${n.trigger}, records=${d.length}, requestedChanges=${c.length}, taskId=${t}`),{content:[{type:"text",text:d.length>0?`Memory changes recorded: ${d.length} JSONL record(s) at ${r}`:"No memory change JSONL records were written because no semantic git commit was created."}]}}catch(t){return e("error","COMPANION","Failed to record memory change:",t),{content:[{type:"text",text:`Failed to record memory change: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}function Id({uploadFile:e,log:n}){return yt("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., ![screenshot](url)).",{filePath:rt.string().describe("Absolute path to the local file to upload"),name:rt.string().optional().describe("Display name for the file (defaults to filename)")},async s=>{try{const n=t("path"),a=s.name||n.basename(s.filePath);return{content:[{type:"text",text:(await e({name:a,path:s.filePath,visibility:"public"})).url}]}}catch(e){return n("error","TOOL","File upload failed:",e),{content:[{type:"text",text:`File upload failed: ${e}`}],isError:!0}}})}const Sd=2147483648,Td=/(^\.env($|\.)|\.pem$|\.key$|\.p12$|\.pfx$|^id_rsa$|^id_dsa$|^id_ecdsa$|^id_ed25519$|credential|credentials|secret|secrets|token)/i;function Ed({taskId:e,chatId:t,historyDb:n,getChannelReplyTarget:s,onChannelMessageInvoked:a,log:i}){return yt("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:rt.string().optional().describe("Text to send to the external user. Required when attachments are omitted."),attachments:rt.array(rt.object({filePath:rt.string().describe("Absolute path to an existing user-facing deliverable file. Relative paths are rejected."),fileName:rt.string().optional().describe("Optional display filename shown to the external user. Defaults to the local basename."),kind:rt.enum(["auto","image","file","audio","video"]).optional().describe("Attachment kind. Use auto unless you know the exact type.")})).optional().describe("Optional user-facing deliverable files to send with the message.")},async o=>{const r=s?.()??null;if(!r)return{content:[{type:"text",text:"Unsupported: this task is not bound to an external channel, so no channel message can be sent."}],isError:!0};a?.();try{const s=o.content?.trim(),a=await async function(e){const t=[];for(const n of e)t.push(await _d(n));return t}(o.attachments??[]);if(!s&&0===a.length)throw new Error("send_channel_message requires content or attachments");const i=await un(e,{content:s||void 0,attachments:a.length>0?a:void 0},r);return i?.error?(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"error",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,kind:e.kind})),error:i.error}}),{content:[{type:"text",text:`Failed to send channel message: ${i.error}`}],isError:!0}):(n.saveTaskEvent({taskId:e,chatId:t,eventType:"channel-message-send",sequence:null,eventData:{status:"sent",channelId:r.channelId,hasContent:Boolean(s),attachments:a.map(e=>({filePath:e.filePath,fileName:e.fileName,mimeType:e.mimeType,kind:e.kind}))}}),{content:[{type:"text",text:a.length>0?`Sent channel message with ${a.length} attachment(s).`:"Sent channel message."}]})}catch(e){return i("warn","CHANNEL","Channel message send rejected or failed:",e),{content:[{type:"text",text:`Failed to send channel message: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Ad({taskId:e,getChannelReplyTarget:t}){return yt("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:rt.number().int().positive().max(100).optional().describe("Maximum messages to return. Defaults to 30; capped at 100."),beforeSeq:rt.number().int().positive().optional().describe("Return messages before this local sequence number for older pages."),afterSeq:rt.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 cn("/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 _d(e){if(!D(e.filePath))throw new Error("filePath must be absolute");const t=await Jt(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>Sd)throw new Error(`file is too large for channel delivery (${t.size} bytes; max 2147483648 bytes)`);const n=e.fileName||C(e.filePath),s=C(e.filePath);if(Td.test(s)||Td.test(n))throw new Error("refusing to send an attachment with a sensitive-looking filename");const a=Fn.lookup(n)||Fn.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 Cd({agentContext:e,log:t}){return yt("list_agents","List all available agents for the current user, including system agents and user-created agents (both published and draft).",{},async()=>{try{const{agents:t,draftAgents:n}=await e.listAgents(),s=e=>`- **${e.displayName||e.name}** (${e.id})\n Type: ${e.type}\n`+(e.developerName?` Developer: ${e.developerName}\n`:"")+` ${e.description||"No description"}\n`;let a="# Available Agents\n\n";return t.length>0&&(a+="## Published Agents\n\n",a+=t.map(s).join("\n")),n.length>0&&(a+="\n## Draft Agents\n\n",a+=n.map(s).join("\n")),0===t.length&&0===n.length&&(a+="No agents available."),{content:[{type:"text",text:a}]}}catch(e){return t("error","AGENTS","Failed to list agents:",e),{content:[{type:"text",text:`Failed to list agents: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}async function*$d(e){yield e}function Nd({visionModel:e,log:t}){return yt("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:rt.string().describe("Absolute path to the image file to analyze"),prompt:rt.string().optional().describe("Optional specific question or instruction about the image (default: describe the image)")},async n=>{if(!e)return{content:[{type:"text",text:"Vision analysis is not available (missing configuration)."}],isError:!0};try{const t=(await Kt(n.imagePath)).toString("base64"),s={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp"}[n.imagePath.split(".").pop()?.toLowerCase()??"jpeg"]??"image/jpeg",a=n.prompt||"Describe this image in detail.",i=vt({prompt:$d({type:"user",message:{role:"user",content:[{type:"image",source:{type:"base64",media_type:s,data:t}},{type:"text",text:a}]},parent_tool_use_id:null,session_id:""}),options:{model:e,permissionMode:"bypassPermissions",maxTurns:1,tools:[]}});let o="";for await(const e of i)if("result"===e.type){o=e.result??"";break}return{content:[{type:"text",text:o||"No description returned."}]}}catch(e){return t("error","VISION","Failed to analyze image:",e),{content:[{type:"text",text:`Failed to analyze image: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function Rd({log:e}){return yt("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:rt.enum(["create","list","delete"]).describe("Operation to perform"),task:rt.string().optional().describe("Task description (required for create)"),type:rt.enum(["once","recurring"]).optional().describe("Task type (required for create)"),due:rt.string().optional().describe("ISO 8601 timestamp for one-time tasks"),cron:rt.string().optional().describe('Cron expression for recurring tasks (e.g., "0 18 * * *")'),timezone:rt.string().optional().describe('IANA timezone (e.g., Asia/Shanghai). Required when timeType is "local"'),timeType:rt.enum(["utc","local"]).optional().describe('How to interpret time — "utc" for absolute UTC, "local" (default) for user timezone'),id:rt.string().optional().describe("Task ID (required for delete)")},async t=>{try{const e=await Ce.readDaemonState();if(!e?.port)return{content:[{type:"text",text:"Daemon not running."}],isError:!0};const n=`http://127.0.0.1:${e.port}`;if("list"===t.action){const e=await fetch(`${n}/schedule`),t=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${t.error}`}],isError:!0};const s=t.tasks??[];return 0===s.length?{content:[{type:"text",text:"No scheduled tasks."}]}:{content:[{type:"text",text:s.map(e=>`- [${e.id}] ${"once"===e.type?`once at ${e.due}`:`recurring: ${e.cron}`} — "${e.task}"`).join("\n")}]}}if("create"===t.action){if(!t.task||!t.type)return{content:[{type:"text",text:"Missing required fields: task, type"}],isError:!0};const e=await fetch(`${n}/schedule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:t.task,type:t.type,due:t.due,cron:t.cron,timezone:t.timezone,timeType:t.timeType})}),s=await e.json();if(!e.ok)return{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0};const a="once"===s.type?`due=${s.due}`:`cron=${s.cron}`;return{content:[{type:"text",text:`Scheduled: id=${s.id}, ${a}`}]}}if("delete"===t.action){if(!t.id)return{content:[{type:"text",text:"Missing required field: id"}],isError:!0};const e=await fetch(`${n}/schedule/${t.id}`,{method:"DELETE"}),s=await e.json();return e.ok?{content:[{type:"text",text:`Deleted: ${t.id}`}]}:{content:[{type:"text",text:`Error: ${s.error}`}],isError:!0}}return{content:[{type:"text",text:`Unknown action: ${t.action}`}],isError:!0}}catch(t){return e("error","SCHEDULE","Schedule task failed:",t),{content:[{type:"text",text:`Failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}})}function Pd({agentContext:e,log:t}){return yt("hive_prepare_repository","Prepare the Agentrix Hive source repository in the local global repo store.\n\nUse this before discovering community agents or skills. This tool only clones/pulls\nthe repository and returns the absolute checkout path. It does not search and does\nnot define the repository layout. After calling it, use Explore with a\ntask-specific goal to find relevant candidates; do not catalog the whole repo\nunless the user explicitly asks for a catalog. If pullSucceeded is false, inspect\nerror and continue with the existing local checkout when it is usable.",{},async()=>{try{const t=await e.prepareHiveRepository();return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Failed to prepare Hive repository:",e),{content:[{type:"text",text:`Failed to prepare Hive repository: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Md({agentContext:e,log:t}){return yt("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:rt.enum(["agent","skill"]),draftAgentId:rt.string().optional().describe("DraftAgent ID for agent publishing"),sourceDir:rt.string().optional().describe("Absolute local skill directory for skill publishing"),name:rt.string().optional().describe("Listing name, lowercase kebab-case"),displayName:rt.string().optional().describe("Human-readable listing name"),description:rt.string().optional(),readme:rt.string().optional(),category:rt.string().optional(),tags:rt.array(rt.string()).optional(),authorType:rt.enum(["user","agent"]).default("user"),authorId:rt.string(),machineId:rt.string().optional(),cloudId:rt.string().optional()},async n=>{try{const t=await e.publishToHive(n);return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive publish failed:",e),{content:[{type:"text",text:`Hive publish failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Dd({agentContext:e,log:t}){return yt("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:rt.string().describe("Owned HiveListing ID to update"),version:rt.string().optional().describe("Optional new version; defaults to next patch version"),changelog:rt.string().optional(),sourceDir:rt.string().optional().describe("Absolute local skill directory for skill listing updates"),machineId:rt.string().optional(),cloudId:rt.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.updateHiveListingVersion(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive update failed:",e),{content:[{type:"text",text:`Hive update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Od({agentContext:e,log:t}){return yt("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:rt.string().describe("HiveListing ID read from agentrix-hive-id.txt in the Hive source directory"),agentDir:rt.string().describe("Absolute local directory where the agent or skill was installed"),name:rt.string().optional().describe("Optional local name for installed agent"),machineId:rt.string().optional(),cloudId:rt.string().optional(),installedVersion:rt.string().optional()},async n=>{try{const{listingId:t,...s}=n,a=await e.recordHiveInstall(t,s);return{content:[{type:"text",text:JSON.stringify(a,null,2)}]}}catch(e){return t("error","HIVE","Hive install record failed:",e),{content:[{type:"text",text:`Hive install record failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Ud({agentContext:e,log:t}){return yt("hive_review","Leave or update structured feedback for a Hive listing after using it or evaluating user/Syn feedback.",{listingId:rt.string().describe("HiveListing ID"),rating:rt.number().int().min(1).max(5),comment:rt.string().optional().describe("Markdown review text")},async n=>{try{const t=await e.createHiveReview(n.listingId,{rating:n.rating,comment:n.comment??null});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive review failed:",e),{content:[{type:"text",text:`Hive review failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function jd({agentContext:e,log:t}){return yt("hive_comment","Leave a discussion comment, bug report, usage suggestion, or reply for a Hive listing.",{listingId:rt.string().describe("HiveListing ID"),content:rt.string().min(1).describe("Markdown comment content"),parentId:rt.string().optional().describe("Parent comment ID for replies")},async n=>{try{const t=await e.createHiveComment(n.listingId,{content:n.content,parentId:n.parentId});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(e){return t("error","HIVE","Hive comment failed:",e),{content:[{type:"text",text:`Hive comment failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function Ld(e){if(e)return e.replace(/\/+$/g,"")||"/"}function qd(e){return{eventData:e.eventData,gitUrl:e.gitUrl,baseBranch:e.baseBranch,branchName:e.branchName,branchBinding:e.branchBinding,cwd:Ld(e.cwd)||"",userCwd:Ld(e.userCwd),forceUserCwd:e.forceUserCwd,useWorktree:e.useWorktree,initPolicies:e.initPolicies,userId:e.userId,taskId:e.taskId,repositorySourceType:e.repositorySourceType,taskRepositoryId:e.repositoryId,gitServerId:e.gitServerId,channelReplyTarget:e.channelReplyTarget}}function Hd(e){return!!e.branchName&&"none"!==e.branchBinding&&"external-observed"!==e.branchBinding}function Gd(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 Bd(e,t){const n=Mt(e);await n.raw(["checkout","-B",t,"HEAD"])}function Fd(e){return`HEAD:refs/heads/${e}`}function Wd(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 zd(e){if(!e)return null;const t=await po();return t?go(e,t):null}async function Kd(e,t){const n=ho(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 ci("git",["config","user.name",t],{cwd:e,windowsHide:!0}),await ci("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 Vd(e,t,n){const s=await zd(n);s?await async function(e,t){const n=ji();try{await ci("git",["-c","credential.helper=","fetch","--prune","origin"],{cwd:t,env:Li(n,e),windowsHide:!0})}finally{f(n)}}(s,e):await async function(e,t){await ci("git",["-c","credential.helper=","fetch","--prune",e,"+refs/heads/*:refs/remotes/origin/*","+refs/tags/*:refs/tags/*"],{cwd:t,env:qi(),windowsHide:!0})}(t,e)}async function Xd(e,t,n,s,a,i){const o=$i(t),c=await di(e);if(!xi(e)&&!c)throw new Error(`Directory ${e} exists but is not a git repository`);const l=await zd(a);return xi(e)?(l?(console.log("[GIT] Using GIT_ASKPASS credential injection for clone"),await async function(e,t,n){const s=P(n);r(s)||d(s,{recursive:!0});const a=ji();try{await ci("git",["-c","credential.helper=","clone",t,n],{env:Li(a,e),windowsHide:!0})}finally{f(a)}}(l,o,e),a&&await Kd(e,a)):await fi(t,e),await Ci(e,"origin",o),i&&await vi(e,i,s),await bi(e)):(await Ni(e,"origin",o),await Vd(e,t,a),a&&await Kd(e,a),i&&await vi(e,i,s),await bi(e))}async function Jd(e,t,n,s={}){const a=await zd(s.gitServerId);a?await async function(e,t,n,s=!1){const a=ji();try{const i=["-c","credential.helper=","push","origin",n];s&&i.push("--force"),await ci("git",i,{cwd:t,env:Li(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 ci("git",a,{cwd:t,env:qi(),windowsHide:!0})}(s.gitUrl,e,t,n):await async function(e,t,n=!1){const s=li(e),a=n?["--force"]:[];await s.push("origin",t,a)}(e,t,n)}async function Yd(e,t,n){const s=n.trim();if(!s)return;const a=Ce.resolveDataDir(e,t),i=_(a,"patch.diff");return await _t(a,{recursive:!0}),await $t(i,`${s}\n`),i}async function Qd(e,t,n){await Ce.writeLastSentArtifactVersion(e,t,n)}function Zd(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 ep(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:Gt()}}function tp(e){return{type:"assistant",message:{role:"assistant",content:[{type:"text",text:e}]},parent_tool_use_id:null,session_id:"",uuid:Gt()}}function np(e){const t="```sh\n",n="\n```";return`${t}${Bl(e.trim()?e:"[Command completed with no output]",1024-Buffer.byteLength(t,"utf8")-Buffer.byteLength(n,"utf8"))}${n}`}function sp(e,t,n,s=6e4){return new Promise(a=>{const i=tt("/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=np(l);n.onOutput(tp(p)),n.onOutput(ep(p,i,d)),n.onComplete(i),a(i)}),i.on("error",e=>{o&&clearTimeout(o);const t=np(`[Error] ${e.message||"Command execution failed"}`);n.onOutput(tp(t)),n.onOutput(ep(t,1,!0)),n.onComplete(1),a(1)})})}class ap{config;messageQueue=[];agentMessageQueue=[];agentMessageResolver=null;workerState="running";messageIdCounter=0;isStopped=!1;runStartTime=Date.now();commandRunning=!1;isDebouncing=!1;agentRunningMap=new Map;backgroundTaskMap=new Map;anonymousBackgroundTaskCount=0;lastActiveAgentsSignature=null;idleTimeoutHandle=null;idleTimeoutMs;constructor(e){this.config=e,this.idleTimeoutMs=Math.max(0,e.idleTimeoutMs??0)}parseMessage(e){if("user"!==e.type)return{type:"normal",content:"",originalMessage:e};const t=("string"==typeof e.message.content?e.message.content:"").trim();return t.startsWith("!")&&!t.startsWith("![")?{type:"bash-command",content:t.slice(1).trim(),originalMessage:e}:"![merge-request]"===t?{type:"merge-request",content:t,originalMessage:e}:"![merge-pr]"===t?{type:"merge-pr",content:t,originalMessage:e}:"![new]"===t?{type:"new-session",content:t,originalMessage:e}:"![agentrix-dev-init]"===t?{type:"agentrix-dev-init",content:t,originalMessage:e}:"![plan]"===t?{type:"plan-mode",content:t,originalMessage:e}:{type:"normal",content:t,originalMessage:e}}async enqueue(e){if(this.isStopped)return void this.log("warn","COORDINATOR","Ignoring message - coordinator is stopped");if(!("user"!==e.type||e.message&&"object"==typeof e.message&&"content"in e.message))return void this.log("warn","COORDINATOR","Ignoring malformed user message (missing content)");const t=this.parseMessage(e),n={id:"msg-"+ ++this.messageIdCounter,type:t.type,priority:"normal",content:t.content,originalMessage:e,timestamp:Date.now()};this.messageQueue.push(n),this.log("info","COORDINATOR",`Enqueued message ${n.id} (type: ${n.type}, queue: ${this.messageQueue.length})`),this.tryUpdateWorkerState(),this.tryProcessNext()}async tryProcessNext(){if(!this.isStopped)if(0!==this.messageQueue.length)try{const e=this.messageQueue.shift();this.log("info","COORDINATOR",`Processing message ${e.id} (type: ${e.type})`),await this.processMessage(e),this.log("info","COORDINATOR",`Completed message ${e.id}`)}catch(e){this.log("error","COORDINATOR",`Error processing message: ${e}`)}finally{this.tryUpdateWorkerState(),this.isStopped||this.tryProcessNext()}else this.tryUpdateWorkerState()}async processMessage(e){switch(e.type){case"normal":await this.processNormalMessage(e);break;case"bash-command":await this.processBashCommand(e);break;case"merge-request":await this.processMergeRequest(e);break;case"merge-pr":await this.processMergePr(e);break;case"new-session":await this.processNewSession(e);break;case"agentrix-dev-init":await this.processAgentrixDevInit(e);break;case"plan-mode":await this.processPlanMode(e);break;default:this.log("warn","COORDINATOR",`Unknown message type: ${e.type}`)}}async processNormalMessage(e){this.log("info","COORDINATOR","Processing normal message for SDK");const t=await this.config.handlers.onNormalMessage(e.originalMessage);this.enqueueAgentMessage(t)}async processBashCommand(e){this.log("info","COORDINATOR",`Processing bash command: ${e.content}`),await this.processCommand(async()=>{await this.config.handlers.onBashCommand(e.content,e.originalMessage)},e)}async processMergeRequest(e){this.log("info","COORDINATOR","Processing merge-request command"),await this.processCommand(async()=>{await this.config.handlers.onMergeRequest(e.originalMessage)},e)}async processMergePr(e){this.log("info","COORDINATOR","Processing merge-pr command"),await this.processCommand(async()=>{await this.config.handlers.onMergePr()},e)}async processNewSession(e){this.log("info","COORDINATOR","Processing new-session command"),await this.processCommand(async()=>{await(this.config.handlers.onNewSession?.())},e)}async processAgentrixDevInit(e){this.log("info","COORDINATOR","Processing agentrix-dev-init command"),await this.processCommand(async()=>{await(this.config.handlers.onAgentrixDevInit?.(e.originalMessage))},e)}async processPlanMode(e){this.log("info","COORDINATOR","Processing plan-mode command"),await this.processCommand(async()=>{if(!this.config.handlers.onPlanMode)return;const t=await this.config.handlers.onPlanMode(e.originalMessage);t&&this.enqueueAgentMessage(t)},e)}async processCommand(e,t){await this.waitWorkerIdle(),this.setCommandRunning(!0),this.markCommandMessageProcessed(t);try{await e()}finally{this.setCommandRunning(!1)}}markCommandMessageProcessed(e){const t=e.originalMessage.__localSequence;void 0!==t&&this.config.onCommandMessageProcessed?.(t)}async waitWorkerIdle(){for(;"idle"!==this.getExecutionState();){if(this.isStopped)throw new Error("Coordinator stopped while waiting for idle");this.log("debug","COORDINATOR","Waiting for worker idle state"),await new Promise(e=>setTimeout(e,100))}}setWorkerState(e){if(this.workerState===e)return;const t=this.workerState;if(this.log("info","COORDINATOR",`Worker state: ${t} → ${e}`),this.workerState=e,"running"===e&&"idle"===t&&(this.runStartTime=Date.now(),this.config.workClient.sendWorkRunning(this.getActiveAgents()),this.lastActiveAgentsSignature=this.getActiveAgentsSignature(),this.clearIdleTimer()),"idle"===e&&"running"===t){let e;this.runStartTime&&(e=Date.now()-this.runStartTime,this.runStartTime=null),this.config.workClient.sendWorkerReady(e),this.lastActiveAgentsSignature=null,this.startIdleTimer(),this.config.onBecameIdle?.()}}updateAgentRunning(e){this.setAgentRunning("default","Agent",e)}setAgentRunning(e,t,n){const s="running"===this.workerState,a=this.lastActiveAgentsSignature;n?this.agentRunningMap.set(e,{agentId:e,agentName:t,startedAt:Date.now()}):this.agentRunningMap.delete(e);const i=this.getActiveAgentsSignature();this.lastActiveAgentsSignature=i,this.tryUpdateWorkerState(),s&&"running"===this.workerState&&i!==a&&this.config.workClient.sendWorkRunning(this.getActiveAgents())}setBackgroundTaskRunning(e,t){e&&(t?this.backgroundTaskMap.set(e,{taskId:e,startedAt:Date.now()}):!this.backgroundTaskMap.delete(e)&&this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Background task ${e} completed via anonymous fallback (remaining: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState())}setAnonymousBackgroundTaskRunning(e){e?(this.anonymousBackgroundTaskCount+=1,this.log("debug","COORDINATOR",`Anonymous background task started (count: ${this.anonymousBackgroundTaskCount})`)):this.anonymousBackgroundTaskCount>0&&(this.anonymousBackgroundTaskCount-=1,this.log("debug","COORDINATOR",`Anonymous background task completed (count: ${this.anonymousBackgroundTaskCount})`)),this.tryUpdateWorkerState()}getActiveAgents(){return Array.from(this.agentRunningMap.values()).map(({agentId:e,agentName:t})=>({agentId:e,agentName:t}))}getActiveAgentsSignature(){const e=this.getActiveAgents().slice().sort((e,t)=>e.agentId.localeCompare(t.agentId));return JSON.stringify(e)}enqueueAgentMessage(e){if(this.isStopped)this.log("warn","COORDINATOR","Ignoring agent message - coordinator is stopped");else if(this.agentMessageQueue.push(e),this.agentMessageResolver){const e=this.agentMessageResolver;this.agentMessageResolver=null,e(this.agentMessageQueue.shift())}}hasAgentMessages(){return this.agentMessageQueue.length>0}getAgentQueueLength(){return this.agentMessageQueue.length}async waitForAgentMessage(){return this.isStopped?null:this.agentMessageQueue.length>0?this.agentMessageQueue.shift():new Promise(e=>{this.agentMessageResolver=e})}cancelAgentWait(){if(!this.agentMessageResolver)return;const e=this.agentMessageResolver;this.agentMessageResolver=null,e(null)}setCommandRunning(e){this.commandRunning!==e&&(this.commandRunning=e,this.tryUpdateWorkerState())}hasExecutionWork(){return this.commandRunning||this.agentRunningMap.size>0||this.backgroundTaskMap.size>0||this.anonymousBackgroundTaskCount>0||this.isDebouncing}getExecutionState(){return this.hasExecutionWork()?"running":"idle"}setDebouncing(e){this.isDebouncing!==e&&(this.isDebouncing=e,this.tryUpdateWorkerState())}tryUpdateWorkerState(){if(this.isStopped)return;const e=this.messageQueue.length>0||this.agentMessageQueue.length>0,t=this.hasExecutionWork(),n=!e&&!t;this.setWorkerState(n?"idle":"running")}startIdleTimer(){0!==this.idleTimeoutMs&&(this.idleTimeoutHandle||(this.idleTimeoutHandle=setTimeout(()=>{this.idleTimeoutHandle=null,this.isStopped||(this.log("info","COORDINATOR","Idle timeout reached, stopping task"),this.cancelAgentWait(),this.config.onIdleTimeout?.())},this.idleTimeoutMs)))}clearIdleTimer(){this.idleTimeoutHandle&&(clearTimeout(this.idleTimeoutHandle),this.idleTimeoutHandle=null)}getStatus(){return{state:this.workerState}}isActivelyExecuting(){return this.hasExecutionWork()}stop(){this.log("info","COORDINATOR","Stopping coordinator"),this.isStopped=!0,this.clearIdleTimer(),this.messageQueue=[],this.agentMessageQueue=[],this.backgroundTaskMap.clear(),this.anonymousBackgroundTaskCount=0,this.cancelAgentWait()}log(e,t,n){this.config.logger&&this.config.logger(e,t,n)}}function ip(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(zl,n)}async function op(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 _i(t),s=await yi(t),d=await async function(e,t){const n=li(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 ip(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 Jd(t,e,!1,{gitServerId:a,gitUrl:i}),"Push"===p))return void ip(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)ip(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 rp(e,t,n){let s=!1;const a={},i=e.updates?.repositoryId;"string"==typeof i&&i.length>0&&t.repositoryId!==i&&(t.repositoryId=i,a.taskRepositoryId=i,s=!0);const o=e.updates?.branchName;"string"==typeof o&&o.length>0&&t.branchName!==o&&(t.branchName=o,a.branchName=o,s=!0);const r=e.updates?.branchBinding;return"none"!==r&&"explicit"!==r&&"platform-managed"!==r&&"external-observed"!==r||t.branchBinding===r||(t.branchBinding=r,a.branchBinding=r,s=!0),s&&n&&await n.updateTaskMetadata(a),s}function cp(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 lp(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:ke(),session_id:e.sessionId}}function dp(e,t){const n=ke();return t.set(e,n),n}function pp(e,t){return t.get(e)||e}function up(e,t,n={}){return"thread.started"===e.type||"turn.started"===e.type||"turn.completed"===e.type||"turn.failed"===e.type?null:"error"===e.type?{type:"system",subtype:"temporary",content:e.message}:"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:dp(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:dp(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:dp(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:dp(e.id,t),name:"web_search",input:{query:e.query}}]},parent_tool_use_id:null,session_id:""}}(e,t);default:return null}}(e.item,t):"item.completed"===e.type?function(e,t,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:ke().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:pp(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??dp(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=pp(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=mp(n,t.taskDataDir);if(s!==n)return[s];const a=hp(e,t.taskDataDir);return a?[n,a]:n}const a=n.map(e=>mp(e,t.taskDataDir)),i=hp(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:pp(e.id,t),content:{type:"web_search_result",results:[]}}]},parent_tool_use_id:null,session_id:""}}(e,t);case"todo_list":return function(e){return{type:"assistant",message:{role:"assistant",content:`📋 Todo List:\n${e.items.map(e=>`${e.completed?"✓":"○"} ${e.text}`).join("\n")}`},parent_tool_use_id:null,session_id:""}}(e);case"error":return function(e){return{type:"assistant",message:{role:"assistant",content:`❌ Error: ${e.message}`},parent_tool_use_id:null,session_id:""}}(e)}}(e.item,t,n):null}function mp(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:gp(i),mimeType:a}:null}(e);if(!n)return e;try{const 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,`${ke()}${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 hp(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=_(t,"attachments");d(e,{recursive:!0});const s=function(e){const t=$(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,`${ke()}${s}`);return k(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 gp(e){const t=e.match(/^data:[^;]+;base64,(.*)$/s);return t?t[1]:e}let fp,vp,yp;function bp(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 wp(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 xp(e){const t=e?.trim();return t||function(){const e=function(){const e=process.env.CODEX_HOME||process.env.AGENTRIX_CODEX_HOME||_(n.homedir(),".codex");return _(e.replace(/^~(?=\/|$)/,n.homedir()),"config.toml")}();if(vp===e&&void 0!==fp)return fp;if(vp=e,fp=null,!r(e))return fp;let t;try{t=c(e,"utf8")}catch{return fp}for(const e of t.split(/\r?\n/)){const t=bp(e).trim();if(!t)continue;if(t.startsWith("["))break;const n=t.match(/^model\s*=\s*(.+)$/);if(!n)continue;const s=wp(n[1])?.trim();return fp=s||null,fp}return fp}()}class kp{createCodex(e){const t={},n=function(){if(void 0!==yp)return yp??void 0;const e=process.env.AGENTRIX_CODEX_PATH?.trim();if(e)return yp=e,e;yp=null}();n&&(t.codexPathOverride=n),e.env&&(t.env=ka(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(ra(`\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 ra(`\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 ra(`\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 Yt(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=xp(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),r=await o.run("string"==typeof e?e:Ta(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});return Ea({sessionId:o.id??t.agentSessionId??"unknown",model:a??"unknown",numTurns:1,usage:r.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0},result:r.finalResponse??"",structuredOutput:Aa(r.finalResponse??"",Boolean(t.structuredOutputSchema))})}async*runStreamed(e,t){const n=t.abortController,s=this.createCodex(t),a=xp(t.model),i={workingDirectory:t.cwd,model:a??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0},o=t.agentSessionId?s.resumeThread(t.agentSessionId,i):s.startThread(i),{events:r}=await o.runStreamed("string"==typeof e?e:Ta(e),{signal:n.signal,outputSchema:t.structuredOutputSchema?.schema||void 0});let c=t.agentSessionId||"",l="",d={input_tokens:0,cached_input_tokens:0,output_tokens:0,reasoning_output_tokens:0};const p=new Map,u={get:e=>p.get(e),set:(e,t)=>{p.set(e,t)}};for await(const e of r){if("thread.started"===e.type&&(c=e.thread_id,yield lp({sessionId:c,cwd:t.cwd,model:a??void 0})),"turn.completed"===e.type){e.usage&&(d=e.usage);break}if("turn.failed"===e.type)throw new Error(e.error.message);if("item.completed"===e.type&&"agent_message"===e.item.type&&e.item.text&&(l=e.item.text),"error"===e.type||"item.started"===e.type||"item.completed"===e.type){const n=up(e,u,{taskDataDir:t.taskDataDir});if(!n)continue;const s=Array.isArray(n)?n:[n];for(const e of s)yield e}}const m=Ea({sessionId:c,model:a??"unknown",numTurns:1,usage:d,result:l,structuredOutput:Aa(l,Boolean(t.structuredOutputSchema))});yield m}loop(e){const t=e.abortController,n=this.createCodex(e),s=xp(e.model),a={workingDirectory:e.cwd,model:s??void 0,sandboxMode:"danger-full-access",approvalPolicy:"never",skipGitRepoCheck:!0};let i=e.agentSessionId?n.resumeThread(e.agentSessionId,a):n.startThread(a),o=!1;const r=[];let c=null,l=e.agentSessionId??null,d=0;const p=()=>{if(!o&&(o=!0,c)){const e=c;c=null,e(null)}},u=e=>"string"==typeof e?e:Ta(e),m=async function*(){try{for(;!o&&!t.signal.aborted;){const n=r.length>0?r.shift():await new Promise(e=>{c=e});if(!n)break;let a="";const p=new Map,m={get:e=>p.get(e),set:(e,t)=>{p.set(e,t)}},{events:h}=await i.runStreamed(u(n),{signal:t.signal,outputSchema:e.structuredOutputSchema?.schema||void 0});for await(const t of h){if(o)break;if("thread.started"!==t.type){if("turn.completed"===t.type){l&&(yield Ea({sessionId:l,model:s??"unknown",numTurns:d+1,usage:t.usage??{input_tokens:0,cached_input_tokens:0,output_tokens:0},result:a,structuredOutput:Aa(a,Boolean(e.structuredOutputSchema))}));break}if("turn.failed"===t.type)throw new Error(t.error.message);if("error"===t.type||"item.started"===t.type||"item.completed"===t.type){"item.completed"===t.type&&"agent_message"===t.item.type&&t.item.text&&(a=t.item.text);const n=up(t,m,{taskDataDir:e.taskDataDir});if(!n)continue;const s=Array.isArray(n)?n:[n];for(const e of s)yield e}}else l=t.thread_id,yield lp({sessionId:l,cwd:e.cwd,model:s??void 0})}d+=1}}finally{p()}}();return t.signal.addEventListener("abort",p,{once:!0}),{push:e=>{if(console.log("CodexRunner.loop.push:",JSON.stringify(e,null,2)),!o){if(c){const t=c;return c=null,void t(e)}r.push(e)}},events:m,stop:p}}}const Ip=["PreToolUse","PostToolUse","SessionStart","SessionEnd","UserPromptSubmit","Stop","SubagentStop","PreCompact","Notification"];function Sp(e){const t={};for(const n of Ip){const s=e[n];"function"==typeof s&&(t[n]=s,console.log(`[Hook Loader] ✓ Loaded hook: ${n}`))}const n=Object.keys(t).length;return 0===n?console.warn("[Hook Loader] No valid hooks found in module"):console.log(`[Hook Loader] Successfully loaded ${n} hook(s)`),t}class Tp{static pool=new Map;static async create(e,t,n){const s=this.pool.get(t);if(s)return s;let a;if("claude"===e||"companion"===e){const s=await async function(e){const{agentId:t,agentDir:n,logger:s}=e;if(!t||"default"===t)return{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};try{si(s,"info",`Loading agent: ${t}`);const e=await xt({agentId:t,framework:"claude",agentDir:n});if(!e.claude)return si(s,"warn",`No claude configuration found for agent ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0};const a=e.claude,i=a.plugins.map(e=>({type:"local",path:e})),o=n||kt().resolveAgentDir(t),r=a.config.sdkMcpTools?.map(e=>_(o,"claude",e)),c={customSystemPrompt:a.systemPrompt,customModel:a.config.model,customFallbackModel:a.config.fallbackModel,customMaxTurns:a.config.maxTurns,customExtraArgs:a.config.extraArgs,customPermissionMode:a.config.settings?.permissionMode,customPlugins:i,systemPromptMode:a.config.systemPrompt?.mode??"append",customPRPromptTemplate:a.prPromptTemplate,prPromptMode:a.config.pullRequestPrompt?.mode??"append",customSdkMcpTools:r};return si(s,"info",`Agent ${t} loaded successfully (${i.length} plugins)`),c}catch{return si(s,"error",`Failed to load agent: ${t}`),{customSystemPrompt:void 0,customModel:void 0,customFallbackModel:void 0,customMaxTurns:void 0,customExtraArgs:void 0,customPermissionMode:void 0,customPlugins:[],systemPromptMode:"append",customPRPromptTemplate:void 0,prPromptMode:"append",customSdkMcpTools:void 0}}}({agentId:t,agentDir:n?.agentDir,logger:n?.logger});let i,o;n?.context&&t&&"default"!==t&&(i=await async function(e,t,n){if(e&&"default"!==e)try{const s=ue(),a=t||s.resolveAgentDir(e),i=_(a,"claude");return await async function(e,t){const n=Ve(e,"hooks");if(!qe(n))return{};const s=[Ve(n,"dist","index.mjs"),Ve(n,"dist","index.js"),Ve(n,"index.mjs"),Ve(n,"index.js")];let a=null;for(const e of s)if(qe(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] ${Ve(n,"index.js")} or ${Ve(n,"index.mjs")}`),{};try{console.log(`[Hook Loader] Loading hooks: ${a}`);const e=`${jt(a).href}?t=${Date.now()}`,n=await import(e);if("function"==typeof n.default){if(t)return console.log("[Hook Loader] Using factory pattern with AgentrixContext"),Sp(n.default(t));console.warn("[Hook Loader] Factory function found but no context provided, skipping factory")}return Sp(n)}catch(e){throw console.error(`[Hook Loader] Failed to load hooks from ${a}:`,e),new Error(`Hook loading failed: ${e instanceof Error?e.message:String(e)}`)}}(i,n)}catch(e){return void console.warn("[AgentRunners] Failed to load hooks:",e)}}(t,n.agentDir,n.context)),n?.context&&s.customSdkMcpTools&&s.customSdkMcpTools.length>0&&(o=await async function(e,t,n){const s={};for(const a of e)try{n&&n("info","MCP",`Loading SDK MCP tools from: ${a}`);const e=await import(a),i=e.default||e;if(!i){n&&n("warn","MCP",`No default export found in ${a}`);continue}const o="function"==typeof i?i(t):i,r=o.name;s[r]=o,n&&n("info","MCP",`Loaded MCP server: ${r}`)}catch(e){n&&n("error","MCP",`Failed to load SDK MCP tools from ${a}: ${e instanceof Error?e.message:String(e)}`)}return s}(s.customSdkMcpTools,n.context,n.logger)),a=new ni(t,e,s,i,o,n?.logger)}else a=new kp;return this.pool.set(t,a),a}static release(e){this.pool.delete(e)}static releaseAll(){this.pool.clear()}}class Ep{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=ze.join(this.workingDirectory,e);return Ue.existsSync(t)?Ue.readFileSync(t,"utf-8"):null}catch{return null}}async fileExists(e){const t=ze.join(this.workingDirectory,e);return Ue.existsSync(t)}listFilesRecursively(e,t,n,s,a){if(!(a>s))try{const i=Ue.readdirSync(e,{withFileTypes:!0});for(const o of i){const i=n?`${n}/${o.name}`:o.name;o.isDirectory()?he.includes(o.name)||this.listFilesRecursively(ze.join(e,o.name),t,i,s,a+1):o.isFile()&&t.push(i)}}catch(e){}}}class Ap{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=Ce.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,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,branchName:l.branchName,branchBinding:l.branchBinding,taskRepositoryId:l.taskRepositoryId,initialCommitHash:d,initPolicies:{...i?.initPolicies,...e.initPolicies,...h}};await Ce.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 di(e))return{currentCommitHash:"",hadUncommittedChanges:!1,hasNewArtifacts:!1,lastSentArtifactVersion:void 0,patchPath:"",diffStats:void 0};const a=await yi(e),i=await bi(e),o=s||Ce.getWorkspaceState(t,n)?.initialCommitHash;if(!o)throw new Error(`Initial commit hash not found for task ${n}`);const r=await Ai(e,o),c=r?await Yd(t,n,r.patch):void 0,l=await Ce.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 Mi(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 Ce.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 Ai(t,n);if(!o)return{};try{await Yd(a,i,o.patch)}catch(t){e.onPatchError?.(t)}const r=await async function(e){const t=new Ep(e);return me(t)}(t),c=await Ce.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=Hd(e)?e.branchName:void 0,d=e.forceUserCwd||!1===e.useWorktree,p="git-server"===n?.repositorySourceType&&!0===n.useWorktree,u=await di(s),m=xi(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){const o=Ld(e)||e,c=$i(n),l=Pi(c);if(!l)throw new Error(`Unable to resolve repository owner/name from git URL: ${c}`);const d=Ce.resolveRepoStoreCheckoutDir(s,l.owner,l.repo),p=Ce.resolveRepoStoreLockPath(s,l.owner,l.repo),u=await Ce.acquireFileLock(p);if(!u)throw new Error(`Timed out waiting for repo store lock at ${p}`);try{await async function(e,t,n,s){const a=$i(t);if(!await di(e)){if(!xi(e))throw new Error(`Repo store directory ${e} exists but is not a git repository`);await hi(e)}await Ni(e,"origin",a),await Vd(e,t,n);const i=function(e,t){if(t&&e.includes(t))return t;if(e.includes("main"))return"main";if(e.includes("master"))return"master";if(e.length>0)return e[0];throw new Error("Cannot create worktree: repository has no remote branches to base the workspace on.")}(await Ri(e),s);return await async function(e,t,n){await ci("git",["checkout","--force","-B",t,n],{cwd:e,windowsHide:!0}),await ci("git",["reset","--hard",n],{cwd:e,windowsHide:!0}),await ci("git",["clean","-fd"],{cwd:e,windowsHide:!0})}(e,i,`origin/${i}`),{baseBranch:i}}(d,n,s,a);const e=i,t=await pi(d);if(t.find(e=>Ld(e.path)===o))return s&&await Kd(o,s),{initialCommitHash:await bi(o)};const c=e?t.find(t=>t.branch===e&&Ld(t.path)!==o):void 0;if(e&&c)throw new Error(`Branch ${e} is already attached to worktree ${c.path}. Remove it before retrying.`);const l=Mt(d),p=await l.branchLocal(),u=!!e&&p.all.includes(e);if(r(o)&&!xi(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{e?u?await l.raw(["worktree","add",o,e]):await ui(d,o,e,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await mi(d,o,!0)}catch{}throw e}return await Kd(o,s),{initialCommitHash:await bi(o)}}finally{await Ce.releaseFileLock(p,u)}}(s,0,a,c,o,l);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 e=await Xd(s,a,0,o,c,l)||await bi(s);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await Ci(s,"origin",$i(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=Hd(e)?e.branchName:void 0;if(!s){if(!a)throw new Error(`[WORKSPACE] Directory ${i} exists but is not a git repository.`);const e=await Xd(i,o,0,c,l,d)||await bi(i);return{initialCommitHash:this.resolveInitialCommitHash(n?.initialCommitHash,e,"none"),isGitRepository:!0,setupAction:"clone",autoCommitPolicy:"enabled",useWorktree:!1}}return await this.assertDirectGitServerRemoteMatches(i,o),{...await this.tryResolveDirtyRepo(e,t,n,{defaultBranchMismatchAction:"Keep"}),setupAction:"reuse",useWorktree:!1}}async assertDirectGitServerRemoteMatches(e,t){const n=Pi($i(t));if(!n)throw new Error(`[WORKSPACE] Unable to parse selected repository remote URL: ${$i(t)}`);const s=await Mi(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 di(s))return this.tryResolveDirtyRepo(e,t,n);if(!xi(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(xi(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};if(!await di(t))return{initialCommitHash:"",isGitRepository:!1,setupAction:"reuse",autoCommitPolicy:"enabled",useWorktree:!1};await wi(t)||await gi(t),await async function(e,t,n,s){const i=e.replace(/^~/,a()),o=Ld(t)||t;if(!await di(i))throw new Error(`Directory ${i} is not a git repository. Worktrees can only be created from existing git repositories.`);if(!await wi(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 pi(i)).find(e=>Ld(e.path)===o))return{initialCommitHash:await bi(o)};const l=Mt(i),d=await l.branchLocal(),p=!!c&&d.all.includes(c);if(r(o)&&!xi(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 ui(i,o,c,"HEAD"):await l.raw(["worktree","add",o,"HEAD"])}catch(e){try{await mi(i,o,!0)}catch{}throw e}return{initialCommitHash:await bi(o)}}(t,s,0,Hd(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 di(s)){await async function(e){return{initialCommitHash:await async function(e){return await hi(e),await gi(e),await bi(e)}(e)}}(s),Hd(e)&&e.branchName&&await vi(s,e.branchName,e.baseBranch);const t=await bi(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 di(e)&&await yi(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}: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=li(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 wi(e.cwd)||await gi(e.cwd),r=Hd(e)?"Ignore"===a?await _i(e.cwd)===e.branchName?"none":"kept":await this.tryResolveBranchMismatch(e,t,n,o,s.defaultBranchMismatchAction??"Switch"):"none";const c=await bi(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(!Hd(e)||!e.branchName)return"none";const i=e.branchName,o=await _i(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 vi(e.cwd,i,e.baseBranch),"switched")}}const _p=rt.object({title:rt.string().describe("Concise PR title following conventional commits format (feat/fix/docs/refactor/test/chore: description), maximum 50 characters"),description:rt.string().describe("Detailed PR description explaining: what changed, why these changes were necessary, any important technical decisions, and impact on existing functionality"),userMessage:rt.string().describe("Friendly message to display to the user, summarizing the PR creation. Should be concise and informative.")}),Cp=ct(_p,{target:"draft-07"}),$p=ct(_p);function Np(e){if("success"!==e.subtype)throw new Error("PR response failed before structured output was returned");const t=e;return t.structured_output?_p.parse(t.structured_output):function(e){if(!e.trim())throw new Error("PR response was empty");const t=Rp(e),n=JSON.parse(t);return _p.parse(n)}(t.result??"")}function Rp(e){const t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);return t?t[1].trim():e.trim()}class Pp{chain=Promise.resolve();run(e){const t=this.chain.then(e,e);return this.chain=t.then(()=>{},()=>{}),t}}const Mp=[{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 Dp(e){const t=e.trim();return t?t.startsWith("/")?t:`/${t}`:""}function Op(e=[]){const t=[],n=new Set;for(const e of Mp.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(Dp).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 Up=rt.object({message:rt.string().describe("A git commit message following conventional commits. Return only the commit message text, optionally with a blank line and body.")}),jp=ct(Up,{target:"draft-07"}),Lp=ct(Up);async function qp(e){if(!await yi(e.workingDirectory))throw new Error("No uncommitted changes to commit");const t=await bi(e.workingDirectory),n=await async function(e){const t=e.runner.runStreamed("Generate a git commit message for the current uncommitted changes.\n\nRequirements:\n- Follow this repository's commit message conventions.\n- Keep the subject line specific and concise.\n- Add a body only if it materially improves clarity.\n- Return only the commit message.",{cwd:e.workingDirectory,model:e.model,abortController:e.abortController,modeConfig:e.modeConfig,disableClaudePlanModeTools:e.disableClaudePlanModeTools,projectAgentrixGuidance:e.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:"claude"===e.schemaTarget?jp:Lp}});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?Up.parse(t.structured_output):Up.parse(JSON.parse(Rp(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=li(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 bi(e)}(e.workingDirectory,n);if(await yi(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 Hp(e){if(e)return{type:"json_schema",schema:e}}async function Gp(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 Gp(n,a):await o.promises.copyFile(n,a)}}function Bp(e){return"oneshot"===function(e){return e.workerExecutionMode??ge}(e)}async function Fp(e){const t=_(e,".agentrix"),n=_(t,"prompt.md"),s=_(t,"plugins"),[a,i]=await Promise.all([Wp(n),zp(s)]);return{systemPromptAppend:a,claudePlugins:i}}async function Wp(e){try{if(!(await I.stat(e)).isFile())return;const t=(await I.readFile(e,"utf8")).trim();return t.length>0?t:void 0}catch(e){if(Kp(e))return;throw e}}async function zp(e){let t;try{t=await I.readdir(e,{withFileTypes:!0})}catch(e){if(Kp(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,s.name),a=_(t,".claude-plugin","plugin.json");try{(await I.stat(a)).isFile()&&n.push({type:"local",path:t})}catch(e){if(Kp(e))continue;throw e}}return n}function Kp(e){return"object"==typeof e&&null!==e&&"code"in e&&"ENOENT"===e.code}function Vp(e){const t=e,n=fe({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 Xp(e){if(!e)return!1;const t=_(e,".agentrix","vision");try{return r(t)&&p(t).isDirectory()}catch{return!1}}function Jp(e){const t=e?.trim();if(t)return t.replace(/\/+$/,"")}async function Yp(e){const t=await async function(e){if(!e.gitServerId)return{};const t=await po();if(!t)return{};const n=go(e.gitServerId,t);if(!n)return{};const s=uo(e.gitServerId),a=Jp(s?.baseUrl),i=Jp(s?.apiUrl);return{GITLAB_TOKEN:n,...a?{GITLAB_BASE_URL:a,CI_SERVER_URL:a}:{},...i?{GITLAB_API_URL:i}:{}}}(e);for(const[e,n]of Object.entries(t))process.env[e]=n;return t}const Qp=Symbol("companionHeartbeatContext"),Zp=Symbol("companionMemoryOrganizationContext");class eu{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=Pe({type:"worker",taskId:a}),this.currentAgentSessionId="agentSessionId"in s?s.agentSessionId:void 0;const o=s.taskAgents||[];this.taskAgentsMap=new Map(o.map(e=>[e.id,e]));const r=this.taskAgentsMap.size>1;this.primaryAgentId=r?"planner":s.agentId,this.primaryAgentName=r?"planner":this.taskAgentsMap.get(s.agentId)?.name??"unknown";const c=this.createWorkerClientConfig(i,a,n),l=Ce.resolveDataDir(i,a);this.historyDb=no({dataDir:l,taskId:a}),this.workClient=new Kl(c.config,{...c.handlers,getPermissionMode:()=>this.getPermissionModeSnapshot(),historyDb:this.historyDb}),this.coordinator=this.createMessageCoordinator(this.workClient,this.options.idleTimeoutSecond),this.agentContext=new Zl({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:Ce.agentrixAgentsHomeDir,taskAgents:s.taskAgents||[],serverUrl:Ce.serverUrl,taskDataKey:this.options.dataEncryptionKey}),this.agentrixTools=this.createAgentrixTools();const d={...qd(this.options.input),cwd:this.workingDirectory};this.workspace=new Ap({options:d,handlers:this.createWorkspaceHandlers(this.workClient)})}abortController=new AbortController;isStopping=!1;askUserAwaiter=new Map;messageFilter=nd();logger;workClient;workspace;coordinator;agentContext;runner;agentQueues=new Map;currentAgentSessionId;currentGroupId=null;historyDb;chatHistoryDb=null;agentrixTools;pendingNavigateTaskId=null;pendingPermissions=new Map;grantedPermissions=new Set;loopPermissionModeSetter=null;configuredPermissionMode="bypassPermissions";desiredPermissionMode=null;activePermissionMode=null;lastBroadcastPermissionMode=null;taskAgentsMap;messageSavedListener=null;messageDebounceHandle=null;messageDebounceMs=1e4;lastProcessedSequence=0;primarySessionReady=!1;pendingPrimaryLastSequence=null;primaryAgentId;primaryAgentName;exitReason="completed";pendingChannelReplies=[];channelMessageInvocationCount=0;projectAgentrixGuidance={claudePlugins:[]};newMessageGroupId(){return`group-${crypto.randomUUID()}`}refreshGroupId(){this.currentGroupId=this.newMessageGroupId()}getConfiguredPermissionMode(){if(this.isOneShotExecution())return"bypassPermissions";const e=this.runner?.getAgentConfiguration()?.customPermissionMode;return e??"bypassPermissions"}isOneShotExecution(){return Bp(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=ie(t);return!!ve(t)||!!ye(t)||!!be(t)||!(!oe(t)&&!a)&&"agent"!==e.senderType&&(s?e.senderId!==this.primaryAgentId:!!a||"system"===e.senderType&&"user"===t.type||"user"===t.type)}shouldDropHeartbeatWhileBusy(){return this.coordinator.isActivelyExecuting()}async processPendingMessages(){const e=this.historyDb.pageMessagesAfter(this.lastProcessedSequence,100),t=this.getRunnerMode(),n="group_chat"===t||"group_work"===t,s=[];for(const t of e.data)if(this.lastProcessedSequence=t.localSequence,this.shouldProcessMessage(t)){if(n&&this.isUnsupportedGroupPlanCommand(t)){this.log("info","PLAN","Ignoring unsupported ![plan] command in group mode");continue}s.push(t)}if(s.length>0){this.deduplicateHeartbeats(s);const e=this.mergeConsecutiveHumanMessages(s);n?await this.processMessagesAsGroup(e):await this.processMessagesIndividually(e)}e.hasMore&&await this.processPendingMessages()}isUnsupportedGroupPlanCommand(e){const t=e.message;return!(!oe(t)||"user"!==t.type)&&"![plan]"===Ta(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(!oe(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=Sl(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[Qp]=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(ye(t)){const e=t,n={type:"user",message:{role:"user",content:this.buildCompanionMemoryOrganizationPrompt(e)},parent_tool_use_id:null,session_id:""};return n[Zp]=e,n}return oe(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 this.log("info","COMPANION",`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[Zp];return t?(delete e[Zp],{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[Qp]?(delete e[Qp],{COMPANION_SHADOW_TASK:"heartbeat"}):void 0}async prepareMessageForRunner(e){return zc(e,{attachmentsDir:Ce.resolveAttachmentsDir(this.options.input.userId,this.taskId),log:(e,t,n,...s)=>{this.log(e,t,n,...s)}})}setupMessageSavedListener(){this.messageSavedListener=()=>{this.triggerMessageProcessing()},this.historyDb.on("message-saved",this.messageSavedListener)}triggerMessageProcessing(){const e=this.getRunnerMode();"group_chat"===e||"group_work"===e?this.scheduleProcessPendingMessages():this.processPendingMessages()}scheduleProcessPendingMessages(){this.coordinator?.setDebouncing(!0),this.messageDebounceHandle&&clearTimeout(this.messageDebounceHandle),this.messageDebounceHandle=setTimeout(async()=>{this.messageDebounceHandle=null,await this.processPendingMessages(),this.coordinator?.setDebouncing(!1)},this.messageDebounceMs)}async start(){let e="completed";try{if(await this.initialize(),!await this.maybeConfirmAgentrixDevOpsInit())return;await this.handleEvent(),await this.runClaude()}catch(t){if(!(t instanceof bt)){e="error",this.log("warn","AGENT","Fatal error:",t);const n=t instanceof Error?t.message:String(t);await this.reportFatalError(n)}}finally{await this.exitWorker("error"===e?"error":this.exitReason)}}async autoInstallAgent(e){const t=this.options.input,n=t.agentGitUrl,s=t.agentGitSubDir;if(n)try{this.log("info","AGENT",`Auto-installing agent ${e} from git`),await ia({agentId:e,gitUrl:n,subDir:s??void 0})}catch(t){this.log("warn","AGENT",`Auto-install failed for agent ${e}: ${t}`)}else this.log("warn","AGENT",`Auto-install skipped: no agentGitUrl provided for agent ${e}`)}async applyAgentUpgrade(e,t,n){const s=Ce.agentrixAgentsHomeDir,a=_(s,`${e}.new`),i=_(s,`${e}-bak`);try{this.log("info","AGENT",`Applying upgrade for ${e}`),oa(n),m(n,a),await Gp(t,i),h(t,{recursive:!0,force:!0}),m(a,t),qe(i)&&h(i,{recursive:!0,force:!0}),this.log("info","AGENT",`Upgrade applied for ${e}`)}catch(n){this.log("warn","AGENT",`Upgrade failed for ${e}: ${n}`),!qe(t)&&qe(i)&&m(i,t),qe(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??Ce.resolveAgentDir(e.agentId,this.workingDirectory);Boolean(t&&"git-server"===e.repositorySourceType&&!e.agentDir&&!qe(_(s,"agent.json")))&&(n=await this.workspace.setup());const a=e.agentDir??Ce.resolveAgentDir(e.agentId,this.workingDirectory),i=_(a,"upgrade"),o=Boolean(a)&&Boolean(e.agentGitUrl)&&!t,r=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&o&&!qe(a)),c=Boolean(e.agentId&&"default"!==e.agentId&&!e.agentDir&&!t&&!r&&qe(i));if(await this.workClient.connect(),this.workClient.sendWorkerInitializing({deployingAgent:r,upgradingAgent:c}),r&&await this.autoInstallAgent(e.agentId),t&&"default"!==e.agentId&&!qe(_(a,"agent.json")))throw new Error(`Filesystem agent not found: ${e.agentId} (${a})`);c&&await this.applyAgentUpgrade(e.agentId,a,i),this.log("info","AGENT",`Resolved agent ${e.agentId}: ${a}`);const l=await Tp.create(e.agentType,e.agentId,{agentDir:a,logger:this.log.bind(this),context:this.agentContext});this.runner=l,this.initializePermissionModeState(),n??=await this.workspace.setup(),this.projectAgentrixGuidance=await Fp(this.workingDirectory),await this.registerWithDaemon(this.workingDirectory),this.log("info","WORKSPACE",`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,this.log("info","HISTORY",`Starting from sequence ${this.lastProcessedSequence} (tracking: ${this.primaryAgentId})`),this.currentAgentSessionId&&(this.historyDb.upsertAgentSession(this.primaryAgentId,this.currentAgentSessionId),this.primarySessionReady=!0),this.setupMessageSavedListener(),this.workClient.sendWorkerInitialized(),this.workClient.sendTaskSlashCommandsUpdate(Op())}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 ln(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}async setEnvironmentVariables(){this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.ANTHROPIC_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.ANTHROPIC_AUTH_TOKEN=this.options.input.api_key),await Yp(this.options.input)}createMessageCoordinator(e,t){const n=1e3*Math.max(0,t??0);return this.coordinator=new ap({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 pn(this.taskId,this.options.input.userId),this.stopTask("event")},onPlanMode:async()=>this.isOneShotExecution()?(this.workClient.sendSystemErrorMessage("![plan] is not supported in oneshot execution mode",{groupId:this.currentGroupId??void 0}),null):(await this.requestPermissionMode("plan"),null)},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:n,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){const e=this.options.input.event,t=this.options.input.eventData;if("sub-task-result-updated"===e){const e=t,n=ed(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=td(e,this.options.dataEncryptionKey);this.historyDb.saveMessage({eventId:e.eventId||`sub-task-ask-${Date.now()}`,message:n,senderType:"system",senderId:"system",senderName:"system"})}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&&ye(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(){this.log("info","MERGE","Executing merge-request command");const e=this.getRunnerMode(),t="group_chat"===e||"group_work"===e;try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await yi(this.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await bi(this.workingDirectory),a=this.workspace.getInitialCommitHash();if(!a){const e="Cannot create PR: initial commit hash is missing.";return this.log("error","MERGE",e),void this.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Ii(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=Hd(o),c=r?Gd(this.options.input.taskId,o.branchName):void 0;if(r&&c){const e=await _i(this.workingDirectory);if(e!==c){const t=Wd(e,c);return this.log("warn","MERGE",t),void this.workClient.sendSystemErrorMessage(t,{groupId:this.currentGroupId??void 0})}}const l=this.runner?.getAgentConfiguration(),d=Zd(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);this.log("debug","MERGE",`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(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),projectAgentrixGuidance:this.projectAgentrixGuidance,allowAskUser:!this.isOneShotExecution(),supportedFeatures:this.options.input.supportedFeatures,structuredOutputSchema:{type:"json_schema",schema:Cp}});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=Np(u),g=Gd(this.options.input.taskId,c,h.title);r||await Bd(this.workingDirectory,g);const f=Fd(g);this.log("info","MERGE",`Pushing HEAD to remote branch ${g}`),await Jd(this.workingDirectory,f,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","Successfully pushed branch to remote");const v=await this.workClient.sendMergeRequest(h.title,h.description,g);"explicit"!==o.branchBinding&&await this.workspace.updateBranchBinding(g,"platform-managed");const y=`${h.userMessage}\n\n✅ Pull request created successfully!\nNumber: #${v.pullRequestNumber}\nURL: ${v.pullRequestUrl}`,b={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(),Ea({sessionId:u.session_id,model:this.options.input.model??"unknown",numTurns:u.num_turns,usage:b,result:y}),{groupId:this.currentGroupId??void 0})}catch(e){const t=e instanceof Error?e.message:String(e);this.log("error","MERGE","Merge-request failed:",e),this.workClient.sendSystemErrorMessage(`❌ Merge-request failed: ${t}\n\nPlease check git status and try again, or create the PR manually.`,{groupId:this.currentGroupId??void 0})}var n,s}async executeBashCommand(e){if(!Ce.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t={senderType:"agent",senderId:"bash",senderName:"bash"},n=await sp(e,this.workingDirectory,{onOutput:e=>{this.workClient.sendTaskMessage(t,e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${n})`)}async executeMergePr(){await op({workingDirectory:this.workingDirectory,workClient:this.workClient,repositoryId:this.options.input.repositoryId,gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl,logger:this.logger,askUser:e=>this.askUser(e,{onTimeout:"abort_task"}),commitChanges:()=>this.commitCurrentChangesWithAgent()})}async commitCurrentChangesWithAgent(){this.log("info","MERGE","Generating commit message with agent"),await qp({runner:this.runner,workingDirectory:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:this.getRunnerModeConfig(),disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),schemaTarget:"claude",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.taskAgentsMap.size>1?e:this.messageFilter.filter(e);null!==t&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing agentSessionId"),this.currentAgentSessionId=void 0,this.primarySessionReady=!1,this.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}isAgentrixDevOpsInitWorker(){return this.options.input.agentId===Kc}async maybeConfirmAgentrixDevOpsInit(){if(!this.isAgentrixDevOpsInitWorker())return!0;const e=Jc(this.options.input),t=(await this.askUser([Yc(e)],{onTimeout:"abort_task"})).answers[0]??"";return("zh-Hans"===e?"先初始化"===t:"Initialize first"===t)||(await dn(this.taskId,this.options.input.userId,"continue"),!1)}getAgentrixExtraTools(){if(this.isAgentrixDevOpsInitWorker())return[yt("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:rt.string().describe("Short user-visible summary of what initialization completed")},async e=>{const t=Jc(this.options.input),n=await this.askUser([Qc(t)],{onTimeout:"abort_task"}),s=function(e,t){const n=e.trim();return"zh-Hans"===t?"继续实现需求"===n||"继续"===n?"continue":"输入修改建议"===n||"修改建议"===n?"modify":"停止任务"===n||"停止"===n?"stop":null:"Continue request"===n||"Continue"===n?"continue":"Provide changes"===n||"Modify"===n?"modify":"Stop task"===n||"Stop"===n?"stop":null}(n.answers[0]??"",t);if(this.log("info","DEVOPS_INIT",`Post-init user decision: ${s??"unrecognized"} (answer=${JSON.stringify(n.answers[0]??"")})`),!s)return{content:[{type:"text",text:"The platform could not recognize the user post-init choice. Ask the user again or call complete_devops_init again after confirming the next action. Do not stop this DevOps init session yet."}]};if("modify"===s){const e=n.details?.[0]?.trim();return{content:[{type:"text",text:e?`The user wants additional Agentrix DevOps init changes before completion:\n${e}`:"The user wants additional Agentrix DevOps init changes before completion. Continue the same initialization session."}]}}return await dn(this.taskId,this.options.input.userId,"continue"===s?"continue":"stop"),setImmediate(()=>this.stopTask("event")),{content:[{type:"text",text:"continue"===s?`Agentrix DevOps initialization completed: ${e.summary}. The platform is switching back to the original development agent.`:`Agentrix DevOps initialization completed: ${e.summary}. The task will stop without starting the development agent.`}]}})]}async runClaude(){if(this.log("info","AGENT",`Starting Claude agent for task ${this.taskId}`),this.isStopping)return void this.log("info","AGENT",`Skipping Claude run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runClaudeOneShot();const e=this.currentAgentSessionId,t=this.runner,n=this.getRunnerModeConfig(),s="group_chat"===n.mode||"group_work"===n.mode,a=this.createPermissionHandler(),i=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.initializePermissionModeState();const o=t.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:e,abortController:this.abortController,initialPermissionMode:this.getPermissionModeSnapshot()??void 0,stderr:e=>{this.log("debug","SDK",e)},modeConfig:n,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(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.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){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of o.events)this.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e,s);this.resetPrimaryPermissionState(),this.log("info","AGENT",`Claude agent finished for task ${this.taskId}`)}async runClaudeOneShot(){const e=this.runner,t=this.getRunnerModeConfig(),n="group_chat"===t.mode||"group_work"===t.mode,s=this.createPermissionHandler(),a=this.buildSystemHooks({trackBackgroundTasks:!0,trackPrimaryAgentStop:!0});this.loopPermissionModeSetter=null,this.activePermissionMode=null,this.lastBroadcastPermissionMode=null,this.initializePermissionModeState(),this.broadcastPermissionMode(this.getPermissionModeSnapshot());const i=await this.coordinator.waitForAgentMessage();if(!i)return this.isStopping||this.stopTask("oneshot_complete"),this.resetPrimaryPermissionState(),void this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId} without runnable message`);const o=i.__localSequence;if(void 0!==o&&this.markPrimaryMessageProcessed(o),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=>{this.log("debug","SDK",e)},modeConfig:t,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,agentrixExtraTools:this.getAgentrixExtraTools(),enableAgentrixComputerUse:this.isComputerUseEnabled(),enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(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(),this.log("info","AGENT",`Claude oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e,t){if("system"===e.type&&"init"===e.subtype)return this.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.workClient.sendTaskSlashCommandsUpdate(Op(e.slash_commands??[]),e.session_id),this.currentAgentSessionId=e.session_id,this.historyDb.upsertAgentSession(this.primaryAgentId,e.session_id),this.primarySessionReady=!0,null!==this.pendingPrimaryLastSequence&&(this.historyDb.updateAgentLastSequence(this.primaryAgentId,this.pendingPrimaryLastSequence),this.pendingPrimaryLastSequence=null),this.refreshGroupId(),void this.updateAgentRunning(!0);if("result"===e.type)return await this.handleSdkResultMessage(e),this.refreshGroupId(),void this.updateAgentRunning(!1);"system"===e.type&&"task_notification"===e.subtype&&this.handleBackgroundTaskNotification(e);const n=t?e:this.messageFilter.filter(e);null!==n&&this.workClient.sendTaskEvent(this.getChatSenderMeta(),n,{groupId:this.currentGroupId??void 0})}resetPrimaryPermissionState(){this.loopPermissionModeSetter=null,this.activePermissionMode=null}updateAgentRunning(e){this.coordinator?.setAgentRunning(this.primaryAgentId,this.primaryAgentName,e)}markPrimaryMessageProcessed(e){this.historyDb.updateAgentLastSequence(this.primaryAgentId,e),this.primarySessionReady||(this.pendingPrimaryLastSequence=null===this.pendingPrimaryLastSequence?e:Math.max(this.pendingPrimaryLastSequence,e))}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}async handleAskUserQuestionPermission(e){const t=e,n=Array.isArray(t.questions)?t.questions:[];if(0===n.length)return this.log("warn","PERMISSION","AskUserQuestion missing questions"),{behavior:"deny",message:"AskUserQuestion missing questions"};const s=n.map(e=>({...e,options:[...e.options,{label:"Other",description:""}]}));try{const e=await this.askUser(s),a={};for(let t=0;t<n.length;t+=1){const s=n[t]?.question;if(!s)continue;const i=e.answers?.[t];"string"==typeof i&&(a[s]=i)}return{behavior:"allow",updatedInput:{...t,answers:a}}}catch(e){return this.log("warn","PERMISSION",`AskUserQuestion failed: ${e}`),{behavior:"deny",message:"AskUserQuestion failed"}}}createPermissionHandler(){return async(e,t)=>{if("AskUserQuestion"===e)return this.handleAskUserQuestionPermission(t);if("ExitPlanMode"===e)return this.handleExitPlanModePermission(t);if(this.grantedPermissions.has(e))return this.log("info","PERMISSION",`Tool "${e}" already granted, skipping`),{behavior:"allow",updatedInput:t};const n=this.pendingPermissions.get(e);if(n)return this.log("info","PERMISSION",`Tool "${e}" has pending request, waiting...`),"allow"===await n?{behavior:"allow",updatedInput:t}:{behavior:"deny",message:"Permission denied by user"};let s;this.log("info","PERMISSION",`Requesting permission for "${e}"`);const a=new Promise(e=>{s=e});this.pendingPermissions.set(e,a);try{const n=await this.requestToolPermission(e);return s(n),"allow"===n?(this.grantedPermissions.add(e),{behavior:"allow",updatedInput:t}):{behavior:"deny",message:"Permission denied by user"}}catch(e){return s("deny"),{behavior:"deny",message:"Permission request failed"}}finally{this.pendingPermissions.delete(e)}}}async handleExitPlanModePermission(e){const t=e.planFilePath??e.filePath;let n,s;if(t){const e=this.workspace.getCwd(),a=e.endsWith("/")?e:e+"/";n=t.startsWith(a)?t.slice(a.length):void 0;try{const e=await We.readFile(t,"utf-8");s=e.length>8e3?e.slice(0,8e3)+"\n\n…(truncated)":e}catch{}}!s&&"string"==typeof e.plan&&e.plan&&(s=e.plan);const a=[{question:"Review the plan and choose how to proceed.",header:"Plan Review",multiSelect:!1,options:[{label:"Approve",description:"Approve the plan and start implementation"},{label:"Revise",description:"Need to revise the plan",additionalInput:{enabled:!0,required:!1,placeholder:"Describe what should change."}},{label:"Cancel",description:"Cancel this plan"}],planFilePath:n,planContent:s}];try{const t=await this.askUser(a,{onTimeout:"abort_task"}),n=t.answers[0],s=t.details?.[0]?.trim();return"Approve"===n?{behavior:"allow",updatedInput:e}:"Revise"===n?{behavior:"deny",message:s?`The user wants to revise the plan. Revision notes: ${s}. Please reconsider and update the plan, then call ExitPlanMode again when ready.`:"The user wants to revise the plan. Please reconsider and update the plan, then call ExitPlanMode again when ready."}:(await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"User cancelled plan review",interrupt:!0})}catch{return await this.restoreConfiguredPermissionMode(),{behavior:"deny",message:"Plan review failed or was interrupted"}}}async requestToolPermission(e){const t=[{question:`Tool "${e}" is requesting permission to execute. Allow this operation?`,header:"Permission",multiSelect:!1,options:[{label:"Allow",description:"Allow this tool to execute"},{label:"Deny",description:"Deny this tool execution"}]}];try{return"Allow"===(await this.askUser(t,{onTimeout:"abort_task"})).answers[0]?"allow":"deny"}catch(e){return this.log("warn","PERMISSION",`Permission request failed: ${e}`),"deny"}}async askUser(e,t={}){if(this.isOneShotExecution())throw new Error("ask_user is not supported in oneshot execution mode");const n=this.workClient;return cp(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>n.sendAssistantMessage(e,{groupId:this.currentGroupId??void 0}),stopTask:e=>this.stopTask(e)},t)}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}getRunnerMode(){const e=this.taskAgentsMap.size>1,t=this.options.input.taskType,n=!(!process.env.AGENTRIX_COMPANION_HOME&&!process.env.AGENTRIX_COMPANION_WORKSPACE);return"shadow"===t?"companion_shadow":n&&"chat"===t?"companion_chat":e?"chat"===t?"group_chat":"group_work":"chat"===t?"chat":"work"}getGroupAgents(){if(!(this.taskAgentsMap.size<=1))return Array.from(this.taskAgentsMap.values()).map(e=>({id:e.id,name:e.name,description:e.description}))}getRunnerModeConfig(){return{mode:this.getRunnerMode(),supportChangeTitle:this.supportChangeTitle,groupAgents:this.getGroupAgents()}}shouldDisableClaudePlanModeTools(){const e=this.options.input.taskType;return"chat"===e||"shadow"===e||this.isChannelBoundTask()||Boolean(this.options.input.parentTaskId)}get supportChangeTitle(){const e=this.options.input.customTitle;return!("string"==typeof e&&e.trim().length>0)}getStructuredOutputSchema(){return Hp(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=Ce.resolveDataDir(t,e);this.chatHistoryDb=no({dataDir:n,taskId:e})}return{createTask:pd(t={agentContext:this.agentContext,workClient:this.workClient,uploadFile:e=>this.agentContext.uploadFile(e),credentials:this.credentials,taskId:this.taskId,chatId:this.options.input.chatId,agentId:this.primaryAgentId,isGroup:e,historyDb:this.historyDb,chatHistoryDb:this.chatHistoryDb??void 0,askUser:e=>this.askUser(e),log:this.log.bind(this),onChannelMessageInvoked:()=>{this.channelMessageInvocationCount+=1},invokeAgent:(e,t)=>this.invokeAgent(e,t),assign:(e,t,n)=>this.assignWork(e,t,n),setPendingNavigateTaskId:e=>{this.pendingNavigateTaskId=e},getChannelReplyTarget:()=>this.getInjectedChannelReplyTarget(),supportedFeatures:this.options.input.supportedFeatures,visionModel:this.options.input.visionModel,workingDirectory:this.workingDirectory}),createSoloTask:ud(t),createGroupTask:md(t),replyToSubTask:rd(t),changeTaskTitle:ad(t),publishTaskPreviewUrl:id(t),sendVisionArtifact:od(t),askUser:hd(t),getTaskHistory:cd(t),getTaskAgents:ld(t),listSubTask:dd(t),invoke:gd(t),assign:vd(t),updateAgentInfo:fd(t),sendReminder:wd(t),recordMemoryChange:kd(t),listTasks:yd(t),readConversation:bd(t),uploadFile:Id(t),sendChannelMessage:Ed(t),getChannelGroupHistory:Ad(t),listAgents:Cd(t),analyzeImage:Nd(t),scheduleTask:Rd(t),prepareHiveRepository:Pd(t),publishToHive:Md(t),updateHiveListingVersion:Dd(t),recordHiveInstall:Od(t),createHiveReview:Ud(t),createHiveComment:jd(t),computerUse:sd(t)};var t}isComputerUseEnabled(){try{return lc(void 0,this.log.bind(this)).enabled}catch(e){return this.log("warn","COMPUTER_USE",`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 Pp,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 Tp.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i=this.getGroupAgents()||[],r={mode:"reply",supportChangeTitle:!1,groupAgents:i},l=this.createPermissionHandler(),d=this.buildSystemHooks({trackBackgroundTasks:!1}),p=nd(),u=s.loop({cwd:this.workingDirectory,model:this.options.input.model,agentSessionId:n.sessionId,abortController:this.abortController,modeConfig:r,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(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=[xa(e,i),"=== CONVERSATION STREAM START FROM HERE ===",Ta(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){this.log("error","INVOKE",`Invoke failed for ${e}:`,t)}finally{this.coordinator?.setAgentRunning(e,o,!1)}}),!0}async assignWork(e,t,n){const s=this.taskAgentsMap.get(e),a=s?.type||"claude";let i=this.agentQueues.get(e);i||(i=new Pp,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 Tp.create(a,e,{logger:this.log.bind(this),context:this.agentContext}),i={mode:"work",supportChangeTitle:!1},r=this.createPermissionHandler(),l=this.buildSystemHooks({trackBackgroundTasks:!1}),d=nd(),p=n.loop({cwd:this.workingDirectory,model:this.options.input.model,abortController:this.abortController,modeConfig:i,disableClaudePlanModeTools:this.shouldDisableClaudePlanModeTools(),agentrixTools:this.agentrixTools,enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(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){this.log("error","RUN_TASK",`Run task failed for ${e}:`,t);const n=t instanceof Error?t.message:String(t);this.sendAgentErrorMessage(e,o,`I meet some error: ${n}`,{groupId:s})}finally{this.coordinator?.setAgentRunning(e,o,!1)}})}buildSubAgentHistoryContext(e,t){const n=this.historyDb;if(!n)return this.log("warn","HISTORY","Task history DB unavailable; delegate cannot build context."),null;const s=n.getAgentSessions().get(e),a=n.getAgentLastSequences().get(e)??0,i=n.pageRecentMessagesAfter(a,20);if(0===i.data.length&&!t)return null;const o=this.mergeConsecutiveHumanMessages(i.data),r=this.buildHistoryMessages(o,t);return r?{message:r,sessionId:s,lastSequence:i.data.length>0?i.data[i.data.length-1].localSequence:a}:null}buildHistoryMessages(e,t){const n=[];for(const t of e){const e=Tl(t);e&&n.push(e)}if(0===n.length&&!t)return null;let s=n.join("\n");return t&&(s=`<hint>\n${t}\n</hint>\n\n${s}`),{type:"user",message:{role:"user",content:s},parent_tool_use_id:null,session_id:""}}buildSystemHooks(e){const t=e?.trackBackgroundTasks??!0,n=e?.trackPrimaryAgentStop??!1,s={};return t&&(s.PostToolUse=async e=>(this.syncPermissionModeFromPostToolUse(e),this.trackBackgroundTaskFromPostToolUse(e),{})),n&&(s.Stop=async()=>(this.updateAgentRunning(!1),{})),s}trackBackgroundTaskFromPostToolUse(e){if(!e||"object"!=typeof e)return void this.log("debug","TASK","PostToolUse hook input is not an object");const t=e,n=t.tool_input;if(!n||!0!==n.run_in_background)return;const s=this.extractBackgroundTaskId(t.tool_response);if(!s)return this.log("debug","TASK",`PostToolUse(${t.tool_name}) run_in_background=true but no task_id found, using anonymous tracking`),void this.coordinator?.setAnonymousBackgroundTaskRunning(!0);this.coordinator?.setBackgroundTaskRunning(s,!0),this.log("info","TASK",`Background task started: ${s} (tool: ${t.tool_name})`)}syncPermissionModeFromPostToolUse(e){if(!e||"object"!=typeof e)return;const t=(n=e.tool_name,s=this.configuredPermissionMode,"EnterPlanMode"===n?"plan":"ExitPlanMode"===n?s:null);var n,s;t&&this.confirmPermissionModeApplied(t)}handleBackgroundTaskNotification(e){this.updateAgentRunning(!0),this.coordinator?.setBackgroundTaskRunning(e.task_id,!1),this.log("info","TASK",`Background task ${e.task_id} ${e.status}`)}extractBackgroundTaskId(e){const t=new Set,n=new Set,s=e=>{if("string"!=typeof e)return;const n=e.trim();n&&t.add(n)},a=e=>{if(null==e)return;if("string"==typeof e)return void(e=>{const t=/(task[_-]?id|agent[_-]?id|shell[_-]?id)["'\s:=]+([A-Za-z0-9._:-]+)/gi;let n;for(;null!==(n=t.exec(e));)s(n[2])})(e);if("object"!=typeof e)return;if(n.has(e))return;if(n.add(e),Array.isArray(e)){for(const t of e)a(t);return}const t=e;"string"==typeof t.task_id&&s(t.task_id),"string"==typeof t.taskId&&s(t.taskId),"string"==typeof t.agent_id&&s(t.agent_id),"string"==typeof t.agentId&&s(t.agentId),"string"==typeof t.shell_id&&s(t.shell_id),"string"==typeof t.shellId&&s(t.shellId);for(const e of Object.values(t))a(e)};a(e);const i=[...t];return i.length>1&&this.log("warn","TASK",`Multiple background task ids extracted (${i.join(", ")}), using first id ${i[0]}`),i[0]}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.taskAgentsMap.get(s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:Ce.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:we(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:K(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString(),activeAgents:this.coordinator?.getActiveAgents(),permissionMode:this.getPermissionModeSnapshot()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>this.logger.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:Ce.resolveAttachmentsDir(e,t),logger:(e,t,n,...s)=>{this.log(e,t,n,...s)},stopTask:async()=>{this.stopTask("event")},shouldPersistTaskMessage:async e=>!ve(e)||!this.shouldDropHeartbeatWhileBusy()||(this.log("debug","WORKER","Dropping heartbeat at WorkerClient receive stage: agent is running"),!1),onTaskMessage:async(e,t)=>{if(ie(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];t&&n&&(this.askUserAwaiter.delete(t),n(e))}},onTaskInfoUpdate:async e=>{await rp(e,this.options.input,this.workspace)},onWorkerStatusRequest:async()=>{const{state:e}=this.coordinator.getStatus();"running"===e?this.workClient.sendWorkRunning():"idle"===e&&this.workClient.sendWorkerReady()},onSubTaskResultUpdated:async e=>{const t=ed(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)},onSubTaskAskUser:async e=>{const t=td(e,this.options.dataEncryptionKey);await this.coordinator.enqueue(t)}}}}async exitWorker(e){this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`),this.coordinator&&this.coordinator.stop(),this.workClient&&(this.workClient.sendWorkerExit(e),await this.workClient.disconnect()),this.historyDb&&this.historyDb.close(),this.chatHistoryDb&&this.chatHistoryDb.close(),process.exit(0)}async reportFatalError(e){await this.workClient.sendTerminalErrorResultAndWait(e,{groupId:this.currentGroupId??void 0})}log(e,t,n,...s){this.logger&&this.logger[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}const s=this.getRunnerMode(),a="group_chat"===s||"group_work"===s,i=this.pendingNavigateTaskId;if(this.pendingNavigateTaskId=null,a?this.workClient.sendTaskEvent(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}):this.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0,navigateToTaskId:i??void 0}),n)try{await Qd(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}await this.forwardResultToChannelIfNeeded(e)}async forwardResultToChannelIfNeeded(e){if("result"!==e.type)return;const t=this.pendingChannelReplies.shift(),n=void 0===t?this.getInjectedChannelReplyTarget():t.target??this.getInjectedChannelReplyTarget();if(void 0===t&&!n)return;const s="success"===e.subtype,a=t?this.channelMessageInvocationCount>t.channelMessageInvocationCountAtStart:this.channelMessageInvocationCount>0;if(s&&a)return;const i=this.extractResultTextForChannel(e);if(!i)return;const o=await un(this.taskId,i,n),r=s;this.historyDb.saveTaskEvent({taskId:this.taskId,chatId:this.options.input.chatId,eventType:"channel-message-send",sequence:null,eventData:{status:o?.error?"error":"sent",delivery:r?"fallback":"error-forward",reason:r?"send_channel_message_not_invoked":"task_failed",channelId:n?.channelId,hasContent:!0,attachments:[],...o?.error?{error:o.error}:{}}}),o?.error&&this.log("debug","CHANNEL",`Claude reply was not sent to channel: ${o.error}`)}getInjectedChannelReplyTarget(){const e=process.env.AGENTRIX_CHANNEL_REPLY_TARGET;if(!e)return null;try{const t=JSON.parse(e);if("string"==typeof t.channelId&&"string"==typeof t.chatId)return{channelId:t.channelId,chatId:t.chatId,..."string"==typeof t.platform?{platform:t.platform}:{},..."string"==typeof t.chatType?{chatType:t.chatType}:{},..."string"==typeof t.chatName?{chatName:t.chatName}:{}}}catch(e){this.log("debug","CHANNEL","Ignoring invalid channel reply target:",e)}return null}isChannelBoundTask(){return null!==this.getInjectedChannelReplyTarget()}isChannelGroupBoundTask(){return"group"===this.getInjectedChannelReplyTarget()?.chatType?.toLowerCase()}getExternalChannelPromptContext(){const e=this.getInjectedChannelReplyTarget();if(e)return{platform:e.platform,chatType:e.chatType,chatName:e.chatName,chatId:e.chatId}}isChannelReplyTarget(e){return Boolean(e&&"object"==typeof e&&"string"==typeof e.channelId&&"string"==typeof e.chatId)}extractResultTextForChannel(e){if("success"===e.subtype){const t=e.result;if("string"!=typeof t)return null;const n=t.trim();return n.length>0?n:null}const t=e.errors,n=Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0).join("\n").trim():"",s=e.subtype;return`Task failed: ${n||("string"==typeof s?s:"Unknown error")}`}}class tu{static async calculateFinalCwd(e){const{repositorySourceType:t,cwd:n,userCwd:s,userId:i,taskId:o,forceUserCwd:r,useWorktree:c}=e,l=e=>Ld(e)||e;if(n)return l(n);const d=Ce.resolveProjectDir(i,o);if(("directory"===t||"git-server"===t)&&s){const e=l(s.replace(/^~/,a()));if(r||!1===c)return e}if("directory"===t&&s){const e=l(s.replace(/^~/,a()));return await this.shouldUseWorktree(e)?l(d):e}return l(d)}static async shouldUseWorktree(e){try{return!xi(e)&&await di(e)}catch{return!1}}}var nu=jn(De);class su{constructor(e,t){this.credentials=e,this.options=t}context;threadId=null;isStopping=!1;filteredToolUseIds=new Set;currentModel=null;dataEncryptionKey=null;abortController=new AbortController;coordinator;logger;askUserAwaiter=new Map;workClient;workspace;historyDb=null;currentGroupId=null;exitReason="completed";projectAgentrixGuidance={claudePlugins:[]};codexAgentrixEventMcp=null;isOneShotExecution(){return Bp(this.options.input)}refreshGroupId(){this.currentGroupId=`group-${ke()}`}async start(){try{await this.initialize(),await this.handleEvent(),await this.runCodex(),await this.exitWorker(this.exitReason)}catch(e){if(!this.isStopping){this.isStopping=!0,this.askUserAwaiter.clear(),this.coordinator?.stop(),this.log("warn","AGENT","Fatal error:",e);const t=e instanceof Error?e.message:String(e);throw await this.exitWorker("error",t),e}this.log("info","AGENT",`Task ${this.taskId} stopped gracefully`),await this.exitWorker(this.exitReason)}finally{process.exit(0)}}async initialize(){const e=this.options.input.taskId,t=this.options.input.userId;this.logger=this.createLogger({type:"worker",taskId:e}),this.dataEncryptionKey=this.options.dataEncryptionKey??null;const n=qd(this.options.input),s=await tu.calculateFinalCwd(n),a={...n,cwd:s};this.log("info","INIT",`Phase 1: Working directory: ${s}`);const i=this.createWorkerClientConfig(t,e,s),o=Ce.resolveDataDir(t,e);this.historyDb=no({dataDir:o,taskId:e});const r=new Kl(i.config,{...i.handlers,historyDb:this.historyDb});this.workClient=r,this.log("info","INIT","Phase 2: WorkerClient created");const c=1e3*Math.max(0,this.options.idleTimeoutSecond??0);this.coordinator=this.createMessageCoordinator(r,c),this.log("info","INIT","Phase 3: Coordinator created"),await r.connect(),r.sendWorkerInitializing(),this.log("info","INIT","Phase 4: Connected to server"),this.log("info","INIT","Phase 5: Skipped (no AgentContext for Codex)"),this.log("info","INIT","Phase 6: Skipped (no custom resources for Codex)");const l=new Ap({options:a,handlers:this.createWorkspaceHandlers(r,s)}),{initialCommitHash:d,gitStateResult:p,setupAction:u}=await l.setup();this.workspace=l,this.projectAgentrixGuidance=await Fp(s),this.log("info","INIT","Phase 7: Workspace setup complete"),r.sendWorkerInitialized(),r.sendTaskSlashCommandsUpdate(Op()),this.log("info","INIT","Phase 8: Initialization finalized"),await this.registerWithDaemon(s),this.log("info","INIT","Phase 9: Registered with daemon"),this.log("info","WORKSPACE",`Prepared ${this.options.input.repositorySourceType} workspace via ${u} at ${s} (${d||"none"})`),this.context={credentials:this.credentials,options:this.options,workClient:r,workingDirectory:s,dataDir:o,initialCommitHash:d,logger:this.logger},process.env.AGENTRIX_WORKING_DIR=s,process.env.AGENTRIX_WORKING_USER=t,process.env.AGENTRIX_WORKING_TASK=e,this.options.input.environmentVariables&&Object.entries(this.options.input.environmentVariables).forEach(([e,t])=>{null!=t&&(process.env[e]=String(t))}),this.options.input.api_base_url&&(process.env.OPENAI_BASE_URL=this.options.input.api_base_url),this.options.input.api_key&&(process.env.CODEX_API_KEY=this.options.input.api_key),await Yp(this.options.input),"agentSessionId"in this.options.input&&this.options.input.agentSessionId&&(this.threadId=this.options.input.agentSessionId,this.log("info","AGENT",`Resuming thread: ${this.threadId}`))}createWorkspaceHandlers(e,t){return this.isOneShotExecution()?{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:async()=>{throw new Error("Uncommitted changes require user input, which is not supported in oneshot execution mode")},onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:async()=>{throw new Error("Branch mismatch requires user input, which is not supported in oneshot execution mode")}}:{onRepositoryDetected:t=>{e.associateRepository(t.host,t.owner,t.repo,t.url)},onUncommittedChanges:this.onUncommittedChanges.bind(this),onCommitUncommittedChanges:async()=>this.commitCurrentChangesWithAgent(t),onBranchMismatch:this.onBranchMismatch.bind(this)}}async registerWithDaemon(e){const t=this.options.input.taskId,n=await ln(t,{cwd:e,machineId:this.credentials.machineId,pid:process.pid,startedBy:this.options.startedBy||"terminal"});n.error?this.log("warn","DAEMON",`Failed to report session ${t}:`,n.error):this.log("info","DAEMON",`Session ${t} registered`)}createMessageCoordinator(e,t){return this.coordinator=new ap({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 pn(this.taskId,this.options.input.userId),this.stopTask("event")}},logger:(e,t,n)=>{const s=e;this.log(s,t,n)},idleTimeoutMs:t,onIdleTimeout:()=>this.stopTask("idle")}),this.coordinator}async handleEvent(){if("task-message"===this.options.input.event){const{eventId:e,message:t}=this.options.input.eventData;t&&oe(t)&&"user"===t.type&&(await this.coordinator.enqueue(t),e&&this.workClient?.sendEventAck(e))}}async executeMergeRequest(){this.refreshGroupId(),this.log("info","MERGE","Executing merge-request command");try{if(!this.options.input.repositoryId){const e="Cannot create PR: task has no git repository configured.";return this.log("warn","MERGE","No repositoryId found in task input"),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}await yi(this.context.workingDirectory)&&await this.commitCurrentChangesWithAgent();const e=await bi(this.context.workingDirectory),t=this.context.initialCommitHash,n=this.workspace.getState(),s=n.branchName?{branchName:n.branchName,branchBinding:n.branchBinding}:this.options.input,a=Hd(s),i=a?Gd(this.options.input.taskId,s.branchName):void 0;if(a&&i){const e=await _i(this.context.workingDirectory);if(e!==i){const t=Wd(e,i);return this.log("warn","MERGE",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 this.log("error","MERGE",e),void this.context.workClient.sendSystemErrorMessage(e,{groupId:this.currentGroupId??void 0})}if(0===(await Ii(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=Zd(t);this.log("debug","MERGE",`PR prompt: ${o.substring(0,200)}...`);const r=this.options.input.agentId??"default",c=await Tp.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,projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:{type:"json_schema",schema:$p}});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=Np(p),m=Gd(this.options.input.taskId,i,u.title);a||await Bd(this.context.workingDirectory,m);const h=Fd(m);this.log("info","MERGE",`Pushing HEAD to remote branch ${m}`),await Jd(this.context.workingDirectory,h,!1,{gitServerId:this.options.input.gitServerId,gitUrl:this.options.input.gitUrl}),this.log("info","MERGE","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);this.log("error","MERGE","Merge-request failed:",e),this.context.workClient.sendSystemErrorMessage(`Merge-request failed: ${t}\n\n`,{groupId:this.currentGroupId??void 0})}}async executeChangeTitle(e){this.log("info","WORKER",`Changing task title to: ${e}`),this.context.workClient.sendChangeTaskTitle(e)}async executeBashCommand(e){if(this.refreshGroupId(),!Ce.isDirectBashAllowed())return this.log("warn","BASH","Direct bash execution is disabled by global settings"),void this.context.workClient.sendSystemErrorMessage("Direct bash execution is disabled by global settings.",{groupId:this.currentGroupId??void 0});this.log("info","BASH",`Executing command: ${e}`);const t=await sp(e,this.context.workingDirectory,{onOutput:e=>{this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0})},onComplete:e=>{this.log("info","BASH",`Command completed with exit code: ${e}`)}});this.log("info","BASH",`Worker ready after command execution (exit code: ${t})`)}async executeMergePr(){this.refreshGroupId(),await op({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 Tp.create("codex",t),s=e||this.context?.workingDirectory;if(!s)throw new Error("Working directory is not available for commit generation");this.log("info","MERGE","Generating commit message with agent"),await qp({runner:n,workingDirectory:s,model:this.currentModel||this.options.input.model||void 0,abortController:this.abortController,modeConfig:{mode:"work",supportChangeTitle:!1},schemaTarget:"openai",projectAgentrixGuidance:this.projectAgentrixGuidance,onStreamMessage:async e=>{const t=this.filterMessages(e);null!==t&&this.getActiveWorkClient().sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})}}),this.log("info","MERGE","Committed changes with agent-generated message")}async executeNewSession(){this.log("info","SESSION","Executing new-session: clearing threadId"),this.threadId=null,this.context.workClient.sendResetTaskSession(),this.log("info","SESSION","Session reset sent, stopping task for clean restart"),this.stopTask("event")}getStructuredOutputSchema(){return Hp(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 Ce.readDaemonState();if(!e?.port)return this.log("debug","MCP","Agentrix event MCP broker unavailable: daemon state not found"),null;const t=Vp(this.options.input),n=Xp(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}.${Mr(s,Pr(e))}`}(this.credentials,{taskId:this.taskId,userId:this.options.input.userId,taskPreviewEnabled:t,visionPlanEnabled:n});return{serverName:jr,url:rn(e,Lr),tokenEnvVar:"AGENTRIX_EVENT_MCP_TOKEN",titleToolName:qr,previewToolName:t?Hr:void 0,sendVisionArtifactToolName:n?Gr:void 0,token:s}}buildCodexRunEnvironment(){if(this.codexAgentrixEventMcp)return{...process.env,[this.codexAgentrixEventMcp.tokenEnvVar]:this.codexAgentrixEventMcp.token}}async runCodex(){this.log("info","AGENT",`Starting Codex agent for task ${this.taskId}`),this.currentModel=xp(this.options.input.model),this.currentModel?this.log("info","AGENT",`Using model: ${this.currentModel}`):this.log("info","AGENT","Using default model from Codex config (model name unavailable)");const e=this.options.input.agentId??"default",t=await Tp.create("codex",e),n={mode:"work",supportChangeTitle:this.supportChangeTitle};if(this.codexAgentrixEventMcp=await this.resolveCodexAgentrixEventMcp(),this.isStopping)return void this.log("info","AGENT",`Skipping Codex run for task ${this.taskId} because worker is stopping`);if(this.isOneShotExecution())return void await this.runCodexOneShot(t,n);const s=t.loop({cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:n,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});(async()=>{try{for(;!this.isStopping;){const e=await this.coordinator.waitForAgentMessage();if(e)this.refreshGroupId(),this.updateAgentRunning(!0),s.push(e);else if(this.isStopping)break}}catch(e){this.log("error","AGENT","Message pump failed:",e),this.stopTask("event")}})();for await(const e of s.events)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.log("info","AGENT",`Codex agent finished for task ${this.taskId}`)}async runCodexOneShot(e,t){const n=await this.coordinator.waitForAgentMessage();if(!n)return this.isStopping||this.stopTask("oneshot_complete"),void this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId} without runnable message`);this.updateAgentRunning(!0);try{this.refreshGroupId();const s=e.runStreamed(n,{cwd:this.context.workingDirectory,model:this.currentModel||void 0,agentSessionId:this.threadId??void 0,abortController:this.abortController,modeConfig:t,env:this.buildCodexRunEnvironment(),codexAgentrixEventMcp:this.codexAgentrixEventMcp??void 0,taskDataDir:this.context.dataDir,enableTaskPreviewUrl:Vp(this.options.input),enableVisionPlan:Xp(this.context.workingDirectory),projectAgentrixGuidance:this.projectAgentrixGuidance,structuredOutputSchema:this.getStructuredOutputSchema()});for await(const e of s)this.context.logger.debug(`sdk message: ${JSON.stringify(e)}`),await this.handlePrimaryRunnerMessage(e);this.isStopping||this.stopTask("oneshot_complete")}finally{this.log("info","AGENT",`Codex oneshot finished for task ${this.taskId}`)}}async handlePrimaryRunnerMessage(e){if("system"===e.type&&"init"===e.subtype)return this.threadId=e.session_id,this.context.workClient.sendUpdateTaskAgentSessionId(e.session_id),this.context.workClient.sendTaskSlashCommandsUpdate(Op(e.slash_commands??[]),e.session_id),this.log("info","AGENT",`Thread started: ${e.session_id}`),void this.updateAgentRunning(!0);const t=this.filterMessages(e);null!==t&&("result"===e.type?await this.handleSdkResultMessage(t):this.context.workClient.sendTaskEvent(this.getChatSenderMeta(),t,{groupId:this.currentGroupId??void 0})),"result"!==e.type?this.updateAgentRunning(!0):this.updateAgentRunning(!1)}filterMessages(e){const t=e,n=t?.message?.content;if(!n||"string"==typeof n)return e;const s=n.filter(e=>{return"tool_use"!==e.type||"agentrix"!==(n=e.server_name)&&n!==jr?!("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:ke().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:ke().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 cp(e,this.askUserAwaiter,{sendAskUser:e=>n.sendAskUser(this.getChatSenderMeta(),e,{groupId:this.currentGroupId??void 0}),sendAskUserResponse:(e,t)=>n.sendAskUserResponse(e,t),onTimeoutMessage:e=>this.sendMessage(e),stopTask:e=>this.stopTask(e)},t)}getActiveWorkClient(){const e=this.context?.workClient??this.workClient;if(!e)throw new Error("[WORKER] WorkerClient not available");return e}resolveTaskAgentName(e){const t=this.options.input.taskAgents??[];return t.find(t=>t.id===e)?.name||""}getChatSenderMeta(){const e=this.options.input.agentId;return{senderType:"agent",senderId:e,senderName:this.resolveTaskAgentName(e)??""}}async onUncommittedChanges(){const e=[{question:"Uncommitted changes detected in the working directory. How would you like to proceed?",header:"Git Status",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:[{label:"Ignore",description:"Keep changes on current branch and continue without switching"},{label:"Commit",description:"Create a commit with an agent-generated message, then switch to task branch"},{label:"Stash",description:"Stash changes, then switch to task branch"},{label:"Abort",description:"Cancel the task, do nothing"}]}];try{const t=await this.askUser(e,{onTimeout:"abort_task"}),n=t.answers[0],s=t.rememberAnswers?.[0]??e[0]?.rememberSelection?.defaultValue??!1;return n.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${n}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Ignore:"Ignore",Commit:"Commit",Stash:"Stash",Abort:"Abort"}[n]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for uncommitted changes: ${e}`),{action:"Abort",remember:!1}}}async onBranchMismatch(e){const t=[{label:"Switch",description:`Checkout ${e.expectedBranch} and continue`},{label:"Keep",description:`Continue on ${e.currentBranch} (may affect task history)`},{label:"Abort",description:"Cancel the task"}],n=[{question:`Branch mismatch detected. Current: ${e.currentBranch}. Expected: ${e.expectedBranch}. How would you like to proceed?`,header:"Git Branch",multiSelect:!1,rememberSelection:{enabled:!0,defaultValue:!0},options:t}];try{const e=await this.askUser(n,{onTimeout:"abort_task"}),t=e.answers[0],s=e.rememberAnswers?.[0]??n[0]?.rememberSelection?.defaultValue??!1;return t.startsWith("other:")?(this.log("info","GIT",`User provided custom input: ${t}, defaulting to Abort`),{action:"Abort",remember:!1}):{action:{Switch:"Switch",Keep:"Keep",Abort:"Abort"}[t]||"Abort",remember:s}}catch(e){return this.log("warn","GIT",`Failed to get user response for branch mismatch: ${e}`),{action:"Abort",remember:!1}}}async createPullRequest(e,t,n){this.log("info","MERGE",`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=Ce.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 Wc(t,n,!1);this.log("info","IMAGE",`Downloaded image from ${t} to ${s}`),e.push(`Image: ${s}`)}catch(e){this.log("error","IMAGE",`Failed to download image from ${t}:`,e)}}else if("document"===s.type&&s.source&&s.source.url){const t=s.source.url;try{const{filePath:a,mimeType:i,filename:o}=await Wc(t,n,!0);this.log("info","DOCUMENT",`Downloaded document from ${t} to ${a}`);const r=s.title||o;e.push(`Document: ${a}\nTitle: ${r}\nType: ${i}`)}catch(e){this.log("error","DOCUMENT",`Failed to download document from ${t}:`,e)}}const s=e.map(e=>e.trim()).filter(Boolean).join("\n\n").trim();if(s)return s}return""}stopTask(e){this.isStopping||(this.isStopping=!0,"oneshot_complete"===e&&(this.exitReason="oneshot_complete",this.log("info","AGENT","One-shot execution completed, stopping task")),"idle"===e?this.log("info","AGENT","Idle timeout reached, stopping task"):"ask_user_timeout"===e&&this.log("info","AGENT","ask_user timed out, stopping task"),this.askUserAwaiter.clear(),this.coordinator?.stop(),"oneshot_complete"!==e&&this.abortController.abort())}updateAgentRunning(e){this.coordinator?.updateAgentRunning(e)}createWorkerClientConfig(e,t,n){const s=this.options.input.agentId,a=this.options.input.taskAgents?.find(e=>e.id===s)?.name;return{config:{userId:e,taskId:t,chatId:this.options.input.chatId,machineId:this.credentials.machineId,agentId:s,agentName:a,cwd:n,serverUrl:Ce.serverUrl.replace(/^http/,"ws"),path:"/v1/ws",auth:we(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:K(),status:n,taskId:t,machineId:this.credentials.machineId,timestamp:Date.now().toString()}}},healthCheckConfig:{enabled:!0,intervalMs:3e4,timeoutMs:5e3},logger:(e,...t)=>(this.context?.logger??this.logger)?.info(`[SOCKET] ${e}`,...t)},handlers:{attachmentsDir:Ce.resolveAttachmentsDir(e,t),stopTask:async()=>{this.stopTask("event")},onTaskMessage:async e=>{if(ie(e)){const[t,n]=this.askUserAwaiter.entries().next().value||[];return void(t&&n&&(this.askUserAwaiter.delete(t),n(e)))}oe(e)&&"user"===e.type&&await this.coordinator.enqueue(e)},onTaskInfoUpdate:async e=>{await rp(e,this.options.input,this.workspace)},onWorkerStatusRequest:async()=>{if(!this.context?.workClient)return;if(!this.coordinator)return;const{state:e}=this.coordinator.getStatus();"running"===e?this.context.workClient.sendWorkRunning():"idle"===e&&this.context.workClient.sendWorkerReady()}}}}async exitWorker(e,t){this.coordinator&&this.coordinator.stop(),this.log("info","WORKER",`Exiting with reason: ${e} for task ${this.taskId}`);const n=this.context?.workClient??this.workClient;n&&("error"===e&&t?await n.sendErrorMessageAndExit(t):(n.sendWorkerExit(e),await n.disconnect()),this.historyDb&&this.historyDb.close())}createLogger(e){const{createLogger:t}=nu;return t(e)}log(e,t,n,...s){const a=this.context?.logger??this.logger;a&&a[e](`[${t}] ${n}`,...s)}get taskId(){return this.options.input.taskId}getCurrentModel(){return this.currentModel||"unknown"}async handleSdkResultMessage(e){let t,n;try{const e=await this.workspace.prepareResultArtifacts({onPatchError:e=>{this.log("warn","GIT","Failed to write patch diff for result:",e)}});t=e.artifacts,n=e.artifactVersion}catch(e){this.log("warn","GIT","Failed to prepare git artifacts for result:",e)}if(this.context.workClient.sendTaskMessage(this.getChatSenderMeta(),e,{...t?{artifacts:t}:{},groupId:this.currentGroupId??void 0}),n)try{await Qd(this.options.input.userId,this.taskId,n)}catch(e){this.log("warn","GIT","Failed to mark artifact version as sent:",e)}}}function au(){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=pt(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 iu(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 ou(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(...ou(A.join(e,a.name),n)):s.push(n))}return s}async function ru(e,t,n){const s=ou(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)},yt("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:rt.boolean().describe("true if the code passes security review, false if it must be rejected"),reasons:rt.array(rt.string()).describe("If rejected: list each specific issue found. If approved: briefly state what was checked."),tags:rt.array(rt.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:iu(e.tags)}),{content:[{type:"text",text:"Review decision recorded."}]})));var u;const m=ft({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=vt({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:au(),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 cu=Pt(ht);function lu(e,t,n){const s=Ce.serverUrl.replace(/^http/,"ws");return Ye(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}async function du(e,...t){const{stdout:n}=await cu("git",t,{cwd:e});return n.trim()}function pu(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"skill"}const uu=Pt(ht);function mu(e,t,n){const s=Ce.serverUrl.replace(/^http/,"ws");return Ye(s,{path:"/v1/ws",transports:["websocket"],auth:{token:e.token,clientType:"worker",machineId:e.machineId,taskId:n}})}const hu=["claude","codex","deployment","companion","hive-publish","hive-install"],gu={claude:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Ce.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=qd(t.input),s=await tu.calculateFinalCwd(n),a=new eu(e,t,s);await a.start()}(e,r)}},codex:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i=Ce.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 su(e,t);await n.start()}(e,r)}},deployment:{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:Ce.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(Ce.agentrixAgentsHomeDir,i);if(o.existsSync(t))throw new Error(`Target agent directory already exists: ${t}`);console.log(`[Deployment] Copying from ${a} to ${t}`),await Gp(a,t),console.log("[Deployment] Deployment completed successfully"),u=function(e,t,n){const s=Ce.serverUrl.replace(/^http/,"ws");return Ye(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:K(),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:K(),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:Ce.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,v=null,y=null;try{if(n.environmentVariables)for(const[e,t]of Object.entries(n.environmentVariables))null!=t&&(process.env[e]=String(t));if(console.log(`[HivePublish] Starting for task ${s}, name=${m}`),function(e,t){if(!o.existsSync(e))throw new Error(`Source directory not found: ${e}`);if(!o.statSync(e).isDirectory())throw new Error(`Source path is not a directory: ${e}`);if("skill"===t&&!o.existsSync(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:pu(r),displayName:r,description:c,readme:n,repoDirName:pu(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}`)}y=A.join(Ce.agentrixHomeDir,"tmp","hive-publish",s),o.mkdirSync(y,{recursive:!0}),console.log("[HivePublish] Cloning hive repo..."),await du(y,"clone","--depth","1",c,".");const t=A.join(y,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 Gp(r,t),o.writeFileSync(A.join(t,"agentrix-hive-id.txt"),`${a}\n`,"utf-8"),await du(y,"add",".");const i=await async function(e){try{return await cu("git",["diff","--cached","--quiet"],{cwd:e}),!1}catch(e){if("number"==typeof e?.code&&1===e.code)return!0;throw e}}(y);if(i){console.log("[HivePublish] Running Claude security review...");const e=await ru(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 du(y,"commit","-m",t),console.log("[HivePublish] Pushing to remote..."),await du(y,"push")}else console.log("[HivePublish] No git changes to publish; using existing HEAD");const b=await du(y,"rev-parse","HEAD");console.log(`[HivePublish] Push succeeded, commit=${b}`),v=lu(e,0,s),await new Promise((e,t)=>{const n=setTimeout(()=>t(new Error("WebSocket connection timeout")),1e4);v.on("connect",()=>{clearTimeout(n),v.emit("hive-publish-complete",{eventId:K(),taskId:s,listingId:a,success:!0,gitCommitHash:b,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)}),v.on("connect_error",e=>{clearTimeout(n),t(e)})})}catch(t){console.error("[HivePublish] Failed:",t);try{v=v??lu(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),i=()=>{v.emit("hive-publish-complete",{eventId:K(),taskId:s,listingId:a,success:!1,error:t instanceof Error?t.message:String(t),reviewReasons:d}),clearTimeout(n),setTimeout(e,1e3)};v.connected?i():(v.on("connect",i),v.on("connect_error",()=>{clearTimeout(n),e()}))})}catch{console.error("[HivePublish] Failed to send error event")}throw t}finally{if(v&&v.disconnect(),y&&o.existsSync(y))try{o.rmSync(y,{recursive:!0,force:!0})}catch{}process.exit(0)}}(e,i)}},"hive-install":{async run({credentials:e,startedBy:t,userId:n,taskId:s,idleTimeoutSecond:a}){const i={input:Ce.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(Ce.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 uu("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(Ce.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 Gp(t,n),"agent"===l)try{console.log(`[HiveInstall] Building agent plugins/hooks in ${n}`),oa(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=mu(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:K(),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??mu(e,0,s),await new Promise(e=>{const n=setTimeout(e,5e3),a=()=>{p.emit("hive-install-complete",{eventId:K(),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=Ce.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 eo();t.input.agentDir=n,process.env.AGENTRIX_COMPANION_HOME=s;const a=qd(t.input),i=await tu.calculateFinalCwd(a),o=new eu(e,t,i);await o.start()}(e,r)}}};async function fu(e,t){const n=`${Ce.serverUrl}/v1/agents/${encodeURIComponent(e)}/git-url`,s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}});return s.ok?s.json():null}function vu(e){try{const t=c(_(e,"agent.json"),"utf-8"),n=JSON.parse(t);return"string"==typeof n.version?n.version:null}catch{return null}}function yu(e,t){const n=e=>e.split(".").map(e=>parseInt(e,10)||0),s=n(e),a=n(t);for(let e=0;e<Math.max(s.length,a.length);e++){const t=s[e]??0,n=a[e]??0;if(t>n)return!0;if(t<n)return!1}return!1}async function bu(e){const t=Ce.agentrixAgentsHomeDir;if(!r(t))return;let n;try{n=g(t).filter(e=>p(_(t,e)).isDirectory())}catch{return}for(const s of n){if("companion"===s||s.startsWith("draftagent-")||s.includes("."))continue;const n=_(t,s),a=_(n,"upgrade");if(r(a))continue;const i=vu(n);$e.info(`[AGENT UPDATE] Checking ${s} (local version: ${i??"unknown"})`);try{const t=await fu(s,e);if(!t||!t.gitUrl){$e.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];mt(e.join(" "),{stdio:"pipe",timeout:12e4});const o=t.subDir?_(n,t.subDir):n;if(t.subDir&&!r(o))throw new Error(`subDir "${t.subDir}" not found in cloned repo`);const c=vu(o);if(!c||i&&!yu(c,i)){$e.info(`[AGENT UPDATE] ${s} up to date (local: ${i??"unknown"}, remote: ${c??"unknown"})`),h(n,{recursive:!0,force:!0});continue}$e.info(`[AGENT UPDATE] Update available for ${s}: ${i??"unknown"} → ${c}`),t.subDir?(m(o,a),h(n,{recursive:!0,force:!0})):m(n,a),$e.info(`[AGENT UPDATE] Staged upgrade for ${s}`)}catch(e){throw r(n)&&h(n,{recursive:!0,force:!0}),e}}catch(e){$e.warn(`[AGENT UPDATE] Check failed for ${s}: ${e}`)}}}let wu=null;function xu(){const e=Ce.getStatePaths();return Ke.join(Ke.dirname(e.daemonStateFile),"upgrade-daemon.state.json")}function ku(){try{const e=xu();if(!je.existsSync(e))return null;const t=je.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function Iu(e){try{const t=xu();if(je.existsSync(t)){if("number"==typeof e){const t=ku();if(!t||t.pid!==e)return}je.unlinkSync(t)}}catch{}}function Su(e){try{return process.kill(e,0),!0}catch{return!1}}async function Tu(e){return(await mn(e)).error?await async function(){try{return await vn(),Gc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),!0}catch{return!1}}()?(wu=null,!0):(wu=e,!1):(wu=null,!0)}async function Eu(){if(wu)return await Tu(wu)?"upgraded":"no-upgrade";if(Dl())return"no-upgrade";const e=await Pl();if(e.hasUpgrade&&await Ol(e)){const e="Automatic CLI upgrade installed";return wu=e,await Tu(e)?"upgraded":"no-upgrade"}try{const e=await Ce.readCredentials();e&&await bu(e)}catch{}return"no-upgrade"}function Au(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 _u(e,t){if(!Qt.isTTY){if(void 0!==t)return t;throw new Error(`${e} is required in non-interactive mode`)}const n=en({input:Qt,output:Zt});try{const s=t?` (${t})`:"";return(await n.question(`${e}${s}: `)).trim()||t||""}finally{n.close()}}function Cu(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function $u(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}function Nu(){return process.env.OPENAPI_BASE_URL||process.env.AGENTRIX_OPENAPI_BASE_URL||Ce.serverUrl}function Ru(e){return(process.env.PATH||"").split(":").filter(Boolean).some(t=>{try{return S(_(t,e),T.X_OK),!0}catch{return!1}})}function Pu(e,t,n){return new Promise((s,a)=>{const i=ut(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 Mu(e){try{return await Rt(e),!0}catch{return!1}}function Du(e){return e.filter(e=>e.required&&!e.installed)}async function Ou(e,t){Ru(e)?console.log(L.green(`✓ ${e} is installed`)):Ru("npm")?(console.log(L.blue(`Installing ${e} with npm...`)),await Pu("npm",["install","-g",t])):console.log(L.yellow(`npm is not available. Install ${t} manually.`))}async function Uu(e,t,n){const s=n?` (${n})`:"";return(await e.question(`${t}${s}: `)).trim()||n||""}async function ju(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 Lu(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(L.yellow("Invalid selection"))}}function qu(e){return JSON.stringify(e)}async function Hu(e,t){const n=await async function(e){try{return(await _e.get(`${Ce.serverUrl}/v1/openapi-config`,{headers:{Authorization:`Bearer ${e.token}`},timeout:1e4})).data.baseUrl||Nu()}catch(e){const t=e instanceof Error?e.message:"unknown error";return console.log(L.yellow(`Could not fetch Agentrix API URL from server, using fallback: ${t}`)),Nu()}}(t),s=en({input:Qt,output:Zt});try{await async function(e,t,n){const s=_(Ce.claudeConfigDir,"settings.json");if(!t&&await Mu(s)&&!await ju(e,`Claude config already exists at ${s}. Overwrite`,!1))return void console.log(L.gray("Skipped Claude config"));const a=await Lu(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(L.gray("Skipped Claude config"));const i={};if("official"===a)i.ANTHROPIC_API_KEY=await Uu(e,"Anthropic API key");else if("agentrix"===a)i.ANTHROPIC_BASE_URL=n,i.ANTHROPIC_AUTH_TOKEN=await Uu(e,"Agentrix API key for Claude");else{const t=await Uu(e,"Anthropic-compatible base URL");i.ANTHROPIC_BASE_URL=t,i.ANTHROPIC_AUTH_TOKEN=await Uu(e,"Anthropic auth token")}const o=await Uu(e,"Claude primary model","claude-sonnet-4-6"),r=await Uu(e,"Claude fast model","claude-haiku-4-5"),c=await Uu(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 _t(Ce.claudeConfigDir,{recursive:!0}),await $t(s,JSON.stringify({env:i,model:o},null,2),"utf-8"),console.log(L.green(`✓ Wrote Claude config: ${s}`))}(s,e,n),await async function(e,t,n){const s=_(Ce.codexHomeDir,"config.toml");if(!t&&await Mu(s)&&!await ju(e,`Codex config already exists at ${s}. Overwrite`,!1))return void console.log(L.gray("Skipped Codex config"));const a=await Lu(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(L.gray("Skipped Codex config"));const i=await Uu(e,"Codex model","gpt-5.5"),o=await Lu(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 Uu(e,"Agentrix API key for Codex")):"openai"===a?(l="OPENAI_API_KEY",r[l]=await Uu(e,"OpenAI API key")):(c=await Uu(e,"Custom OpenAI-compatible base URL"),l="CUSTOM_API_KEY",r[l]=await Uu(e,"Custom API key")),await _t(Ce.codexHomeDir,{recursive:!0}),await $t(s,function(e){const t=e.provider,n=[`model = ${qu(e.model)}`,`model_provider = ${qu(t)}`,"",`[model_providers.${t}]`,`name = ${qu("agentrix"===t?"Agentrix":"openai"===t?"Openai":"Custom")}`,`wire_api = ${qu(e.wireApi)}`];if(e.baseUrl){const s="agentrix"===t?e.baseUrl.replace(/\/+$/,"")+"/v1":e.baseUrl;n.push(`base_url = ${qu(s)}`)}return e.envKey&&n.push(`env_key = ${qu(e.envKey)}`),`${n.join("\n")}\n`}({provider:a,baseUrl:c||void 0,envKey:l,model:i,wireApi:o}),"utf-8"),function(e){const t=Ce.readOrInitSettings({sandbox:Ce.getSandboxSettings(),daemonEnv:{enabled:!1,variables:{}},daemonControl:{allowLanAccess:!1},allowDirectBash:!0}),n=t.daemonEnv||{enabled:!1,variables:{}},s={...n.variables||{},...e};Ce.writeSettings({...t,daemonEnv:{...n,enabled:!0,variables:s}});for(const[t,n]of Object.entries(e))process.env[t]=n}(r),console.log(L.green(`✓ Wrote Codex config: ${s}`)),console.log(L.green(`✓ Wrote Codex env vars to ${Ce.getStatePaths().settingsFile}`))}(s,e,n)}finally{s.close()}}async function Gu(e={}){console.log(L.bold("\nAgentrix CLI initialization\n")),e.skipDeps||await async function(){const e=Ps(),t=[...Du(e.cli.filter(e=>"claude"!==e.name)),...Du(e.sandbox)];"linux"!==process.platform||Ru("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(L.green("✓ System dependencies are installed"));if("linux"!==process.platform){console.log(L.yellow("Automatic dependency installation is currently only supported on Linux."));for(const t of e)console.log(L.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=>Ru(e.name))||null;if(!t){console.log(L.yellow("No supported package manager found. Install these dependencies manually:"));for(const t of e)console.log(L.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(L.blue(`Installing system dependencies with ${t.name}: ${n.join(", ")}`));const s=t.installCommand(n);"apt-get"===t.name?await Pu(s.join(" "),[],{shell:!0}):await Pu(s[0],s.slice(1))}(t),await Ou("claude","@anthropic-ai/claude-code@latest"),await Ou("codex","@openai/codex@latest");const n=Ms();if(!n.ok)throw new Error(`Missing critical dependencies after installation: ${n.missing.join(", ")}`)}();const t=await kn();await Hu(Boolean(e.force),t),e.skipDaemon||await async function(){if(await gn())console.log(L.green("✓ Daemon is already running"));else{console.log(L.blue("Starting Agentrix daemon...")),Gc(["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 hn())return void console.log(L.green("✓ Daemon started successfully"));console.log(L.yellow("Daemon may still be starting. Run `agentrix status` to check."))}}(),console.log(L.green("\n✓ Agentrix CLI initialization complete"))}function Bu(e,t){const n=e[t]?.trim();return n||void 0}function Fu(e){return e.replace(/^~(?=\/|$)/,n.homedir())}function Wu(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 zu(e){const t=Bu(e,"AGENTRIX_API_KEY");if(t)return t;const n=Bu(e,"AGENTRIX_API_KEY_FILE");if(!n)return;const s=(await async function(e){try{return(await Ct(Fu(e),"utf-8")).replace(/[\r\n]/g,"")}catch{throw new Error(`AGENTRIX_API_KEY_FILE is set but is not readable: ${e}`)}}(n)).trim();return s||void 0}function Ku(e){return JSON.stringify(e)}function Vu(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 Xu(e){var t;return`${[`model = ${Ku(e.codexModel)}`,'model_provider = "agentrix"',"","[model_providers.agentrix]",'name = "Agentrix"','wire_api = "responses"',`base_url = ${Ku((t=e.baseUrl,`${t.replace(/\/+$/,"")}/v1`))}`,'env_key = "AGENTRIX_API_KEY"'].join("\n")}\n`}function Ju(e,t){return`${JSON.stringify({connectionMode:"gemini-compatible",baseUrl:e.baseUrl,apiKey:t,imageModel:e.geminiImageModel},null,2)}\n`}function Yu(e,t){return"skip"===e?"skip":t?"would write":"write"}const Qu=U(j(process.argv)).scriptName("agentrix").version(Re.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 Zu(e){try{return process.kill(e,0),!0}catch{return!1}}async function em(e){let t;if("string"==typeof e["report-json"])try{t=JSON.parse(e["report-json"])}catch{console.error(L.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 Ce.readDaemonState():null,n=e.oldPid??(t&&ql(t.pid)?t.pid:void 0),s=e.expectedCliVersion??Rl();var a;if(e.report&&(a={...e.report,oldPid:n,expectedCliVersion:s,reason:e.reason,createdAt:(new Date).toISOString()},u(jl(),JSON.stringify(a,null,2),"utf-8")),e.stopExistingDaemon&&void 0!==n&&ql(n)&&await vn(),void 0!==n){const t=await async function(e,t){const n=Date.now()+t;for(;Date.now()<n;){if(!ql(e))return!0;await Ll(100)}return!ql(e)}(n,e.oldDaemonExitTimeoutMs??12e4);if(!t)return{success:!1,error:`Old daemon PID ${n} did not exit before timeout`}}try{Gc(["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 Ce.readDaemonState();if(n&&n.pid!==e&&n.cliVersion===t&&ql(n.pid))return n;await Ll(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(L.red("Error:"),a.error??"Daemon restart failed"),process.exit(1))}Ce.getStatePaths,Qu.command("upgrade","Upgrade CLI to the latest version",{},async e=>{console.log(L.dim(`Current version: ${Re.version}`));const t=await hn(),n=t?await Ce.readDaemonState():null;await Ol()||process.exit(1);try{const e=await Ce.readCredentials();e&&(console.log(L.dim("Checking agent updates...")),await bu(e))}catch{}if(t){console.log(L.blue("Preparing daemon restart..."));const e=await mn("CLI upgrade installed");let t=!0;const s=Rl();e.error?(console.log(L.yellow(`⚠️ Could not prepare graceful restart: ${e.error}`)),console.log(L.blue("Restarting daemon directly...")),await vn(),Gc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref()):"pending_restart"===e.state&&(console.log(L.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&&!a){if(Zu(e.pid)){await new Promise(e=>setTimeout(e,100));continue}a=!0}const n=await Ce.readDaemonState();if(n&&n.pid!==e?.pid&&n.cliVersion===t&&Zu(n.pid))return!0;await new Promise(e=>setTimeout(e,100))}return!1}(n,s),a?console.log(L.green("✓ Daemon restarted successfully")):console.log(L.yellow("⚠️ Daemon may still be starting. Run 'agentrix status' to check.")))}const s=Rl();"0.0.0"!==s?console.log(L.green(`\n✓ Now running version: ${s}`)):console.log(L.dim("\nRun 'agentrix --version' to see the new version")),process.exit(0)}),Qu.command("doctor","System diagnostics & troubleshooting",{},async e=>{await Os(),process.exit(0)}),Qu.command("logout","Logout from Agentrix",{},async e=>{try{await async function(){if(!await Ce.readCredentials())return void console.log(L.yellow("Not currently authenticated"));console.log(L.blue("This will log you out of Agentrix")),console.log(L.yellow("⚠️ You will need to re-authenticate to use Agentrix again"));const e=Oe({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(L.yellow("Are you sure you want to log out? (y/N): "),t)});if(e.close(),"y"===t.toLowerCase()||"yes"===t.toLowerCase())try{try{await vn(),console.log(L.gray("Stopped daemon"))}catch{}await Ce.clearCredentials(),console.log(L.gray("Removed credentials")),console.log(L.green("✓ Successfully logged out"))}catch(e){throw new Error(`Failed to logout: ${e instanceof Error?e.message:"Unknown error"}`)}else console.log(L.blue("Logout cancelled"))}()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}process.exit(0)}),Qu.command("stop","Stop the daemon",{},async e=>{!function(){const e=ku();if(e)try{Su(e.pid)&&process.kill(e.pid,"SIGTERM")}catch{}finally{Iu()}}(),await vn(),process.exit(0)}),Qu.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 em(e),console.log(L.green("✓ Daemon restarted successfully")),process.exit(0)}),Qu.command("status","Show daemon and authentication status",{},async e=>{await Os("daemon"),console.log(""),await async function(){const e=await Ce.readCredentials();if(console.log(L.bold("\nAuthentication Status\n")),!e)return void console.log(L.red("✗ Not authenticated"));console.log(L.green("✓ Authenticated"));const t=e.token.substring(0,30)+"...";console.log(L.gray(` Token: ${t}`)),e.machineId?(console.log(L.green("✓ Machine registered")),console.log(L.gray(` Machine ID: ${e.machineId}`)),console.log(L.gray(` Host: ${n.hostname()}`))):console.log(L.yellow("⚠️ Machine not registered")),console.log(L.gray(`\n Data directory: ${Ce.agentrixHomeDir}`));try{await hn()?console.log(L.green("✓ Daemon running")):console.log(L.gray("✗ Daemon not running"))}catch{console.log(L.gray("✗ Daemon not running"))}}(),process.exit(0)}),Qu.command("ls","List active sessions",{},async e=>{try{const e=await async function(){return(await cn("/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)}),Qu.command("killall","Clean up all runaway agentrix processes",{},async()=>{const e=await async function(){const e=await async function(){return(await Ns()).filter(e=>e.pid!==process.pid&&("daemon"===e.type||"worker"===e.type||"upgrade-daemon"===e.type)).map(e=>({pid:e.pid,command:e.command}))}(),t=[];let n=0;for(const{pid:s,command:a}of e)try{if(console.log(`Killing runaway process PID ${s}: ${a}`),"win32"===process.platform){const e=at.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 st()).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=Au(Cu(e["base-url"])??await _u("GitLab base URL"),"baseUrl"),n=Au(Cu(e["api-url"])??await _u("GitLab API URL",function(e){return`${Au(e,"baseUrl")}/api/v4`}(t)),"apiUrl"),s=new URL(t).hostname,a=Cu(e.name)??await _u("Git server name",s),i=(Cu(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()}(Cu(e["pat-file"])):void 0)??await async function(e){return Qt.isTTY&&Zt.isTTY&&"function"==typeof Qt.setRawMode?new Promise((t,n)=>{let s="";const a=()=>{Qt.setRawMode(!1),Qt.pause(),Qt.off("data",i)},i=e=>{const i=e.toString("utf8");return""===i?(a(),Zt.write("\n"),void n(new Error("Interrupted"))):"\r"===i||"\n"===i?(a(),Zt.write("\n"),void t(s.trim())):void(""!==i&&"\b"!==i?s+=i:s=s.slice(0,-1))};Zt.write(`${e}: `),Qt.setRawMode(!0),Qt.resume(),Qt.on("data",i)}):_u(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(!Qt.isTTY)return t;const n=(await _u("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 cn("/git-server/bind",e)}({name:a,baseUrl:t,apiUrl:n,pat:i,useAsProxy:o});if(d.error||!d.success||!d.gitServer)throw new Error(`Backend Git server bind 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??At(p.id),webhookUrl:d.webhookUrl??Et(p.id,await Ce.readDaemonState()),backendRegistered:!0,proxyRegistered:d.proxyRegistered??o,patConfigured:!0,patMeta:d.patMeta??ho(p.id),webhookSecret:d.webhookSecret},null,2))}(e),process.exit(0)}catch(e){$u(e)}}).command("list","List local private GitLab server config",{},async()=>{try{await async function(){const e=await async function(){const e=await po();if(!e)throw new Error("No Agentrix auth secret found. Run `agentrix start` and complete machine binding first.");return e}(),t=await Ce.readDaemonState(),n=await async function(){return await cn("/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=uo(e.id)??{},a=mo(e.id,t)??{};return{id:e.id,type:"gitlab",baseUrl:e.baseUrl||s.baseUrl,apiUrl:e.apiUrl||s.apiUrl,webhookEndpointPath:At(e.id),webhookUrl:Et(e.id,n),patConfigured:(i=e.id,lo.hasPat(i)),patMeta:ho(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){$u(e)}}).demandCommand(1,"Please specify one of: add, list").strict(),()=>{})}(Qu),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 Gu({skipDeps:e.skipDeps,skipDaemon:e.skipDaemon,force:e.force}),process.exit(0)}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(Qu),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 async function(e={}){const t=e.env||process.env,s=!0===e.force,a=!0===e.dryRun,i=await async function(e){const t=Fu(Bu(e,"AGENTRIX_HOME_DIR")||Bu(e,"AGENTRIX_DIR")||_(n.homedir(),".agentrix")),s=Fu(Bu(e,"AGENTRIX_CLAUDE_HOME")||_(t,"config","claude")),a=Fu(Bu(e,"AGENTRIX_CODEX_HOME")||_(t,"config","codex")),i=Fu(Bu(e,"AGENTRIX_GEMINI_HOME")||_(t,"config","gemini")),o=Bu(e,"AGENTRIX_CLAUDE_MODEL")||"claude-sonnet-4-6";return{agentrixHomeDir:t,claudeConfigDir:s,codexHomeDir:a,geminiConfigDir:i,baseUrl:Wu(Bu(e,"AGENTRIX_BASE_URL")||"https://api.xmz.ai"),apiKey:await zu(e),codexModel:Bu(e,"AGENTRIX_CODEX_MODEL")||"gpt-5.5",claudeModel:o,claudeFastModel:Bu(e,"AGENTRIX_CLAUDE_FAST_MODEL")||"claude-haiku-4-5",claudeSubagentModel:Bu(e,"AGENTRIX_CLAUDE_SUBAGENT_MODEL")||o,geminiImageModel:Bu(e,"AGENTRIX_GEMINI_IMAGE_MODEL")||"gemini-2.5-flash-image"}}(t);if(function(e,t){return!(!t&&r(_(e.claudeConfigDir,"settings.json"))&&r(_(e.codexHomeDir,"config.toml"))&&r(_(e.geminiConfigDir,"settings.json")))}(i,s)&&!i.apiKey)throw new Error("AGENTRIX_API_KEY 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.claudeConfigDir,"settings.json"),content:Vu(e,t)},{kind:"codex",path:_(e.codexHomeDir,"config.toml"),content:Xu(e)},{kind:"gemini",path:_(e.geminiConfigDir,"settings.json"),content:Ju(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 _t(P(e.path),{recursive:!0}),await $t(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}:{}}}({force:!0===e.force,dryRun:!0===e.dryRun,env:process.env}),s=t.files.filter(e=>"write"===e.action).length,a=t.files.filter(e=>"skip"===e.action).length,i=t.dryRun?"LLM config dry run":"LLM config applied";if(console.log(L.green(`✓ ${i}: ${s} write(s), ${a} skipped`)),!0===e.verbose||t.dryRun)for(const e of t.files)console.log(`${Yu(e.action,t.dryRun)} ${e.kind}: ${e.path}`);t.env.AGENTRIX_API_KEY&&console.log(L.gray("AGENTRIX_API_KEY prepared for this process.")),process.exit(0)}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}})}(Qu),Qu.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 cn("/stop-session",{sessionId:e})).success||!1}(e.sessionId);console.log(t?L.green("✓ Session stopped"):L.red("Failed to stop session"))}catch(e){console.log(L.red("No daemon running"))}process.exit(0)}),Qu.command("daemon",!1,{},async e=>{try{await kn()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}await Hl(),process.exit(0)}),Qu.command("worker",!1,e=>e.option("type",{type:"string",choices:hu,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=gu[t];if(!n)throw new Error(`Unsupported worker type: ${String(e.type)}`);const s=e["started-by"],a=await kn(),i=e["user-id"],o=e["task-id"],r=e["idle-timeout"];await n.run({credentials:a,startedBy:s,userId:i,taskId:o,idleTimeoutSecond:r})}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Unknown error"),process.env.DEBUG&&console.error(e),process.exit(1)}}),Qu.command("upgrade-daemon",!1,{},async e=>{await async function(){await async function(){!function(e){const t=xu();je.writeFileSync(t,JSON.stringify(e,null,2))}({pid:process.pid,startedAt:(new Date).toISOString()}),process.on("SIGTERM",()=>{Iu(process.pid),process.exit(0)}),process.on("SIGINT",()=>{Iu(process.pid),process.exit(0)});try{"upgraded"===await Eu()&&(Gc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}for(;;){await new Promise(e=>setTimeout(e,216e5));try{"upgraded"===await Eu()&&(Gc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref(),process.exit(0))}catch(e){}}}()}(),process.exit(0)}),Qu.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 em(e),process.exit(0)}),Qu.command("start","Start daemon (if not running) and show status",{},async e=>{try{await kn()}catch(e){console.error(L.red("Error:"),e instanceof Error?e.message:"Authentication failed"),process.env.DEBUG&&console.error(e),process.exit(1)}const t=Ms();if(t.ok||(console.log(L.bold.red("\n⚠️ Missing Critical Dependencies")),console.log(L.yellow(`Cannot start daemon. Missing: ${t.missing.join(", ")}`)),console.log(L.blue('\nRun "agentrix doctor" for detailed dependency information and installation instructions.')),process.exit(1)),!await gn()){console.log("Starting Agentrix background service..."),Gc(["daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();let e=!1;for(let t=0;t<50;t++)if(await new Promise(e=>setTimeout(e,100)),await hn()){e=!0;break}e?(await new Promise(e=>setTimeout(e,1200)),await hn()?console.log(L.green("✓ Daemon started successfully")):await async function(){const e=await async function(){const e=_(Ce.getStatePaths().logsDir,"daemon.log");try{return(await Ct(e,"utf8")).trim().split("\n").filter(Boolean).slice(-12).join("\n")||null}catch{return null}}();if(console.log(L.red("✗ Daemon exited shortly after startup")),!e)return;const t=e.split("\n").reverse().find(e=>e.includes("Machine binding revoked")||e.includes("Run `agentrix logout` and bind again"));t?console.log(L.yellow(t)):(console.log(L.gray("Recent daemon log:")),console.log(e))}()):console.log(L.yellow("⚠️ Daemon may still be starting..."))}if(Dl()){const e=await Pl();e.hasUpgrade&&(n=e).hasUpgrade&&n.latestVersion&&(console.log(""),console.log(L.yellow("┌────────────────────────────────────────────────────┐")),console.log(L.yellow("│")+" "+L.bold("Upgrade Available")+" "+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+` Current: ${L.dim(n.currentVersion)} → Latest: ${L.green.bold(n.latestVersion)} `+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+" Run "+L.cyan.bold("agentrix upgrade")+" to upgrade "+L.yellow("│")),console.log(L.yellow("│")+" "+L.yellow("│")),console.log(L.yellow("│")+" To enable auto-upgrade, set: "+L.yellow("│")),console.log(L.yellow("│")+" "+L.dim("AGENTRIX_DISABLE_AUTO_UPGRADE=false")+" "+L.yellow("│")),console.log(L.yellow("└────────────────────────────────────────────────────┘")),console.log(""))}else(function(){const e=ku();return!(!e||!Su(e.pid)&&(Iu(),1))})()||Gc(["upgrade-daemon"],{detached:!0,stdio:"ignore",env:process.env}).unref();var n;await Os("daemon"),process.exit(0)}),Qu.demandCommand(1,"Please specify a command. Use --help to see available commands.").parse();