everclaw 0.3.10 → 0.3.11

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.
@@ -1,64 +1,58 @@
1
1
  #!/usr/bin/env node
2
- import"dotenv/config";import ht from"node:fs";import Rn from"node:path";import Zt from"node:fs";import st from"node:os";import j from"node:path";import{fileURLToPath as Qt}from"node:url";var qe=".everclaw",q="~/.everclaw/config.json",it=j.join("~",qe,"workspace");function at(s=st.homedir()){return j.join(s,qe,"workspace")}function lt(s=st.homedir()){return j.join(s,qe,"config.json")}function er(){let s=Qt(import.meta.url),t=j.dirname(s);return s.endsWith("/index.js")||s.endsWith("\\index.js")?t:j.resolve(t,"..")}var tr=er();function ct(...s){let t=j.resolve(tr,...s);if(!Zt.existsSync(t))throw new Error(`Runtime asset not found: ${t}`);return t}var rr=[{spec:{name:"zai",keywords:["zai"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://api.z.ai/api/coding/paas/v4"},models:["glm-5-turbo"]},{spec:{name:"openrouter",displayName:"OpenRouter",keywords:["openrouter"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://openrouter.ai/api/v1",detectByKeyPrefix:"sk-or-",detectByBaseKeyword:"openrouter"},models:["anthropic/claude-opus-4-1","anthropic/claude-sonnet-4","openai/gpt-4.1","google/gemini-2.5-pro"]},{spec:{name:"aihubmix",displayName:"AIHubMix",keywords:["aihubmix"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://aihubmix.com/v1",detectByBaseKeyword:"aihubmix"},models:[]},{spec:{name:"siliconflow",displayName:"SiliconFlow",keywords:["siliconflow"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://api.siliconflow.cn/v1",detectByBaseKeyword:"siliconflow"},models:["openai/deepseek-ai/DeepSeek-R1"]},{spec:{name:"volcengine",displayName:"VolcEngine",keywords:["volcengine","volces","ark"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://ark.cn-beijing.volces.com/api/v3",detectByBaseKeyword:"volces"},models:["volcengine/deepseek-r1-250120"]},{spec:{name:"anthropic",displayName:"Anthropic",keywords:["anthropic","claude"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["anthropic/claude-opus-4-5","anthropic/claude-sonnet-4"]},{spec:{name:"openai",displayName:"OpenAI",keywords:["openai","gpt"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["gpt-5.2","gpt-5.2-pro","gpt-5.3-codex","gpt-5.2-codex","gpt-5.1","gpt-5.1-codex","gpt-5-mini","gpt-5-nano","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4o","gpt-4o-mini"]},{spec:{name:"openai_codex",displayName:"OpenAI Codex",keywords:["openai-codex","codex"],isOauth:!0,isGateway:!1,isLocal:!1,defaultApiBase:"https://chatgpt.com/backend-api"},models:[]},{spec:{name:"github_copilot",displayName:"GitHub Copilot",keywords:["github_copilot","copilot"],isOauth:!0,isGateway:!1,isLocal:!1,defaultApiBase:""},models:[]},{spec:{name:"deepseek",displayName:"DeepSeek",keywords:["deepseek"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["deepseek/deepseek-chat","deepseek/deepseek-reasoner"]},{spec:{name:"gemini",displayName:"Google Gemini",keywords:["gemini"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["gemini/gemini-3-flash-preview","gemini/gemini-2.5-pro","gemini/gemini-2.5-flash"]},{spec:{name:"zhipu",displayName:"Zhipu AI",keywords:["zhipu","glm","zai"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["zai/glm-4.5"]},{spec:{name:"dashscope",displayName:"DashScope",keywords:["qwen","dashscope"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["dashscope/qwen-max"]},{spec:{name:"moonshot",displayName:"Moonshot AI",keywords:["moonshot","kimi"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:"https://api.moonshot.ai/v1"},models:["moonshot/kimi-k2.5"]},{spec:{name:"minimax",displayName:"MiniMax",keywords:["minimax"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:"https://api.minimax.io/v1"},models:["minimax/MiniMax-M2.1"]},{spec:{name:"vllm",displayName:"vLLM",keywords:["vllm"],isOauth:!1,isGateway:!1,isLocal:!0,defaultApiBase:""},models:["hosted_vllm/llama-3.1-8b-instruct"]},{spec:{name:"groq",displayName:"Groq",keywords:["groq"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["openai/gpt-oss-120b","openai/gpt-oss-20b","meta-llama/llama-4-maverick-17b-128e-instruct","groq/compound","groq/compound-mini"]},{spec:{name:"ollama",displayName:"Ollama",keywords:["ollama"],isOauth:!1,isGateway:!1,isLocal:!0,defaultApiBase:"http://localhost:11434/v1"},models:["ollama/llama3.3","ollama/qwen2.5","ollama/deepseek-r1"]}];function We(){return rr.map(s=>s.spec)}var W=We(),nr=Object.fromEntries(We().map(s=>[s.name,{apiKey:"",apiBase:null,extraHeaders:null,models:[]}])),oe="custom:",G={agents:{defaults:{workspace:it,model:"gpt-4.1",provider:"auto",maxTokens:8192,temperature:.1,maxToolIterations:40,memoryWindow:100}},subagents:[{id:"researcher",name:"Researcher",task:"Research the given topic thoroughly and provide detailed findings.",createdAt:0},{id:"advisor",name:"Advisor",task:"Analyze the current conversation context and provide exactly 3 concise suggestion options for the user's next logical message. Reply with a JSON array of 3 strings.",createdAt:0}],channels:{sendProgress:!0,sendToolHints:!1,telegram:{enabled:!1,token:"",allowFrom:[],proxy:null,replyToMessage:!1,debounce:{enabled:!0,quietMs:500,maxWaitMs:3e3},groups:{requireMention:!0,allowedGroupIds:null},commands:{native:!0,custom:[]}},discord:{enabled:!1,token:"",allowFrom:[],gatewayUrl:"wss://gateway.discord.gg/?v=10&encoding=json",intents:37377,debounce:{enabled:!0,quietMs:500,maxWaitMs:3e3}}},providers:nr,customLlmProviders:[],customAcpProviders:[],gateway:{host:"127.0.0.1",port:6767,dashboard:{enabled:!0},heartbeat:{enabled:!0,intervalS:1800}},tools:{web:{search:{apiKey:"",maxResults:5}},exec:{timeout:60,pathAppend:""},restrictToWorkspace:!1,mcpServers:{},chromeSession:{enabled:!1,debugPort:9222,minChromeVersion:136,daemonIdleTimeoutS:1200,targetPrefixLength:8,stealth:{enabled:!1,cursorMovement:!0,humanizedTyping:!0,interStepDelay:[300,1500]}},browserRelay:{enabled:!1,authToken:"",extensionPath:""},rtk:{enabled:!0,autoInstall:!0,ultraCompact:!1,version:"latest"}},security:{enabled:!1,auth:{enabled:!1,pinHash:"",sessionTtlS:3600,lockOnIdle:!1,idleTimeoutS:900},toolGuard:{enabled:!1,guardedTools:null,deniedTools:[],rules:[],failOpen:!0},skillScanner:{enabled:!1,scanOnLoad:!1,blockUnsafe:!0,maxFileCount:1e3,maxFileSizeBytes:5242880},inputSanitizer:{enabled:!1,maxInputLength:5e4,stripHtmlTags:!1,blockPromptInjection:!1}},logging:{enabled:!0,level:"info",retentionHours:4,maxFileSizeMb:10,purgeIntervalMs:6e5},compaction:{enabled:!0,microCompactThresholdRatio:.6,autoCompactThresholdRatio:.8,keepRecentMessages:10,maxConsecutiveFailures:3}};function B(s){return s.toLowerCase().replace(/[\s-]+/g,"_")}function ut(s){return`${oe}${B(s)}`}function dt(s,t){let e=B(t.startsWith(oe)?t.slice(oe.length):t);return s.customLlmProviders.find(n=>B(n.name)===e)??null}function or(s,t){if(!t.includes("/"))return null;let n=t.split("/",1)[0];return n?dt(s,n):null}function $(s){return!!s&&s.startsWith(oe)}function F(s,t,e){let n=(t??s.agents.defaults.provider).trim();if(n&&n!=="auto"&&!s.providers[n])return dt(s,n);let r=or(s,e??s.agents.defaults.model);if(r)return r;let o=s.customLlmProviders.filter(i=>i.name.trim()&&i.baseUrl.trim());return o.length===1?o[0]??null:null}function se(s,t){let e=s.agents.defaults.provider;if(e!=="auto"){if(s.providers[e])return e;let a=F(s,e,t);return a?ut(a.name):null}let n=(t??s.agents.defaults.model).toLowerCase(),r=B(n),o=n.includes("/")?n.split("/",1)[0]:"";for(let a of W){let l=s.providers[a.name];if(o&&B(o)===a.name&&(a.isOauth||l?.apiKey))return a.name}for(let a of W){let l=s.providers[a.name];if(a.keywords.some(c=>n.includes(c)||r.includes(B(c)))&&(a.isOauth||l?.apiKey))return a.name}for(let a of W){if(a.isOauth)continue;if(s.providers[a.name]?.apiKey)return a.name}let i=F(s,e,t);return i?ut(i.name):null}function mt(s,t){let e=se(s,t);if(e&&$(e)){let n=F(s,e,t);return n?{apiKey:n.apiKey,apiBase:n.baseUrl,extraHeaders:n.extraHeaders}:null}return e?s.providers[e]??null:null}function ie(s,t){let e=se(s,t);if(!e)return null;if($(e))return F(s,e,t)?.baseUrl??null;let n=s.providers[e];if(n?.apiBase)return n.apiBase;let r=W.find(o=>o.name===e);return r?.isGateway?r.defaultApiBase:null}import sr from"node:fs";import ir from"node:path";import gt from"node:os";function pt(s){return sr.mkdirSync(s,{recursive:!0}),s}function ft(s){let t=s?s.replace(/^~(?=$|[\\/])/,gt.homedir()):at(gt.homedir());return pt(ir.resolve(t))}function lr(){return lt()}function yt(s,t){if(!t||typeof t!="object")return s;let e=Array.isArray(s)?[...s]:{...s};for(let[n,r]of Object.entries(t))r&&typeof r=="object"&&!Array.isArray(r)&&e[n]&&typeof e[n]=="object"&&!Array.isArray(e[n])?e[n]=yt(e[n],r):e[n]=r;return e}function bt(s){let t=s??lr();if(!ht.existsSync(t))return structuredClone(G);try{let e=ht.readFileSync(t,"utf8"),n=JSON.parse(e),r=yt(structuredClone(G),n),o=["advisor"];for(let i of o)if(!r.subagents.find(a=>a.id===i)){let a=G.subagents.find(l=>l.id===i);a&&r.subagents.push(structuredClone(a))}return r}catch(e){return console.warn(`Warning: Failed to load config from ${t}: ${String(e)}`),structuredClone(G)}}function K(s){return s.map(t=>{let e=t.content;if(typeof e=="string"&&e.length===0)return t.role==="assistant"&&t.tool_calls?{...t,content:null}:{...t,content:"(empty)"};if(Array.isArray(e)){let n=e.filter(r=>!(typeof r=="object"&&r&&["text","input_text","output_text"].includes(r.type)&&!r.text));if(n.length!==e.length)return n.length>0?{...t,content:n}:t.role==="assistant"&&t.tool_calls?{...t,content:null}:{...t,content:"(empty)"}}return t})}function Ge(){let s=new Error("Operation aborted");return s.name="AbortError",s}function w(s){return s instanceof Error&&s.name==="AbortError"}function v(s){if(s?.aborted)throw Ge()}function vt(s){return s.trim().toLowerCase().replace(/[\s-]+/g,"_")}function St(s){if(typeof s!="string")return s&&typeof s=="object"?s:{};try{return JSON.parse(s)}catch{return{}}}var ae=class{constructor(t,e,n,r={}){this.apiKey=t;this.apiBase=e;this.defaultModel=n;this.options=r}getDefaultModel(){return this.defaultModel}get requestFormat(){return this.options.apiFormat??"v1/chat/completions"}resolveModel(t){let e=t.trim();if(!e.includes("/"))return e;let n=e.split("/",2),r=n[0],o=n[1];return!r||!o?e:new Set(["custom",vt(this.options.providerLabel??"")]).has(vt(r))?o:e}buildHeaders(){let t={"Content-Type":"application/json",...this.options.extraHeaders??{}};return this.apiKey.trim()&&(t.Authorization=`Bearer ${this.apiKey}`),t}async readJson(t){try{return await t.json()}catch{return{}}}async chatCompletions(t){let e=await fetch(`${this.apiBase.replace(/\/$/,"")}/chat/completions`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:this.resolveModel(t.model??this.defaultModel),messages:K(t.messages),tools:t.tools,tool_choice:t.tools?.length?"auto":void 0,max_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7,...t.reasoning?{reasoning_effort:"medium"}:{},...t.imageOutput?{include_image_output:!0}:{}}),...t.signal?{signal:t.signal}:{}}),n=await this.readJson(e);if(!e.ok)return{content:`Error calling LLM: ${n?.error?.message??JSON.stringify(n)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let r=n.choices?.[0];if(!r?.message)return{content:`Error calling LLM: ${JSON.stringify(n)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let o=(r.message.tool_calls??[]).map(i=>({id:i.id,name:i.function.name,arguments:St(i.function.arguments)}));return{content:r.message.content??null,toolCalls:o,finishReason:r.finish_reason??"stop",usage:{prompt_tokens:n.usage?.prompt_tokens??0,completion_tokens:n.usage?.completion_tokens??0,total_tokens:n.usage?.total_tokens??0},reasoningContent:r.message.reasoning_content??null}}toResponsesInput(t){let e=[];for(let n of K(t)){let r=String(n.role??"");if(r==="tool"){e.push({type:"function_call_output",call_id:String(n.tool_call_id??""),output:typeof n.content=="string"?n.content:JSON.stringify(n.content??null)});continue}if(r==="assistant"&&Array.isArray(n.tool_calls))for(let o of n.tool_calls)e.push({type:"function_call",call_id:String(o.id??""),name:String(o.name??""),arguments:typeof o.arguments=="string"?o.arguments:JSON.stringify(o.arguments??{})});(r==="system"||r==="user"||r==="assistant")&&e.push({role:r,content:n.content??""})}return e}async responses(t){let e=await fetch(`${this.apiBase.replace(/\/$/,"")}/responses`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:this.resolveModel(t.model??this.defaultModel),input:this.toResponsesInput(t.messages),tools:t.tools,tool_choice:t.tools?.length?"auto":void 0,max_output_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7,...t.reasoning?{reasoning:{effort:"medium"}}:{},...t.imageOutput?{include_image_output:!0}:{}}),...t.signal?{signal:t.signal}:{}}),n=await this.readJson(e);if(!e.ok)return{content:`Error calling LLM: ${n?.error?.message??JSON.stringify(n)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let r=Array.isArray(n.output)?n.output:[],o=r.filter(a=>a?.type==="function_call").map(a=>({id:String(a.call_id??a.id??""),name:String(a.name??""),arguments:St(a.arguments)}));return{content:r.filter(a=>a?.type==="message").flatMap(a=>Array.isArray(a?.content)?a.content:[]).filter(a=>a?.type==="output_text").map(a=>String(a.text??"")).join(`
3
- `).trim()||null,toolCalls:o,finishReason:o.length?"tool_calls":n.status??"stop",usage:{prompt_tokens:n.usage?.input_tokens??0,completion_tokens:n.usage?.output_tokens??0,total_tokens:n.usage?.total_tokens??0},reasoningContent:null}}async chat(t){try{return v(t.signal),this.requestFormat==="v1/responses"?await this.responses(t):await this.chatCompletions(t)}catch(e){if(w(e))throw e;return{content:`Error calling LLM: ${String(e)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};import{nanoid as cr}from"nanoid";var le=class s{constructor(t,e,n){this.apiKey=t;this.apiBase=e;this.defaultModel=n}static DEFAULT_BASE="https://generativelanguage.googleapis.com/v1beta";getDefaultModel(){return this.defaultModel}resolveModel(t){let e=t.trim();if(e.includes("/")){let n=e.split("/",2),r=n[0],o=n[1];if(!r||!o)return e;let i=r.toLowerCase();(i==="gemini"||i==="google")&&(e=o)}return e.startsWith("models/")?e.slice(7):e}asText(t){if(typeof t=="string")return t;if(t==null)return"";try{return JSON.stringify(t)}catch{return String(t)}}parseToolArgs(t){if(t&&typeof t=="object"&&!Array.isArray(t))return t;if(typeof t=="string")try{let e=JSON.parse(t);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}toGemini(t){let e=[],n=[];for(let i of t.messages){let a=String(i.role??"");if(a==="system"){let l=this.asText(i.content).trim();l&&e.push(l);continue}if(a==="user"){let l=this.asText(i.content).trim();if(!l)continue;n.push({role:"user",parts:[{text:l}]});continue}if(a==="assistant"||a==="model"){let l=[],c=this.asText(i.content).trim();c&&l.push({text:c});let u=Array.isArray(i.tool_calls)?i.tool_calls:[];for(let d of u){let m=d.function;m?.name&&l.push({functionCall:{name:m.name,args:this.parseToolArgs(m.arguments)}})}l.length&&n.push({role:"model",parts:l});continue}if(a==="tool"){let l=typeof i.name=="string"?i.name:"";if(!l)continue;let c=this.asText(i.content);n.push({role:"user",parts:[{functionResponse:{name:l,response:{result:c}}}]})}}n.length||n.push({role:"user",parts:[{text:"Hello"}]});let r={contents:n,generationConfig:{temperature:t.temperature??.1,maxOutputTokens:Math.max(1,t.maxTokens??4096),...t.reasoning?{thinkingConfig:{thinkingBudget:Math.max(1,t.maxTokens??4096)}}:{}}};e.length&&(r.systemInstruction={parts:[{text:e.join(`
4
-
5
- `)}]});let o=(t.tools??[]).map(i=>i).filter(i=>i.type==="function"&&i.function?.name).map(i=>({name:i.function.name,description:i.function?.description??"",parameters:i.function?.parameters??{type:"object",properties:{}}}));return o.length&&(r.tools=[{functionDeclarations:o}],r.toolConfig={functionCallingConfig:{mode:"AUTO"}}),t.imageOutput&&(r.responseModalities=["TEXT","IMAGE"]),r}async chat(t){try{v(t.signal);let e=this.resolveModel(t.model??this.defaultModel),r=`${(this.apiBase??s.DEFAULT_BASE).replace(/\/$/,"")}/models/${encodeURIComponent(e)}:generateContent`,o=this.toGemini(t),i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json","x-goog-api-key":this.apiKey},body:JSON.stringify(o),...t.signal?{signal:t.signal}:{}}),a=await i.json();if(!i.ok)return{content:`Error calling LLM: ${a?.error?.message??JSON.stringify(a)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let l=a?.candidates?.[0],c=l?.content?.parts??[],u=c.filter(y=>typeof y?.text=="string").map(y=>String(y.text)),d=c.filter(y=>y?.functionCall?.name).map(y=>({id:cr(9),name:String(y.functionCall.name),arguments:this.parseToolArgs(y.functionCall.args)})),m={};a?.usageMetadata&&(m.prompt_tokens=Number(a.usageMetadata.promptTokenCount??0),m.completion_tokens=Number(a.usageMetadata.candidatesTokenCount??0),m.total_tokens=Number(a.usageMetadata.totalTokenCount??0));let f=String(l?.finishReason??"STOP").toLowerCase();return{content:u.length?u.join(`
6
- `):null,toolCalls:d,finishReason:f,usage:m,reasoningContent:null}}catch(e){if(w(e))throw e;return{content:`Error calling LLM: ${String(e)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};import{nanoid as ur}from"nanoid";var ce=class s{constructor(t,e,n,r){this.apiKey=t;this.apiBase=e;this.defaultModel=n;this.providerName=r}static DEFAULT_BASE_BY_PROVIDER={openrouter:"https://openrouter.ai/api/v1",openai:"https://api.openai.com/v1",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",moonshot:"https://api.moonshot.ai/v1",minimax:"https://api.minimax.io/v1",dashscope:"https://dashscope.aliyuncs.com/compatible-mode/v1",zhipu:"https://open.bigmodel.cn/api/paas/v4",siliconflow:"https://api.siliconflow.cn/v1",volcengine:"https://ark.cn-beijing.volces.com/api/v3",vllm:"http://localhost:8000/v1",ollama:"http://localhost:11434/v1",zai:"https://api.z.ai/api/coding/paas/v4"};static UNSUPPORTED_PROVIDERS=new Set(["anthropic","gemini","openai_codex","github_copilot"]);getDefaultModel(){return this.defaultModel}resolveModel(t){let e=n=>n.toLowerCase().replace(/-/g,"_");if(t.includes("/")){let n=t.split("/",2),r=n[0],o=n[1];if(!r||!o)return t;if(e(r)==="github_copilot")return`github_copilot/${o}`;if(e(r)==="openai_codex")return`openai_codex/${o}`;if(e(r)==="groq")return o==="compound"||o==="compound-mini"?`groq/${o}`:o;if(e(r)==="ollama")return o}return t}async chat(t){let n={model:this.resolveModel(t.model??this.defaultModel),messages:K(t.messages),max_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7};t.tools?.length&&(n.tools=t.tools,n.tool_choice="auto"),t.reasoning&&(n.reasoning_effort="medium"),t.imageOutput&&(n.include_image_output=!0);try{v(t.signal);let r=(this.providerName??"").trim();if(r&&s.UNSUPPORTED_PROVIDERS.has(r))return{content:`Error calling LLM: provider '${r}' is not supported in this TypeScript port yet. Use openrouter/openai/deepseek/groq/custom.`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let o=this.apiBase??(r?s.DEFAULT_BASE_BY_PROVIDER[r]:void 0)??(this.apiKey?.startsWith("sk-or-")?s.DEFAULT_BASE_BY_PROVIDER.openrouter:void 0);if(!o)return{content:`Error calling LLM: api_base not configured. Set provider/api_base in ${q} or run everclaw onboard.`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let i={"Content-Type":"application/json"};this.apiKey&&(i.Authorization=`Bearer ${this.apiKey}`);let a=await fetch(`${o.replace(/\/$/,"")}/chat/completions`,{method:"POST",headers:i,body:JSON.stringify(n),...t.signal?{signal:t.signal}:{}}),l=await a.json();if(!a.ok){let d=l?.error?.code??"",m=l?.error?.message??JSON.stringify(l);return d==="model_not_found"?{content:`Error calling LLM: ${m}
7
- ${r==="groq"?"Try a Groq-supported model like llama-3.3-70b-versatile or openai/gpt-oss-120b. You can run `everclaw doctor`.":"Check your model id and provider access. You can run `everclaw doctor`."}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}:{content:`Error calling LLM: ${m}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}let c=l.choices?.[0]?.message?l.choices[0]:null;if(!c)return{content:`Error calling LLM: ${JSON.stringify(l)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let u=(c.message.tool_calls??[]).map(d=>({id:ur(9),name:d.function.name,arguments:typeof d.function.arguments=="string"?JSON.parse(d.function.arguments||"{}"):d.function.arguments}));return{content:c.message.content??null,toolCalls:u,finishReason:c.finish_reason??"stop",usage:l.usage??{},reasoningContent:c.message.reasoning_content??null}}catch(r){if(w(r))throw r;return{content:`Error calling LLM: ${String(r)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};function wt(s){let t=s.agents.defaults.model,e=se(s,t),n=mt(s,t),r=e&&$(e)?F(s,e,t):null,o=new Set(["openai_codex","github_copilot"]),i=new Set(["anthropic"]);if(!e)throw new Error("No provider could be resolved from config. Run `everclaw onboard` and set provider/model/API key.");if($(e)&&!r)throw new Error(`Custom provider '${e}' could not be found. Check ${q}.`);if(i.has(e))throw new Error(`Provider '${e}' is not supported in this TypeScript port yet. Use openrouter/openai/deepseek/groq/custom.`);if(!o.has(e)&&e!=="vllm"&&e!=="custom"&&!$(e)&&!(n?.apiKey||"").trim())throw new Error(`No API key configured for provider '${e}'. Run 'everclaw onboard' or edit ${q}.`);return e==="custom"||$(e)?new ae(n?.apiKey||r?.apiKey||"no-key",ie(s,t)||r?.baseUrl||"http://localhost:8000/v1",t,{providerLabel:r?.name??e,apiFormat:r?.apiFormat,extraHeaders:r?.extraHeaders??n?.extraHeaders??null}):e==="gemini"?new le(n?.apiKey||"",ie(s,t),t):new ce(n?.apiKey??null,ie(s,t),t,e)}import{randomUUID as Ai}from"node:crypto";import on from"node:path";import{randomUUID as mo}from"node:crypto";import po from"cron-parser";function He(s){return s??"builtin"}function dr(){return{beforeAgentTurn:[],afterAgentTurn:[],beforeOutbound:[],afterOutbound:[],beforeScheduledJob:[],afterScheduledJob:[],shutdown:[]}}function ue(s,t,e,n){let r=He(e.source),o=t.get(n.name);if(o)throw new Error(`${s} '${n.name}' from extension '${e.name}' conflicts with extension '${o.extension}'`);t.set(n.name,{extension:e.name,source:r,contribution:n})}function mr(s,t,e){let n=(r,o)=>{let i=r.find(a=>a.contribution.name===o.name);if(i)throw new Error(`lifecycle '${o.slot}:${o.name}' from extension '${t.name}' conflicts with extension '${i.extension}'`);r.push({extension:t.name,source:He(t.source),contribution:o})};switch(e.slot){case"beforeAgentTurn":n(s.beforeAgentTurn,e);return;case"afterAgentTurn":n(s.afterAgentTurn,e);return;case"beforeOutbound":n(s.beforeOutbound,e);return;case"afterOutbound":n(s.afterOutbound,e);return;case"beforeScheduledJob":n(s.beforeScheduledJob,e);return;case"afterScheduledJob":n(s.afterScheduledJob,e);return;case"shutdown":n(s.shutdown,e);return}}function R(s){return{...s,source:"builtin"}}var Ke=class{extensions=new Map;register(t){if(this.extensions.has(t.name))throw new Error(`Extension '${t.name}' is already registered`);return this.extensions.set(t.name,{...t,source:He(t.source)}),this}list(){return[...this.extensions.values()]}compose(){let t=new Map,e=new Map,n=new Map,r=new Map,o=dr();for(let i of this.extensions.values()){for(let a of i.tools??[])ue("tool",t,i,a);for(let a of i.channels??[])ue("channel",e,i,a);for(let a of i.jobs??[])ue("job",n,i,a);for(let a of i.commands??[])ue("command",r,i,a);for(let a of i.lifecycle??[])mr(o,i,a)}return{extensions:this.list(),tools:t,channels:e,jobs:n,commands:r,lifecycle:{beforeAgentTurn:o.beforeAgentTurn,afterAgentTurn:o.afterAgentTurn,beforeOutbound:o.beforeOutbound,afterOutbound:o.afterOutbound,beforeScheduledJob:o.beforeScheduledJob,afterScheduledJob:o.afterScheduledJob,shutdown:o.shutdown}}}};function kt(s){let t=new Ke;for(let e of s)t.register(e);return t.compose()}import ro from"node:path";import{createRequire as gr}from"node:module";var io=gr(import.meta.url);import So from"node:fs";import ko from"node:path";var g=class s{static typeMap={string:t=>typeof t=="string",integer:t=>Number.isInteger(t),number:t=>typeof t=="number"&&Number.isFinite(t),boolean:t=>typeof t=="boolean",array:t=>Array.isArray(t),object:t=>!!t&&typeof t=="object"&&!Array.isArray(t)};validateParams(t){let e=this.parameters??{};if(e.type!=="object")throw new Error(`Schema must be object type, got ${String(e.type)}`);return this.validateValue(t,{...e,type:"object"},"parameter")}validateValue(t,e,n){let r=e.type,o=[];if(r&&s.typeMap[r]&&!s.typeMap[r](t))return[`${n} should be ${r}`];if(e.enum&&!e.enum.includes(t)&&o.push(`${n} must be one of ${JSON.stringify(e.enum)}`),(r==="integer"||r==="number")&&typeof t=="number"&&(typeof e.minimum=="number"&&t<e.minimum&&o.push(`${n} must be >= ${e.minimum}`),typeof e.maximum=="number"&&t>e.maximum&&o.push(`${n} must be <= ${e.maximum}`)),r==="string"&&typeof t=="string"&&(typeof e.minLength=="number"&&t.length<e.minLength&&o.push(`${n} must be at least ${e.minLength} chars`),typeof e.maxLength=="number"&&t.length>e.maxLength&&o.push(`${n} must be at most ${e.maxLength} chars`)),r==="object"&&t&&typeof t=="object"&&!Array.isArray(t)){let i=t,a=e.properties??{};for(let l of e.required??[])l in i||o.push(`missing required ${n==="parameter"?l:`${n}.${l}`}`);for(let[l,c]of Object.entries(i))a[l]&&o.push(...this.validateValue(c,a[l],n==="parameter"?l:`${n}.${l}`))}return r==="array"&&Array.isArray(t)&&e.items&&typeof e.items=="object"&&t.forEach((i,a)=>o.push(...this.validateValue(i,e.items,`${n}[${a}]`))),o}toSchema(){return{type:"function",function:{name:this.name,description:this.description,parameters:this.parameters}}}};var de=class extends g{constructor(e){super();this.cron=e}name="cron";description="Schedule reminders and recurring tasks. Actions: add, list, remove.";parameters={type:"object",properties:{action:{type:"string",enum:["add","list","remove"]},message:{type:"string"},every_seconds:{type:"integer"},cron_expr:{type:"string"},tz:{type:"string"},at:{type:"string"},job_id:{type:"string"}},required:["action"]};channel="";chatId="";setContext(e,n){this.channel=e,this.chatId=n}async execute(e,n){let r=String(e.action??"");return r==="add"?this.addJob(e):r==="list"?this.listJobs():r==="remove"?this.removeJob(String(e.job_id??"")):`Unknown action: ${r}`}addJob(e){let n=String(e.message??"");if(!n)return"Error: message is required for add";if(!this.channel||!this.chatId)return"Error: no session context (channel/chat_id)";let r=e.every_seconds!=null?Number(e.every_seconds):null,o=e.cron_expr!=null?String(e.cron_expr):null,i=e.tz!=null?String(e.tz):null,a=e.at!=null?String(e.at):null,l,c=!1;if(r)l={kind:"every",everyMs:r*1e3};else if(o){let u={kind:"cron",expr:o};i&&(u.tz=i),l=u}else if(a){let u=new Date(a);if(Number.isNaN(u.getTime()))return"Error: invalid ISO datetime in at";l={kind:"at",atMs:u.getTime()},c=!0}else return"Error: either every_seconds, cron_expr, or at is required";try{let u=this.cron.addJob({name:n.slice(0,30),schedule:l,message:n,deliver:!0,channel:this.channel,to:this.chatId,deleteAfterRun:c});return`Created job '${u.name}' (id: ${u.id})`}catch(u){return`Error: ${String(u).replace(/^Error:\s*/,"")}`}}listJobs(){let e=this.cron.listJobs();return e.length?`Scheduled jobs:
8
- ${e.map(n=>`- ${n.name} (id: ${n.id}, ${n.schedule.kind})`).join(`
9
- `)}`:"No scheduled jobs."}removeJob(e){return e?this.cron.removeJob(e)?`Removed job ${e}`:`Job ${e} not found`:"Error: job_id is required for remove"}};import E from"node:fs";import J from"node:path";import M from"node:fs";import C from"node:path";function xt(s){let t=C.resolve(s);for(;t!=="/"&&t!==".";)try{return M.lstatSync(t),t}catch{let e=C.dirname(t);if(e===t)break;t=e}return t||"/"}function Tt(s,t){let e=C.resolve(s),n=C.resolve(t),r=n.endsWith(C.sep)?n.slice(0,-1):n,o=e===r||e.startsWith(r+C.sep);if(!M.existsSync(r))return o;try{let i=r;try{i=M.realpathSync.native(r)}catch{}if(M.existsSync(e)){let c=M.realpathSync.native(e);return c===i||c.startsWith(i+C.sep)}let a=xt(e);if(a===i||a===r)return!0;if(a!=="/")try{let c=M.realpathSync.native(a);if(c===i||c.startsWith(i+C.sep))return!0;if(!o)return!1}catch{return o}let l=e;for(;l!=="/"&&l!==".";){let c=C.dirname(l);if(c===l)break;try{if(M.lstatSync(c).isSymbolicLink()){let d=M.realpathSync.native(c);if(d!==i&&!d.startsWith(i+C.sep))return!1}}catch{}l=c}return o}catch{return!1}}function Ct(s,t){let e=C.resolve(s),n=C.resolve(t);if(!Tt(s,t))throw new Error(`Path '${s}' is outside allowed workspace '${t}'`);let r=C.dirname(e),o=xt(r),i=n;try{M.existsSync(n)&&(i=M.realpathSync.native(n))}catch{}if(o!=="/"&&o!==i)try{let a=M.realpathSync.native(o);if(a!==i&&!a.startsWith(i+C.sep))throw new Error(`Path '${s}' would be created outside workspace via symlinked parent directory`)}catch(a){throw a instanceof Error&&a.message.includes("symlinked parent")?a:new Error(`Could not validate path '${s}' is within workspace`)}}function At(s,t){if(!Tt(s,t))throw new Error(`Path '${s}' is outside allowed workspace '${t}'`)}function he(s,t,e,n=!1){let r=s.startsWith("~")?J.join(process.env.USERPROFILE||process.env.HOME||"",s.slice(1)):s,o=J.isAbsolute(r)?r:t?J.join(t,r):r,i=J.resolve(o);if(e)try{n?Ct(i,e):At(i,e)}catch(a){throw new Error(a instanceof Error?a.message:`Path ${s} validation failed`)}return i}var me=class extends g{constructor(e,n){super();this.workspace=e;this.allowedDir=n}name="read_file";description="Read the contents of a file at the given path.";parameters={type:"object",properties:{path:{type:"string",description:"The file path to read"}},required:["path"]};async execute(e,n){try{let r=he(String(e.path),this.workspace,this.allowedDir);return E.existsSync(r)?E.statSync(r).isFile()?E.readFileSync(r,"utf8"):`Error: Not a file: ${String(e.path)}`:`Error: File not found: ${String(e.path)}`}catch(r){return`Error reading file: ${String(r)}`}}},ge=class extends g{constructor(e,n){super();this.workspace=e;this.allowedDir=n}name="write_file";description="Write content to a file at the given path. Creates parent directories if needed.";parameters={type:"object",properties:{path:{type:"string"},content:{type:"string"}},required:["path","content"]};async execute(e,n){try{let r=he(String(e.path),this.workspace,this.allowedDir,!0);E.mkdirSync(J.dirname(r),{recursive:!0});let o=String(e.content??"");return E.writeFileSync(r,o,"utf8"),`Successfully wrote ${o.length} bytes to ${r}`}catch(r){return`Error writing file: ${String(r)}`}}},pe=class extends g{constructor(e,n){super();this.workspace=e;this.allowedDir=n}name="edit_file";description="Edit a file by replacing old_text with new_text. The old_text must exist exactly in the file.";parameters={type:"object",properties:{path:{type:"string"},old_text:{type:"string"},new_text:{type:"string"}},required:["path","old_text","new_text"]};async execute(e,n){try{let r=he(String(e.path),this.workspace,this.allowedDir,!0);if(!E.existsSync(r))return`Error: File not found: ${String(e.path)}`;let o=E.readFileSync(r,"utf8"),i=String(e.old_text??""),a=String(e.new_text??"");return o.includes(i)?o.split(i).length-1>1?`Warning: old_text appears ${o.split(i).length-1} times. Please provide more context to make it unique.`:(E.writeFileSync(r,o.replace(i,a),"utf8"),`Successfully edited ${r}`):`Error: old_text not found in ${String(e.path)}. Verify the file content.`}catch(r){return`Error editing file: ${String(r)}`}}},fe=class extends g{constructor(e,n){super();this.workspace=e;this.allowedDir=n}name="list_dir";description="List the contents of a directory.";parameters={type:"object",properties:{path:{type:"string"}},required:["path"]};async execute(e,n){try{let r=he(String(e.path),this.workspace,this.allowedDir);if(!E.existsSync(r))return`Error: Directory not found: ${String(e.path)}`;if(!E.statSync(r).isDirectory())return`Error: Not a directory: ${String(e.path)}`;let o=E.readdirSync(r).sort().map(i=>{let a=J.join(r,i);return`${E.statSync(a).isDirectory()?"[DIR]":"[FILE]"} ${i}`});return o.length?o.join(`
10
- `):`Directory ${String(e.path)} is empty`}catch(r){return`Error listing directory: ${String(r)}`}}};var ye=class extends g{constructor(e){super();this.sendCallback=e}name="message";description="Send a message to the user. Use this when you want to communicate something.";parameters={type:"object",properties:{content:{type:"string",description:"The message content to send"},channel:{type:"string",description:"Optional target channel"},chat_id:{type:"string",description:"Optional target chat/user ID"},media:{type:"array",items:{type:"string"},description:"Optional file attachments"}},required:["content"]};defaultChannel="";defaultChatId="";defaultMessageId=null;setContext(e,n,r){this.defaultChannel=e,this.defaultChatId=n,this.defaultMessageId=r??null}setSendCallback(e){this.sendCallback=e}async execute(e,n){let r=String(e.content??""),o=String(e.channel??this.defaultChannel),i=String(e.chat_id??this.defaultChatId),a=String(e.message_id??this.defaultMessageId??""),l=Array.isArray(e.media)?e.media:[];if(!o||!i)return"Error: No target channel/chat specified";if(!this.sendCallback)return"Error: Message sending not configured";try{await this.sendCallback({channel:o,chatId:i,content:r,media:l,metadata:{message_id:a}});let c=o===this.defaultChannel&&i===this.defaultChatId,u=`Message sent to ${o}:${i}${l.length?` with ${l.length} attachments`:""}`;return c?`__TERMINAL__${u}`:u}catch(c){return`Error sending message: ${String(c)}`}}};import ze from"node:path";import{spawn as Et}from"node:child_process";var fr={"agent-turn":{target:"agent-turn",mode:"in-process",risk:"safe",cleanup:"none",observation:"basic",reason:"Normal agent turns stay in-process unless a later surface explicitly routes them through isolation."},"tool.exec":{target:"tool.exec",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Shell execution already crosses the local OS boundary and needs explicit launch, timeout, output capture, and cleanup semantics."},subagent:{target:"subagent",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Spawned subagents are a high-risk local execution path that later Wave D routing can move onto this process boundary."},"scheduled-job":{target:"scheduled-job",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Scheduled jobs can run unattended and should share the same local-process isolation contract when routed in later Wave D work."},"background-job":{target:"background-job",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Long-running background work needs the same local process cleanup and attribution boundary as other risky execution paths."}};function Ve(s){return{...fr[s]}}var I=class{async run(t){let e=Math.max(1,t.maxCaptureBytes??1048576),n=typeof t.timeoutMs=="number"&&Number.isFinite(t.timeoutMs)&&t.timeoutMs>0?t.timeoutMs:null,r=this.launch(t);if(r instanceof Error)return{status:"failed",pid:null,stdout:"",stderr:"",exitCode:null,signal:null,failureAttribution:"spawn_error",cleanupTriggered:!1,cleanupReason:null,errorMessage:r.message};let{child:o,spawnError:i}=r;t.stdinText!=null?o.stdin?.end(t.stdinText,"utf8"):o.stdin?.end();let a="",l="",c=!1,u=null,d=!1,m=(x,_)=>{let p=typeof x=="string"?x:x.toString("utf8"),T=e-Buffer.byteLength(_);return T<=0?_:_+p.slice(0,T)};o.stdout?.on("data",x=>{a=m(x,a)}),o.stderr?.on("data",x=>{l=m(x,l)});let f=null,y=x=>{c||(c=!0,u=x,d=x==="timeout",this.killChild(o,"SIGTERM"),f=setTimeout(()=>this.killChild(o,"SIGKILL"),250),f.unref?.())},b=()=>y("abort");t.signal?.aborted?b():t.signal?.addEventListener("abort",b,{once:!0});let A=n!=null?setTimeout(()=>y("timeout"),n):null;A?.unref?.();let k=await new Promise(x=>{let _=!1,p=T=>{_||(_=!0,x(T))};o.once("error",T=>{i.current=T,p({code:null,signal:null})}),o.once("close",(T,L)=>p({code:T,signal:L}))});return A&&clearTimeout(A),f&&clearTimeout(f),t.signal?.removeEventListener("abort",b),u==="abort"?{status:"aborted",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"aborted",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:d?{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"timeout",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:i.current?{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"spawn_error",cleanupTriggered:c,cleanupReason:u,errorMessage:i.current.message}:k.code===0?{status:"ok",pid:o.pid??null,stdout:a,stderr:l,exitCode:0,signal:k.signal,failureAttribution:"none",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:k.signal?"signal":"exit_code",cleanupTriggered:c,cleanupReason:u,errorMessage:null}}launch(t){try{return{child:t.command.kind==="shell"?Et(t.command.command,{cwd:t.cwd,env:t.env,shell:!0,detached:process.platform!=="win32",stdio:["pipe","pipe","pipe"]}):Et(t.command.file,t.command.args??[],{cwd:t.cwd,env:t.env,detached:process.platform!=="win32",stdio:["pipe","pipe","pipe"]}),spawnError:{current:null}}}catch(e){return e instanceof Error?e:new Error(String(e))}}killChild(t,e){try{if(process.platform!=="win32"&&typeof t.pid=="number"){process.kill(-t.pid,e);return}}catch{}try{t.kill(e)}catch{}}};var be=class extends g{constructor(e=60,n,r=!1,o="",i=new I,a,l=!1){super();this.timeout=e;this.workingDir=n;this.restrictToWorkspace=r;this.pathAppend=o;this.runner=i;this.rtkService=a;this.rtkUltraCompact=l}name="exec";description="Execute a shell command and return its output. Use with caution.";parameters={type:"object",properties:{command:{type:"string",description:"The shell command to execute"},working_dir:{type:"string",description:"Optional working directory for the command"}},required:["command"]};guard(e,n){let r=e.toLowerCase();if([/\brm\s+-[rf]{1,2}\b/,/\bdel\s+\/[fq]\b/,/\brmdir\s+\/s\b/,/(?:^|[;&|]\s*)format\b/,/\b(mkfs|diskpart)\b/,/\bdd\s+if=/,/>\s*\/dev\/sd/,/\b(shutdown|reboot|poweroff)\b/,/:\(\)\s*\{.*\};\s*:/].some(i=>i.test(r)))return"Error: Command blocked by safety guard (dangerous pattern detected)";if(this.restrictToWorkspace){if(e.includes("../")||e.includes("..\\"))return"Error: Command blocked by safety guard (path traversal detected)";let i=e.match(/[A-Za-z]:\\[^\s"']+/g)??[];for(let a of i){let l=ze.resolve(a),c=ze.resolve(n);if(!l.startsWith(c))return"Error: Command blocked by safety guard (path outside working dir)"}}return null}async execute(e,n){let r=String(e.command??""),o=String(e.working_dir??this.workingDir??process.cwd()),i=this.guard(r,o);if(i)return i;v(n?.signal);let a=Ve("tool.exec"),l={...process.env};if(this.pathAppend&&(l.PATH=`${l.PATH??""}${ze.delimiter}${this.pathAppend}`),a.mode!=="local-process")return"Error: exec tool requires local-process isolation";let c={command:{kind:"shell",command:r},cwd:o,env:l,timeoutMs:this.timeout*1e3,maxCaptureBytes:1024*1024};n?.signal&&(c.signal=n.signal);let u=await this.runner.run(c);if(u.status==="aborted")throw Ge();if(u.failureAttribution==="timeout")return`Error: Command timed out after ${this.timeout} seconds`;let d=u.stdout?`${u.stdout}${u.status==="failed"?`
11
- `:""}`:"";if(this.rtkService?.getRuntime().available&&d)try{let A=await this.rtkService.compress({command:r,stdout:d,stderr:u.stderr,exitCode:u.exitCode,ultraCompact:this.rtkUltraCompact});A.compressed&&(d=A.stdout)}catch{}let m=u.stderr.trim()?`STDERR:
2
+ import"dotenv/config";import St from"node:fs";import jn from"node:path";import sr from"node:fs";import ct from"node:os";import U from"node:path";import{fileURLToPath as ir}from"node:url";var He=".everclaw",K="~/.everclaw/config.json",ut=U.join("~",He,"workspace");function dt(s=ct.homedir()){return U.join(s,He,"workspace")}function mt(s=ct.homedir()){return U.join(s,He,"config.json")}function ar(){let s=ir(import.meta.url),t=U.dirname(s);return s.endsWith("/index.js")||s.endsWith("\\index.js")?t:U.resolve(t,"..")}var lr=ar();function gt(...s){let t=U.resolve(lr,...s);if(!sr.existsSync(t))throw new Error(`Runtime asset not found: ${t}`);return t}var cr=[{spec:{name:"zai",keywords:["zai"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://api.z.ai/api/coding/paas/v4"},models:["glm-5-turbo"]},{spec:{name:"openrouter",displayName:"OpenRouter",keywords:["openrouter"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://openrouter.ai/api/v1",detectByKeyPrefix:"sk-or-",detectByBaseKeyword:"openrouter"},models:["anthropic/claude-opus-4-1","anthropic/claude-sonnet-4","openai/gpt-4.1","google/gemini-2.5-pro"]},{spec:{name:"aihubmix",displayName:"AIHubMix",keywords:["aihubmix"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://aihubmix.com/v1",detectByBaseKeyword:"aihubmix"},models:[]},{spec:{name:"siliconflow",displayName:"SiliconFlow",keywords:["siliconflow"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://api.siliconflow.cn/v1",detectByBaseKeyword:"siliconflow"},models:["openai/deepseek-ai/DeepSeek-R1"]},{spec:{name:"volcengine",displayName:"VolcEngine",keywords:["volcengine","volces","ark"],isOauth:!1,isGateway:!0,isLocal:!1,defaultApiBase:"https://ark.cn-beijing.volces.com/api/v3",detectByBaseKeyword:"volces"},models:["volcengine/deepseek-r1-250120"]},{spec:{name:"anthropic",displayName:"Anthropic",keywords:["anthropic","claude"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["anthropic/claude-opus-4-5","anthropic/claude-sonnet-4"]},{spec:{name:"openai",displayName:"OpenAI",keywords:["openai","gpt"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["gpt-5.2","gpt-5.2-pro","gpt-5.3-codex","gpt-5.2-codex","gpt-5.1","gpt-5.1-codex","gpt-5-mini","gpt-5-nano","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4o","gpt-4o-mini"]},{spec:{name:"openai_codex",displayName:"OpenAI Codex",keywords:["openai-codex","codex"],isOauth:!0,isGateway:!1,isLocal:!1,defaultApiBase:"https://chatgpt.com/backend-api"},models:[]},{spec:{name:"github_copilot",displayName:"GitHub Copilot",keywords:["github_copilot","copilot"],isOauth:!0,isGateway:!1,isLocal:!1,defaultApiBase:""},models:[]},{spec:{name:"deepseek",displayName:"DeepSeek",keywords:["deepseek"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["deepseek/deepseek-chat","deepseek/deepseek-reasoner"]},{spec:{name:"gemini",displayName:"Google Gemini",keywords:["gemini"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["gemini/gemini-3-flash-preview","gemini/gemini-2.5-pro","gemini/gemini-2.5-flash"]},{spec:{name:"zhipu",displayName:"Zhipu AI",keywords:["zhipu","glm","zai"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["zai/glm-4.5"]},{spec:{name:"dashscope",displayName:"DashScope",keywords:["qwen","dashscope"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["dashscope/qwen-max"]},{spec:{name:"moonshot",displayName:"Moonshot AI",keywords:["moonshot","kimi"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:"https://api.moonshot.ai/v1"},models:["moonshot/kimi-k2.5"]},{spec:{name:"minimax",displayName:"MiniMax",keywords:["minimax"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:"https://api.minimax.io/v1"},models:["minimax/MiniMax-M2.1"]},{spec:{name:"vllm",displayName:"vLLM",keywords:["vllm"],isOauth:!1,isGateway:!1,isLocal:!0,defaultApiBase:""},models:["hosted_vllm/llama-3.1-8b-instruct"]},{spec:{name:"groq",displayName:"Groq",keywords:["groq"],isOauth:!1,isGateway:!1,isLocal:!1,defaultApiBase:""},models:["openai/gpt-oss-120b","openai/gpt-oss-20b","meta-llama/llama-4-maverick-17b-128e-instruct","groq/compound","groq/compound-mini"]},{spec:{name:"ollama",displayName:"Ollama",keywords:["ollama"],isOauth:!1,isGateway:!1,isLocal:!0,defaultApiBase:"http://localhost:11434/v1"},models:["ollama/llama3.3","ollama/qwen2.5","ollama/deepseek-r1"]}];function Ve(){return cr.map(s=>s.spec)}var H=Ve(),ur=Object.fromEntries(Ve().map(s=>[s.name,{apiKey:"",apiBase:null,extraHeaders:null,models:[]}])),ae="custom:",V={agents:{defaults:{workspace:ut,model:"gpt-4.1",provider:"auto",maxTokens:8192,temperature:.1,maxToolIterations:40,memoryWindow:100}},subagents:[{id:"researcher",name:"Researcher",task:"Research the given topic thoroughly and provide detailed findings.",createdAt:0},{id:"advisor",name:"Advisor",task:"Analyze the current conversation context and provide exactly 3 concise suggestion options for the user's next logical message. Reply with a JSON array of 3 strings.",createdAt:0}],channels:{sendProgress:!0,sendToolHints:!1,telegram:{enabled:!1,token:"",allowFrom:[],proxy:null,replyToMessage:!1,debounce:{enabled:!0,quietMs:500,maxWaitMs:3e3},groups:{requireMention:!0,allowedGroupIds:null},commands:{native:!0,custom:[]}},discord:{enabled:!1,token:"",allowFrom:[],gatewayUrl:"wss://gateway.discord.gg/?v=10&encoding=json",intents:37377,debounce:{enabled:!0,quietMs:500,maxWaitMs:3e3}}},providers:ur,customLlmProviders:[],customAcpProviders:[],gateway:{host:"127.0.0.1",port:6767,dashboard:{enabled:!0},heartbeat:{enabled:!0,intervalS:1800}},tools:{web:{search:{apiKey:"",maxResults:5}},exec:{timeout:60,pathAppend:""},restrictToWorkspace:!1,mcpServers:{},chromeSession:{enabled:!1,debugPort:9222,minChromeVersion:136,daemonIdleTimeoutS:1200,targetPrefixLength:8,stealth:{enabled:!1,cursorMovement:!0,humanizedTyping:!0,interStepDelay:[300,1500]}},browserRelay:{enabled:!1,authToken:"",extensionPath:""},rtk:{enabled:!0,autoInstall:!0,ultraCompact:!1,version:"latest"}},security:{enabled:!1,auth:{enabled:!1,pinHash:"",sessionTtlS:3600,lockOnIdle:!1,idleTimeoutS:900},toolGuard:{enabled:!1,guardedTools:null,deniedTools:[],rules:[],failOpen:!0},skillScanner:{enabled:!1,scanOnLoad:!1,blockUnsafe:!0,maxFileCount:1e3,maxFileSizeBytes:5242880},inputSanitizer:{enabled:!1,maxInputLength:5e4,stripHtmlTags:!1,blockPromptInjection:!1}},logging:{enabled:!0,level:"info",retentionHours:4,maxFileSizeMb:10,purgeIntervalMs:6e5},compaction:{enabled:!0,microCompactThresholdRatio:.6,autoCompactThresholdRatio:.8,keepRecentMessages:10,maxConsecutiveFailures:3}};function J(s){return s.toLowerCase().replace(/[\s-]+/g,"_")}function pt(s){return`${ae}${J(s)}`}function ft(s,t){let e=J(t.startsWith(ae)?t.slice(ae.length):t);return s.customLlmProviders.find(r=>J(r.name)===e)??null}function dr(s,t){if(!t.includes("/"))return null;let r=t.split("/",1)[0];return r?ft(s,r):null}function N(s){return!!s&&s.startsWith(ae)}function q(s,t,e){let r=(t??s.agents.defaults.provider).trim();if(r&&r!=="auto"&&!s.providers[r])return ft(s,r);let n=dr(s,e??s.agents.defaults.model);if(n)return n;let o=s.customLlmProviders.filter(i=>i.name.trim()&&i.baseUrl.trim());return o.length===1?o[0]??null:null}function le(s,t){let e=s.agents.defaults.provider;if(e!=="auto"){if(s.providers[e])return e;let a=q(s,e,t);return a?pt(a.name):null}let r=(t??s.agents.defaults.model).toLowerCase(),n=J(r),o=r.includes("/")?r.split("/",1)[0]:"";for(let a of H){let l=s.providers[a.name];if(o&&J(o)===a.name&&(a.isOauth||l?.apiKey))return a.name}for(let a of H){let l=s.providers[a.name];if(a.keywords.some(c=>r.includes(c)||n.includes(J(c)))&&(a.isOauth||l?.apiKey))return a.name}for(let a of H){if(a.isOauth)continue;if(s.providers[a.name]?.apiKey)return a.name}let i=q(s,e,t);return i?pt(i.name):null}function ht(s,t){let e=le(s,t);if(e&&N(e)){let r=q(s,e,t);return r?{apiKey:r.apiKey,apiBase:r.baseUrl,extraHeaders:r.extraHeaders}:null}return e?s.providers[e]??null:null}function ce(s,t){let e=le(s,t);if(!e)return null;if(N(e))return q(s,e,t)?.baseUrl??null;let r=s.providers[e];if(r?.apiBase)return r.apiBase;let n=H.find(o=>o.name===e);return n?.isGateway?n.defaultApiBase:null}import mr from"node:fs";import gr from"node:path";import yt from"node:os";function bt(s){return mr.mkdirSync(s,{recursive:!0}),s}function vt(s){let t=s?s.replace(/^~(?=$|[\\/])/,yt.homedir()):dt(yt.homedir());return bt(gr.resolve(t))}function fr(){return mt()}function wt(s,t){if(!t||typeof t!="object")return s;let e=Array.isArray(s)?[...s]:{...s};for(let[r,n]of Object.entries(t))n&&typeof n=="object"&&!Array.isArray(n)&&e[r]&&typeof e[r]=="object"&&!Array.isArray(e[r])?e[r]=wt(e[r],n):e[r]=n;return e}function kt(s){let t=s??fr();if(!St.existsSync(t))return structuredClone(V);try{let e=St.readFileSync(t,"utf8"),r=JSON.parse(e),n=wt(structuredClone(V),r),o=["advisor"];for(let i of o)if(!n.subagents.find(a=>a.id===i)){let a=V.subagents.find(l=>l.id===i);a&&n.subagents.push(structuredClone(a))}return n}catch(e){return console.warn(`Warning: Failed to load config from ${t}: ${String(e)}`),structuredClone(V)}}function z(s){return s.map(t=>{let e=t.content;if(typeof e=="string"&&e.length===0)return t.role==="assistant"&&t.tool_calls?{...t,content:null}:{...t,content:"(empty)"};if(Array.isArray(e)){let r=e.filter(n=>!(typeof n=="object"&&n&&["text","input_text","output_text"].includes(n.type)&&!n.text));if(r.length!==e.length)return r.length>0?{...t,content:r}:t.role==="assistant"&&t.tool_calls?{...t,content:null}:{...t,content:"(empty)"}}return t})}function ze(){let s=new Error("Operation aborted");return s.name="AbortError",s}function x(s){return s instanceof Error&&s.name==="AbortError"}function v(s){if(s?.aborted)throw ze()}function xt(s){return s.trim().toLowerCase().replace(/[\s-]+/g,"_")}function Tt(s){if(typeof s!="string")return s&&typeof s=="object"?s:{};try{return JSON.parse(s)}catch{return{}}}var ue=class{constructor(t,e,r,n={}){this.apiKey=t;this.apiBase=e;this.defaultModel=r;this.options=n}getDefaultModel(){return this.defaultModel}get requestFormat(){return this.options.apiFormat??"v1/chat/completions"}resolveModel(t){let e=t.trim();if(!e.includes("/"))return e;let r=e.split("/",2),n=r[0],o=r[1];return!n||!o?e:new Set(["custom",xt(this.options.providerLabel??"")]).has(xt(n))?o:e}buildHeaders(){let t={"Content-Type":"application/json",...this.options.extraHeaders??{}};return this.apiKey.trim()&&(t.Authorization=`Bearer ${this.apiKey}`),t}async readJson(t){try{return await t.json()}catch{return{}}}async chatCompletions(t){let e=await fetch(`${this.apiBase.replace(/\/$/,"")}/chat/completions`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:this.resolveModel(t.model??this.defaultModel),messages:z(t.messages),tools:t.tools,tool_choice:t.tools?.length?"auto":void 0,max_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7,...t.reasoning?{reasoning_effort:"medium"}:{},...t.imageOutput?{include_image_output:!0}:{}}),...t.signal?{signal:t.signal}:{}}),r=await this.readJson(e);if(!e.ok)return{content:`Error calling LLM: ${r?.error?.message??JSON.stringify(r)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let n=r.choices?.[0];if(!n?.message)return{content:`Error calling LLM: ${JSON.stringify(r)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let o=(n.message.tool_calls??[]).map(i=>({id:i.id,name:i.function.name,arguments:Tt(i.function.arguments)}));return{content:n.message.content??null,toolCalls:o,finishReason:n.finish_reason??"stop",usage:{prompt_tokens:r.usage?.prompt_tokens??0,completion_tokens:r.usage?.completion_tokens??0,total_tokens:r.usage?.total_tokens??0},reasoningContent:n.message.reasoning_content??null}}toResponsesInput(t){let e=[];for(let r of z(t)){let n=String(r.role??"");if(n==="tool"){e.push({type:"function_call_output",call_id:String(r.tool_call_id??""),output:typeof r.content=="string"?r.content:JSON.stringify(r.content??null)});continue}if(n==="assistant"&&Array.isArray(r.tool_calls))for(let o of r.tool_calls)e.push({type:"function_call",call_id:String(o.id??""),name:String(o.name??""),arguments:typeof o.arguments=="string"?o.arguments:JSON.stringify(o.arguments??{})});(n==="system"||n==="user"||n==="assistant")&&e.push({role:n,content:r.content??""})}return e}async responses(t){let e=await fetch(`${this.apiBase.replace(/\/$/,"")}/responses`,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({model:this.resolveModel(t.model??this.defaultModel),input:this.toResponsesInput(t.messages),tools:t.tools,tool_choice:t.tools?.length?"auto":void 0,max_output_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7,...t.reasoning?{reasoning:{effort:"medium"}}:{},...t.imageOutput?{include_image_output:!0}:{}}),...t.signal?{signal:t.signal}:{}}),r=await this.readJson(e);if(!e.ok)return{content:`Error calling LLM: ${r?.error?.message??JSON.stringify(r)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let n=Array.isArray(r.output)?r.output:[],o=n.filter(a=>a?.type==="function_call").map(a=>({id:String(a.call_id??a.id??""),name:String(a.name??""),arguments:Tt(a.arguments)}));return{content:n.filter(a=>a?.type==="message").flatMap(a=>Array.isArray(a?.content)?a.content:[]).filter(a=>a?.type==="output_text").map(a=>String(a.text??"")).join(`
3
+ `).trim()||null,toolCalls:o,finishReason:o.length?"tool_calls":r.status??"stop",usage:{prompt_tokens:r.usage?.input_tokens??0,completion_tokens:r.usage?.output_tokens??0,total_tokens:r.usage?.total_tokens??0},reasoningContent:null}}async chat(t){try{return v(t.signal),this.requestFormat==="v1/responses"?await this.responses(t):await this.chatCompletions(t)}catch(e){if(x(e))throw e;return{content:`Error calling LLM: ${String(e)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};import{nanoid as hr}from"nanoid";var de=class s{constructor(t,e,r){this.apiKey=t;this.apiBase=e;this.defaultModel=r}static DEFAULT_BASE="https://generativelanguage.googleapis.com/v1beta";getDefaultModel(){return this.defaultModel}resolveModel(t){let e=t.trim();if(e.includes("/")){let r=e.split("/",2),n=r[0],o=r[1];if(!n||!o)return e;let i=n.toLowerCase();(i==="gemini"||i==="google")&&(e=o)}return e.startsWith("models/")?e.slice(7):e}asText(t){if(typeof t=="string")return t;if(t==null)return"";try{return JSON.stringify(t)}catch{return String(t)}}parseToolArgs(t){if(t&&typeof t=="object"&&!Array.isArray(t))return t;if(typeof t=="string")try{let e=JSON.parse(t);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}toGemini(t){let e=[],r=[];for(let i of t.messages){let a=String(i.role??"");if(a==="system"){let l=this.asText(i.content).trim();l&&e.push(l);continue}if(a==="user"){let l=this.asText(i.content).trim();if(!l)continue;r.push({role:"user",parts:[{text:l}]});continue}if(a==="assistant"||a==="model"){let l=[],c=this.asText(i.content).trim();c&&l.push({text:c});let u=Array.isArray(i.tool_calls)?i.tool_calls:[];for(let d of u){let m=d.function;m?.name&&l.push({functionCall:{name:m.name,args:this.parseToolArgs(m.arguments)}})}l.length&&r.push({role:"model",parts:l});continue}if(a==="tool"){let l=typeof i.name=="string"?i.name:"";if(!l)continue;let c=this.asText(i.content);r.push({role:"user",parts:[{functionResponse:{name:l,response:{result:c}}}]})}}r.length||r.push({role:"user",parts:[{text:"Hello"}]});let n={contents:r,generationConfig:{temperature:t.temperature??.1,maxOutputTokens:Math.max(1,t.maxTokens??4096),...t.reasoning?{thinkingConfig:{thinkingBudget:Math.max(1,t.maxTokens??4096)}}:{}}};e.length&&(n.systemInstruction={parts:[{text:e.join(`
4
+
5
+ `)}]});let o=(t.tools??[]).map(i=>i).filter(i=>i.type==="function"&&i.function?.name).map(i=>({name:i.function.name,description:i.function?.description??"",parameters:i.function?.parameters??{type:"object",properties:{}}}));return o.length&&(n.tools=[{functionDeclarations:o}],n.toolConfig={functionCallingConfig:{mode:"AUTO"}}),t.imageOutput&&(n.responseModalities=["TEXT","IMAGE"]),n}async chat(t){try{v(t.signal);let e=this.resolveModel(t.model??this.defaultModel),n=`${(this.apiBase??s.DEFAULT_BASE).replace(/\/$/,"")}/models/${encodeURIComponent(e)}:generateContent`,o=this.toGemini(t),i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json","x-goog-api-key":this.apiKey},body:JSON.stringify(o),...t.signal?{signal:t.signal}:{}}),a=await i.json();if(!i.ok)return{content:`Error calling LLM: ${a?.error?.message??JSON.stringify(a)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let l=a?.candidates?.[0],c=l?.content?.parts??[],u=c.filter(f=>typeof f?.text=="string").map(f=>String(f.text)),d=c.filter(f=>f?.functionCall?.name).map(f=>({id:hr(9),name:String(f.functionCall.name),arguments:this.parseToolArgs(f.functionCall.args)})),m={};a?.usageMetadata&&(m.prompt_tokens=Number(a.usageMetadata.promptTokenCount??0),m.completion_tokens=Number(a.usageMetadata.candidatesTokenCount??0),m.total_tokens=Number(a.usageMetadata.totalTokenCount??0));let p=String(l?.finishReason??"STOP").toLowerCase();return{content:u.length?u.join(`
6
+ `):null,toolCalls:d,finishReason:p,usage:m,reasoningContent:null}}catch(e){if(x(e))throw e;return{content:`Error calling LLM: ${String(e)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};import{nanoid as yr}from"nanoid";var me=class s{constructor(t,e,r,n){this.apiKey=t;this.apiBase=e;this.defaultModel=r;this.providerName=n}static DEFAULT_BASE_BY_PROVIDER={openrouter:"https://openrouter.ai/api/v1",openai:"https://api.openai.com/v1",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",moonshot:"https://api.moonshot.ai/v1",minimax:"https://api.minimax.io/v1",dashscope:"https://dashscope.aliyuncs.com/compatible-mode/v1",zhipu:"https://open.bigmodel.cn/api/paas/v4",siliconflow:"https://api.siliconflow.cn/v1",volcengine:"https://ark.cn-beijing.volces.com/api/v3",vllm:"http://localhost:8000/v1",ollama:"http://localhost:11434/v1",zai:"https://api.z.ai/api/coding/paas/v4"};static UNSUPPORTED_PROVIDERS=new Set(["anthropic","gemini","openai_codex","github_copilot"]);getDefaultModel(){return this.defaultModel}resolveModel(t){let e=r=>r.toLowerCase().replace(/-/g,"_");if(t.includes("/")){let r=t.split("/",2),n=r[0],o=r[1];if(!n||!o)return t;if(e(n)==="github_copilot")return`github_copilot/${o}`;if(e(n)==="openai_codex")return`openai_codex/${o}`;if(e(n)==="groq")return o==="compound"||o==="compound-mini"?`groq/${o}`:o;if(e(n)==="ollama")return o}return t}async chat(t){let r={model:this.resolveModel(t.model??this.defaultModel),messages:z(t.messages),max_tokens:Math.max(1,t.maxTokens??4096),temperature:t.temperature??.7};t.tools?.length&&(r.tools=t.tools,r.tool_choice="auto"),t.reasoning&&(r.reasoning_effort="medium"),t.imageOutput&&(r.include_image_output=!0);try{v(t.signal);let n=(this.providerName??"").trim();if(n&&s.UNSUPPORTED_PROVIDERS.has(n))return{content:`Error calling LLM: provider '${n}' is not supported in this TypeScript port yet. Use openrouter/openai/deepseek/groq/custom.`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let o=this.apiBase??(n?s.DEFAULT_BASE_BY_PROVIDER[n]:void 0)??(this.apiKey?.startsWith("sk-or-")?s.DEFAULT_BASE_BY_PROVIDER.openrouter:void 0);if(!o)return{content:`Error calling LLM: api_base not configured. Set provider/api_base in ${K} or run everclaw onboard.`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let i={"Content-Type":"application/json"};this.apiKey&&(i.Authorization=`Bearer ${this.apiKey}`);let a=await fetch(`${o.replace(/\/$/,"")}/chat/completions`,{method:"POST",headers:i,body:JSON.stringify(r),...t.signal?{signal:t.signal}:{}}),l=await a.json();if(!a.ok){let d=l?.error?.code??"",m=l?.error?.message??JSON.stringify(l);return d==="model_not_found"?{content:`Error calling LLM: ${m}
7
+ ${n==="groq"?"Try a Groq-supported model like llama-3.3-70b-versatile or openai/gpt-oss-120b. You can run `everclaw doctor`.":"Check your model id and provider access. You can run `everclaw doctor`."}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}:{content:`Error calling LLM: ${m}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}let c=l.choices?.[0]?.message?l.choices[0]:null;if(!c)return{content:`Error calling LLM: ${JSON.stringify(l)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null};let u=(c.message.tool_calls??[]).map(d=>({id:yr(9),name:d.function.name,arguments:typeof d.function.arguments=="string"?JSON.parse(d.function.arguments||"{}"):d.function.arguments}));return{content:c.message.content??null,toolCalls:u,finishReason:c.finish_reason??"stop",usage:l.usage??{},reasoningContent:c.message.reasoning_content??null}}catch(n){if(x(n))throw n;return{content:`Error calling LLM: ${String(n)}`,toolCalls:[],finishReason:"error",usage:{},reasoningContent:null}}}};function Ct(s){let t=s.agents.defaults.model,e=le(s,t),r=ht(s,t),n=e&&N(e)?q(s,e,t):null,o=new Set(["openai_codex","github_copilot"]),i=new Set(["anthropic"]);if(!e)throw new Error("No provider could be resolved from config. Run `everclaw onboard` and set provider/model/API key.");if(N(e)&&!n)throw new Error(`Custom provider '${e}' could not be found. Check ${K}.`);if(i.has(e))throw new Error(`Provider '${e}' is not supported in this TypeScript port yet. Use openrouter/openai/deepseek/groq/custom.`);if(!o.has(e)&&e!=="vllm"&&e!=="custom"&&!N(e)&&!(r?.apiKey||"").trim())throw new Error(`No API key configured for provider '${e}'. Run 'everclaw onboard' or edit ${K}.`);return e==="custom"||N(e)?new ue(r?.apiKey||n?.apiKey||"no-key",ce(s,t)||n?.baseUrl||"http://localhost:8000/v1",t,{providerLabel:n?.name??e,apiFormat:n?.apiFormat,extraHeaders:n?.extraHeaders??r?.extraHeaders??null}):e==="gemini"?new de(r?.apiKey||"",ce(s,t),t):new me(r?.apiKey??null,ce(s,t),t,e)}import{randomUUID as Ni}from"node:crypto";import fn from"node:path";import{randomUUID as ko}from"node:crypto";import To from"cron-parser";function Ye(s){return s??"builtin"}function br(){return{beforeAgentTurn:[],afterAgentTurn:[],beforeOutbound:[],afterOutbound:[],beforeScheduledJob:[],afterScheduledJob:[],shutdown:[]}}function ge(s,t,e,r){let n=Ye(e.source),o=t.get(r.name);if(o)throw new Error(`${s} '${r.name}' from extension '${e.name}' conflicts with extension '${o.extension}'`);t.set(r.name,{extension:e.name,source:n,contribution:r})}function vr(s,t,e){let r=(n,o)=>{let i=n.find(a=>a.contribution.name===o.name);if(i)throw new Error(`lifecycle '${o.slot}:${o.name}' from extension '${t.name}' conflicts with extension '${i.extension}'`);n.push({extension:t.name,source:Ye(t.source),contribution:o})};switch(e.slot){case"beforeAgentTurn":r(s.beforeAgentTurn,e);return;case"afterAgentTurn":r(s.afterAgentTurn,e);return;case"beforeOutbound":r(s.beforeOutbound,e);return;case"afterOutbound":r(s.afterOutbound,e);return;case"beforeScheduledJob":r(s.beforeScheduledJob,e);return;case"afterScheduledJob":r(s.afterScheduledJob,e);return;case"shutdown":r(s.shutdown,e);return}}function E(s){return{...s,source:"builtin"}}var Xe=class{extensions=new Map;register(t){if(this.extensions.has(t.name))throw new Error(`Extension '${t.name}' is already registered`);return this.extensions.set(t.name,{...t,source:Ye(t.source)}),this}list(){return[...this.extensions.values()]}compose(){let t=new Map,e=new Map,r=new Map,n=new Map,o=br();for(let i of this.extensions.values()){for(let a of i.tools??[])ge("tool",t,i,a);for(let a of i.channels??[])ge("channel",e,i,a);for(let a of i.jobs??[])ge("job",r,i,a);for(let a of i.commands??[])ge("command",n,i,a);for(let a of i.lifecycle??[])vr(o,i,a)}return{extensions:this.list(),tools:t,channels:e,jobs:r,commands:n,lifecycle:{beforeAgentTurn:o.beforeAgentTurn,afterAgentTurn:o.afterAgentTurn,beforeOutbound:o.beforeOutbound,afterOutbound:o.afterOutbound,beforeScheduledJob:o.beforeScheduledJob,afterScheduledJob:o.afterScheduledJob,shutdown:o.shutdown}}}};function At(s){let t=new Xe;for(let e of s)t.register(e);return t.compose()}import go from"node:path";import{createRequire as Sr}from"node:module";var yo=Sr(import.meta.url);import _o from"node:fs";import Lo from"node:path";var g=class s{static typeMap={string:t=>typeof t=="string",integer:t=>Number.isInteger(t),number:t=>typeof t=="number"&&Number.isFinite(t),boolean:t=>typeof t=="boolean",array:t=>Array.isArray(t),object:t=>!!t&&typeof t=="object"&&!Array.isArray(t)};validateParams(t){let e=this.parameters??{};if(e.type!=="object")throw new Error(`Schema must be object type, got ${String(e.type)}`);return this.validateValue(t,{...e,type:"object"},"parameter")}validateValue(t,e,r){let n=e.type,o=[];if(n&&s.typeMap[n]&&!s.typeMap[n](t))return[`${r} should be ${n}`];if(e.enum&&!e.enum.includes(t)&&o.push(`${r} must be one of ${JSON.stringify(e.enum)}`),(n==="integer"||n==="number")&&typeof t=="number"&&(typeof e.minimum=="number"&&t<e.minimum&&o.push(`${r} must be >= ${e.minimum}`),typeof e.maximum=="number"&&t>e.maximum&&o.push(`${r} must be <= ${e.maximum}`)),n==="string"&&typeof t=="string"&&(typeof e.minLength=="number"&&t.length<e.minLength&&o.push(`${r} must be at least ${e.minLength} chars`),typeof e.maxLength=="number"&&t.length>e.maxLength&&o.push(`${r} must be at most ${e.maxLength} chars`)),n==="object"&&t&&typeof t=="object"&&!Array.isArray(t)){let i=t,a=e.properties??{};for(let l of e.required??[])l in i||o.push(`missing required ${r==="parameter"?l:`${r}.${l}`}`);for(let[l,c]of Object.entries(i))a[l]&&o.push(...this.validateValue(c,a[l],r==="parameter"?l:`${r}.${l}`))}return n==="array"&&Array.isArray(t)&&e.items&&typeof e.items=="object"&&t.forEach((i,a)=>o.push(...this.validateValue(i,e.items,`${r}[${a}]`))),o}toSchema(){return{type:"function",function:{name:this.name,description:this.description,parameters:this.parameters}}}};var pe=class extends g{constructor(e){super();this.cron=e}name="cron";description="Schedule reminders and recurring tasks. Actions: add, list, remove.";parameters={type:"object",properties:{action:{type:"string",enum:["add","list","remove"]},message:{type:"string"},every_seconds:{type:"integer"},cron_expr:{type:"string"},tz:{type:"string"},at:{type:"string"},job_id:{type:"string"}},required:["action"]};channel="";chatId="";setContext(e,r){this.channel=e,this.chatId=r}async execute(e,r){let n=String(e.action??"");return n==="add"?this.addJob(e):n==="list"?this.listJobs():n==="remove"?this.removeJob(String(e.job_id??"")):`Unknown action: ${n}`}addJob(e){let r=String(e.message??"");if(!r)return"Error: message is required for add";if(!this.channel||!this.chatId)return"Error: no session context (channel/chat_id)";let n=e.every_seconds!=null?Number(e.every_seconds):null,o=e.cron_expr!=null?String(e.cron_expr):null,i=e.tz!=null?String(e.tz):null,a=e.at!=null?String(e.at):null,l,c=!1;if(n)l={kind:"every",everyMs:n*1e3};else if(o){let u={kind:"cron",expr:o};i&&(u.tz=i),l=u}else if(a){let u=new Date(a);if(Number.isNaN(u.getTime()))return"Error: invalid ISO datetime in at";l={kind:"at",atMs:u.getTime()},c=!0}else return"Error: either every_seconds, cron_expr, or at is required";try{let u=this.cron.addJob({name:r.slice(0,30),schedule:l,message:r,deliver:!0,channel:this.channel,to:this.chatId,deleteAfterRun:c});return`Created job '${u.name}' (id: ${u.id})`}catch(u){return`Error: ${String(u).replace(/^Error:\s*/,"")}`}}listJobs(){let e=this.cron.listJobs();return e.length?`Scheduled jobs:
8
+ ${e.map(r=>`- ${r.name} (id: ${r.id}, ${r.schedule.kind})`).join(`
9
+ `)}`:"No scheduled jobs."}removeJob(e){return e?this.cron.removeJob(e)?`Removed job ${e}`:`Job ${e} not found`:"Error: job_id is required for remove"}};import A from"node:fs";import W from"node:path";import R from"node:fs";import T from"node:path";function Et(s){let t=T.resolve(s);for(;t!=="/"&&t!==".";)try{return R.lstatSync(t),t}catch{let e=T.dirname(t);if(e===t)break;t=e}return t||"/"}function Rt(s,t){let e=T.resolve(s),r=T.resolve(t),n=r.endsWith(T.sep)?r.slice(0,-1):r,o=e===n||e.startsWith(n+T.sep);if(!R.existsSync(n))return o;try{let i=n;try{i=R.realpathSync.native(n)}catch{}if(R.existsSync(e)){let c=R.realpathSync.native(e);return c===i||c.startsWith(i+T.sep)}let a=Et(e);if(a===i||a===n)return!0;if(a!=="/")try{let c=R.realpathSync.native(a);if(c===i||c.startsWith(i+T.sep))return!0;if(!o)return!1}catch{return o}let l=e;for(;l!=="/"&&l!==".";){let c=T.dirname(l);if(c===l)break;try{if(R.lstatSync(c).isSymbolicLink()){let d=R.realpathSync.native(c);if(d!==i&&!d.startsWith(i+T.sep))return!1}}catch{}l=c}return o}catch{return!1}}function Mt(s,t){let e=T.resolve(s),r=T.resolve(t);if(!Rt(s,t))throw new Error(`Path '${s}' is outside allowed workspace '${t}'`);let n=T.dirname(e),o=Et(n),i=r;try{R.existsSync(r)&&(i=R.realpathSync.native(r))}catch{}if(o!=="/"&&o!==i)try{let a=R.realpathSync.native(o);if(a!==i&&!a.startsWith(i+T.sep))throw new Error(`Path '${s}' would be created outside workspace via symlinked parent directory`)}catch(a){throw a instanceof Error&&a.message.includes("symlinked parent")?a:new Error(`Could not validate path '${s}' is within workspace`)}}function _t(s,t){if(!Rt(s,t))throw new Error(`Path '${s}' is outside allowed workspace '${t}'`)}function ve(s,t,e,r=!1){let n=s.startsWith("~")?W.join(process.env.USERPROFILE||process.env.HOME||"",s.slice(1)):s,o=W.isAbsolute(n)?n:t?W.join(t,n):n,i=W.resolve(o);if(e)try{r?Mt(i,e):_t(i,e)}catch(a){throw new Error(a instanceof Error?a.message:`Path ${s} validation failed`)}return i}var fe=class extends g{constructor(e,r){super();this.workspace=e;this.allowedDir=r}name="read_file";description="Read the contents of a file at the given path.";parameters={type:"object",properties:{path:{type:"string",description:"The file path to read"}},required:["path"]};async execute(e,r){try{let n=ve(String(e.path),this.workspace,this.allowedDir);return A.existsSync(n)?A.statSync(n).isFile()?A.readFileSync(n,"utf8"):`Error: Not a file: ${String(e.path)}`:`Error: File not found: ${String(e.path)}`}catch(n){return`Error reading file: ${String(n)}`}}},he=class extends g{constructor(e,r){super();this.workspace=e;this.allowedDir=r}name="write_file";description="Write content to a file at the given path. Creates parent directories if needed.";parameters={type:"object",properties:{path:{type:"string"},content:{type:"string"}},required:["path","content"]};async execute(e,r){try{let n=ve(String(e.path),this.workspace,this.allowedDir,!0);A.mkdirSync(W.dirname(n),{recursive:!0});let o=String(e.content??"");return A.writeFileSync(n,o,"utf8"),`Successfully wrote ${o.length} bytes to ${n}`}catch(n){return`Error writing file: ${String(n)}`}}},ye=class extends g{constructor(e,r){super();this.workspace=e;this.allowedDir=r}name="edit_file";description="Edit a file by replacing old_text with new_text. The old_text must exist exactly in the file.";parameters={type:"object",properties:{path:{type:"string"},old_text:{type:"string"},new_text:{type:"string"}},required:["path","old_text","new_text"]};async execute(e,r){try{let n=ve(String(e.path),this.workspace,this.allowedDir,!0);if(!A.existsSync(n))return`Error: File not found: ${String(e.path)}`;let o=A.readFileSync(n,"utf8"),i=String(e.old_text??""),a=String(e.new_text??"");return o.includes(i)?o.split(i).length-1>1?`Warning: old_text appears ${o.split(i).length-1} times. Please provide more context to make it unique.`:(A.writeFileSync(n,o.replace(i,a),"utf8"),`Successfully edited ${n}`):`Error: old_text not found in ${String(e.path)}. Verify the file content.`}catch(n){return`Error editing file: ${String(n)}`}}},be=class extends g{constructor(e,r){super();this.workspace=e;this.allowedDir=r}name="list_dir";description="List the contents of a directory.";parameters={type:"object",properties:{path:{type:"string"}},required:["path"]};async execute(e,r){try{let n=ve(String(e.path),this.workspace,this.allowedDir);if(!A.existsSync(n))return`Error: Directory not found: ${String(e.path)}`;if(!A.statSync(n).isDirectory())return`Error: Not a directory: ${String(e.path)}`;let o=A.readdirSync(n).sort().map(i=>{let a=W.join(n,i);return`${A.statSync(a).isDirectory()?"[DIR]":"[FILE]"} ${i}`});return o.length?o.join(`
10
+ `):`Directory ${String(e.path)} is empty`}catch(n){return`Error listing directory: ${String(n)}`}}};var Se=class extends g{constructor(e){super();this.sendCallback=e}name="message";description="Send a message to the user. Use this when you want to communicate something.";parameters={type:"object",properties:{content:{type:"string",description:"The message content to send"},channel:{type:"string",description:"Optional target channel"},chat_id:{type:"string",description:"Optional target chat/user ID"},media:{type:"array",items:{type:"string"},description:"Optional file attachments"}},required:["content"]};defaultChannel="";defaultChatId="";defaultMessageId=null;setContext(e,r,n){this.defaultChannel=e,this.defaultChatId=r,this.defaultMessageId=n??null}setSendCallback(e){this.sendCallback=e}async execute(e,r){let n=String(e.content??""),o=String(e.channel??this.defaultChannel),i=String(e.chat_id??this.defaultChatId),a=String(e.message_id??this.defaultMessageId??""),l=Array.isArray(e.media)?e.media:[];if(!o||!i)return"Error: No target channel/chat specified";if(!this.sendCallback)return"Error: Message sending not configured";try{await this.sendCallback({channel:o,chatId:i,content:n,media:l,metadata:{message_id:a}});let c=o===this.defaultChannel&&i===this.defaultChatId,u=`Message sent to ${o}:${i}${l.length?` with ${l.length} attachments`:""}`;return c?`__TERMINAL__${u}`:u}catch(c){return`Error sending message: ${String(c)}`}}};import Qe from"node:path";import{spawn as Pt}from"node:child_process";var kr={"agent-turn":{target:"agent-turn",mode:"in-process",risk:"safe",cleanup:"none",observation:"basic",reason:"Normal agent turns stay in-process unless a later surface explicitly routes them through isolation."},"tool.exec":{target:"tool.exec",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Shell execution already crosses the local OS boundary and needs explicit launch, timeout, output capture, and cleanup semantics."},subagent:{target:"subagent",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Spawned subagents are a high-risk local execution path that later Wave D routing can move onto this process boundary."},"scheduled-job":{target:"scheduled-job",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Scheduled jobs can run unattended and should share the same local-process isolation contract when routed in later Wave D work."},"background-job":{target:"background-job",mode:"local-process",risk:"risky-local",cleanup:"terminate-process",observation:"stdio",reason:"Long-running background work needs the same local process cleanup and attribution boundary as other risky execution paths."}};function Ze(s){return{...kr[s]}}var D=class{async run(t){let e=Math.max(1,t.maxCaptureBytes??1048576),r=typeof t.timeoutMs=="number"&&Number.isFinite(t.timeoutMs)&&t.timeoutMs>0?t.timeoutMs:null,n=this.launch(t);if(n instanceof Error)return{status:"failed",pid:null,stdout:"",stderr:"",exitCode:null,signal:null,failureAttribution:"spawn_error",cleanupTriggered:!1,cleanupReason:null,errorMessage:n.message};let{child:o,spawnError:i}=n;t.stdinText!=null?o.stdin?.end(t.stdinText,"utf8"):o.stdin?.end();let a="",l="",c=!1,u=null,d=!1,m=(S,_)=>{let B=typeof S=="string"?S:S.toString("utf8"),M=e-Buffer.byteLength(_);return M<=0?_:_+B.slice(0,M)};o.stdout?.on("data",S=>{a=m(S,a)}),o.stderr?.on("data",S=>{l=m(S,l)});let p=null,f=S=>{c||(c=!0,u=S,d=S==="timeout",this.killChild(o,"SIGTERM"),p=setTimeout(()=>this.killChild(o,"SIGKILL"),250),p.unref?.())},b=()=>f("abort");t.signal?.aborted?b():t.signal?.addEventListener("abort",b,{once:!0});let C=r!=null?setTimeout(()=>f("timeout"),r):null;C?.unref?.();let k=await new Promise(S=>{let _=!1,B=M=>{_||(_=!0,S(M))};o.once("error",M=>{i.current=M,B({code:null,signal:null})}),o.once("close",(M,ie)=>B({code:M,signal:ie}))});return C&&clearTimeout(C),p&&clearTimeout(p),t.signal?.removeEventListener("abort",b),u==="abort"?{status:"aborted",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"aborted",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:d?{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"timeout",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:i.current?{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:"spawn_error",cleanupTriggered:c,cleanupReason:u,errorMessage:i.current.message}:k.code===0?{status:"ok",pid:o.pid??null,stdout:a,stderr:l,exitCode:0,signal:k.signal,failureAttribution:"none",cleanupTriggered:c,cleanupReason:u,errorMessage:null}:{status:"failed",pid:o.pid??null,stdout:a,stderr:l,exitCode:k.code,signal:k.signal,failureAttribution:k.signal?"signal":"exit_code",cleanupTriggered:c,cleanupReason:u,errorMessage:null}}launch(t){try{return{child:t.command.kind==="shell"?Pt(t.command.command,{cwd:t.cwd,env:t.env,shell:!0,detached:process.platform!=="win32",stdio:["pipe","pipe","pipe"]}):Pt(t.command.file,t.command.args??[],{cwd:t.cwd,env:t.env,detached:process.platform!=="win32",stdio:["pipe","pipe","pipe"]}),spawnError:{current:null}}}catch(e){return e instanceof Error?e:new Error(String(e))}}killChild(t,e){try{if(process.platform!=="win32"&&typeof t.pid=="number"){process.kill(-t.pid,e);return}}catch{}try{t.kill(e)}catch{}}};var we=class extends g{constructor(e=60,r,n=!1,o="",i=new D,a,l=!1){super();this.timeout=e;this.workingDir=r;this.restrictToWorkspace=n;this.pathAppend=o;this.runner=i;this.rtkService=a;this.rtkUltraCompact=l}name="exec";description="Execute a shell command and return its output. Use with caution.";parameters={type:"object",properties:{command:{type:"string",description:"The shell command to execute"},working_dir:{type:"string",description:"Optional working directory for the command"}},required:["command"]};guard(e,r){let n=e.toLowerCase();if([/\brm\s+-[rf]{1,2}\b/,/\bdel\s+\/[fq]\b/,/\brmdir\s+\/s\b/,/(?:^|[;&|]\s*)format\b/,/\b(mkfs|diskpart)\b/,/\bdd\s+if=/,/>\s*\/dev\/sd/,/\b(shutdown|reboot|poweroff)\b/,/:\(\)\s*\{.*\};\s*:/].some(i=>i.test(n)))return"Error: Command blocked by safety guard (dangerous pattern detected)";if(this.restrictToWorkspace){if(e.includes("../")||e.includes("..\\"))return"Error: Command blocked by safety guard (path traversal detected)";let i=e.match(/[A-Za-z]:\\[^\s"']+/g)??[];for(let a of i){let l=Qe.resolve(a),c=Qe.resolve(r);if(!l.startsWith(c))return"Error: Command blocked by safety guard (path outside working dir)"}}return null}async execute(e,r){let n=String(e.command??""),o=String(e.working_dir??this.workingDir??process.cwd()),i=this.guard(n,o);if(i)return i;v(r?.signal);let a=Ze("tool.exec"),l={...process.env};if(this.pathAppend&&(l.PATH=`${l.PATH??""}${Qe.delimiter}${this.pathAppend}`),a.mode!=="local-process")return"Error: exec tool requires local-process isolation";let c={command:{kind:"shell",command:n},cwd:o,env:l,timeoutMs:this.timeout*1e3,maxCaptureBytes:1024*1024};r?.signal&&(c.signal=r.signal);let u=await this.runner.run(c);if(u.status==="aborted")throw ze();if(u.failureAttribution==="timeout")return`Error: Command timed out after ${this.timeout} seconds`;let d=u.stdout?`${u.stdout}${u.status==="failed"?`
11
+ `:""}`:"";if(this.rtkService?.getRuntime().available&&d)try{let C=await this.rtkService.compress({command:n,stdout:d,stderr:u.stderr,exitCode:u.exitCode,ultraCompact:this.rtkUltraCompact});C.compressed&&(d=C.stdout)}catch{}let m=u.stderr.trim()?`STDERR:
12
12
  ${u.stderr}
13
- `:"",f=u.status==="failed"&&typeof u.exitCode=="number"?`
14
- Exit code: ${u.exitCode}`:"",y=u.status==="failed"&&u.signal?`
15
- Signal: ${u.signal}`:"",b=`${d}${m}${f}${y}`.trim();return b?b.length>1e4?`${b.slice(0,1e4)}
16
- ... (truncated, ${b.length-1e4} more chars)`:b:u.status==="failed"?u.errorMessage?`Error executing command: ${u.errorMessage}`:"Error executing command":"(no output)"}};var hr={general:{name:"general",description:"General-purpose subagent with full tool access",systemPromptSuffix:"Complete the assigned task using all available tools."},researcher:{name:"researcher",description:"Read-only researcher \u2014 no file modifications",systemPromptSuffix:"Research and report findings. Do NOT modify any files.",allowedTools:["read_file","list_files","search","web_search","web_fetch","session.info","session.search"]},coder:{name:"coder",description:"Code modification specialist",systemPromptSuffix:"Implement the requested code changes.",deniedTools:["web_search","web_fetch"]}};function Rt(){return Object.values(hr)}var ve=class extends g{constructor(e){super();this.manager=e}name="spawn";description="Spawn a subagent to handle a task in the background.";parameters={type:"object",properties:{task:{type:"string",description:"The task for the subagent to complete"},label:{type:"string",description:"Optional short label"},model:{type:"string",description:"Optional model override (e.g. 'anthropic/claude-sonnet-4'). Falls back to subagent config or global default if omitted."},provider:{type:"string",description:"Optional provider override (e.g. 'openai'). Falls back to subagent config or global default if omitted."},context:{type:"string",enum:["fresh","fork"],description:"Context mode: 'fresh' (default) starts with minimal context, 'fork' inherits parent conversation for prompt cache reuse."},type:{type:"string",description:`Agent type defining available tools and behavior. Available types: ${Rt().map(e=>`'${e.name}'`).join(", ")}. Defaults to 'general'.`}},required:["task"]};originChannel="cli";originChatId="direct";sessionKey="cli:direct";parentSystemPrompt;setContext(e,n,r=`${e}:${n}`,o){this.originChannel=e,this.originChatId=n,this.sessionKey=r,this.parentSystemPrompt=o}async execute(e,n){let r=e.context??"fresh",o=e.type??"general",i={task:String(e.task??""),label:e.label!=null?String(e.label):null,originChannel:this.originChannel,originChatId:this.originChatId,sessionKey:this.sessionKey,contextMode:r,agentType:o};return e.model!=null&&(i.model=String(e.model)),e.provider!=null&&(i.providerName=String(e.provider)),r==="fork"&&this.parentSystemPrompt&&(i.parentSystemPrompt=this.parentSystemPrompt),this.manager.spawn(i)}};var Se=class extends g{name="session.search";description="Search the current session's message history for content matching the query.";parameters={type:"object",properties:{query:{type:"string",description:"The search query to match against message content"},limit:{type:"integer",description:"Maximum number of results to return",minimum:1,maximum:100}},required:["query"]};sessionManager=null;sessionKey="cli:direct";constructor(){super()}setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t,e){if(!this.sessionManager)return"Error: Session manager not available";let n=String(t.query??""),r=typeof t.limit=="number"?Math.min(Math.max(1,Math.floor(t.limit)),100):10;if(!n)return"Error: Query cannot be empty";let i=this.sessionManager.getOrCreate(this.sessionKey).search(n,r);return JSON.stringify(i,null,2)}};import Pt from"node:fs";import Te from"node:path";import Lt from"node:os";import H from"node:fs";import ke from"node:path";var yr={"gpt-4.1":1047576,"gpt-4.1-mini":1047576,"gpt-4.1-nano":1047576,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4-turbo":128e3,"gpt-4":8192,"gpt-3.5-turbo":16385,"claude-sonnet-4":2e5,"claude-sonnet-4-20250514":2e5,"claude-3-5-sonnet":2e5,"claude-3-5-sonnet-20241022":2e5,"claude-3-5-haiku":2e5,"claude-3-opus":2e5,"claude-3-sonnet":2e5,"claude-3-haiku":2e5,"gemini-2.5-pro":1e6,"gemini-2.0-flash":1e6,"gemini-1.5-pro":1e6,"gemini-1.5-flash":1e6,"deepseek-chat":64e3,"deepseek-reasoner":64e3,"grok-2":131072,"grok-2-mini":131072},br=128e3;function we(s){if(!s)return 0;let t=typeof s=="string"?s:JSON.stringify(s);return Math.ceil(t.length/4)}function Mt(s,t){if(t){let n=t.providers?.[t.agents.defaults.provider]?.models?.find(r=>r.id.toLowerCase()===s.toLowerCase())?.capabilities;if(n?.contextWindow)return n.contextWindow;for(let r of t.customLlmProviders??[]){let o=r.models.find(i=>i.id.toLowerCase()===s.toLowerCase());if(o?.capabilities?.contextWindow)return o.capabilities.contextWindow}}let e=s.toLowerCase();for(let[n,r]of Object.entries(yr))if(n.toLowerCase()===e||e.includes(n.toLowerCase()))return r;return br}var vr=[{type:"function",function:{name:"save_memory",description:"Save the memory consolidation result to persistent storage.",parameters:{type:"object",properties:{history_entry:{type:"string"},memory_update:{type:"string"}},required:["history_entry","memory_update"]}}}],V=class{memoryDir;memoryFile;historyFile;constructor(t,e){let n=ke.join(t,"memory");this.memoryDir=e?ke.join(n,e):n,H.mkdirSync(this.memoryDir,{recursive:!0}),this.memoryFile=ke.join(this.memoryDir,"MEMORY.md"),this.historyFile=ke.join(this.memoryDir,"HISTORY.md")}readLongTerm(){return H.existsSync(this.memoryFile)?H.readFileSync(this.memoryFile,"utf8"):""}writeLongTerm(t){H.writeFileSync(this.memoryFile,t,"utf8")}appendHistory(t){H.appendFileSync(this.historyFile,`${t.trim()}
13
+ `:"",p=u.status==="failed"&&typeof u.exitCode=="number"?`
14
+ Exit code: ${u.exitCode}`:"",f=u.status==="failed"&&u.signal?`
15
+ Signal: ${u.signal}`:"",b=`${d}${m}${p}${f}`.trim();return b?b.length>1e4?`${b.slice(0,1e4)}
16
+ ... (truncated, ${b.length-1e4} more chars)`:b:u.status==="failed"?u.errorMessage?`Error executing command: ${u.errorMessage}`:"Error executing command":"(no output)"}};var xr={general:{name:"general",description:"General-purpose subagent with full tool access",systemPromptSuffix:"Complete the assigned task using all available tools."},researcher:{name:"researcher",description:"Read-only researcher \u2014 no file modifications",systemPromptSuffix:"Research and report findings. Do NOT modify any files.",allowedTools:["read_file","list_files","search","web_search","web_fetch","session.info","session.search"]},coder:{name:"coder",description:"Code modification specialist",systemPromptSuffix:"Implement the requested code changes.",deniedTools:["web_search","web_fetch"]}};function Lt(){return Object.values(xr)}var ke=class extends g{constructor(e){super();this.manager=e}name="spawn";description="Spawn a subagent to handle a task in the background.";parameters={type:"object",properties:{task:{type:"string",description:"The task for the subagent to complete"},label:{type:"string",description:"Optional short label"},model:{type:"string",description:"Optional model override (e.g. 'anthropic/claude-sonnet-4'). Falls back to subagent config or global default if omitted."},provider:{type:"string",description:"Optional provider override (e.g. 'openai'). Falls back to subagent config or global default if omitted."},context:{type:"string",enum:["fresh","fork"],description:"Context mode: 'fresh' (default) starts with minimal context, 'fork' inherits parent conversation for prompt cache reuse."},type:{type:"string",description:`Agent type defining available tools and behavior. Available types: ${Lt().map(e=>`'${e.name}'`).join(", ")}. Defaults to 'general'.`}},required:["task"]};originChannel="cli";originChatId="direct";sessionKey="cli:direct";parentSystemPrompt;setContext(e,r,n=`${e}:${r}`,o){this.originChannel=e,this.originChatId=r,this.sessionKey=n,this.parentSystemPrompt=o}async execute(e,r){let n=e.context??"fresh",o=e.type??"general",i={task:String(e.task??""),label:e.label!=null?String(e.label):null,originChannel:this.originChannel,originChatId:this.originChatId,sessionKey:this.sessionKey,contextMode:n,agentType:o};return e.model!=null&&(i.model=String(e.model)),e.provider!=null&&(i.providerName=String(e.provider)),n==="fork"&&this.parentSystemPrompt&&(i.parentSystemPrompt=this.parentSystemPrompt),this.manager.spawn(i)}};var xe=class extends g{name="session.search";description="Search the current session's message history for content matching the query.";parameters={type:"object",properties:{query:{type:"string",description:"The search query to match against message content"},limit:{type:"integer",description:"Maximum number of results to return",minimum:1,maximum:100}},required:["query"]};sessionManager=null;sessionKey="cli:direct";constructor(){super()}setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t,e){if(!this.sessionManager)return"Error: Session manager not available";let r=String(t.query??""),n=typeof t.limit=="number"?Math.min(Math.max(1,Math.floor(t.limit)),100):10;if(!r)return"Error: Query cannot be empty";let i=this.sessionManager.getOrCreate(this.sessionKey).search(r,n);return JSON.stringify(i,null,2)}};import Dt from"node:fs";import Re from"node:path";import jt from"node:os";import X from"node:fs";import Ce from"node:path";var Tr={"gpt-4.1":1047576,"gpt-4.1-mini":1047576,"gpt-4.1-nano":1047576,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4-turbo":128e3,"gpt-4":8192,"gpt-3.5-turbo":16385,"claude-sonnet-4":2e5,"claude-sonnet-4-20250514":2e5,"claude-3-5-sonnet":2e5,"claude-3-5-sonnet-20241022":2e5,"claude-3-5-haiku":2e5,"claude-3-opus":2e5,"claude-3-sonnet":2e5,"claude-3-haiku":2e5,"gemini-2.5-pro":1e6,"gemini-2.0-flash":1e6,"gemini-1.5-pro":1e6,"gemini-1.5-flash":1e6,"deepseek-chat":64e3,"deepseek-reasoner":64e3,"grok-2":131072,"grok-2-mini":131072},Cr=128e3;function Te(s){if(!s)return 0;let t=typeof s=="string"?s:JSON.stringify(s);return Math.ceil(t.length/4)}function Ot(s,t){if(t){let r=t.providers?.[t.agents.defaults.provider]?.models?.find(n=>n.id.toLowerCase()===s.toLowerCase())?.capabilities;if(r?.contextWindow)return r.contextWindow;for(let n of t.customLlmProviders??[]){let o=n.models.find(i=>i.id.toLowerCase()===s.toLowerCase());if(o?.capabilities?.contextWindow)return o.capabilities.contextWindow}}let e=s.toLowerCase();for(let[r,n]of Object.entries(Tr))if(r.toLowerCase()===e||e.includes(r.toLowerCase()))return n;return Cr}var $t=1e3,Ar=250,Ae=`
17
+ ... (truncated for archival)`;function It(s){return Math.max(0,Math.floor(s*4))}function Er(s,t){if(t<=0)return"";let e=It(t);if(s.length<=e)return s;let r=Math.max(0,e-Ae.length);return`${Ae}${s.slice(-r)}`}function Rr(s,t){if(t<=0||s.length===0)return{text:"",omittedLines:s.length};let e=It(t),r=[],n=0,o=0;for(let i=s.length-1;i>=0;i--){let a=s[i],l=r.length?1:0,c=e-n-l;if(c<=0){o=i+1;break}if(a.length<=c){r.unshift(a),n+=a.length+l;continue}let u=Math.max(0,c-Ae.length);r.unshift(`${Ae}${a.slice(-u)}`),n=e,o=i;break}return{text:r.join(`
18
+ `),omittedLines:o}}var Mr=[{type:"function",function:{name:"save_memory",description:"Save the memory consolidation result to persistent storage.",parameters:{type:"object",properties:{history_entry:{type:"string"},memory_update:{type:"string"}},required:["history_entry","memory_update"]}}}],Y=class{memoryDir;memoryFile;historyFile;constructor(t,e){let r=Ce.join(t,"memory");this.memoryDir=e?Ce.join(r,e):r,X.mkdirSync(this.memoryDir,{recursive:!0}),this.memoryFile=Ce.join(this.memoryDir,"MEMORY.md"),this.historyFile=Ce.join(this.memoryDir,"HISTORY.md")}readLongTerm(){return X.existsSync(this.memoryFile)?X.readFileSync(this.memoryFile,"utf8"):""}writeLongTerm(t){X.writeFileSync(this.memoryFile,t,"utf8")}appendHistory(t){X.appendFileSync(this.historyFile,`${t.trim()}
17
19
 
18
20
  `,"utf8")}getMemoryContext(){let t=this.readLongTerm();return t?`## Long-term Memory
19
- ${t}`:""}async consolidate(t,e,n,r){let o=r?.archiveAll??!1,i=r?.memoryWindow??50,a=[],l=0;if(o)a=t.messages,l=0;else if(l=Math.floor(i/2),t.messages.length<=l||t.messages.length-t.lastConsolidated<=0||(a=t.messages.slice(t.lastConsolidated,t.messages.length-l),!a.length))return!0;let c=[],u=[];for(let p of a)p._type==="anchor"?c.push(p):u.push(p);let d=[];for(let p of c)d.push(`[ANCHOR] ${p.name}: ${p.summary??"(no summary)"}`);for(let p of u){if(!p.content&&!p._full_content)continue;let T=Array.isArray(p.tools_used)&&p.tools_used.length?` [tools: ${p.tools_used.join(", ")}]`:"",L=p._full_content??p.content;d.push(`[${String(p.timestamp??"?").slice(0,16)}] ${String(p.role).toUpperCase()}${T}: ${String(L)}`)}let m=this.readLongTerm(),f=`Process this conversation and call the save_memory tool with your consolidation.
20
-
21
- ## Current Long-term Memory
22
- ${m||"(empty)"}
23
-
24
- ## Conversation to Process
25
- ${d.join(`
26
- `)}`,y=we(`Process this conversation and call the save_memory tool with your consolidation.
21
+ ${t}`:""}async consolidate(t,e,r,n){let o=n?.archiveAll??!1,i=n?.memoryWindow??50,a=[],l=0;if(o)a=t.messages,l=0;else if(l=Math.floor(i/2),t.messages.length<=l||t.messages.length-t.lastConsolidated<=0||(a=t.messages.slice(t.lastConsolidated,t.messages.length-l),!a.length))return!0;let c=[],u=[];for(let h of a)h._type==="anchor"?c.push(h):u.push(h);let d=[];for(let h of c)d.push(`[ANCHOR] ${h.name}: ${h.summary??"(no summary)"}`);for(let h of u){if(!h.content&&!h._full_content)continue;let F=Array.isArray(h.tools_used)&&h.tools_used.length?` [tools: ${h.tools_used.join(", ")}]`:"",L=h._full_content??h.content;d.push(`[${String(h.timestamp??"?").slice(0,16)}] ${String(h.role).toUpperCase()}${F}: ${String(L)}`)}let m=this.readLongTerm(),p=d.join(`
22
+ `),f=m||"(empty)",b="## Conversation to Process",C=p,k=Te(`Process this conversation and call the save_memory tool with your consolidation.
27
23
 
28
24
  ## Current Long-term Memory
29
25
 
30
26
 
31
27
  ## Conversation to Process
32
- `),b=we(m||"(empty)"),A=we(d.join(`
33
- `)),k=y+b+A,x=Mt(n),_=Math.floor(x*.9);if(k>_){let p=Math.max(1e3,_-y-b),T=Math.floor(p*4),D=d.join(`
34
- `).slice(-T);f=`Process this conversation and call the save_memory tool with your consolidation.
28
+ `),S=Te(m||"(empty)"),_=Te(p),B=k+S+_,M=Ot(r),ie=Math.floor(M*.9);if(B>ie){let h=Math.max(1,ie-k),F=Math.min(S,Math.max(Ar,Math.floor(h*.3))),L=Math.min(S,Math.max(0,h-$t),F),$=Math.max($t,h-L);if(L<S&&(f=Er(f,L)),$<_){let O=Rr(d,$);C=O.text,b=O.text!==p?`## Conversation to Process (truncated, most recent ${d.length-O.omittedLines} entries)`:"## Conversation to Process"}}let or=`Process this conversation and call the save_memory tool with your consolidation.
35
29
 
36
30
  ## Current Long-term Memory
37
- ${m||"(empty)"}
31
+ ${f}
38
32
 
39
- ## Conversation to Process (truncated, most recent)
40
- ${D}`}try{let p=await e.chat({model:n,messages:[{role:"system",content:"You are a memory consolidation agent. Call the save_memory tool."},{role:"user",content:f}],tools:vr});if(!p.toolCalls.length)return!1;let T=p.toolCalls[0];if(!T)return!1;let L=T.arguments??{},D=L.history_entry,ne=L.memory_update;if(D!=null&&this.appendHistory(typeof D=="string"?D:JSON.stringify(D)),ne!=null){let O=typeof ne=="string"?ne:JSON.stringify(ne);O!==m&&this.writeLongTerm(O)}let nt=o?0:t.messages.length-l,ot=t.messages.slice(0,nt),Ue=-1;for(let O=ot.length-1;O>=0;O--)if(ot[O]?._type==="anchor"){Ue=O;break}return Ue!==-1?t.lastConsolidated=Ue+1:t.lastConsolidated=nt,!0}catch{return!1}}};import z from"node:fs";import X from"node:path";var _t=/^[a-z0-9][a-z0-9-]*$/;var xe=class{workspaceSkills;userSkills;builtinSkills;scannerConfig;scanner;constructor(t,e,n,r,o){this.workspaceSkills=X.join(t,"skills"),this.userSkills=e??null,this.builtinSkills=n??ct("skills"),this.scannerConfig=r??null,this.scanner=o??null}listSkills(t=!0){return(t?this.getResolvedSkills().filter(n=>n.status==="available"):this.getResolvedSkills()).map(({name:n,path:r,source:o})=>({name:n,path:r,source:o}))}listResolvedSkills(){return this.getResolvedSkills().map(({content:t,metadata:e,runtimeMeta:n,...r})=>r)}loadSkill(t){let e=this.getSkillByName(t);return e?.status==="available"?e.content:null}loadSkillsForContext(t){let e=[];for(let n of t){let r=this.getSkillByName(n);if(!r){e.push(this.renderLoadFailure(n,`Skill '${n}' is not installed. ${this.getAvailableSkillsHint()}`));continue}if(r.status!=="available"){let o=r.status==="malformed"?`Skill '${n}' is malformed: ${r.reason}.`:r.status==="blocked"?`Skill '${n}' is blocked by security scanner: ${r.reason}.`:`Skill '${n}' is unavailable: ${r.reason}.`;e.push(this.renderLoadFailure(n,o));continue}e.push(`### Skill: ${n}
33
+ ${b}
34
+ ${C}`;try{let h=await e.chat({model:r,messages:[{role:"system",content:"You are a memory consolidation agent. Call the save_memory tool."},{role:"user",content:or}],tools:Mr});if(!h.toolCalls.length)return!1;let F=h.toolCalls[0];if(!F)return!1;let L=F.arguments??{},$=L.history_entry,O=L.memory_update;if($!=null&&this.appendHistory(typeof $=="string"?$:JSON.stringify($)),O!=null){let I=typeof O=="string"?O:JSON.stringify(O);I!==m&&this.writeLongTerm(I)}let at=o?0:t.messages.length-l,lt=t.messages.slice(0,at),Ke=-1;for(let I=lt.length-1;I>=0;I--)if(lt[I]?._type==="anchor"){Ke=I;break}return Ke!==-1?t.lastConsolidated=Ke+1:t.lastConsolidated=at,!0}catch{return!1}}};import Z from"node:fs";import Q from"node:path";var Nt=/^[a-z0-9][a-z0-9-]*$/;var Ee=class{workspaceSkills;userSkills;builtinSkills;scannerConfig;scanner;constructor(t,e,r,n,o){this.workspaceSkills=Q.join(t,"skills"),this.userSkills=e??null,this.builtinSkills=r??gt("skills"),this.scannerConfig=n??null,this.scanner=o??null}listSkills(t=!0){return(t?this.getResolvedSkills().filter(r=>r.status==="available"):this.getResolvedSkills()).map(({name:r,path:n,source:o})=>({name:r,path:n,source:o}))}listResolvedSkills(){return this.getResolvedSkills().map(({content:t,metadata:e,runtimeMeta:r,...n})=>n)}loadSkill(t){let e=this.getSkillByName(t);return e?.status==="available"?e.content:null}loadSkillsForContext(t){let e=[];for(let r of t){let n=this.getSkillByName(r);if(!n){e.push(this.renderLoadFailure(r,`Skill '${r}' is not installed. ${this.getAvailableSkillsHint()}`));continue}if(n.status!=="available"){let o=n.status==="malformed"?`Skill '${r}' is malformed: ${n.reason}.`:n.status==="blocked"?`Skill '${r}' is blocked by security scanner: ${n.reason}.`:`Skill '${r}' is unavailable: ${n.reason}.`;e.push(this.renderLoadFailure(r,o));continue}e.push(`### Skill: ${r}
41
35
 
42
- ${this.stripFrontmatter(r.content)}`)}return e.join(`
36
+ ${this.stripFrontmatter(n.content)}`)}return e.join(`
43
37
 
44
38
  ---
45
39
 
46
- `)}buildSkillsSummary(){let t=this.getResolvedSkills();if(!t.length)return"";let e=r=>r.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;"),n=["<skills>"];for(let r of t)n.push(` <skill available="${r.status==="available"}" source="${e(r.source)}">`),n.push(` <name>${e(r.name)}</name>`),n.push(` <description>${e(r.description)}</description>`),n.push(` <location>${e(r.path)}</location>`),n.push(` <status>${e(r.status)}</status>`),r.reason&&n.push(` <reason>${e(r.reason)}</reason>`),n.push(" </skill>");return n.push("</skills>"),n.join(`
47
- `)}getAlwaysSkills(){return this.getResolvedSkills().filter(t=>t.status==="available"&&t.always).map(t=>t.name)}getSkillMetadata(t){return this.getSkillByName(t)?.metadata??null}stripFrontmatter(t){let e=t.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/);return e?t.slice(e[0].length).trim():t}getResolvedSkills(){let t=new Map;for(let{root:e,source:n}of this.getSkillRoots()){if(!z.existsSync(e))continue;let r=z.readdirSync(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).sort((o,i)=>o.name.localeCompare(i.name));for(let o of r){if(t.has(o.name))continue;let i=X.join(e,o.name,"SKILL.md");z.existsSync(i)&&t.set(o.name,this.readSkill(o.name,i,n))}}return[...t.values()].sort((e,n)=>e.name.localeCompare(n.name))}getSkillByName(t){return this.getResolvedSkills().find(e=>e.name===t)??null}getSkillRoots(){let t=[{root:this.workspaceSkills,source:"workspace"}];return this.userSkills&&t.push({root:this.userSkills,source:"user"}),t.push({root:this.builtinSkills,source:"builtin"}),t}readSkill(t,e,n){let r=z.readFileSync(e,"utf8"),o=this.parseSkill(t,r);if(o.errors.length)return{name:t,path:e,source:n,content:r,metadata:o.metadata,runtimeMeta:{},description:o.description,status:"malformed",reason:o.errors.join("; "),always:!1};let i=this.getRequirementErrors(o.runtimeMeta),a=this.runSecurityScan(e,t);if(a&&!a.isSafe&&this.scannerConfig?.blockUnsafe)return{name:t,path:e,source:n,content:r,metadata:o.metadata,runtimeMeta:o.runtimeMeta,description:o.description,status:"blocked",reason:this.formatBlockedReason(a),always:o.always};if(a&&a.findings.length>0){let l=a.findings.map(c=>`[${c.severity}] ${c.title} (${c.category})`);console.warn(`SkillScanner: skill '${t}' has ${a.findings.length} finding(s): ${l.join("; ")}`)}return{name:t,path:e,source:n,content:r,metadata:o.metadata,runtimeMeta:o.runtimeMeta,description:o.description,status:i.length?"unavailable":"available",reason:i.length?i.join("; "):null,always:o.always}}runSecurityScan(t,e){if(!this.scannerConfig?.enabled||!this.scannerConfig.scanOnLoad||!this.scanner)return null;let n=X.dirname(t);return this.scanner.scanSkill(n,e,{maxFileCount:this.scannerConfig.maxFileCount,maxFileSizeBytes:this.scannerConfig.maxFileSizeBytes})}formatBlockedReason(t){let e=t.findings.filter(r=>r.severity==="CRITICAL");return e.length===0?"Security scan failed":`Blocked by security scanner: ${e.map(r=>`[${r.severity}] ${r.title} (${r.category})`).join("; ")}`}parseSkill(t,e){let n=this.extractFrontmatter(e);if(!n.frontmatter)return{metadata:null,runtimeMeta:{},description:t,always:!1,errors:[n.error??"missing YAML frontmatter"]};let r=this.parseFrontmatter(n.frontmatter),o=r.metadata,i=typeof o.description=="string"&&o.description.trim()?o.description.trim():t,a=[...r.errors],l=typeof o.name=="string"?o.name.trim():"";l?l!==t?a.push(`frontmatter name '${l}' does not match directory '${t}'`):_t.test(l)||a.push(`frontmatter name '${l}' must match ${_t}`):a.push("missing required frontmatter field 'name'"),typeof o.description=="string"&&o.description.trim()||a.push("missing required frontmatter field 'description'");let c=this.parseRuntimeMetadata(o.metadata);a.push(...c.errors);let u=o.always;return u!==void 0&&typeof u!="boolean"&&a.push("frontmatter field 'always' must be a boolean"),{metadata:o,runtimeMeta:c.runtimeMeta,description:i,always:u??c.runtimeMeta.always??!1,errors:a}}extractFrontmatter(t){if(!(t.startsWith(`---
40
+ `)}buildSkillsSummary(){let t=this.getResolvedSkills();if(!t.length)return"";let e=n=>n.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;"),r=["<skills>"];for(let n of t)r.push(` <skill available="${n.status==="available"}" source="${e(n.source)}">`),r.push(` <name>${e(n.name)}</name>`),r.push(` <description>${e(n.description)}</description>`),r.push(` <location>${e(n.path)}</location>`),r.push(` <status>${e(n.status)}</status>`),n.reason&&r.push(` <reason>${e(n.reason)}</reason>`),r.push(" </skill>");return r.push("</skills>"),r.join(`
41
+ `)}getAlwaysSkills(){return this.getResolvedSkills().filter(t=>t.status==="available"&&t.always).map(t=>t.name)}getSkillMetadata(t){return this.getSkillByName(t)?.metadata??null}stripFrontmatter(t){let e=t.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/);return e?t.slice(e[0].length).trim():t}getResolvedSkills(){let t=new Map;for(let{root:e,source:r}of this.getSkillRoots()){if(!Z.existsSync(e))continue;let n=Z.readdirSync(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).sort((o,i)=>o.name.localeCompare(i.name));for(let o of n){if(t.has(o.name))continue;let i=Q.join(e,o.name,"SKILL.md");Z.existsSync(i)&&t.set(o.name,this.readSkill(o.name,i,r))}}return[...t.values()].sort((e,r)=>e.name.localeCompare(r.name))}getSkillByName(t){return this.getResolvedSkills().find(e=>e.name===t)??null}getSkillRoots(){let t=[{root:this.workspaceSkills,source:"workspace"}];return this.userSkills&&t.push({root:this.userSkills,source:"user"}),t.push({root:this.builtinSkills,source:"builtin"}),t}readSkill(t,e,r){let n=Z.readFileSync(e,"utf8"),o=this.parseSkill(t,n);if(o.errors.length)return{name:t,path:e,source:r,content:n,metadata:o.metadata,runtimeMeta:{},description:o.description,status:"malformed",reason:o.errors.join("; "),always:!1};let i=this.getRequirementErrors(o.runtimeMeta),a=this.runSecurityScan(e,t);if(a&&!a.isSafe&&this.scannerConfig?.blockUnsafe)return{name:t,path:e,source:r,content:n,metadata:o.metadata,runtimeMeta:o.runtimeMeta,description:o.description,status:"blocked",reason:this.formatBlockedReason(a),always:o.always};if(a&&a.findings.length>0){let l=a.findings.map(c=>`[${c.severity}] ${c.title} (${c.category})`);console.warn(`SkillScanner: skill '${t}' has ${a.findings.length} finding(s): ${l.join("; ")}`)}return{name:t,path:e,source:r,content:n,metadata:o.metadata,runtimeMeta:o.runtimeMeta,description:o.description,status:i.length?"unavailable":"available",reason:i.length?i.join("; "):null,always:o.always}}runSecurityScan(t,e){if(!this.scannerConfig?.enabled||!this.scannerConfig.scanOnLoad||!this.scanner)return null;let r=Q.dirname(t);return this.scanner.scanSkill(r,e,{maxFileCount:this.scannerConfig.maxFileCount,maxFileSizeBytes:this.scannerConfig.maxFileSizeBytes})}formatBlockedReason(t){let e=t.findings.filter(n=>n.severity==="CRITICAL");return e.length===0?"Security scan failed":`Blocked by security scanner: ${e.map(n=>`[${n.severity}] ${n.title} (${n.category})`).join("; ")}`}parseSkill(t,e){let r=this.extractFrontmatter(e);if(!r.frontmatter)return{metadata:null,runtimeMeta:{},description:t,always:!1,errors:[r.error??"missing YAML frontmatter"]};let n=this.parseFrontmatter(r.frontmatter),o=n.metadata,i=typeof o.description=="string"&&o.description.trim()?o.description.trim():t,a=[...n.errors],l=typeof o.name=="string"?o.name.trim():"";l?l!==t?a.push(`frontmatter name '${l}' does not match directory '${t}'`):Nt.test(l)||a.push(`frontmatter name '${l}' must match ${Nt}`):a.push("missing required frontmatter field 'name'"),typeof o.description=="string"&&o.description.trim()||a.push("missing required frontmatter field 'description'");let c=this.parseRuntimeMetadata(o.metadata);a.push(...c.errors);let u=o.always;return u!==void 0&&typeof u!="boolean"&&a.push("frontmatter field 'always' must be a boolean"),{metadata:o,runtimeMeta:c.runtimeMeta,description:i,always:u??c.runtimeMeta.always??!1,errors:a}}extractFrontmatter(t){if(!(t.startsWith(`---
48
42
  `)||t.startsWith(`---\r
49
- `)))return{frontmatter:null,error:"missing YAML frontmatter"};let e=t.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return e?{frontmatter:e[1]??null,error:null}:{frontmatter:null,error:"unterminated YAML frontmatter"}}parseFrontmatter(t){let e={},n=[];for(let r of t.split(/\r?\n/)){let o=r.trim();if(!o)continue;let i=o.indexOf(":");if(i<=0){n.push(`invalid frontmatter line '${o}'`);continue}let a=o.slice(0,i).trim(),l=o.slice(i+1).trim();e[a]=this.parseFrontmatterValue(l)}return{metadata:e,errors:n}}parseFrontmatterValue(t){let e=t.replace(/^['"]|['"]$/g,"");return e==="true"?!0:e==="false"?!1:e}parseRuntimeMetadata(t){if(t===void 0||t==="")return{runtimeMeta:{},errors:[]};if(typeof t!="string")return{runtimeMeta:{},errors:["frontmatter field 'metadata' must be a JSON object string"]};let e;try{e=JSON.parse(t)}catch{return{runtimeMeta:{},errors:["frontmatter field 'metadata' must contain valid JSON"]}}if(!this.isRecord(e))return{runtimeMeta:{},errors:["frontmatter field 'metadata' must decode to an object"]};let n=e.everclaw??e.openclaw??{};if(!this.isRecord(n))return{runtimeMeta:{},errors:["skill metadata for 'everclaw'/'openclaw' must be an object"]};let r=[],o={};if(n.always!==void 0&&(typeof n.always!="boolean"?r.push("skill metadata field 'always' must be a boolean"):o.always=n.always),n.requires!==void 0)if(!this.isRecord(n.requires))r.push("skill metadata field 'requires' must be an object");else{let i=n.requires.bins,a=n.requires.env;i!==void 0&&!this.isStringArray(i)&&r.push("skill metadata field 'requires.bins' must be an array of strings"),a!==void 0&&!this.isStringArray(a)&&r.push("skill metadata field 'requires.env' must be an array of strings");let l={};this.isStringArray(i)&&(l.bins=i),this.isStringArray(a)&&(l.env=a),Object.keys(l).length>0&&(o.requires=l)}return{runtimeMeta:o,errors:r}}getRequirementErrors(t){let e=t.requires??{},n=(e.bins??[]).filter(i=>!this.hasBinary(i)),r=(e.env??[]).filter(i=>!process.env[i]),o=[];return n.length&&o.push(`missing required binaries: ${n.join(", ")}`),r.length&&o.push(`missing required env vars: ${r.join(", ")}`),o}hasBinary(t){let e=(process.env.PATH??"").split(X.delimiter).filter(Boolean),n=process.platform==="win32"?["",".exe",".cmd",".bat"]:[""];return e.some(r=>n.some(o=>z.existsSync(X.join(r,`${t}${o}`))))}getAvailableSkillsHint(){let t=this.getResolvedSkills().filter(e=>e.status==="available").map(e=>e.name);return t.length?`Available skills: ${t.join(", ")}`:"No skills are currently available."}renderLoadFailure(t,e){return`### Skill unavailable: ${t}
43
+ `)))return{frontmatter:null,error:"missing YAML frontmatter"};let e=t.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return e?{frontmatter:e[1]??null,error:null}:{frontmatter:null,error:"unterminated YAML frontmatter"}}parseFrontmatter(t){let e={},r=[];for(let n of t.split(/\r?\n/)){let o=n.trim();if(!o)continue;let i=o.indexOf(":");if(i<=0){r.push(`invalid frontmatter line '${o}'`);continue}let a=o.slice(0,i).trim(),l=o.slice(i+1).trim();e[a]=this.parseFrontmatterValue(l)}return{metadata:e,errors:r}}parseFrontmatterValue(t){let e=t.replace(/^['"]|['"]$/g,"");return e==="true"?!0:e==="false"?!1:e}parseRuntimeMetadata(t){if(t===void 0||t==="")return{runtimeMeta:{},errors:[]};if(typeof t!="string")return{runtimeMeta:{},errors:["frontmatter field 'metadata' must be a JSON object string"]};let e;try{e=JSON.parse(t)}catch{return{runtimeMeta:{},errors:["frontmatter field 'metadata' must contain valid JSON"]}}if(!this.isRecord(e))return{runtimeMeta:{},errors:["frontmatter field 'metadata' must decode to an object"]};let r=e.everclaw??e.openclaw??{};if(!this.isRecord(r))return{runtimeMeta:{},errors:["skill metadata for 'everclaw'/'openclaw' must be an object"]};let n=[],o={};if(r.always!==void 0&&(typeof r.always!="boolean"?n.push("skill metadata field 'always' must be a boolean"):o.always=r.always),r.requires!==void 0)if(!this.isRecord(r.requires))n.push("skill metadata field 'requires' must be an object");else{let i=r.requires.bins,a=r.requires.env;i!==void 0&&!this.isStringArray(i)&&n.push("skill metadata field 'requires.bins' must be an array of strings"),a!==void 0&&!this.isStringArray(a)&&n.push("skill metadata field 'requires.env' must be an array of strings");let l={};this.isStringArray(i)&&(l.bins=i),this.isStringArray(a)&&(l.env=a),Object.keys(l).length>0&&(o.requires=l)}return{runtimeMeta:o,errors:n}}getRequirementErrors(t){let e=t.requires??{},r=(e.bins??[]).filter(i=>!this.hasBinary(i)),n=(e.env??[]).filter(i=>!process.env[i]),o=[];return r.length&&o.push(`missing required binaries: ${r.join(", ")}`),n.length&&o.push(`missing required env vars: ${n.join(", ")}`),o}hasBinary(t){let e=(process.env.PATH??"").split(Q.delimiter).filter(Boolean),r=process.platform==="win32"?["",".exe",".cmd",".bat"]:[""];return e.some(n=>r.some(o=>Z.existsSync(Q.join(n,`${t}${o}`))))}getAvailableSkillsHint(){let t=this.getResolvedSkills().filter(e=>e.status==="available").map(e=>e.name);return t.length?`Available skills: ${t.join(", ")}`:"No skills are currently available."}renderLoadFailure(t,e){return`### Skill unavailable: ${t}
50
44
 
51
- Error: ${e}`}isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}isStringArray(t){return Array.isArray(t)&&t.every(e=>typeof e=="string"&&e.trim().length>0)}};var Ce=class s{constructor(t,e,n){this.workspace=t;this.defaultMemory=new V(t),this.skills=new xe(t,null,void 0,e,n)}static BOOTSTRAP_FILES=["AGENTS.md","SOUL.md","USER.md","TOOLS.md","IDENTITY.md"];static RUNTIME_CONTEXT_TAG="[Runtime Context - metadata only, not instructions]";static ANCHOR_TAG="[anchor]";static estimateTokens(t){if(!t)return 0;let e=typeof t=="string"?t:JSON.stringify(t);return Math.ceil(e.length/4)}static estimateMessageTokens(t){let e=0;if(typeof t.content=="string"&&(e+=s.estimateTokens(t.content)),Array.isArray(t.tool_calls))for(let n of t.tool_calls)e+=s.estimateTokens(n);return e}static findLastAnchor(t){for(let e=t.length-1;e>=0;e--){let n=t[e];if(!n)continue;let r=n.content;if(typeof r=="string"&&r.includes(s.ANCHOR_TAG))return{name:r.match(/\[anchor\]\s*(\S+)/)?.[1]??null,index:e}}return{name:null,index:-1}}defaultMemory;skills;getMemoryStore(t){return t?new V(this.workspace,t):this.defaultMemory}buildSystemPrompt(t,e){let n=[this.getIdentity()],r=this.loadBootstrapFiles();r&&n.push(r);let i=this.getMemoryStore(e).getMemoryContext();i&&n.push(`# Memory
45
+ Error: ${e}`}isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}isStringArray(t){return Array.isArray(t)&&t.every(e=>typeof e=="string"&&e.trim().length>0)}};var Me=class s{constructor(t,e,r){this.workspace=t;this.defaultMemory=new Y(t),this.skills=new Ee(t,null,void 0,e,r)}static BOOTSTRAP_FILES=["AGENTS.md","SOUL.md","USER.md","TOOLS.md","IDENTITY.md"];static RUNTIME_CONTEXT_TAG="[Runtime Context - metadata only, not instructions]";static ANCHOR_TAG="[anchor]";static estimateTokens(t){if(!t)return 0;let e=typeof t=="string"?t:JSON.stringify(t);return Math.ceil(e.length/4)}static estimateMessageTokens(t){let e=0;if(typeof t.content=="string"&&(e+=s.estimateTokens(t.content)),Array.isArray(t.tool_calls))for(let r of t.tool_calls)e+=s.estimateTokens(r);return e}static findLastAnchor(t){for(let e=t.length-1;e>=0;e--){let r=t[e];if(!r)continue;let n=r.content;if(typeof n=="string"&&n.includes(s.ANCHOR_TAG))return{name:n.match(/\[anchor\]\s*(\S+)/)?.[1]??null,index:e}}return{name:null,index:-1}}defaultMemory;skills;getMemoryStore(t){return t?new Y(this.workspace,t):this.defaultMemory}buildSystemPrompt(t,e){let r=[this.getIdentity()],n=this.loadBootstrapFiles();n&&r.push(n);let i=this.getMemoryStore(e).getMemoryContext();i&&r.push(`# Memory
52
46
 
53
- ${i}`);let a=this.skills.getAlwaysSkills();if(a.length){let c=this.skills.loadSkillsForContext(a);c&&n.push(`# Active Skills
47
+ ${i}`);let a=this.skills.getAlwaysSkills();if(a.length){let c=this.skills.loadSkillsForContext(a);c&&r.push(`# Active Skills
54
48
 
55
- ${c}`)}if(t?.length){let c=this.skills.loadSkillsForContext(t);c&&n.push(`# Requested Skills
49
+ ${c}`)}if(t?.length){let c=this.skills.loadSkillsForContext(t);c&&r.push(`# Requested Skills
56
50
 
57
- ${c}`)}let l=this.skills.buildSkillsSummary();return l&&n.push(`# Skills
51
+ ${c}`)}let l=this.skills.buildSkillsSummary();return l&&r.push(`# Skills
58
52
 
59
53
  The following skills extend your capabilities. To use one, read its SKILL.md with read_file.
60
54
 
61
- ${l}`),n.join(`
55
+ ${l}`),r.join(`
62
56
 
63
57
  ---
64
58
 
@@ -67,29 +61,29 @@ ${l}`),n.join(`
67
61
  You are everclaw, a helpful AI assistant.
68
62
 
69
63
  ## Runtime
70
- ${Lt.platform()} ${Lt.arch()}, Node ${process.version}
64
+ ${jt.platform()} ${jt.arch()}, Node ${process.version}
71
65
 
72
66
  ## Workspace
73
67
  Your workspace is at: ${this.workspace}
74
- - Long-term memory: ${Te.join(this.workspace,"memory","MEMORY.md")}
75
- - History log: ${Te.join(this.workspace,"memory","HISTORY.md")}
76
- - Custom skills: ${Te.join(this.workspace,"skills","{skill-name}","SKILL.md")}
68
+ - Long-term memory: ${Re.join(this.workspace,"memory","MEMORY.md")}
69
+ - History log: ${Re.join(this.workspace,"memory","HISTORY.md")}
70
+ - Custom skills: ${Re.join(this.workspace,"skills","{skill-name}","SKILL.md")}
77
71
 
78
72
  ## Guidelines
79
73
  - State intent before tool calls, but never claim results before receiving them.
80
74
  - Before modifying a file, read it first.
81
- - Ask for clarification when the request is ambiguous.`}loadBootstrapFiles(){let t=[];for(let e of s.BOOTSTRAP_FILES){let n=Te.join(this.workspace,e);Pt.existsSync(n)&&t.push(`## ${e}
75
+ - Ask for clarification when the request is ambiguous.`}loadBootstrapFiles(){let t=[];for(let e of s.BOOTSTRAP_FILES){let r=Re.join(this.workspace,e);Dt.existsSync(r)&&t.push(`## ${e}
82
76
 
83
- ${Pt.readFileSync(n,"utf8")}`)}return t.join(`
77
+ ${Dt.readFileSync(r,"utf8")}`)}return t.join(`
84
78
 
85
- `)}static buildRuntimeContext(t,e,n){let o=[`Current Time: ${new Date().toISOString()}`];return t&&e&&(o.push(`Channel: ${t}`),o.push(`Chat ID: ${e}`)),n?.chat_type&&o.push(`Chat Type: ${n.chat_type}`),n?.bot_mentioned&&o.push("Bot Mentioned: yes"),`${s.RUNTIME_CONTEXT_TAG}
79
+ `)}static buildRuntimeContext(t,e,r){let o=[`Current Time: ${new Date().toISOString()}`];return t&&e&&(o.push(`Channel: ${t}`),o.push(`Chat ID: ${e}`)),r?.chat_type&&o.push(`Chat Type: ${r.chat_type}`),r?.bot_mentioned&&o.push("Bot Mentioned: yes"),`${s.RUNTIME_CONTEXT_TAG}
86
80
  ${o.join(`
87
- `)}`}buildMessages(t){return[{role:"system",content:this.buildSystemPrompt(t.skillNames,t.memoryNamespace)},...t.history,{role:"user",content:s.buildRuntimeContext(t.channel,t.chatId,t.metadata)},{role:"user",content:t.currentMessage}]}addToolResult(t,e,n,r){return t.push({role:"tool",tool_call_id:e,name:n,content:r}),t}addAssistantMessage(t,e,n,r){let o={role:"assistant",content:e};return n?.length&&(o.tool_calls=n),r!=null&&(o.reasoning_content=r),t.push(o),t}buildNotificationContext(t){let e=t.status==="completed"?"\u2713":"\u2717";if(t.kind==="cron_completed"||t.kind==="subagent_completed"||t.kind==="subagent_failed"){let n=[`[${e}] ${t.kind==="cron_completed"?"Cron Job":"Subagent"}: ${t.label}`,`Task: ${t.originalTask}`,`Status: ${t.status}`];t.result&&n.push(`Result: ${t.result}`),t.error&&n.push(`Error: ${t.error}`);let r=t.kind==="cron_completed"?"cron job":"subagent";return n.push("",`The ${r} has finished. Acknowledge this result briefly and continue with any follow-up work if needed.`),n.join(`
81
+ `)}`}buildMessages(t){return[{role:"system",content:this.buildSystemPrompt(t.skillNames,t.memoryNamespace)},...t.history,{role:"user",content:s.buildRuntimeContext(t.channel,t.chatId,t.metadata)},{role:"user",content:t.currentMessage}]}addToolResult(t,e,r,n){return t.push({role:"tool",tool_call_id:e,name:r,content:n}),t}addAssistantMessage(t,e,r,n){let o={role:"assistant",content:e};return r?.length&&(o.tool_calls=r),n!=null&&(o.reasoning_content=n),t.push(o),t}buildNotificationContext(t){let e=t.status==="completed"?"\u2713":"\u2717";if(t.kind==="cron_completed"||t.kind==="subagent_completed"||t.kind==="subagent_failed"){let r=[`[${e}] ${t.kind==="cron_completed"?"Cron Job":"Subagent"}: ${t.label}`,`Task: ${t.originalTask}`,`Status: ${t.status}`];t.result&&r.push(`Result: ${t.result}`),t.error&&r.push(`Error: ${t.error}`);let n=t.kind==="cron_completed"?"cron job":"subagent";return r.push("",`The ${n} has finished. Acknowledge this result briefly and continue with any follow-up work if needed.`),r.join(`
88
82
  `)}return`[${e}] Task: ${t.label}
89
- Status: ${t.status}`}};var Ae=class extends g{name="session.info";description="Returns information about the current session: message count, token estimate, last anchor name, and messages since last anchor.";parameters={type:"object",properties:{},required:[]};sessionManager=null;sessionKey="cli:direct";setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t){if(!this.sessionManager)return"Error: Session manager not available";let e=this.sessionManager.getOrCreate(this.sessionKey),n=e.getHistory(1e3),r=0;for(let l of n)r+=Ce.estimateMessageTokens(l);let o=e.getLastAnchor(),i=e.getMessagesSinceLastAnchor().length,a={messageCount:e.messages.length,tokenEstimate:r,lastAnchor:o?.name??null,messagesSinceAnchor:i};return JSON.stringify(a,null,2)}};var Ee=class extends g{name="session.anchor";description="Create a named anchor in the session. Messages before the anchor become eligible for summarization. Anchors survive consolidation.";parameters={type:"object",properties:{name:{type:"string",description:"The name of the anchor"},summary:{type:"string",description:"Optional summary describing what happened before this anchor"}},required:["name"]};sessionManager=null;sessionKey="cli:direct";setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t){if(!this.sessionManager)return"Error: Session manager not available";let e=String(t.name??"");if(!e)return"Error: Anchor name is required";let n=t.summary!=null?String(t.summary):void 0,o=this.sessionManager.getOrCreate(this.sessionKey).anchor(e,n);return JSON.stringify({success:!0,anchor:{name:o.name,summary:o.summary,timestamp:o.timestamp}},null,2)}};import{readFileSync as Sr,existsSync as wr}from"node:fs";import{join as h}from"node:path";import kr from"node:http";import{homedir as xr}from"node:os";import Tr from"node:net";import $t from"ws";var Cr={existsSync:wr,readFileSync:Sr},Ot=Cr;var Ar=kr,It=Ar;var Er=1;var Rr="/tmp/chrome-debug-profile";function Mr(s){let t=s??process.platform,e=xr(),n=h(Rr,"DevToolsActivePort");switch(t){case"darwin":return[n,h(e,"Library/Application Support/Google/Chrome/DevToolsActivePort"),h(e,"Library/Application Support/Chromium/DevToolsActivePort"),h(e,"Library/Application Support/BraveSoftware/Brave-Browser/DevToolsActivePort"),h(e,"Library/Application Support/Microsoft Edge/DevToolsActivePort"),h(e,"Library/Application Support/Vivaldi/DevToolsActivePort")];case"linux":{let r=process.env.XDG_CONFIG_HOME||h(e,".config");return[n,h(r,"google-chrome","DevToolsActivePort"),h(r,"chromium","DevToolsActivePort"),h(r,"BraveSoftware","Brave-Browser","DevToolsActivePort"),h(r,"microsoft-edge","DevToolsActivePort"),h(r,"vivaldi","DevToolsActivePort"),h(e,".config","google-chrome","DevToolsActivePort"),h(e,".config","chromium","DevToolsActivePort"),h(e,"snap","chromium","common","chromium","DevToolsActivePort"),h(e,".var","app","com.google.Chrome","config","google-chrome","DevToolsActivePort"),h(e,".var","app","org.chromium.Chromium","config","chromium","DevToolsActivePort")]}case"win32":{let r=process.env.LOCALAPPDATA||h(e,"AppData","Local");return[n,h(r,"Google","Chrome","User Data","DevToolsActivePort"),h(r,"Chromium","User Data","DevToolsActivePort"),h(r,"BraveSoftware","Brave-Browser","User Data","DevToolsActivePort"),h(r,"Microsoft","Edge","User Data","DevToolsActivePort"),h(r,"Vivaldi","User Data","DevToolsActivePort")]}default:return[]}}function Me(s){return _e(s)?.port}function _e(s){let t=Mr(s);for(let e of t)try{if(!Ot.existsSync(e))continue;let r=Ot.readFileSync(e,"utf-8").split(`
90
- `),o=r[0]?.trim(),i=r[1]?.trim()||void 0;if(o){let a=parseInt(o,10);if(a>0&&a<=65535)return{port:a,browserWsPath:i}}}catch{}}function _r(s=9222){return new Promise(t=>{let e=`http://127.0.0.1:${s}/json/version`,n=It.get(e,{timeout:5e3},r=>{if(r.statusCode!==200){r.resume(),t(void 0);return}let o=[];r.on("data",i=>o.push(i)),r.on("end",()=>{try{let i=Buffer.concat(o).toString("utf-8"),a=JSON.parse(i);t(a)}catch{t(void 0)}}),r.on("error",()=>t(void 0))});n.on("timeout",()=>{n.destroy(),t(void 0)}),n.on("error",()=>t(void 0))})}function Pr(s,t="127.0.0.1"){return new Promise(e=>{let n=new Tr.Socket;n.setTimeout(2e3),n.once("connect",()=>{n.destroy(),e(!0)}),n.once("timeout",()=>{n.destroy(),e(!1)}),n.once("error",()=>{e(!1)}),n.connect(s,t)})}function Lr(s){return new Promise(t=>{try{let e=new $t(s),n=setTimeout(()=>{e.close(),t(!1)},3e3);e.on("open",()=>{clearTimeout(n),e.close(),t(!0)}),e.on("error",()=>{clearTimeout(n),t(!1)})}catch{t(!1)}})}async function Nt(s=9222){let t=_e(),e=t?.port??s;if(await Pr(e)){for(let r=0;r<2;r++){try{let o=await _r(e);if(o)return{port:e,versionInfo:o}}catch{}r<1&&await new Promise(o=>setTimeout(o,500))}if(t?.browserWsPath){let r=`ws://127.0.0.1:${e}${t.browserWsPath}`;if(await Lr(r))return{port:e,versionInfo:{Browser:"Chrome","Protocol-Version":"1.3","User-Agent":"","V8-Version":"","WebKit-Version":"",webSocketDebuggerUrl:r}}}return new Promise(r=>{let o=It.get(`http://127.0.0.1:${e}/json/version`,{timeout:3e3},i=>{i.resume(),i.statusCode===404||i.statusCode===403?r({port:e,versionInfo:{},pendingApproval:!0}):r(void 0)});o.on("error",()=>r(void 0)),o.on("timeout",()=>{o.destroy(),r(void 0)})})}}async function Y(s){let e=_e()?.browserWsPath;if(!e)return[];let n=await Re.connect(`ws://127.0.0.1:${s}${e}`);try{return((await n.send("Target.getTargets")).targetInfos??[]).map(i=>({id:i.targetId,type:i.type,title:i.title,url:i.url,webSocketDebuggerUrl:i.webSocketDebuggerUrl??`ws://127.0.0.1:${s}/devtools/page/${i.targetId}`}))}finally{n.close()}}async function Dt(s,t){let n=_e()?.browserWsPath;if(!n)throw new Error("No browser WebSocket path found in DevToolsActivePort");let r=await Re.connect(`ws://127.0.0.1:${s}${n}`);try{let i=(await r.send("Target.createTarget",{url:t})).targetId;if(!i)throw new Error("Target.createTarget returned no targetId");return{id:i,type:"page",title:"",url:t,webSocketDebuggerUrl:`ws://127.0.0.1:${s}/devtools/page/${i}`}}finally{r.close()}}var Re=class s{ws;nextId=1;pending=new Map;eventListeners=new Map;closed=!1;constructor(t){this.ws=t}static connect(t){return new Promise((e,n)=>{let r=new $t(t);r.on("open",()=>{let o=new s(r);s.attachHandlers(o,r),e(o)}),r.on("error",(...o)=>{let i=o[0];n(new Error(`Failed to connect to CDP: ${i.message}`))})})}static fromWebSocket(t){let e=new s(t);return s.attachHandlers(e,t),e}static attachHandlers(t,e){e.on("message",n=>{let r=typeof n=="string"?n:Buffer.from(n).toString("utf-8");t.handleMessage(r)}),e.on("close",()=>{t.closed=!0;for(let[,n]of t.pending)n.reject(new Error("WebSocket closed"));t.pending.clear()}),e.on("error",(...n)=>{let r=n[0];for(let[,o]of t.pending)o.reject(r);t.pending.clear()})}async send(t,e){if(this.closed||this.ws.readyState!==Er)throw new Error("WebSocket is closed");let n=this.nextId++,r=JSON.stringify({id:n,method:t,params:e??{}});return new Promise((o,i)=>{this.pending.set(n,{resolve:o,reject:i}),this.ws.send(r)})}onEvent(t,e){return this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e),()=>{this.eventListeners.get(t)?.delete(e)}}waitForEvent(t,e=1e4){return new Promise((n,r)=>{let o=setTimeout(()=>{i(),r(new Error(`Timeout waiting for event '${t}' after ${e}ms`))},e),i=this.onEvent(t,a=>{clearTimeout(o),i(),n(a)})})}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}handleMessage(t){let e;try{e=JSON.parse(t)}catch{return}if("id"in e&&typeof e.id=="number"){let n=e,r=this.pending.get(n.id);r&&(this.pending.delete(n.id),n.error?r.reject(new Error(`CDP error ${n.error.code}: ${n.error.message}`)):r.resolve(n.result??{}));return}if("method"in e&&typeof e.method=="string"){let n=e,r=this.eventListeners.get(n.method);if(r)for(let o of r)try{o(n.params??{})}catch{}}}};import{spawn as Or}from"node:child_process";import{createConnection as $r}from"node:net";import{tmpdir as Ir}from"node:os";import{join as Bt,dirname as Nr}from"node:path";import{unlink as Dr,unlinkSync as jr,mkdirSync as Br,existsSync as Pe}from"node:fs";import N from"node:fs";function Xe(s){let t="electron"in process.versions,e=s;try{e=N.realpathSync(s)}catch{}let n,r;if(e.endsWith(".js")){if(!N.existsSync(e))throw new Error(`No executable found: ${e} does not exist.`);n=e,r=!1}else if(e.endsWith(".ts")){if(!N.existsSync(e))throw new Error(`No executable found: ${e} does not exist.`);n=e,r=!0}else{let a=e+".js",l=e+".ts";if(N.existsSync(a)){try{n=N.realpathSync(a)}catch{n=a}r=!1}else if(N.existsSync(l)){try{n=N.realpathSync(l)}catch{n=l}r=!0}else throw new Error(`No executable found: neither ${a} nor ${l} exists.`)}let o=process.execPath,i=r?["--import","tsx",n]:[n];return t?{file:o,args:i,env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}}:{file:o,args:i,env:process.env}}var Fr=null,Jr=null,Ur=null,qr=!1;function Z(){return Jr??process.platform}function Wr(){return Fr??Or}function Gr(){return Ur??$r}function Kr(s,t){let e=Z(),n=t??Ir(),r=s.replace(/[^a-zA-Z0-9]/g,"_").slice(0,32);return e==="win32"?`\\\\.\\pipe\\airclaw-daemon-${r}`:Bt(n,`airclaw-daemon-${r}.sock`)}function jt(s,t){let e=s.split(`
91
- `),n=e.pop()??"";for(let r of e){let o=r.trim();if(o)try{let i=JSON.parse(o);t(i)}catch{}}return n}var Le=class s{static instance=null;daemons=new Map;constructor(){}static getInstance(){return s.instance||(s.instance=new s),s.instance}async getOrCreateDaemon(t,e,n){if(this.daemons.has(t))return;let r=Kr(t,n?.socketDir),o=n?.idleTimeoutMs??12e5;if(Z()==="win32"||Pe(r)){let f={targetId:t,child:null,socketPath:r,clientSocket:null,commandId:1,pendingCommands:new Map,ndjsonBuffer:""};this.daemons.set(t,f);try{await this.connectToDaemon(t);return}catch{if(this.daemons.delete(t),Z()!=="win32"&&Pe(r))try{jr(r)}catch{}}}let i=Nr(r);if(!Pe(i)&&Z()!=="win32")try{Br(i,{recursive:!0})}catch{}let a={targetId:t,child:null,socketPath:r,clientSocket:null,commandId:1,pendingCommands:new Map,ndjsonBuffer:""};if(this.daemons.set(t,a),qr)return;let l=Bt(import.meta.dirname,"daemon-worker"),{file:c,args:u,env:d}=Xe(l),m=Wr()(c,[...u,"--target",t,"--ws-url",e,"--socket",r,"--idle-timeout",String(o)],{stdio:["ignore","pipe","pipe"],detached:!1,env:d});a.child=m,m.on("exit",()=>{this.cleanupDaemon(t)}),m.on("error",()=>{this.cleanupDaemon(t)}),await new Promise((f,y)=>{let b=setTimeout(()=>{y(new Error("Daemon startup timeout"))},1e4),A=k=>{k.toString("utf8").includes("READY")&&(clearTimeout(b),m.stdout?.off("data",A),f())};m.stdout?.on("data",A)}),await this.connectToDaemon(t)}async connectToDaemon(t){let e=this.daemons.get(t);if(!e)throw new Error(`No daemon for target ${t}`);return new Promise((n,r)=>{let o=Gr()(e.socketPath);o.on("connect",()=>{e.clientSocket=o,o.on("data",i=>{e.ndjsonBuffer=jt(e.ndjsonBuffer+i.toString("utf8"),a=>{let l=e.pendingCommands.get(a.id);l&&(e.pendingCommands.delete(a.id),l.resolve(a))})}),o.on("close",()=>{e.clientSocket=null;for(let[,i]of e.pendingCommands)i.reject(new Error("Daemon socket closed"));e.pendingCommands.clear()}),o.on("error",()=>{}),n()}),o.on("error",i=>{r(new Error(`Failed to connect to daemon: ${i.message}`))}),setTimeout(()=>{e.clientSocket||(o.destroy(),r(new Error("Daemon connection timeout")))},5e3)})}async sendCommand(t,e,n={}){let r=this.daemons.get(t);if(!r)throw new Error(`No daemon for target ${t}`);if(!r.clientSocket)throw new Error(`Daemon socket not connected for ${t}`);let o=r.commandId++,a=JSON.stringify({id:o,cmd:e,args:n})+`
92
- `;return new Promise((l,c)=>{r.pendingCommands.set(o,{resolve:l,reject:c});try{r.clientSocket.write(a)}catch(u){r.pendingCommands.delete(o),c(u)}setTimeout(()=>{r.pendingCommands.has(o)&&(r.pendingCommands.delete(o),c(new Error(`Command ${o} timed out`)))},3e4)})}hasDaemon(t){return this.daemons.has(t)}getSocketPath(t){return this.daemons.get(t)?.socketPath}stopDaemon(t){let e=this.daemons.get(t);e&&(e.clientSocket&&e.clientSocket.destroy(),e.child&&e.child.kill("SIGTERM"),this.cleanupDaemon(t))}stopAll(){for(let t of this.daemons.keys())this.stopDaemon(t)}getActiveTargets(){return Array.from(this.daemons.keys())}__setClientSocket(t,e){let n=this.daemons.get(t);n&&(n.clientSocket=e,e&&(e.on("data",r=>{n.ndjsonBuffer=jt(n.ndjsonBuffer+r.toString("utf8"),o=>{let i=n.pendingCommands.get(o.id);i&&(n.pendingCommands.delete(o.id),i.resolve(o))})}),e.on("close",()=>{n.clientSocket=null;for(let[,r]of n.pendingCommands)r.reject(new Error("Daemon socket closed"));n.pendingCommands.clear()})))}cleanupDaemon(t){let e=this.daemons.get(t);if(e){e.clientSocket&&e.clientSocket.destroy(),e.child&&e.child.kill("SIGTERM");for(let[,n]of e.pendingCommands)n.reject(new Error("Daemon stopped"));Z()!=="win32"&&Pe(e.socketPath)&&Dr(e.socketPath,()=>{}),this.daemons.delete(t)}}};import{writeFileSync as Hr,mkdirSync as Vr,existsSync as zr}from"node:fs";import{dirname as Xr,join as Oe}from"node:path";import{tmpdir as Yr}from"node:os";var Ye={minChromeVersion:136,daemonIdleTimeoutS:1200,targetPrefixLength:8},Q=class extends g{name="chrome_session";description=`Interact with Chrome browser via Chrome DevTools Protocol (CDP).
83
+ Status: ${t.status}`}};var _e=class extends g{name="session.info";description="Returns information about the current session: message count, token estimate, last anchor name, and messages since last anchor.";parameters={type:"object",properties:{},required:[]};sessionManager=null;sessionKey="cli:direct";setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t){if(!this.sessionManager)return"Error: Session manager not available";let e=this.sessionManager.getOrCreate(this.sessionKey),r=e.getHistory(1e3),n=0;for(let l of r)n+=Me.estimateMessageTokens(l);let o=e.getLastAnchor(),i=e.getMessagesSinceLastAnchor().length,a={messageCount:e.messages.length,tokenEstimate:n,lastAnchor:o?.name??null,messagesSinceAnchor:i};return JSON.stringify(a,null,2)}};var Pe=class extends g{name="session.anchor";description="Create a named anchor in the session. Messages before the anchor become eligible for summarization. Anchors survive consolidation.";parameters={type:"object",properties:{name:{type:"string",description:"The name of the anchor"},summary:{type:"string",description:"Optional summary describing what happened before this anchor"}},required:["name"]};sessionManager=null;sessionKey="cli:direct";setSessionManager(t){this.sessionManager=t}setContext(t){this.sessionKey=t}async execute(t){if(!this.sessionManager)return"Error: Session manager not available";let e=String(t.name??"");if(!e)return"Error: Anchor name is required";let r=t.summary!=null?String(t.summary):void 0,o=this.sessionManager.getOrCreate(this.sessionKey).anchor(e,r);return JSON.stringify({success:!0,anchor:{name:o.name,summary:o.summary,timestamp:o.timestamp}},null,2)}};import{readFileSync as _r,existsSync as Pr}from"node:fs";import{join as y}from"node:path";import Lr from"node:http";import{homedir as Or}from"node:os";import $r from"node:net";import Ft from"ws";var Ir={existsSync:Pr,readFileSync:_r},Bt=Ir;var Nr=Lr,Ut=Nr;var Dr=1;var jr="/tmp/chrome-debug-profile";function Br(s){let t=s??process.platform,e=Or(),r=y(jr,"DevToolsActivePort");switch(t){case"darwin":return[r,y(e,"Library/Application Support/Google/Chrome/DevToolsActivePort"),y(e,"Library/Application Support/Chromium/DevToolsActivePort"),y(e,"Library/Application Support/BraveSoftware/Brave-Browser/DevToolsActivePort"),y(e,"Library/Application Support/Microsoft Edge/DevToolsActivePort"),y(e,"Library/Application Support/Vivaldi/DevToolsActivePort")];case"linux":{let n=process.env.XDG_CONFIG_HOME||y(e,".config");return[r,y(n,"google-chrome","DevToolsActivePort"),y(n,"chromium","DevToolsActivePort"),y(n,"BraveSoftware","Brave-Browser","DevToolsActivePort"),y(n,"microsoft-edge","DevToolsActivePort"),y(n,"vivaldi","DevToolsActivePort"),y(e,".config","google-chrome","DevToolsActivePort"),y(e,".config","chromium","DevToolsActivePort"),y(e,"snap","chromium","common","chromium","DevToolsActivePort"),y(e,".var","app","com.google.Chrome","config","google-chrome","DevToolsActivePort"),y(e,".var","app","org.chromium.Chromium","config","chromium","DevToolsActivePort")]}case"win32":{let n=process.env.LOCALAPPDATA||y(e,"AppData","Local");return[r,y(n,"Google","Chrome","User Data","DevToolsActivePort"),y(n,"Chromium","User Data","DevToolsActivePort"),y(n,"BraveSoftware","Brave-Browser","User Data","DevToolsActivePort"),y(n,"Microsoft","Edge","User Data","DevToolsActivePort"),y(n,"Vivaldi","User Data","DevToolsActivePort")]}default:return[]}}function Oe(s){return $e(s)?.port}function $e(s){let t=Br(s);for(let e of t)try{if(!Bt.existsSync(e))continue;let n=Bt.readFileSync(e,"utf-8").split(`
84
+ `),o=n[0]?.trim(),i=n[1]?.trim()||void 0;if(o){let a=parseInt(o,10);if(a>0&&a<=65535)return{port:a,browserWsPath:i}}}catch{}}function Fr(s=9222){return new Promise(t=>{let e=`http://127.0.0.1:${s}/json/version`,r=Ut.get(e,{timeout:5e3},n=>{if(n.statusCode!==200){n.resume(),t(void 0);return}let o=[];n.on("data",i=>o.push(i)),n.on("end",()=>{try{let i=Buffer.concat(o).toString("utf-8"),a=JSON.parse(i);t(a)}catch{t(void 0)}}),n.on("error",()=>t(void 0))});r.on("timeout",()=>{r.destroy(),t(void 0)}),r.on("error",()=>t(void 0))})}function Ur(s,t="127.0.0.1"){return new Promise(e=>{let r=new $r.Socket;r.setTimeout(2e3),r.once("connect",()=>{r.destroy(),e(!0)}),r.once("timeout",()=>{r.destroy(),e(!1)}),r.once("error",()=>{e(!1)}),r.connect(s,t)})}function Jr(s){return new Promise(t=>{try{let e=new Ft(s),r=setTimeout(()=>{e.close(),t(!1)},3e3);e.on("open",()=>{clearTimeout(r),e.close(),t(!0)}),e.on("error",()=>{clearTimeout(r),t(!1)})}catch{t(!1)}})}async function Jt(s=9222){let t=$e(),e=t?.port??s;if(await Ur(e)){for(let n=0;n<2;n++){try{let o=await Fr(e);if(o)return{port:e,versionInfo:o}}catch{}n<1&&await new Promise(o=>setTimeout(o,500))}if(t?.browserWsPath){let n=`ws://127.0.0.1:${e}${t.browserWsPath}`;if(await Jr(n))return{port:e,versionInfo:{Browser:"Chrome","Protocol-Version":"1.3","User-Agent":"","V8-Version":"","WebKit-Version":"",webSocketDebuggerUrl:n}}}return new Promise(n=>{let o=Ut.get(`http://127.0.0.1:${e}/json/version`,{timeout:3e3},i=>{i.resume(),i.statusCode===404||i.statusCode===403?n({port:e,versionInfo:{},pendingApproval:!0}):n(void 0)});o.on("error",()=>n(void 0)),o.on("timeout",()=>{o.destroy(),n(void 0)})})}}async function ee(s){let e=$e()?.browserWsPath;if(!e)return[];let r=await Le.connect(`ws://127.0.0.1:${s}${e}`);try{return((await r.send("Target.getTargets")).targetInfos??[]).map(i=>({id:i.targetId,type:i.type,title:i.title,url:i.url,webSocketDebuggerUrl:i.webSocketDebuggerUrl??`ws://127.0.0.1:${s}/devtools/page/${i.targetId}`}))}finally{r.close()}}async function qt(s,t){let r=$e()?.browserWsPath;if(!r)throw new Error("No browser WebSocket path found in DevToolsActivePort");let n=await Le.connect(`ws://127.0.0.1:${s}${r}`);try{let i=(await n.send("Target.createTarget",{url:t})).targetId;if(!i)throw new Error("Target.createTarget returned no targetId");return{id:i,type:"page",title:"",url:t,webSocketDebuggerUrl:`ws://127.0.0.1:${s}/devtools/page/${i}`}}finally{n.close()}}var Le=class s{ws;nextId=1;pending=new Map;eventListeners=new Map;closed=!1;constructor(t){this.ws=t}static connect(t){return new Promise((e,r)=>{let n=new Ft(t);n.on("open",()=>{let o=new s(n);s.attachHandlers(o,n),e(o)}),n.on("error",(...o)=>{let i=o[0];r(new Error(`Failed to connect to CDP: ${i.message}`))})})}static fromWebSocket(t){let e=new s(t);return s.attachHandlers(e,t),e}static attachHandlers(t,e){e.on("message",r=>{let n=typeof r=="string"?r:Buffer.from(r).toString("utf-8");t.handleMessage(n)}),e.on("close",()=>{t.closed=!0;for(let[,r]of t.pending)r.reject(new Error("WebSocket closed"));t.pending.clear()}),e.on("error",(...r)=>{let n=r[0];for(let[,o]of t.pending)o.reject(n);t.pending.clear()})}async send(t,e){if(this.closed||this.ws.readyState!==Dr)throw new Error("WebSocket is closed");let r=this.nextId++,n=JSON.stringify({id:r,method:t,params:e??{}});return new Promise((o,i)=>{this.pending.set(r,{resolve:o,reject:i}),this.ws.send(n)})}onEvent(t,e){return this.eventListeners.has(t)||this.eventListeners.set(t,new Set),this.eventListeners.get(t).add(e),()=>{this.eventListeners.get(t)?.delete(e)}}waitForEvent(t,e=1e4){return new Promise((r,n)=>{let o=setTimeout(()=>{i(),n(new Error(`Timeout waiting for event '${t}' after ${e}ms`))},e),i=this.onEvent(t,a=>{clearTimeout(o),i(),r(a)})})}close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}}}handleMessage(t){let e;try{e=JSON.parse(t)}catch{return}if("id"in e&&typeof e.id=="number"){let r=e,n=this.pending.get(r.id);n&&(this.pending.delete(r.id),r.error?n.reject(new Error(`CDP error ${r.error.code}: ${r.error.message}`)):n.resolve(r.result??{}));return}if("method"in e&&typeof e.method=="string"){let r=e,n=this.eventListeners.get(r.method);if(n)for(let o of n)try{o(r.params??{})}catch{}}}};import{spawn as qr}from"node:child_process";import{createConnection as Wr}from"node:net";import{tmpdir as Gr}from"node:os";import{join as Gt,dirname as Kr}from"node:path";import{unlink as Hr,unlinkSync as Vr,mkdirSync as zr,existsSync as Ie}from"node:fs";import j from"node:fs";function et(s){let t="electron"in process.versions,e=s;try{e=j.realpathSync(s)}catch{}let r,n;if(e.endsWith(".js")){if(!j.existsSync(e))throw new Error(`No executable found: ${e} does not exist.`);r=e,n=!1}else if(e.endsWith(".ts")){if(!j.existsSync(e))throw new Error(`No executable found: ${e} does not exist.`);r=e,n=!0}else{let a=e+".js",l=e+".ts";if(j.existsSync(a)){try{r=j.realpathSync(a)}catch{r=a}n=!1}else if(j.existsSync(l)){try{r=j.realpathSync(l)}catch{r=l}n=!0}else throw new Error(`No executable found: neither ${a} nor ${l} exists.`)}let o=process.execPath,i=n?["--import","tsx",r]:[r];return t?{file:o,args:i,env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}}:{file:o,args:i,env:process.env}}var Xr=null,Yr=null,Zr=null,Qr=!1;function te(){return Yr??process.platform}function en(){return Xr??qr}function tn(){return Zr??Wr}function rn(s,t){let e=te(),r=t??Gr(),n=s.replace(/[^a-zA-Z0-9]/g,"_").slice(0,32);return e==="win32"?`\\\\.\\pipe\\airclaw-daemon-${n}`:Gt(r,`airclaw-daemon-${n}.sock`)}function Wt(s,t){let e=s.split(`
85
+ `),r=e.pop()??"";for(let n of e){let o=n.trim();if(o)try{let i=JSON.parse(o);t(i)}catch{}}return r}var Ne=class s{static instance=null;daemons=new Map;constructor(){}static getInstance(){return s.instance||(s.instance=new s),s.instance}async getOrCreateDaemon(t,e,r){if(this.daemons.has(t))return;let n=rn(t,r?.socketDir),o=r?.idleTimeoutMs??12e5;if(te()==="win32"||Ie(n)){let p={targetId:t,child:null,socketPath:n,clientSocket:null,commandId:1,pendingCommands:new Map,ndjsonBuffer:""};this.daemons.set(t,p);try{await this.connectToDaemon(t);return}catch{if(this.daemons.delete(t),te()!=="win32"&&Ie(n))try{Vr(n)}catch{}}}let i=Kr(n);if(!Ie(i)&&te()!=="win32")try{zr(i,{recursive:!0})}catch{}let a={targetId:t,child:null,socketPath:n,clientSocket:null,commandId:1,pendingCommands:new Map,ndjsonBuffer:""};if(this.daemons.set(t,a),Qr)return;let l=Gt(import.meta.dirname,"daemon-worker"),{file:c,args:u,env:d}=et(l),m=en()(c,[...u,"--target",t,"--ws-url",e,"--socket",n,"--idle-timeout",String(o)],{stdio:["ignore","pipe","pipe"],detached:!1,env:d});a.child=m,m.on("exit",()=>{this.cleanupDaemon(t)}),m.on("error",()=>{this.cleanupDaemon(t)}),await new Promise((p,f)=>{let b=setTimeout(()=>{f(new Error("Daemon startup timeout"))},1e4),C=k=>{k.toString("utf8").includes("READY")&&(clearTimeout(b),m.stdout?.off("data",C),p())};m.stdout?.on("data",C)}),await this.connectToDaemon(t)}async connectToDaemon(t){let e=this.daemons.get(t);if(!e)throw new Error(`No daemon for target ${t}`);return new Promise((r,n)=>{let o=tn()(e.socketPath);o.on("connect",()=>{e.clientSocket=o,o.on("data",i=>{e.ndjsonBuffer=Wt(e.ndjsonBuffer+i.toString("utf8"),a=>{let l=e.pendingCommands.get(a.id);l&&(e.pendingCommands.delete(a.id),l.resolve(a))})}),o.on("close",()=>{e.clientSocket=null;for(let[,i]of e.pendingCommands)i.reject(new Error("Daemon socket closed"));e.pendingCommands.clear()}),o.on("error",()=>{}),r()}),o.on("error",i=>{n(new Error(`Failed to connect to daemon: ${i.message}`))}),setTimeout(()=>{e.clientSocket||(o.destroy(),n(new Error("Daemon connection timeout")))},5e3)})}async sendCommand(t,e,r={}){let n=this.daemons.get(t);if(!n)throw new Error(`No daemon for target ${t}`);if(!n.clientSocket)throw new Error(`Daemon socket not connected for ${t}`);let o=n.commandId++,a=JSON.stringify({id:o,cmd:e,args:r})+`
86
+ `;return new Promise((l,c)=>{n.pendingCommands.set(o,{resolve:l,reject:c});try{n.clientSocket.write(a)}catch(u){n.pendingCommands.delete(o),c(u)}setTimeout(()=>{n.pendingCommands.has(o)&&(n.pendingCommands.delete(o),c(new Error(`Command ${o} timed out`)))},3e4)})}hasDaemon(t){return this.daemons.has(t)}getSocketPath(t){return this.daemons.get(t)?.socketPath}stopDaemon(t){let e=this.daemons.get(t);e&&(e.clientSocket&&e.clientSocket.destroy(),e.child&&e.child.kill("SIGTERM"),this.cleanupDaemon(t))}stopAll(){for(let t of this.daemons.keys())this.stopDaemon(t)}getActiveTargets(){return Array.from(this.daemons.keys())}__setClientSocket(t,e){let r=this.daemons.get(t);r&&(r.clientSocket=e,e&&(e.on("data",n=>{r.ndjsonBuffer=Wt(r.ndjsonBuffer+n.toString("utf8"),o=>{let i=r.pendingCommands.get(o.id);i&&(r.pendingCommands.delete(o.id),i.resolve(o))})}),e.on("close",()=>{r.clientSocket=null;for(let[,n]of r.pendingCommands)n.reject(new Error("Daemon socket closed"));r.pendingCommands.clear()})))}cleanupDaemon(t){let e=this.daemons.get(t);if(e){e.clientSocket&&e.clientSocket.destroy(),e.child&&e.child.kill("SIGTERM");for(let[,r]of e.pendingCommands)r.reject(new Error("Daemon stopped"));te()!=="win32"&&Ie(e.socketPath)&&Hr(e.socketPath,()=>{}),this.daemons.delete(t)}}};import{writeFileSync as nn,mkdirSync as on,existsSync as sn}from"node:fs";import{dirname as an,join as De}from"node:path";import{tmpdir as ln}from"node:os";var tt={minChromeVersion:136,daemonIdleTimeoutS:1200,targetPrefixLength:8},re=class extends g{name="chrome_session";description=`Interact with Chrome browser via Chrome DevTools Protocol (CDP).
93
87
 
94
88
  Core Commands:
95
89
  - status: Check Chrome connectivity, version, and remote debugging status
@@ -124,7 +118,7 @@ Examples:
124
118
  - chrome_session clickxy --target "ABC123" --x 100 --y 200
125
119
  - chrome_session type --target "ABC123" --text "Hello World"
126
120
  - chrome_session loadall --target "ABC123" --selector "button.load-more" --interval 500
127
- - chrome_session evalraw --target "ABC123" --method "Page.getTitle" --params '{}'`;parameters={type:"object",properties:{command:{type:"string",description:"The command to execute",enum:["status","list","open","stop","snap","shot","eval","html","nav","net","click","clickxy","type","loadall","evalraw"]},target:{type:"string",description:"Target ID prefix (required for page interaction commands)"},url:{type:"string",description:"URL to open (for 'open' and 'nav' commands)"},path:{type:"string",description:"File path to save screenshot (for 'shot' command)"},selector:{type:"string",description:"CSS selector for element-specific operations (for 'shot', 'html', 'click', 'loadall' commands)"},expression:{type:"string",description:"JavaScript expression to evaluate (for 'eval' command)"},depth:{type:"number",description:"Maximum depth for accessibility tree (for 'snap' command)"},timeout:{type:"number",description:"Timeout in milliseconds (for 'nav' command)"},outer:{type:"boolean",description:"Return outer HTML (default true, for 'html' command)"},x:{type:"number",description:"X coordinate in CSS pixels (for 'clickxy' command)"},y:{type:"number",description:"Y coordinate in CSS pixels (for 'clickxy' command)"},text:{type:"string",description:"Text to type at focused element (for 'type' command)"},interval:{type:"number",description:"Interval in milliseconds between clicks (for 'loadall' command, default 500)"},method:{type:"string",description:"CDP method name (for 'evalraw' command)"},params:{type:"object",description:"CDP method parameters as JSON object (for 'evalraw' command)"}},required:["command"]};config;daemonManager;commands;workspace;restrictToWorkspace;constructor(t={},e,n=!1){super(),this.config={minChromeVersion:t.minChromeVersion??Ye.minChromeVersion,daemonIdleTimeoutS:t.daemonIdleTimeoutS??Ye.daemonIdleTimeoutS,targetPrefixLength:t.targetPrefixLength??Ye.targetPrefixLength,...t.stealth?{stealth:t.stealth}:{}},this.workspace=e,this.restrictToWorkspace=n,this.daemonManager=Le.getInstance(),this.commands=new Map([["status",this.handleStatus.bind(this)],["list",this.handleList.bind(this)],["open",this.handleOpen.bind(this)],["stop",this.handleStop.bind(this)],["snap",this.handleSnap.bind(this)],["shot",this.handleShot.bind(this)],["eval",this.handleEval.bind(this)],["html",this.handleHtml.bind(this)],["nav",this.handleNav.bind(this)],["net",this.handleNet.bind(this)],["click",this.handleClick.bind(this)],["clickxy",this.handleClickxy.bind(this)],["type",this.handleType.bind(this)],["loadall",this.handleLoadall.bind(this)],["evalraw",this.handleEvalraw.bind(this)]])}async execute(t,e){let n=t.command;if(!n)return this.formatError("Missing required 'command' parameter. Available commands: status, list, open, stop, snap, shot, eval, html, nav, net, click, clickxy, type, loadall, evalraw");let r=this.commands.get(n);if(!r)return this.formatError(`Unknown command '${n}'. Available commands: status, list, open, stop, snap, shot, eval, html, nav, net, click, clickxy, type, loadall, evalraw`);try{return await r(t,e)}catch(o){let i=o instanceof Error?o.message:String(o);return this.formatError(`Command '${n}' failed: ${i}`)}}async handleStatus(){let t=this.config,e=await Nt();if(!e)return this.formatResult({available:!1,reason:"Chrome remote debugging not detected",hint:"Enable remote debugging in Chrome at chrome://inspect/#remote-debugging or launch Chrome with --remote-debugging-port=9222"});if(e.pendingApproval)return this.formatResult({available:!1,pendingApproval:!0,reason:`Chrome is listening on port ${e.port} but remote debugging approval may be required`,hint:"Look for a remote debugging approval prompt in Chrome, or quit Chrome and relaunch with: open -a 'Google Chrome' --args --remote-debugging-port=9222",port:e.port});let{port:n,versionInfo:r}=e,o=r.Browser.match(/(\w+)\/(\d+)/),i=o?.[1]??"Chrome",a=o?parseInt(o[2],10):0;return a>0&&a<t.minChromeVersion?this.formatResult({available:!1,reason:`Chrome version ${a} is below minimum required version ${t.minChromeVersion}`,hint:`Update Chrome to version ${t.minChromeVersion} or higher`,version:r.Browser,port:n,browser:i}):this.formatResult({available:!0,version:r.Browser,protocolVersion:r["Protocol-Version"],userAgent:r["User-Agent"],webSocketDebuggerUrl:r.webSocketDebuggerUrl,port:n,browser:i})}async handleList(){let t=Me();if(!t)return this.formatError("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let e;try{let i=await fetch(`http://127.0.0.1:${t}/json/list`);i.ok?e=await i.json():e=await Y(t)}catch{e=await Y(t)}let n=e.filter(i=>i.type==="page"&&!i.url.startsWith("chrome://"));if(n.length===0)return this.formatResult({tabs:[],message:"No open tabs found"});let r=this.config.targetPrefixLength,o=n.map(i=>({id:i.id.slice(0,r),fullId:i.id,title:i.title,url:i.url}));return this.formatResult({tabs:o,count:o.length})}async handleOpen(t){let e=Me();if(!e)return this.formatError("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let n=t.url??"about:blank",r=this.config.targetPrefixLength;try{let o=await fetch(`http://127.0.0.1:${e}/json/new?${n}`,{method:"PUT"});if(o.ok){let i=await o.json();return this.formatResult({success:!0,id:i.id.slice(0,r),fullId:i.id,url:i.url,message:`Opened new tab: ${i.url}`})}}catch{}try{let o=await Dt(e,n);return this.formatResult({success:!0,id:o.id.slice(0,r),fullId:o.id,url:o.url,message:`Opened new tab: ${o.url}`})}catch(o){return this.formatError(`Cannot open tab via HTTP or WebSocket on port ${e}: ${o instanceof Error?o.message:String(o)}. Run 'chrome_session status' for details.`)}}async handleStop(t){let e=t.target;if(e){let o=this.daemonManager.getActiveTargets().find(i=>i.toUpperCase().startsWith(e.toUpperCase()));return o?(this.daemonManager.stopDaemon(o),this.formatResult({success:!0,target:o.slice(0,this.config.targetPrefixLength),message:`Stopped daemon for target ${o.slice(0,this.config.targetPrefixLength)}`})):this.formatError(`No daemon found for target prefix '${e}'`)}let n=this.daemonManager.getActiveTargets().length;return n===0?this.formatResult({success:!0,message:"No active daemons to stop"}):(this.daemonManager.stopAll(),this.formatResult({success:!0,message:`Stopped ${n} daemon(s)`}))}async handleSnap(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r={};t.depth!==void 0&&(r.depth=t.depth);let o=await this.sendDaemonCommand(e,n,"snap",r);return o.ok?this.formatResult({tree:o.result?.tree,nodeCount:o.result?.nodeCount}):this.formatError(o.error??"Failed to get accessibility tree")}async handleShot(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.path,o=this.resolveScreenshotPath(r),i={};o&&(i.path=o),t.selector&&(i.selector=t.selector);let a=await this.sendDaemonCommand(e,n,"shot",i);return a.ok?(o&&a.result?.data&&this.saveScreenshot(o,a.result.data),this.formatResult({path:o,dpr:a.result?.dpr,viewport:a.result?.viewport,message:o?`Screenshot saved to ${o}`:"Screenshot captured (base64 data in 'data' field)",data:o?void 0:a.result?.data})):this.formatError(a.error??"Failed to capture screenshot")}async handleEval(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.expression;if(!r)return this.formatError("Missing required 'expression' parameter");let o=await this.sendDaemonCommand(e,n,"eval",{expression:r,awaitPromise:!0});return o.ok?this.formatResult({ok:!0,result:o.result?.result,type:o.result?.type,subtype:o.result?.subtype}):this.formatError(o.error??"JavaScript evaluation failed")}async handleHtml(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r={};t.selector&&(r.selector=t.selector),t.outer!==void 0&&(r.outer=t.outer);let o=await this.sendDaemonCommand(e,n,"html",r);return o.ok?this.formatResult({html:o.result?.html,selector:o.result?.selector}):this.formatError(o.error??"Failed to get HTML")}async handleNav(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.url;if(!r)return this.formatError("Missing required 'url' parameter");let o={url:r};t.timeout!==void 0&&(o.timeout=t.timeout);let i=await this.sendDaemonCommand(e,n,"nav",o);return i.ok?this.formatResult({ok:!0,url:i.result?.url,frameId:i.result?.frameId,loaderId:i.result?.loaderId,message:i.result?.message}):this.formatError(i.error??"Navigation failed")}async handleNet(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=await this.sendDaemonCommand(e,n,"net",{});return r.ok?this.formatResult({entries:r.result?.entries,count:r.result?.count}):this.formatError(r.error??"Failed to get network timing")}async handleClick(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.selector;if(!r)return this.formatError("Missing required 'selector' parameter");let o=await this.sendDaemonCommand(e,n,"click",{selector:r});return o.ok?this.formatResult({ok:!0,selector:r,tag:o.result?.tag,text:o.result?.text,message:o.result?.message}):this.formatError(o.error??"Click failed")}async handleClickxy(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.x,o=t.y;if(typeof r!="number"||typeof o!="number")return this.formatError("Missing required 'x' and 'y' parameters");let i=await this.sendDaemonCommand(e,n,"clickxy",{x:r,y:o});return i.ok?this.formatResult({ok:!0,x:r,y:o,message:`Clicked at (${r}, ${o})`}):this.formatError(i.error??"Click at coordinates failed")}async handleType(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.text;if(!r)return this.formatError("Missing required 'text' parameter");let o=await this.sendDaemonCommand(e,n,"type",{text:r});return o.ok?this.formatResult({ok:!0,text:r,message:`Typed ${r.length} character(s)`}):this.formatError(o.error??"Type failed")}async handleLoadall(t,e){let{targetId:n,wsUrl:r}=await this.resolveTarget(t.target),o=t.selector,i=t.interval??500;if(!o)return this.formatError("Missing required 'selector' parameter");let a=await this.sendDaemonCommand(n,r,"loadall",{selector:o,interval:i,timeout:3e5});return a.ok?this.formatResult({ok:!0,selector:o,clickCount:a.result?.clickCount,timedOut:a.result?.timedOut,message:a.result?.message}):this.formatError(a.error??"Loadall failed")}async handleEvalraw(t){let{targetId:e,wsUrl:n}=await this.resolveTarget(t.target),r=t.method,o=t.params??{};if(!r)return this.formatError("Missing required 'method' parameter");let i=await this.sendDaemonCommand(e,n,"evalraw",{method:r,params:o});return i.ok?this.formatResult({ok:!0,method:r,result:i.result?.result}):this.formatError(i.error??"Raw CDP command failed")}async resolveTarget(t){if(!t)throw new Error("Missing required 'target' parameter. Use 'chrome_session list' to see available targets.");let e=Me();if(!e)throw new Error("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let n;try{let l=await fetch(`http://127.0.0.1:${e}/json/list`);l.ok?n=await l.json():n=await Y(e)}catch{n=await Y(e)}let r=n.filter(l=>l.type==="page"&&!l.url.startsWith("chrome://")),o=t.toUpperCase(),i=r.filter(l=>l.id.toUpperCase().startsWith(o));if(i.length===0)throw new Error(`No target found matching prefix '${t}'`);if(i.length>1){let l=i.map(c=>c.id.slice(0,this.config.targetPrefixLength)).join(", ");throw new Error(`Ambiguous prefix '${t}' matches ${i.length} targets: ${l}`)}let a=i[0];return{targetId:a.id,wsUrl:a.webSocketDebuggerUrl}}async sendDaemonCommand(t,e,n,r){return await this.daemonManager.getOrCreateDaemon(t,e,{idleTimeoutMs:this.config.daemonIdleTimeoutS*1e3}),this.config.stealth?.enabled&&await this.daemonManager.sendCommand(t,"setStealthConfig",{stealth:this.config.stealth}),this.daemonManager.sendCommand(t,n,r)}resolveScreenshotPath(t){if(!t)return;let e;if(t.startsWith("/")?e=t:t.startsWith("./")||t.startsWith("../")?this.restrictToWorkspace&&this.workspace?e=Oe(this.workspace,t):e=Oe(process.cwd(),t):this.restrictToWorkspace&&this.workspace?e=Oe(this.workspace,t):e=Oe(Yr(),`airclaw-screenshot-${Date.now()}.png`),this.restrictToWorkspace&&this.workspace&&!e.startsWith(this.workspace))throw new Error(`Screenshot path '${t}' is outside workspace (restrictToWorkspace is enabled)`);return e}saveScreenshot(t,e){let n=Xr(t);zr(n)||Vr(n,{recursive:!0});let r=Buffer.from(e,"base64");Hr(t,r)}formatResult(t){return JSON.stringify(t,null,2)}formatError(t){return JSON.stringify({error:t},null,2)}};var ee=class extends g{constructor(e){super();this.relay=e}name="chrome_relay";description="Control Chrome browser through the relay extension. Commands: list_tabs, navigate, click, type, screenshot, read, evaluate, attach, detach.";parameters={type:"object",properties:{command:{type:"string",enum:["list_tabs","navigate","click","type","screenshot","read","evaluate","attach","detach"],description:"The command to execute"},tabId:{type:"number",description:"Tab ID for tab-specific commands"},url:{type:"string",description:"URL to navigate to"},selector:{type:"string",description:"CSS selector for click command"},text:{type:"string",description:"Text to type"},expression:{type:"string",description:"JavaScript expression to evaluate"},format:{type:"string",description:"Screenshot format (png or jpeg)"}},required:["command"]};async execute(e){let n=String(e.command??"");try{switch(n){case"list_tabs":{let r=await this.relay.listTabs();return JSON.stringify(r,null,2)}case"navigate":{let r=Number(e.tabId),o=String(e.url??"");return r?o?(await this.relay.navigate(r,o),`Navigated tab ${r} to ${o}`):"Error: url is required":"Error: tabId is required"}case"click":{let r=Number(e.tabId),o=String(e.selector??"");return r?o?(await this.relay.click(r,o),`Clicked "${o}" in tab ${r}`):"Error: selector is required":"Error: tabId is required"}case"type":{let r=Number(e.tabId),o=String(e.text??""),i=e.selector?String(e.selector):void 0;return r?o?(await this.relay.type(r,o,i),`Typed "${o}" in tab ${r}${i?` (selector: ${i})`:""}`):"Error: text is required":"Error: tabId is required"}case"screenshot":{let r=Number(e.tabId),o=String(e.format??"png");return r?`Screenshot captured: ${(await this.relay.screenshot(r,o)).slice(0,100)}...`:"Error: tabId is required"}case"read":{let r=Number(e.tabId);if(!r)return"Error: tabId is required";let o=await this.relay.evaluate(r,"document.body.innerText");return JSON.stringify(o,null,2)}case"evaluate":{let r=Number(e.tabId),o=String(e.expression??"");if(!r)return"Error: tabId is required";if(!o)return"Error: expression is required";let i=await this.relay.evaluate(r,o);return JSON.stringify(i,null,2)}case"attach":{let r=Number(e.tabId);return r?(await this.relay.attachTab(r),`Attached to tab ${r}`):"Error: tabId is required"}case"detach":{let r=Number(e.tabId);return r?(await this.relay.detachTab(r),`Detached from tab ${r}`):"Error: tabId is required"}default:return`Unknown command: ${n}. Available commands: list_tabs, navigate, click, type, screenshot, read, evaluate, attach, detach`}}catch(r){return`Error: ${r instanceof Error?r.message:String(r)}`}}};import S from"node:fs";import te from"node:path";import{randomUUID as Zr}from"node:crypto";var Qr="automations",en="index.json";function tn(s){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,50)}function Ze(s){return te.join(s,Qr)}function Ft(s){return te.join(Ze(s),en)}function $e(s,t){return te.join(Ze(s),t)}function Qe(s,t){return te.join($e(s,t),"rule.json")}function et(s,t){return te.join($e(s,t),"script.js")}function tt(s){let t=Ze(s);S.existsSync(t)||S.mkdirSync(t,{recursive:!0})}function Ie(s){tt(s);let t=Ft(s);if(!S.existsSync(t))return{rules:[]};try{let e=S.readFileSync(t,"utf-8"),n=JSON.parse(e),r=!1;for(let o of n.rules){if(o.stepCount===void 0){let i=U(s,o.id);o.stepCount=i?.steps?.length||0,r=!0}if(o.toolType===void 0){let i=U(s,o.id);i?.toolType&&(o.toolType=i.toolType,r=!0)}}return r&&Ne(s,n),n}catch{return{rules:[]}}}function Ne(s,t){tt(s);let e=Ft(s),n=`${e}.tmp`;S.writeFileSync(n,JSON.stringify(t,null,2)),S.renameSync(n,e)}function Jt(s){return Ie(s).rules}function U(s,t){let e=Qe(s,t);if(!S.existsSync(e))return null;try{let n=S.readFileSync(e,"utf-8"),r=JSON.parse(n),o=et(s,t);return S.existsSync(o)&&(r.scriptContent=S.readFileSync(o,"utf-8")),r}catch{return null}}function Ut(s,t){tt(s);let e=tn(t.name)||Zr().slice(0,8),n=Date.now(),r={id:e,name:t.name,description:t.description,createdAt:n,updatedAt:n,enabled:!0,stepCount:t.steps.length,steps:t.steps,scriptPath:`automations/${e}/script.js`,tags:t.tags||[],source:t.source||"manual",...t.toolType?{toolType:t.toolType}:{},...t.variables?{variables:t.variables}:{}},o=$e(s,e);S.existsSync(o)||S.mkdirSync(o,{recursive:!0});let i=Qe(s,e);S.writeFileSync(i,JSON.stringify(r,null,2));let a=Gt(r),l=et(s,e);S.writeFileSync(l,a);let c=Ie(s),u={id:r.id,name:r.name,description:r.description,enabled:r.enabled,updatedAt:r.updatedAt,stepCount:r.steps.length};return t.toolType&&(u.toolType=t.toolType),c.rules.push(u),Ne(s,c),r}function qt(s,t,e){let n=U(s,t);if(!n)return null;let r=Date.now(),o={...n,...e,id:n.id,createdAt:n.createdAt,updatedAt:r,stepCount:(e.steps||n.steps).length},i=Qe(s,t);if(S.writeFileSync(i,JSON.stringify(o,null,2)),e.steps){let c=Gt(o),u=et(s,t);S.writeFileSync(u,c)}let a=Ie(s),l=a.rules.findIndex(c=>c.id===t);if(l>=0){let c={id:o.id,name:o.name,description:o.description,enabled:o.enabled,updatedAt:o.updatedAt,stepCount:o.steps.length};o.toolType&&(c.toolType=o.toolType),a.rules[l]=c,Ne(s,a)}return o}function Wt(s,t){let e=$e(s,t);if(!S.existsSync(e))return!1;S.rmSync(e,{recursive:!0,force:!0});let n=Ie(s),r=n.rules.length;return n.rules=n.rules.filter(o=>o.id!==t),n.rules.length!==r?(Ne(s,n),!0):!1}function Gt(s){let t=new Date().toISOString();return`// Automation: ${s.name}
121
+ - chrome_session evalraw --target "ABC123" --method "Page.getTitle" --params '{}'`;parameters={type:"object",properties:{command:{type:"string",description:"The command to execute",enum:["status","list","open","stop","snap","shot","eval","html","nav","net","click","clickxy","type","loadall","evalraw"]},target:{type:"string",description:"Target ID prefix (required for page interaction commands)"},url:{type:"string",description:"URL to open (for 'open' and 'nav' commands)"},path:{type:"string",description:"File path to save screenshot (for 'shot' command)"},selector:{type:"string",description:"CSS selector for element-specific operations (for 'shot', 'html', 'click', 'loadall' commands)"},expression:{type:"string",description:"JavaScript expression to evaluate (for 'eval' command)"},depth:{type:"number",description:"Maximum depth for accessibility tree (for 'snap' command)"},timeout:{type:"number",description:"Timeout in milliseconds (for 'nav' command)"},outer:{type:"boolean",description:"Return outer HTML (default true, for 'html' command)"},x:{type:"number",description:"X coordinate in CSS pixels (for 'clickxy' command)"},y:{type:"number",description:"Y coordinate in CSS pixels (for 'clickxy' command)"},text:{type:"string",description:"Text to type at focused element (for 'type' command)"},interval:{type:"number",description:"Interval in milliseconds between clicks (for 'loadall' command, default 500)"},method:{type:"string",description:"CDP method name (for 'evalraw' command)"},params:{type:"object",description:"CDP method parameters as JSON object (for 'evalraw' command)"}},required:["command"]};config;daemonManager;commands;workspace;restrictToWorkspace;constructor(t={},e,r=!1){super(),this.config={minChromeVersion:t.minChromeVersion??tt.minChromeVersion,daemonIdleTimeoutS:t.daemonIdleTimeoutS??tt.daemonIdleTimeoutS,targetPrefixLength:t.targetPrefixLength??tt.targetPrefixLength,...t.stealth?{stealth:t.stealth}:{}},this.workspace=e,this.restrictToWorkspace=r,this.daemonManager=Ne.getInstance(),this.commands=new Map([["status",this.handleStatus.bind(this)],["list",this.handleList.bind(this)],["open",this.handleOpen.bind(this)],["stop",this.handleStop.bind(this)],["snap",this.handleSnap.bind(this)],["shot",this.handleShot.bind(this)],["eval",this.handleEval.bind(this)],["html",this.handleHtml.bind(this)],["nav",this.handleNav.bind(this)],["net",this.handleNet.bind(this)],["click",this.handleClick.bind(this)],["clickxy",this.handleClickxy.bind(this)],["type",this.handleType.bind(this)],["loadall",this.handleLoadall.bind(this)],["evalraw",this.handleEvalraw.bind(this)]])}async execute(t,e){let r=t.command;if(!r)return this.formatError("Missing required 'command' parameter. Available commands: status, list, open, stop, snap, shot, eval, html, nav, net, click, clickxy, type, loadall, evalraw");let n=this.commands.get(r);if(!n)return this.formatError(`Unknown command '${r}'. Available commands: status, list, open, stop, snap, shot, eval, html, nav, net, click, clickxy, type, loadall, evalraw`);try{return await n(t,e)}catch(o){let i=o instanceof Error?o.message:String(o);return this.formatError(`Command '${r}' failed: ${i}`)}}async handleStatus(){let t=this.config,e=await Jt();if(!e)return this.formatResult({available:!1,reason:"Chrome remote debugging not detected",hint:"Enable remote debugging in Chrome at chrome://inspect/#remote-debugging or launch Chrome with --remote-debugging-port=9222"});if(e.pendingApproval)return this.formatResult({available:!1,pendingApproval:!0,reason:`Chrome is listening on port ${e.port} but remote debugging approval may be required`,hint:"Look for a remote debugging approval prompt in Chrome, or quit Chrome and relaunch with: open -a 'Google Chrome' --args --remote-debugging-port=9222",port:e.port});let{port:r,versionInfo:n}=e,o=n.Browser.match(/(\w+)\/(\d+)/),i=o?.[1]??"Chrome",a=o?parseInt(o[2],10):0;return a>0&&a<t.minChromeVersion?this.formatResult({available:!1,reason:`Chrome version ${a} is below minimum required version ${t.minChromeVersion}`,hint:`Update Chrome to version ${t.minChromeVersion} or higher`,version:n.Browser,port:r,browser:i}):this.formatResult({available:!0,version:n.Browser,protocolVersion:n["Protocol-Version"],userAgent:n["User-Agent"],webSocketDebuggerUrl:n.webSocketDebuggerUrl,port:r,browser:i})}async handleList(){let t=Oe();if(!t)return this.formatError("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let e;try{let i=await fetch(`http://127.0.0.1:${t}/json/list`);i.ok?e=await i.json():e=await ee(t)}catch{e=await ee(t)}let r=e.filter(i=>i.type==="page"&&!i.url.startsWith("chrome://"));if(r.length===0)return this.formatResult({tabs:[],message:"No open tabs found"});let n=this.config.targetPrefixLength,o=r.map(i=>({id:i.id.slice(0,n),fullId:i.id,title:i.title,url:i.url}));return this.formatResult({tabs:o,count:o.length})}async handleOpen(t){let e=Oe();if(!e)return this.formatError("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let r=t.url??"about:blank",n=this.config.targetPrefixLength;try{let o=await fetch(`http://127.0.0.1:${e}/json/new?${r}`,{method:"PUT"});if(o.ok){let i=await o.json();return this.formatResult({success:!0,id:i.id.slice(0,n),fullId:i.id,url:i.url,message:`Opened new tab: ${i.url}`})}}catch{}try{let o=await qt(e,r);return this.formatResult({success:!0,id:o.id.slice(0,n),fullId:o.id,url:o.url,message:`Opened new tab: ${o.url}`})}catch(o){return this.formatError(`Cannot open tab via HTTP or WebSocket on port ${e}: ${o instanceof Error?o.message:String(o)}. Run 'chrome_session status' for details.`)}}async handleStop(t){let e=t.target;if(e){let o=this.daemonManager.getActiveTargets().find(i=>i.toUpperCase().startsWith(e.toUpperCase()));return o?(this.daemonManager.stopDaemon(o),this.formatResult({success:!0,target:o.slice(0,this.config.targetPrefixLength),message:`Stopped daemon for target ${o.slice(0,this.config.targetPrefixLength)}`})):this.formatError(`No daemon found for target prefix '${e}'`)}let r=this.daemonManager.getActiveTargets().length;return r===0?this.formatResult({success:!0,message:"No active daemons to stop"}):(this.daemonManager.stopAll(),this.formatResult({success:!0,message:`Stopped ${r} daemon(s)`}))}async handleSnap(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n={};t.depth!==void 0&&(n.depth=t.depth);let o=await this.sendDaemonCommand(e,r,"snap",n);return o.ok?this.formatResult({tree:o.result?.tree,nodeCount:o.result?.nodeCount}):this.formatError(o.error??"Failed to get accessibility tree")}async handleShot(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.path,o=this.resolveScreenshotPath(n),i={};o&&(i.path=o),t.selector&&(i.selector=t.selector);let a=await this.sendDaemonCommand(e,r,"shot",i);return a.ok?(o&&a.result?.data&&this.saveScreenshot(o,a.result.data),this.formatResult({path:o,dpr:a.result?.dpr,viewport:a.result?.viewport,message:o?`Screenshot saved to ${o}`:"Screenshot captured (base64 data in 'data' field)",data:o?void 0:a.result?.data})):this.formatError(a.error??"Failed to capture screenshot")}async handleEval(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.expression;if(!n)return this.formatError("Missing required 'expression' parameter");let o=await this.sendDaemonCommand(e,r,"eval",{expression:n,awaitPromise:!0});return o.ok?this.formatResult({ok:!0,result:o.result?.result,type:o.result?.type,subtype:o.result?.subtype}):this.formatError(o.error??"JavaScript evaluation failed")}async handleHtml(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n={};t.selector&&(n.selector=t.selector),t.outer!==void 0&&(n.outer=t.outer);let o=await this.sendDaemonCommand(e,r,"html",n);return o.ok?this.formatResult({html:o.result?.html,selector:o.result?.selector}):this.formatError(o.error??"Failed to get HTML")}async handleNav(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.url;if(!n)return this.formatError("Missing required 'url' parameter");let o={url:n};t.timeout!==void 0&&(o.timeout=t.timeout);let i=await this.sendDaemonCommand(e,r,"nav",o);return i.ok?this.formatResult({ok:!0,url:i.result?.url,frameId:i.result?.frameId,loaderId:i.result?.loaderId,message:i.result?.message}):this.formatError(i.error??"Navigation failed")}async handleNet(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=await this.sendDaemonCommand(e,r,"net",{});return n.ok?this.formatResult({entries:n.result?.entries,count:n.result?.count}):this.formatError(n.error??"Failed to get network timing")}async handleClick(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.selector;if(!n)return this.formatError("Missing required 'selector' parameter");let o=await this.sendDaemonCommand(e,r,"click",{selector:n});return o.ok?this.formatResult({ok:!0,selector:n,tag:o.result?.tag,text:o.result?.text,message:o.result?.message}):this.formatError(o.error??"Click failed")}async handleClickxy(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.x,o=t.y;if(typeof n!="number"||typeof o!="number")return this.formatError("Missing required 'x' and 'y' parameters");let i=await this.sendDaemonCommand(e,r,"clickxy",{x:n,y:o});return i.ok?this.formatResult({ok:!0,x:n,y:o,message:`Clicked at (${n}, ${o})`}):this.formatError(i.error??"Click at coordinates failed")}async handleType(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.text;if(!n)return this.formatError("Missing required 'text' parameter");let o=await this.sendDaemonCommand(e,r,"type",{text:n});return o.ok?this.formatResult({ok:!0,text:n,message:`Typed ${n.length} character(s)`}):this.formatError(o.error??"Type failed")}async handleLoadall(t,e){let{targetId:r,wsUrl:n}=await this.resolveTarget(t.target),o=t.selector,i=t.interval??500;if(!o)return this.formatError("Missing required 'selector' parameter");let a=await this.sendDaemonCommand(r,n,"loadall",{selector:o,interval:i,timeout:3e5});return a.ok?this.formatResult({ok:!0,selector:o,clickCount:a.result?.clickCount,timedOut:a.result?.timedOut,message:a.result?.message}):this.formatError(a.error??"Loadall failed")}async handleEvalraw(t){let{targetId:e,wsUrl:r}=await this.resolveTarget(t.target),n=t.method,o=t.params??{};if(!n)return this.formatError("Missing required 'method' parameter");let i=await this.sendDaemonCommand(e,r,"evalraw",{method:n,params:o});return i.ok?this.formatResult({ok:!0,method:n,result:i.result?.result}):this.formatError(i.error??"Raw CDP command failed")}async resolveTarget(t){if(!t)throw new Error("Missing required 'target' parameter. Use 'chrome_session list' to see available targets.");let e=Oe();if(!e)throw new Error("Chrome remote debugging not detected. Run 'chrome_session status' for details.");let r;try{let l=await fetch(`http://127.0.0.1:${e}/json/list`);l.ok?r=await l.json():r=await ee(e)}catch{r=await ee(e)}let n=r.filter(l=>l.type==="page"&&!l.url.startsWith("chrome://")),o=t.toUpperCase(),i=n.filter(l=>l.id.toUpperCase().startsWith(o));if(i.length===0)throw new Error(`No target found matching prefix '${t}'`);if(i.length>1){let l=i.map(c=>c.id.slice(0,this.config.targetPrefixLength)).join(", ");throw new Error(`Ambiguous prefix '${t}' matches ${i.length} targets: ${l}`)}let a=i[0];return{targetId:a.id,wsUrl:a.webSocketDebuggerUrl}}async sendDaemonCommand(t,e,r,n){return await this.daemonManager.getOrCreateDaemon(t,e,{idleTimeoutMs:this.config.daemonIdleTimeoutS*1e3}),this.config.stealth?.enabled&&await this.daemonManager.sendCommand(t,"setStealthConfig",{stealth:this.config.stealth}),this.daemonManager.sendCommand(t,r,n)}resolveScreenshotPath(t){if(!t)return;let e;if(t.startsWith("/")?e=t:t.startsWith("./")||t.startsWith("../")?this.restrictToWorkspace&&this.workspace?e=De(this.workspace,t):e=De(process.cwd(),t):this.restrictToWorkspace&&this.workspace?e=De(this.workspace,t):e=De(ln(),`airclaw-screenshot-${Date.now()}.png`),this.restrictToWorkspace&&this.workspace&&!e.startsWith(this.workspace))throw new Error(`Screenshot path '${t}' is outside workspace (restrictToWorkspace is enabled)`);return e}saveScreenshot(t,e){let r=an(t);sn(r)||on(r,{recursive:!0});let n=Buffer.from(e,"base64");nn(t,n)}formatResult(t){return JSON.stringify(t,null,2)}formatError(t){return JSON.stringify({error:t},null,2)}};var ne=class extends g{constructor(e){super();this.relay=e}name="chrome_relay";description="Control Chrome browser through the relay extension. Commands: list_tabs, navigate, click, type, screenshot, read, evaluate, attach, detach.";parameters={type:"object",properties:{command:{type:"string",enum:["list_tabs","navigate","click","type","screenshot","read","evaluate","attach","detach"],description:"The command to execute"},tabId:{type:"number",description:"Tab ID for tab-specific commands"},url:{type:"string",description:"URL to navigate to"},selector:{type:"string",description:"CSS selector for click command"},text:{type:"string",description:"Text to type"},expression:{type:"string",description:"JavaScript expression to evaluate"},format:{type:"string",description:"Screenshot format (png or jpeg)"}},required:["command"]};async execute(e){let r=String(e.command??"");try{switch(r){case"list_tabs":{let n=await this.relay.listTabs();return JSON.stringify(n,null,2)}case"navigate":{let n=Number(e.tabId),o=String(e.url??"");return n?o?(await this.relay.navigate(n,o),`Navigated tab ${n} to ${o}`):"Error: url is required":"Error: tabId is required"}case"click":{let n=Number(e.tabId),o=String(e.selector??"");return n?o?(await this.relay.click(n,o),`Clicked "${o}" in tab ${n}`):"Error: selector is required":"Error: tabId is required"}case"type":{let n=Number(e.tabId),o=String(e.text??""),i=e.selector?String(e.selector):void 0;return n?o?(await this.relay.type(n,o,i),`Typed "${o}" in tab ${n}${i?` (selector: ${i})`:""}`):"Error: text is required":"Error: tabId is required"}case"screenshot":{let n=Number(e.tabId),o=String(e.format??"png");return n?`Screenshot captured: ${(await this.relay.screenshot(n,o)).slice(0,100)}...`:"Error: tabId is required"}case"read":{let n=Number(e.tabId);if(!n)return"Error: tabId is required";let o=await this.relay.evaluate(n,"document.body.innerText");return JSON.stringify(o,null,2)}case"evaluate":{let n=Number(e.tabId),o=String(e.expression??"");if(!n)return"Error: tabId is required";if(!o)return"Error: expression is required";let i=await this.relay.evaluate(n,o);return JSON.stringify(i,null,2)}case"attach":{let n=Number(e.tabId);return n?(await this.relay.attachTab(n),`Attached to tab ${n}`):"Error: tabId is required"}case"detach":{let n=Number(e.tabId);return n?(await this.relay.detachTab(n),`Detached from tab ${n}`):"Error: tabId is required"}default:return`Unknown command: ${r}. Available commands: list_tabs, navigate, click, type, screenshot, read, evaluate, attach, detach`}}catch(n){return`Error: ${n instanceof Error?n.message:String(n)}`}}};import w from"node:fs";import oe from"node:path";import{randomUUID as cn}from"node:crypto";var un="automations",dn="index.json";function mn(s){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,50)}function rt(s){return oe.join(s,un)}function Kt(s){return oe.join(rt(s),dn)}function je(s,t){return oe.join(rt(s),t)}function nt(s,t){return oe.join(je(s,t),"rule.json")}function ot(s,t){return oe.join(je(s,t),"script.js")}function st(s){let t=rt(s);w.existsSync(t)||w.mkdirSync(t,{recursive:!0})}function Be(s){st(s);let t=Kt(s);if(!w.existsSync(t))return{rules:[]};try{let e=w.readFileSync(t,"utf-8"),r=JSON.parse(e),n=!1;for(let o of r.rules){if(o.stepCount===void 0){let i=G(s,o.id);o.stepCount=i?.steps?.length||0,n=!0}if(o.toolType===void 0){let i=G(s,o.id);i?.toolType&&(o.toolType=i.toolType,n=!0)}}return n&&Fe(s,r),r}catch{return{rules:[]}}}function Fe(s,t){st(s);let e=Kt(s),r=`${e}.tmp`;w.writeFileSync(r,JSON.stringify(t,null,2)),w.renameSync(r,e)}function Ht(s){return Be(s).rules}function G(s,t){let e=nt(s,t);if(!w.existsSync(e))return null;try{let r=w.readFileSync(e,"utf-8"),n=JSON.parse(r),o=ot(s,t);return w.existsSync(o)&&(n.scriptContent=w.readFileSync(o,"utf-8")),n}catch{return null}}function Vt(s,t){st(s);let e=mn(t.name)||cn().slice(0,8),r=Date.now(),n={id:e,name:t.name,description:t.description,createdAt:r,updatedAt:r,enabled:!0,stepCount:t.steps.length,steps:t.steps,scriptPath:`automations/${e}/script.js`,tags:t.tags||[],source:t.source||"manual",...t.toolType?{toolType:t.toolType}:{},...t.variables?{variables:t.variables}:{}},o=je(s,e);w.existsSync(o)||w.mkdirSync(o,{recursive:!0});let i=nt(s,e);w.writeFileSync(i,JSON.stringify(n,null,2));let a=Yt(n),l=ot(s,e);w.writeFileSync(l,a);let c=Be(s),u={id:n.id,name:n.name,description:n.description,enabled:n.enabled,updatedAt:n.updatedAt,stepCount:n.steps.length};return t.toolType&&(u.toolType=t.toolType),c.rules.push(u),Fe(s,c),n}function zt(s,t,e){let r=G(s,t);if(!r)return null;let n=Date.now(),o={...r,...e,id:r.id,createdAt:r.createdAt,updatedAt:n,stepCount:(e.steps||r.steps).length},i=nt(s,t);if(w.writeFileSync(i,JSON.stringify(o,null,2)),e.steps){let c=Yt(o),u=ot(s,t);w.writeFileSync(u,c)}let a=Be(s),l=a.rules.findIndex(c=>c.id===t);if(l>=0){let c={id:o.id,name:o.name,description:o.description,enabled:o.enabled,updatedAt:o.updatedAt,stepCount:o.steps.length};o.toolType&&(c.toolType=o.toolType),a.rules[l]=c,Fe(s,a)}return o}function Xt(s,t){let e=je(s,t);if(!w.existsSync(e))return!1;w.rmSync(e,{recursive:!0,force:!0});let r=Be(s),n=r.rules.length;return r.rules=r.rules.filter(o=>o.id!==t),r.rules.length!==n?(Fe(s,r),!0):!1}function Yt(s){let t=new Date().toISOString();return`// Automation: ${s.name}
128
122
  // Tool: ${s.toolType??"auto-detect"}
129
123
  // Generated: ${t}
130
124
  // Description: ${s.description}
@@ -145,20 +139,20 @@ fetch(URL, { method: 'POST' })
145
139
  else console.error('Failed:', r.error);
146
140
  })
147
141
  .catch(e => console.error('Could not reach everclaw:', e.message));
148
- `}var Kt={chrome_session:{navigate:"nav",click:"click",type:"type",screenshot:"shot",read:"snap",eval:"eval"},chrome_relay:{navigate:"navigate",click:"click",type:"type",screenshot:"screenshot",read:"read",eval:"evaluate"}},re=s=>new Promise(t=>setTimeout(t,s)),De=class extends g{constructor(e,n,r){super();this.browserTool=n;this.stealthConfig=r;this.workspace=ft(e)}name="automation";description="Manage browser automation workflows. Commands: list, get, save, delete, run.";parameters={type:"object",properties:{command:{type:"string",enum:["list","get","save","delete","run"],description:"The command to execute"},id:{type:"string",description:"Automation ID (for get, delete, run)"},name:{type:"string",description:"Automation name (for save)"},description:{type:"string",description:"Brief description (for save)"},steps:{type:"array",items:{type:"object",properties:{order:{type:"number"},action:{type:"string"},target:{type:"string"},value:{type:"string"},description:{type:"string"},optional:{type:"boolean"},assert:{type:"object",properties:{check:{type:"string",enum:["selector_exists","selector_text","url_contains","eval_truthy"]},value:{type:"string"},expected:{type:"string"},timeoutMs:{type:"number"}}},retries:{type:"number"},retryDelayMs:{type:"number"}}},description:"Automation steps (for save)"},tags:{type:"array",items:{type:"string"},description:"Optional tags (for save)"},enabled:{type:"boolean",description:"Enable/disable (for save)"},variables:{type:"object",description:'Variable overrides for run command (e.g., {"USERNAME": "user"})'}},required:["command"]};workspace;async execute(e,n){let r=String(e.command??"");try{switch(r){case"list":{let o=Jt(this.workspace);return JSON.stringify(o,null,2)}case"get":{let o=String(e.id??"");if(!o)return"Error: id is required for get command";let i=U(this.workspace,o);return i?JSON.stringify(i,null,2):`Error: Automation '${o}' not found`}case"save":{let o=e.id?String(e.id):void 0,i=String(e.name??"Untitled Automation"),a=String(e.description??""),l=e.steps||[],c=e.tags||[];if(l.length===0)return"Error: At least one step is required";let u=this.browserTool?.name,d;if(o){let m={name:i,description:a,steps:l,tags:c};return u&&(m.toolType=u),d=qt(this.workspace,o,m),d?`Updated automation '${d.name}' (${d.id})`:`Error: Automation '${o}' not found for update`}else{let m={name:i,description:a,steps:l,tags:c,source:"conversation"};return u&&(m.toolType=u),d=Ut(this.workspace,m),`Created automation '${d.name}' (${d.id})`}}case"delete":{let o=String(e.id??"");return o?Wt(this.workspace,o)?`Deleted automation '${o}'`:`Error: Automation '${o}' not found or could not be deleted`:"Error: id is required for delete command"}case"run":{let o=String(e.id??"");if(!o)return"Error: id is required for run command";let i=U(this.workspace,o);if(!i)return`Error: Automation '${o}' not found`;if(!i.enabled)return`Error: Automation '${i.name}' is disabled`;let a=e.variables;return this.executeAutomation(i,n?.signal,a)}default:return`Unknown command: ${r}. Available commands: list, get, save, delete, run`}}catch(o){return`Error: ${o instanceof Error?o.message:String(o)}`}}async executeAutomation(e,n,r){if(!this.browserTool)return"Error: No browser tool available. Enable chrome_session or chrome_relay to run automations.";if(e.toolType&&e.toolType!==this.browserTool.name)return`Error: Automation '${e.name}' requires ${e.toolType} but ${this.browserTool.name} is active. Change browser tool or update the automation.`;let o=[];o.push(`Running automation: ${e.name}`),o.push(`Tool: ${this.browserTool.name}`),o.push(`Steps: ${e.steps.length}`);let i=await this.resolveTabContext();if(!i.tabId&&!i.target)return"Error: Could not resolve tab context. Open a browser tab first.";let a=[...e.steps].sort((l,c)=>l.order-c.order);for(let l of a){if(n?.aborted){o.push(`Aborted at step ${l.order}`);break}l.stealth?.preDelay&&await re(l.stealth.preDelay),o.push(`[Step ${l.order}] ${l.description}`);try{let c=this.resolveStep(l,e.variables,r),u=await this.executeStepWithRetries(c,n,i),d=this.maskSensitiveValues(u,e.variables);if(o.push(` -> ${d.slice(0,200)}${d.length>200?"...":""}`),this.stealthConfig?.enabled){let[m,f]=this.stealthConfig.interStepDelay;await re(m+Math.random()*(f-m))}}catch(c){let u=c instanceof Error?c.message:String(c);if(l.optional)o.push(` -> Optional step failed (continuing): ${u}`);else return o.push(` -> FAILED: ${u}`),o.push(`Automation '${e.name}' stopped due to error.`),o.join(`
142
+ `}var Zt={chrome_session:{navigate:"nav",click:"click",type:"type",screenshot:"shot",read:"snap",eval:"eval"},chrome_relay:{navigate:"navigate",click:"click",type:"type",screenshot:"screenshot",read:"read",eval:"evaluate"}},se=s=>new Promise(t=>setTimeout(t,s)),Ue=class extends g{constructor(e,r,n){super();this.browserTool=r;this.stealthConfig=n;this.workspace=vt(e)}name="automation";description="Manage browser automation workflows. Commands: list, get, save, delete, run.";parameters={type:"object",properties:{command:{type:"string",enum:["list","get","save","delete","run"],description:"The command to execute"},id:{type:"string",description:"Automation ID (for get, delete, run)"},name:{type:"string",description:"Automation name (for save)"},description:{type:"string",description:"Brief description (for save)"},steps:{type:"array",items:{type:"object",properties:{order:{type:"number"},action:{type:"string"},target:{type:"string"},value:{type:"string"},description:{type:"string"},optional:{type:"boolean"},assert:{type:"object",properties:{check:{type:"string",enum:["selector_exists","selector_text","url_contains","eval_truthy"]},value:{type:"string"},expected:{type:"string"},timeoutMs:{type:"number"}}},retries:{type:"number"},retryDelayMs:{type:"number"}}},description:"Automation steps (for save)"},tags:{type:"array",items:{type:"string"},description:"Optional tags (for save)"},enabled:{type:"boolean",description:"Enable/disable (for save)"},variables:{type:"object",description:'Variable overrides for run command (e.g., {"USERNAME": "user"})'}},required:["command"]};workspace;async execute(e,r){let n=String(e.command??"");try{switch(n){case"list":{let o=Ht(this.workspace);return JSON.stringify(o,null,2)}case"get":{let o=String(e.id??"");if(!o)return"Error: id is required for get command";let i=G(this.workspace,o);return i?JSON.stringify(i,null,2):`Error: Automation '${o}' not found`}case"save":{let o=e.id?String(e.id):void 0,i=String(e.name??"Untitled Automation"),a=String(e.description??""),l=e.steps||[],c=e.tags||[];if(l.length===0)return"Error: At least one step is required";let u=this.browserTool?.name,d;if(o){let m={name:i,description:a,steps:l,tags:c};return u&&(m.toolType=u),d=zt(this.workspace,o,m),d?`Updated automation '${d.name}' (${d.id})`:`Error: Automation '${o}' not found for update`}else{let m={name:i,description:a,steps:l,tags:c,source:"conversation"};return u&&(m.toolType=u),d=Vt(this.workspace,m),`Created automation '${d.name}' (${d.id})`}}case"delete":{let o=String(e.id??"");return o?Xt(this.workspace,o)?`Deleted automation '${o}'`:`Error: Automation '${o}' not found or could not be deleted`:"Error: id is required for delete command"}case"run":{let o=String(e.id??"");if(!o)return"Error: id is required for run command";let i=G(this.workspace,o);if(!i)return`Error: Automation '${o}' not found`;if(!i.enabled)return`Error: Automation '${i.name}' is disabled`;let a=e.variables;return this.executeAutomation(i,r?.signal,a)}default:return`Unknown command: ${n}. Available commands: list, get, save, delete, run`}}catch(o){return`Error: ${o instanceof Error?o.message:String(o)}`}}async executeAutomation(e,r,n){if(!this.browserTool)return"Error: No browser tool available. Enable chrome_session or chrome_relay to run automations.";if(e.toolType&&e.toolType!==this.browserTool.name)return`Error: Automation '${e.name}' requires ${e.toolType} but ${this.browserTool.name} is active. Change browser tool or update the automation.`;let o=[];o.push(`Running automation: ${e.name}`),o.push(`Tool: ${this.browserTool.name}`),o.push(`Steps: ${e.steps.length}`);let i=await this.resolveTabContext();if(!i.tabId&&!i.target)return"Error: Could not resolve tab context. Open a browser tab first.";let a=[...e.steps].sort((l,c)=>l.order-c.order);for(let l of a){if(r?.aborted){o.push(`Aborted at step ${l.order}`);break}l.stealth?.preDelay&&await se(l.stealth.preDelay),o.push(`[Step ${l.order}] ${l.description}`);try{let c=this.resolveStep(l,e.variables,n),u=await this.executeStepWithRetries(c,r,i),d=this.maskSensitiveValues(u,e.variables);if(o.push(` -> ${d.slice(0,200)}${d.length>200?"...":""}`),this.stealthConfig?.enabled){let[m,p]=this.stealthConfig.interStepDelay;await se(m+Math.random()*(p-m))}}catch(c){let u=c instanceof Error?c.message:String(c);if(l.optional)o.push(` -> Optional step failed (continuing): ${u}`);else return o.push(` -> FAILED: ${u}`),o.push(`Automation '${e.name}' stopped due to error.`),o.join(`
149
143
  `)}}return o.push(`Automation '${e.name}' completed successfully.`),o.join(`
150
- `)}async resolveTabContext(){if(!this.browserTool)return{};let e=this.browserTool.name;if(e==="chrome_relay"){try{let n=await this.browserTool.execute({command:"list_tabs"}),r=JSON.parse(n);if(Array.isArray(r)&&r.length>0)return{tabId:(r.find(i=>i.active)||r[0]).id}}catch{}return{}}if(e==="chrome_session"){try{let n=await this.browserTool.execute({command:"list"}),r=JSON.parse(n);if(r.tabs&&Array.isArray(r.tabs)&&r.tabs.length>0)return{target:r.tabs[0].id}}catch{}return{}}return{}}resolveStep(e,n,r){let o=l=>l&&l.replace(/\$\{(\w+)\}/g,(c,u)=>{if(r&&r[u]!==void 0)return r[u];if(n&&n[u]?.defaultValue!==void 0)return n[u].defaultValue;if(n&&n[u]?.required)throw new Error(`Required variable '${u}' not provided`);return`\${${u}}`}),i=o(e.target),a=o(e.value);return{...e,...i!==void 0?{target:i}:{},...a!==void 0?{value:a}:{}}}maskSensitiveValues(e,n){if(!n)return e;let r=e;for(let[o,i]of Object.entries(n))i.sensitive&&(r=r.replaceAll(`\${${o}}`,`[REDACTED:${o}]`));return r}async executeStepWithRetries(e,n,r){let o=1+(e.retries??0),i=e.retryDelayMs??1e3,a;for(let l=1;l<=o;l++)try{let c=await this.executeStepOnce(e,n,r);return e.assert&&await this.pollAssertion(e.assert,n,r),c}catch(c){a=c instanceof Error?c:new Error(String(c)),l<o&&await re(i)}throw a??new Error("Unknown error")}async executeStepOnce(e,n,r){if(!this.browserTool)throw new Error("No browser tool available");let o=this.browserTool.name,i=Kt[o];if(!i)throw new Error(`Unsupported browser tool: ${o}`);let a=i[e.action];if(!a)throw new Error(`Action '${e.action}' not supported by ${o}`);let l={command:a};switch(o==="chrome_relay"&&r.tabId&&(l.tabId=r.tabId),o==="chrome_session"&&r.target&&(l.target=r.target),e.action){case"navigate":l.url=e.value??e.target??"";break;case"click":l.selector=e.target??"";break;case"type":l.text=e.value??"",e.stealth?.typingSpeed&&(l.typingSpeed=e.stealth.typingSpeed);break;case"read":break;case"screenshot":e.target&&(l.selector=e.target);break;case"eval":l.expression=e.value??"";break;case"wait":let c=parseInt(e.value??"1000",10);return await re(c),`Waited ${c}ms`;default:throw new Error(`Unknown action: ${e.action}`)}return this.browserTool.execute(l,n?{signal:n}:void 0)}toExpression(e){switch(e.check){case"selector_exists":return`!!document.querySelector(${JSON.stringify(e.value)})`;case"selector_text":return`(document.querySelector(${JSON.stringify(e.value)})?.textContent?.trim() ?? "") === ${JSON.stringify(e.expected??"")}`;case"url_contains":return`window.location.href.includes(${JSON.stringify(e.value)})`;case"eval_truthy":return`!!(${e.value})`}}isAssertionPassing(e,n){try{let r=JSON.parse(e);if(n==="chrome_session"){let o=r.result;return o&&typeof o.value=="boolean"?o.value:o&&typeof o.value=="string"?o.value.length>0:o&&typeof o.value=="number"?o.value!==0:r.result===!0}return n==="chrome_relay"?r===!0:!1}catch{return!1}}async pollAssertion(e,n,r){if(!this.browserTool)throw new Error("No browser tool available");let o=e.timeoutMs??5e3,i=500,a=this.toExpression(e),l=Date.now();do{if(n?.aborted)throw new Error("Aborted during assertion");try{let c=this.browserTool.name,d=Kt[c]?.eval;if(!d)throw new Error(`Evaluation not supported by ${c}`);let m={command:d,expression:a};c==="chrome_relay"&&r.tabId&&(m.tabId=r.tabId),c==="chrome_session"&&r.target&&(m.target=r.target);let f=await this.browserTool.execute(m);if(this.isAssertionPassing(f,c))return}catch{}if(Date.now()-l>=o)break;await re(i)}while(Date.now()-l<o);throw new Error(`Assertion failed after ${o}ms: ${e.check} (${e.value})`)}};var je=class s{tools=new Map;guardEngine=null;register(t){this.tools.set(t.name,t)}unregister(t){return this.tools.delete(t)}clear(){this.tools.clear()}get(t){return this.tools.get(t)}getDefinitions(){return[...this.tools.values()].map(t=>t.toSchema())}get toolNames(){return[...this.tools.keys()]}setGuardEngine(t){this.guardEngine=t}getGuardEngine(){return this.guardEngine}filterByNames(t){let e=new s;e.guardEngine=this.guardEngine;for(let n of t){let r=this.tools.get(n);r&&e.register(r)}return e}excludeByNames(t){let e=new Set(t),n=new s;n.guardEngine=this.guardEngine;for(let[r,o]of this.tools)e.has(r)||n.register(o);return n}async execute(t,e,n){let r=this.tools.get(t);if(!r)return{kind:"error",content:`Error: Tool '${t}' not found. Available: ${this.toolNames.join(", ")}`,retryable:!1};try{if(v(n?.signal),this.guardEngine){let a=this.guardEngine.guard(t,e);if(a&&!a.isSafe){let l=a.findings.map(c=>` - [${c.severity}] ${c.title}: ${c.description}`).join(`
144
+ `)}async resolveTabContext(){if(!this.browserTool)return{};let e=this.browserTool.name;if(e==="chrome_relay"){try{let r=await this.browserTool.execute({command:"list_tabs"}),n=JSON.parse(r);if(Array.isArray(n)&&n.length>0)return{tabId:(n.find(i=>i.active)||n[0]).id}}catch{}return{}}if(e==="chrome_session"){try{let r=await this.browserTool.execute({command:"list"}),n=JSON.parse(r);if(n.tabs&&Array.isArray(n.tabs)&&n.tabs.length>0)return{target:n.tabs[0].id}}catch{}return{}}return{}}resolveStep(e,r,n){let o=l=>l&&l.replace(/\$\{(\w+)\}/g,(c,u)=>{if(n&&n[u]!==void 0)return n[u];if(r&&r[u]?.defaultValue!==void 0)return r[u].defaultValue;if(r&&r[u]?.required)throw new Error(`Required variable '${u}' not provided`);return`\${${u}}`}),i=o(e.target),a=o(e.value);return{...e,...i!==void 0?{target:i}:{},...a!==void 0?{value:a}:{}}}maskSensitiveValues(e,r){if(!r)return e;let n=e;for(let[o,i]of Object.entries(r))i.sensitive&&(n=n.replaceAll(`\${${o}}`,`[REDACTED:${o}]`));return n}async executeStepWithRetries(e,r,n){let o=1+(e.retries??0),i=e.retryDelayMs??1e3,a;for(let l=1;l<=o;l++)try{let c=await this.executeStepOnce(e,r,n);return e.assert&&await this.pollAssertion(e.assert,r,n),c}catch(c){a=c instanceof Error?c:new Error(String(c)),l<o&&await se(i)}throw a??new Error("Unknown error")}async executeStepOnce(e,r,n){if(!this.browserTool)throw new Error("No browser tool available");let o=this.browserTool.name,i=Zt[o];if(!i)throw new Error(`Unsupported browser tool: ${o}`);let a=i[e.action];if(!a)throw new Error(`Action '${e.action}' not supported by ${o}`);let l={command:a};switch(o==="chrome_relay"&&n.tabId&&(l.tabId=n.tabId),o==="chrome_session"&&n.target&&(l.target=n.target),e.action){case"navigate":l.url=e.value??e.target??"";break;case"click":l.selector=e.target??"";break;case"type":l.text=e.value??"",e.stealth?.typingSpeed&&(l.typingSpeed=e.stealth.typingSpeed);break;case"read":break;case"screenshot":e.target&&(l.selector=e.target);break;case"eval":l.expression=e.value??"";break;case"wait":let c=parseInt(e.value??"1000",10);return await se(c),`Waited ${c}ms`;default:throw new Error(`Unknown action: ${e.action}`)}return this.browserTool.execute(l,r?{signal:r}:void 0)}toExpression(e){switch(e.check){case"selector_exists":return`!!document.querySelector(${JSON.stringify(e.value)})`;case"selector_text":return`(document.querySelector(${JSON.stringify(e.value)})?.textContent?.trim() ?? "") === ${JSON.stringify(e.expected??"")}`;case"url_contains":return`window.location.href.includes(${JSON.stringify(e.value)})`;case"eval_truthy":return`!!(${e.value})`}}isAssertionPassing(e,r){try{let n=JSON.parse(e);if(r==="chrome_session"){let o=n.result;return o&&typeof o.value=="boolean"?o.value:o&&typeof o.value=="string"?o.value.length>0:o&&typeof o.value=="number"?o.value!==0:n.result===!0}return r==="chrome_relay"?n===!0:!1}catch{return!1}}async pollAssertion(e,r,n){if(!this.browserTool)throw new Error("No browser tool available");let o=e.timeoutMs??5e3,i=500,a=this.toExpression(e),l=Date.now();do{if(r?.aborted)throw new Error("Aborted during assertion");try{let c=this.browserTool.name,d=Zt[c]?.eval;if(!d)throw new Error(`Evaluation not supported by ${c}`);let m={command:d,expression:a};c==="chrome_relay"&&n.tabId&&(m.tabId=n.tabId),c==="chrome_session"&&n.target&&(m.target=n.target);let p=await this.browserTool.execute(m);if(this.isAssertionPassing(p,c))return}catch{}if(Date.now()-l>=o)break;await se(i)}while(Date.now()-l<o);throw new Error(`Assertion failed after ${o}ms: ${e.check} (${e.value})`)}};var Je=class s{tools=new Map;guardEngine=null;register(t){this.tools.set(t.name,t)}unregister(t){return this.tools.delete(t)}clear(){this.tools.clear()}get(t){return this.tools.get(t)}getDefinitions(){return[...this.tools.values()].map(t=>t.toSchema())}get toolNames(){return[...this.tools.keys()]}setGuardEngine(t){this.guardEngine=t}getGuardEngine(){return this.guardEngine}filterByNames(t){let e=new s;e.guardEngine=this.guardEngine;for(let r of t){let n=this.tools.get(r);n&&e.register(n)}return e}excludeByNames(t){let e=new Set(t),r=new s;r.guardEngine=this.guardEngine;for(let[n,o]of this.tools)e.has(n)||r.register(o);return r}async execute(t,e,r){let n=this.tools.get(t);if(!n)return{kind:"error",content:`Error: Tool '${t}' not found. Available: ${this.toolNames.join(", ")}`,retryable:!1};try{if(v(r?.signal),this.guardEngine){let a=this.guardEngine.guard(t,e);if(a&&!a.isSafe){let l=a.findings.map(c=>` - [${c.severity}] ${c.title}: ${c.description}`).join(`
151
145
  `);return{kind:"error",content:`Security: Tool call blocked. The tool '${t}' was denied by the security guard.
152
146
 
153
147
  Findings:
154
- ${l}`,retryable:!1}}}let o=r.validateParams(e);if(o.length)return{kind:"error",content:`Error: Invalid parameters for tool '${t}': ${o.join("; ")}
148
+ ${l}`,retryable:!1}}}let o=n.validateParams(e);if(o.length)return{kind:"error",content:`Error: Invalid parameters for tool '${t}': ${o.join("; ")}
155
149
 
156
- [Analyze the error above and try a different approach.]`,retryable:!0};let i=await r.execute(e,n);return v(n?.signal),i.startsWith("__TERMINAL__")?{kind:"terminal",content:i.slice(12)}:{kind:"ok",content:i}}catch(o){if(w(o))throw o;return{kind:"error",content:`Error executing ${t}: ${String(o)}
150
+ [Analyze the error above and try a different approach.]`,retryable:!0};let i=await n.execute(e,r);return v(r?.signal),i.startsWith("__TERMINAL__")?{kind:"terminal",content:i.slice(12)}:{kind:"ok",content:i}}catch(o){if(x(o))throw o;return{kind:"error",content:`Error executing ${t}: ${String(o)}
157
151
 
158
- [Analyze the error above and try a different approach.]`,retryable:!0}}}};function Ht(s){return s.replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g,"").trim()}function rn(s){return s.replace(/[ \t]+/g," ").replace(/\n{3,}/g,`
152
+ [Analyze the error above and try a different approach.]`,retryable:!0}}}};function Qt(s){return s.replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g,"").trim()}function gn(s){return s.replace(/[ \t]+/g," ").replace(/\n{3,}/g,`
159
153
 
160
- `).trim()}function nn(s){try{let t=new URL(s);return["http:","https:"].includes(t.protocol)?t.hostname?[!0,""]:[!1,"Missing domain"]:[!1,`Only http/https allowed, got '${t.protocol.replace(":","")}'`]}catch(t){return[!1,String(t)]}}var Be=class extends g{constructor(e,n=5){super();this.apiKey=e;this.maxResults=n}name="web_search";description="Search the web. Returns titles, URLs, and snippets.";parameters={type:"object",properties:{query:{type:"string",description:"Search query"},count:{type:"integer",minimum:1,maximum:10,description:"Results (1-10)"}},required:["query"]};async execute(e,n){let r=String(e.query??""),o=Math.min(Math.max(Number(e.count??this.maxResults),1),10),i=this.apiKey||process.env.BRAVE_API_KEY||"";if(!i)return"Error: Brave Search API key not configured. Set tools.web.search.apiKey or BRAVE_API_KEY.";try{v(n?.signal);let a=new URL("https://api.search.brave.com/res/v1/web/search");a.searchParams.set("q",r),a.searchParams.set("count",String(o));let l=await fetch(a,{headers:{Accept:"application/json","X-Subscription-Token":i},...n?.signal?{signal:n.signal}:{}});if(!l.ok)return`Error: ${l.status} ${l.statusText}`;let u=(await l.json()).web?.results??[];if(!u.length)return`No results for: ${r}`;let d=[`Results for: ${r}`,""];return u.slice(0,o).forEach((m,f)=>{d.push(`${f+1}. ${m.title??""}`),d.push(` ${m.url??""}`),m.description&&d.push(` ${m.description}`)}),d.join(`
161
- `)}catch(a){if(w(a))throw a;return`Error: ${String(a)}`}}},Fe=class extends g{constructor(e=5e4){super();this.maxChars=e}name="web_fetch";description="Fetch URL and extract readable content (HTML to markdown/text).";parameters={type:"object",properties:{url:{type:"string",description:"URL to fetch"},extractMode:{type:"string",enum:["markdown","text"]},maxChars:{type:"integer",minimum:100}},required:["url"]};async execute(e,n){let r=String(e.url??""),o=String(e.extractMode??"markdown"),i=Number(e.maxChars??this.maxChars),[a,l]=nn(r);if(!a)return JSON.stringify({error:`URL validation failed: ${l}`,url:r});try{v(n?.signal);let c=await fetch(r,{redirect:"follow",headers:{"User-Agent":"Mozilla/5.0"},...n?.signal?{signal:n.signal}:{}}),u=c.headers.get("content-type")||"",d="",m="raw";if(u.includes("application/json"))d=JSON.stringify(await c.json(),null,2),m="json";else{let b=await c.text();u.includes("text/html")||/^\s*<!doctype|^\s*<html/i.test(b.slice(0,256))?(d=o==="text"?Ht(b):rn(Ht(b)),m="html"):d=b}let f=d.length>i,y=f?d.slice(0,i):d;return JSON.stringify({url:r,finalUrl:c.url,status:c.status,extractor:m,truncated:f,length:y.length,text:y})}catch(c){if(w(c))throw c;return JSON.stringify({error:String(c),url:r})}}};function P(s){return on.resolve(s.workspace)}function Je(s){let t=P(s);return s.restrictToWorkspace?t:void 0}function sn(s){let t=[R({name:"builtin-filesystem-tools",tools:[{name:"read_file",create:e=>new me(P(e),Je(e))},{name:"write_file",create:e=>new ge(P(e),Je(e))},{name:"edit_file",create:e=>new pe(P(e),Je(e))},{name:"list_dir",create:e=>new fe(P(e),Je(e))}]}),R({name:"builtin-shell-tools",tools:[{name:"exec",create:e=>new be(e.execConfig?.timeout??60,P(e),!!e.restrictToWorkspace,e.execConfig?.pathAppend??"",new I,e.rtkService,e.rtkConfig?.ultraCompact??!1)}]}),R({name:"builtin-web-tools",tools:[{name:"web_search",create:e=>new Be(e.braveApiKey??null)},{name:"web_fetch",create:()=>new Fe}]})];return s.bus&&t.push(R({name:"builtin-messaging-tools",tools:[{name:"message",create:e=>{if(!e.bus)throw new Error("Builtin message tool requires a message bus");let n=new ye(async r=>{e.turn?.isCurrent&&!e.turn.isCurrent()||await e.bus.publishOutbound(r)});return e.turn&&n.setContext(e.turn.channel,e.turn.chatId,e.turn.messageId),n}}]})),s.subagents&&t.push(R({name:"builtin-subagent-tools",tools:[{name:"spawn",create:e=>{if(!e.subagents)throw new Error("Builtin spawn tool requires a subagent manager");let n=new ve(e.subagents);return e.turn&&n.setContext(e.turn.channel,e.turn.chatId,e.turn.sessionKey,e.turn.systemPrompt),n}}]})),s.cronService&&t.push(R({name:"builtin-scheduler-tools",tools:[{name:"cron",create:e=>{if(!e.cronService)throw new Error("Builtin cron tool requires a cron service");let n=new de(e.cronService);return e.turn&&n.setContext(e.turn.channel,e.turn.chatId),n}}]})),s.sessionManager&&t.push(R({name:"builtin-session-tools",tools:[{name:"session.info",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.info tool requires a session manager");let n=new Ae;return n.setSessionManager(e.sessionManager),e.turn&&n.setContext(e.turn.sessionKey),n}},{name:"session.anchor",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.anchor tool requires a session manager");let n=new Ee;return n.setSessionManager(e.sessionManager),e.turn&&n.setContext(e.turn.sessionKey),n}},{name:"session.search",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.search tool requires a session manager");let n=new Se;return n.setSessionManager(e.sessionManager),e.turn&&n.setContext(e.turn.sessionKey),n}}]})),s.chromeSessionConfig?.enabled&&t.push(R({name:"builtin-chrome-session-tools",tools:[{name:"chrome_session",create:e=>new Q(e.chromeSessionConfig,P(e),!!e.restrictToWorkspace)}]})),s.browserRelay&&t.push(R({name:"builtin-browser-relay-tools",tools:[{name:"chrome_relay",create:e=>{if(!e.browserRelay)throw new Error("Builtin chrome_relay tool requires a browser relay server");return new ee(e.browserRelay)}}]})),t.push(R({name:"builtin-automation-tools",tools:[{name:"automation",create:e=>{let n=e.browserRelay?new ee(e.browserRelay):e.chromeSessionConfig?.enabled?new Q(e.chromeSessionConfig,P(e),!!e.restrictToWorkspace):void 0;return new De(P(e),n,e.chromeSessionConfig?.stealth)}}]})),t}function an(s){return kt(sn(s))}function Vt(s){let t=new je,e=an(s);for(let n of e.tools.values())t.register(n.contribution.create(s));return t}var Xt="EVERCLAW_SUBAGENT_RESULT ";function zt(s,t){let e=new Date().toLocaleString(),n=t??"You are operating as a subagent spawned by the main agent to complete a specific task. Stay focused and concise. Complete the assigned task and report your findings.";return s?`${s}
154
+ `).trim()}function pn(s){try{let t=new URL(s);return["http:","https:"].includes(t.protocol)?t.hostname?[!0,""]:[!1,"Missing domain"]:[!1,`Only http/https allowed, got '${t.protocol.replace(":","")}'`]}catch(t){return[!1,String(t)]}}var qe=class extends g{constructor(e,r=5){super();this.apiKey=e;this.maxResults=r}name="web_search";description="Search the web. Returns titles, URLs, and snippets.";parameters={type:"object",properties:{query:{type:"string",description:"Search query"},count:{type:"integer",minimum:1,maximum:10,description:"Results (1-10)"}},required:["query"]};async execute(e,r){let n=String(e.query??""),o=Math.min(Math.max(Number(e.count??this.maxResults),1),10),i=this.apiKey||process.env.BRAVE_API_KEY||"";if(!i)return"Error: Brave Search API key not configured. Set tools.web.search.apiKey or BRAVE_API_KEY.";try{v(r?.signal);let a=new URL("https://api.search.brave.com/res/v1/web/search");a.searchParams.set("q",n),a.searchParams.set("count",String(o));let l=await fetch(a,{headers:{Accept:"application/json","X-Subscription-Token":i},...r?.signal?{signal:r.signal}:{}});if(!l.ok)return`Error: ${l.status} ${l.statusText}`;let u=(await l.json()).web?.results??[];if(!u.length)return`No results for: ${n}`;let d=[`Results for: ${n}`,""];return u.slice(0,o).forEach((m,p)=>{d.push(`${p+1}. ${m.title??""}`),d.push(` ${m.url??""}`),m.description&&d.push(` ${m.description}`)}),d.join(`
155
+ `)}catch(a){if(x(a))throw a;return`Error: ${String(a)}`}}},We=class extends g{constructor(e=5e4){super();this.maxChars=e}name="web_fetch";description="Fetch URL and extract readable content (HTML to markdown/text).";parameters={type:"object",properties:{url:{type:"string",description:"URL to fetch"},extractMode:{type:"string",enum:["markdown","text"]},maxChars:{type:"integer",minimum:100}},required:["url"]};async execute(e,r){let n=String(e.url??""),o=String(e.extractMode??"markdown"),i=Number(e.maxChars??this.maxChars),[a,l]=pn(n);if(!a)return JSON.stringify({error:`URL validation failed: ${l}`,url:n});try{v(r?.signal);let c=await fetch(n,{redirect:"follow",headers:{"User-Agent":"Mozilla/5.0"},...r?.signal?{signal:r.signal}:{}}),u=c.headers.get("content-type")||"",d="",m="raw";if(u.includes("application/json"))d=JSON.stringify(await c.json(),null,2),m="json";else{let b=await c.text();u.includes("text/html")||/^\s*<!doctype|^\s*<html/i.test(b.slice(0,256))?(d=o==="text"?Qt(b):gn(Qt(b)),m="html"):d=b}let p=d.length>i,f=p?d.slice(0,i):d;return JSON.stringify({url:n,finalUrl:c.url,status:c.status,extractor:m,truncated:p,length:f.length,text:f})}catch(c){if(x(c))throw c;return JSON.stringify({error:String(c),url:n})}}};function P(s){return fn.resolve(s.workspace)}function Ge(s){let t=P(s);return s.restrictToWorkspace?t:void 0}function hn(s){let t=[E({name:"builtin-filesystem-tools",tools:[{name:"read_file",create:e=>new fe(P(e),Ge(e))},{name:"write_file",create:e=>new he(P(e),Ge(e))},{name:"edit_file",create:e=>new ye(P(e),Ge(e))},{name:"list_dir",create:e=>new be(P(e),Ge(e))}]}),E({name:"builtin-shell-tools",tools:[{name:"exec",create:e=>new we(e.execConfig?.timeout??60,P(e),!!e.restrictToWorkspace,e.execConfig?.pathAppend??"",new D,e.rtkService,e.rtkConfig?.ultraCompact??!1)}]}),E({name:"builtin-web-tools",tools:[{name:"web_search",create:e=>new qe(e.braveApiKey??null)},{name:"web_fetch",create:()=>new We}]})];return s.bus&&t.push(E({name:"builtin-messaging-tools",tools:[{name:"message",create:e=>{if(!e.bus)throw new Error("Builtin message tool requires a message bus");let r=new Se(async n=>{e.turn?.isCurrent&&!e.turn.isCurrent()||await e.bus.publishOutbound(n)});return e.turn&&r.setContext(e.turn.channel,e.turn.chatId,e.turn.messageId),r}}]})),s.subagents&&t.push(E({name:"builtin-subagent-tools",tools:[{name:"spawn",create:e=>{if(!e.subagents)throw new Error("Builtin spawn tool requires a subagent manager");let r=new ke(e.subagents);return e.turn&&r.setContext(e.turn.channel,e.turn.chatId,e.turn.sessionKey,e.turn.systemPrompt),r}}]})),s.cronService&&t.push(E({name:"builtin-scheduler-tools",tools:[{name:"cron",create:e=>{if(!e.cronService)throw new Error("Builtin cron tool requires a cron service");let r=new pe(e.cronService);return e.turn&&r.setContext(e.turn.channel,e.turn.chatId),r}}]})),s.sessionManager&&t.push(E({name:"builtin-session-tools",tools:[{name:"session.info",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.info tool requires a session manager");let r=new _e;return r.setSessionManager(e.sessionManager),e.turn&&r.setContext(e.turn.sessionKey),r}},{name:"session.anchor",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.anchor tool requires a session manager");let r=new Pe;return r.setSessionManager(e.sessionManager),e.turn&&r.setContext(e.turn.sessionKey),r}},{name:"session.search",create:e=>{if(!e.sessionManager)throw new Error("Builtin session.search tool requires a session manager");let r=new xe;return r.setSessionManager(e.sessionManager),e.turn&&r.setContext(e.turn.sessionKey),r}}]})),s.chromeSessionConfig?.enabled&&t.push(E({name:"builtin-chrome-session-tools",tools:[{name:"chrome_session",create:e=>new re(e.chromeSessionConfig,P(e),!!e.restrictToWorkspace)}]})),s.browserRelay&&t.push(E({name:"builtin-browser-relay-tools",tools:[{name:"chrome_relay",create:e=>{if(!e.browserRelay)throw new Error("Builtin chrome_relay tool requires a browser relay server");return new ne(e.browserRelay)}}]})),t.push(E({name:"builtin-automation-tools",tools:[{name:"automation",create:e=>{let r=e.browserRelay?new ne(e.browserRelay):e.chromeSessionConfig?.enabled?new re(e.chromeSessionConfig,P(e),!!e.restrictToWorkspace):void 0;return new Ue(P(e),r,e.chromeSessionConfig?.stealth)}}]})),t}function yn(s){return At(hn(s))}function er(s){let t=new Je,e=yn(s);for(let r of e.tools.values())t.register(r.contribution.create(s));return t}var rr="EVERCLAW_SUBAGENT_RESULT ";function tr(s,t){let e=new Date().toLocaleString(),r=t??"You are operating as a subagent spawned by the main agent to complete a specific task. Stay focused and concise. Complete the assigned task and report your findings.";return s?`${s}
162
156
 
163
157
  ---
164
158
 
@@ -166,17 +160,17 @@ ${l}`,retryable:!1}}}let o=r.validateParams(e);if(o.length)return{kind:"error",c
166
160
 
167
161
  Current Time: ${e}
168
162
 
169
- ${n}`:`# Subagent
163
+ ${r}`:`# Subagent
170
164
 
171
165
  Current Time: ${e}
172
166
 
173
- ${n}`}async function Yt(s){let t=Vt({workspace:s.workspace,restrictToWorkspace:s.restrictToWorkspace,braveApiKey:s.braveApiKey,execConfig:s.execConfig}),e=s.definition;e?.allowedTools&&e.allowedTools.length>0?t=t.filterByNames(e.allowedTools):e?.deniedTools&&e.deniedTools.length>0&&(t=t.excludeByNames(e.deniedTools));let n=e?.systemPromptSuffix,r;if(s.contextMode==="fork"&&s.existingMessages?.length){let i=n?`# Subagent Mode
167
+ ${r}`}async function nr(s){let t=er({workspace:s.workspace,restrictToWorkspace:s.restrictToWorkspace,braveApiKey:s.braveApiKey,execConfig:s.execConfig}),e=s.definition;e?.allowedTools&&e.allowedTools.length>0?t=t.filterByNames(e.allowedTools):e?.deniedTools&&e.deniedTools.length>0&&(t=t.excludeByNames(e.deniedTools));let r=e?.systemPromptSuffix,n;if(s.contextMode==="fork"&&s.existingMessages?.length){let i=r?`# Subagent Mode
174
168
 
175
- ${n}`:`# Subagent Mode
169
+ ${r}`:`# Subagent Mode
176
170
 
177
- You are operating as a subagent spawned by the main agent to complete a specific task. Stay focused and concise. Complete the assigned task and report your findings.`;r=s.existingMessages.map((a,l)=>l===0&&a.role==="system"&&typeof a.content=="string"?{...a,content:`${a.content}
171
+ You are operating as a subagent spawned by the main agent to complete a specific task. Stay focused and concise. Complete the assigned task and report your findings.`;n=s.existingMessages.map((a,l)=>l===0&&a.role==="system"&&typeof a.content=="string"?{...a,content:`${a.content}
178
172
 
179
173
  ---
180
174
 
181
- ${i}`}:a),r.push({role:"user",content:s.task})}else s.contextMode==="inherit-system"&&s.parentSystemPrompt?r=[{role:"system",content:zt(s.parentSystemPrompt,n)},{role:"user",content:s.task}]:r=s.existingMessages?[...s.existingMessages,{role:"user",content:s.task}]:[{role:"system",content:zt(void 0,n)},{role:"user",content:s.task}];let o="Task completed but no final response was generated.";for(let i=0;i<15;i++){v(s.signal);let a=await s.provider.chat({messages:r,tools:t.getDefinitions(),model:s.model,temperature:s.temperature,maxTokens:s.maxTokens,...s.signal?{signal:s.signal}:{}});if(v(s.signal),a.toolCalls.length){r.push({role:"assistant",content:a.content??"",tool_calls:a.toolCalls.map(l=>({id:l.id,type:"function",function:{name:l.name,arguments:JSON.stringify(l.arguments)}}))});for(let l of a.toolCalls){v(s.signal);let c=await t.execute(l.name,l.arguments,s.signal?{signal:s.signal}:{});v(s.signal);let u=typeof c=="object"&&"kind"in c?c.content??String(c):String(c);r.push({role:"tool",tool_call_id:l.id,name:l.name,content:u})}continue}o=a.content??o;break}return o}async function ln(){let s=[];for await(let t of process.stdin)s.push(typeof t=="string"?t:t.toString("utf8"));return s.join("")}function rt(s){process.stdout.write(`${Xt}${JSON.stringify(s)}
182
- `)}async function cn(){let s=new AbortController,t=()=>s.abort();process.once("SIGTERM",t),process.once("SIGINT",t);try{let e=(await ln()).trim();if(!e)throw new Error("Missing subagent payload.");let n=JSON.parse(e),r=bt();n.providerName&&(r.agents.defaults.provider=n.providerName),n.model&&(r.agents.defaults.model=n.model);let o=wt(r),i=await Yt({...n,provider:o,signal:s.signal});rt({status:"completed",finalResult:i})}catch(e){if(s.signal.aborted||w(e)){rt({status:"aborted",errorMessage:null,failureAttribution:"aborted"});return}let n=e instanceof Error?e.message:String(e);console.error(e instanceof Error&&e.stack?e.stack:n),rt({status:"failed",errorMessage:n,failureAttribution:"exception"}),process.exitCode=1}finally{process.removeListener("SIGTERM",t),process.removeListener("SIGINT",t)}}cn();
175
+ ${i}`}:a),n.push({role:"user",content:s.task})}else s.contextMode==="inherit-system"&&s.parentSystemPrompt?n=[{role:"system",content:tr(s.parentSystemPrompt,r)},{role:"user",content:s.task}]:n=s.existingMessages?[...s.existingMessages,{role:"user",content:s.task}]:[{role:"system",content:tr(void 0,r)},{role:"user",content:s.task}];let o="Task completed but no final response was generated.";for(let i=0;i<15;i++){v(s.signal);let a=await s.provider.chat({messages:n,tools:t.getDefinitions(),model:s.model,temperature:s.temperature,maxTokens:s.maxTokens,...s.signal?{signal:s.signal}:{}});if(v(s.signal),a.toolCalls.length){n.push({role:"assistant",content:a.content??"",tool_calls:a.toolCalls.map(l=>({id:l.id,type:"function",function:{name:l.name,arguments:JSON.stringify(l.arguments)}}))});for(let l of a.toolCalls){v(s.signal);let c=await t.execute(l.name,l.arguments,s.signal?{signal:s.signal}:{});v(s.signal);let u=typeof c=="object"&&"kind"in c?c.content??String(c):String(c);n.push({role:"tool",tool_call_id:l.id,name:l.name,content:u})}continue}o=a.content??o;break}return o}async function bn(){let s=[];for await(let t of process.stdin)s.push(typeof t=="string"?t:t.toString("utf8"));return s.join("")}function it(s){process.stdout.write(`${rr}${JSON.stringify(s)}
176
+ `)}async function vn(){let s=new AbortController,t=()=>s.abort();process.once("SIGTERM",t),process.once("SIGINT",t);try{let e=(await bn()).trim();if(!e)throw new Error("Missing subagent payload.");let r=JSON.parse(e),n=kt();r.providerName&&(n.agents.defaults.provider=r.providerName),r.model&&(n.agents.defaults.model=r.model);let o=Ct(n),i=await nr({...r,provider:o,signal:s.signal});it({status:"completed",finalResult:i})}catch(e){if(s.signal.aborted||x(e)){it({status:"aborted",errorMessage:null,failureAttribution:"aborted"});return}let r=e instanceof Error?e.message:String(e);console.error(e instanceof Error&&e.stack?e.stack:r),it({status:"failed",errorMessage:r,failureAttribution:"exception"}),process.exitCode=1}finally{process.removeListener("SIGTERM",t),process.removeListener("SIGINT",t)}}vn();