vole-agent 0.1.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -8
- package/README.zh-CN.md +35 -8
- package/dist/app.js +1 -1
- package/dist/chunk-OHRUXR5B.js +325 -0
- package/dist/index.js +1 -1
- package/dist/web/server.js +68 -31
- package/package.json +3 -1
- package/dist/chunk-EBLG3T72.js +0 -147
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import"dotenv/config";import{Command as Pr}from"commander";import{createInterface as Lr}from"readline";import{readdir as Fe,readFile as ge,rm as Dr,stat as J}from"fs/promises";import{spawn as Rs}from"child_process";import{dirname as L,join as _}from"path";import{fileURLToPath as js}from"url";import{existsSync as Ue,mkdirSync as je,readdirSync as Ws,readFileSync as wt,renameSync as Js,statSync as Xs,writeFileSync as re}from"fs";import{join as K,resolve as X}from"path";var Gs={baseURL:"https://openrouter.ai/api/v1"},zs={model:"claude-haiku-4-5-20251001"},C=class extends Error{constructor(e){super(e),this.name="ConfigValidationError"}},Qs={model:{provider:"openai-compatible",baseURL:"https://api.openai.com/v1",model:"gpt-4.1-mini",temperature:.2,maxTokens:4096},workspace:{root:"."},agents:{},runtime:{defaultMode:"confirm",maxSteps:12},trace:{verbosity:"explainable"},tools:{fileSystem:!0,shell:!0,web:!1},permissions:{allowLowRisk:!0},sessions:{directory:"~/.vole/sessions"},memory:{longTermFiles:"disabled",writes:"disabled"},secrets:{apiKey:void 0}};function Be(s={}){let e=Zs(Qs);return yt(e,s.userConfig),yt(e,s.projectConfig),en(e,s.env??{}),tn(e),e}function oe(s){return{...s,model:{...s.model},workspace:{...s.workspace},agents:{...s.agents},runtime:{...s.runtime},trace:{...s.trace},tools:{...s.tools},permissions:{...s.permissions},sessions:{...s.sessions},memory:{...s.memory},secrets:{apiKey:s.secrets.apiKey===void 0?"missing":"configured"}}}function Zs(s){return{model:{...s.model},workspace:{...s.workspace},agents:{...s.agents},runtime:{...s.runtime},trace:{...s.trace},tools:{...s.tools},permissions:{...s.permissions},sessions:{...s.sessions},memory:{...s.memory},secrets:{...s.secrets}}}function yt(s,e){if(e!==void 0){if(!kt(e))throw new C("Configuration must be an object.");Y(s.model,e.model),Y(s.workspace,e.workspace),Y(s.agents,e.agents),Y(s.runtime,e.runtime),Y(s.trace,e.trace),Y(s.tools,e.tools),Y(s.permissions,e.permissions),Y(s.sessions,e.sessions),Y(s.memory,e.memory)}}function Y(s,e){if(e!==void 0){if(!kt(e))throw new C("Configuration sections must be objects.");for(let[t,n]of Object.entries(e))t in s&&(s[t]=n)}}function en(s,e){e.OPENROUTER_API_KEY!==void 0&&(s.model.provider="openai-compatible",s.model.baseURL=Gs.baseURL,s.model.model="",s.secrets.apiKey=e.OPENROUTER_API_KEY),e.ANTHROPIC_API_KEY!==void 0&&(s.model.provider="anthropic",s.model.model=zs.model,s.secrets.apiKey=e.ANTHROPIC_API_KEY),e.VOLE_BASE_URL!==void 0&&(s.model.baseURL=e.VOLE_BASE_URL),e.VOLE_MODEL!==void 0&&(s.model.model=e.VOLE_MODEL),e.VOLE_DEFAULT_MODE!==void 0&&(s.runtime.defaultMode=e.VOLE_DEFAULT_MODE),e.VOLE_WORKSPACE_ROOT!==void 0&&(s.workspace.root=e.VOLE_WORKSPACE_ROOT),e.VOLE_AGENT!==void 0&&(s.agents.default=e.VOLE_AGENT),e.VOLE_LONG_TERM_MEMORY!==void 0&&(s.memory.longTermFiles=e.VOLE_LONG_TERM_MEMORY),e.VOLE_API_KEY!==void 0&&(s.secrets.apiKey=e.VOLE_API_KEY),e.VOLE_PROMPT_MODE!==void 0&&(s.runtime.promptMode=e.VOLE_PROMPT_MODE),e.VOLE_EXECUTION_CONTRACT!==void 0&&(s.runtime.executionContract=e.VOLE_EXECUTION_CONTRACT),e.VOLE_TOOL_PROFILE!==void 0&&(s.runtime.toolProfile=e.VOLE_TOOL_PROFILE),e.VOLE_SANDBOX!==void 0&&(s.runtime.sandboxed=e.VOLE_SANDBOX==="true"),e.VOLE_THINKING_BUDGET!==void 0&&(s.model.thinkingBudget=e.VOLE_THINKING_BUDGET)}function tn(s){if(s.model.provider!=="openai-compatible"&&s.model.provider!=="anthropic")throw new C(`Invalid model.provider "${String(s.model.provider)}". Expected openai-compatible or anthropic.`);if(s.model.model.trim().length===0)throw new C("No model configured. Set VOLE_MODEL=<model-name> (e.g. VOLE_MODEL=openai/gpt-4o for OpenRouter).");if(!sn(s.runtime.defaultMode))throw new C(`Invalid runtime.defaultMode "${String(s.runtime.defaultMode)}". Expected observe, confirm, or auto.`);if(!nn(s.trace.verbosity))throw new C(`Invalid trace.verbosity "${String(s.trace.verbosity)}". Expected explainable or debug.`);if(!rn(s.memory.longTermFiles))throw new C(`Invalid memory.longTermFiles "${String(s.memory.longTermFiles)}". Expected disabled or read-only.`);if(s.memory.writes!=="disabled")throw new C(`Invalid memory.writes "${String(s.memory.writes)}". Only disabled is supported.`);if(s.runtime.promptMode!==void 0&&!on(s.runtime.promptMode))throw new C(`Invalid runtime.promptMode "${String(s.runtime.promptMode)}". Expected full, minimal, or none.`);if(s.runtime.executionContract!==void 0&&!an(s.runtime.executionContract))throw new C(`Invalid runtime.executionContract "${String(s.runtime.executionContract)}". Expected default or strict-agentic.`);if(s.runtime.toolProfile!==void 0&&!cn(s.runtime.toolProfile))throw new C(`Invalid runtime.toolProfile "${String(s.runtime.toolProfile)}". Expected coding, full, messaging, or background.`);if(s.model.thinkingBudget!==void 0&&!dn(s.model.thinkingBudget))throw new C(`Invalid model.thinkingBudget "${String(s.model.thinkingBudget)}". Expected off, minimal, low, medium, high, max, or adaptive.`)}function kt(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}function sn(s){return s==="observe"||s==="confirm"||s==="auto"}function nn(s){return s==="explainable"||s==="debug"}function rn(s){return s==="disabled"||s==="read-only"||s==="write"}function on(s){return s==="full"||s==="minimal"||s==="none"}function an(s){return s==="default"||s==="strict-agentic"}function cn(s){return s==="coding"||s==="full"||s==="messaging"||s==="background"}function dn(s){return s==="off"||s==="minimal"||s==="low"||s==="medium"||s==="high"||s==="max"||s==="adaptive"}function P(s,e){let t=s.sessions.directory;if(!t.startsWith("~/"))return t;let n=e?.HOME??process.env.HOME;return n===void 0?t:K(n,t.slice(2))}var ln=[["AGENTS.md","agentsMd"],["SOUL.md","soulMd"],["USER.md","userMd"],["MEMORY.md","memoryMd"],["IDENTITY.md","identityMd"],["TOOLS.md","toolsMd"]],Ye=/^[A-Za-z0-9][A-Za-z0-9_.-]*$/;function D(s){return Ye.test(s)&&!s.startsWith(".")}function we(s){let e=X(s,"agents"),t;try{t=Ws(e)}catch{return[]}return t.filter(n=>D(n)).filter(n=>{try{return Xs(K(e,n)).isDirectory()}catch{return!1}}).sort()}function vt(s,e){let t=X(s,".vole","active-agent");try{let r=wt(t,"utf8").trim();if(r.length>0&&D(r))return r}catch{}return e.agents.default!==void 0&&D(e.agents.default)?e.agents.default:we(s)[0]}function Et(s,e){if(!D(e))throw new C(`Invalid agent id "${e}". Must match ${Ye.source}.`);let t=X(s,"agents",e);if(!Ue(t))throw new C(`Agent "${e}" not found at ${t}.`);let n={};for(let[r,o]of ln)try{n[o]=wt(K(t,r),"utf8")}catch{}return{id:e,root:t,files:n}}function St(s,e){if(!D(e))throw new C(`Invalid agent id "${e}". Must match ${Ye.source}.`);let t=X(s,"agents",e);if(Ue(t))throw new C(`Agent "${e}" already exists at ${t}.`);je(t,{recursive:!0});let n=`# ${e}
|
|
3
|
+
|
|
4
|
+
`;return re(K(t,"AGENTS.md"),`${n}Project conventions and operating rules for this agent.
|
|
5
|
+
`),re(K(t,"SOUL.md"),`${n}Persona, tone, and values for this agent.
|
|
6
|
+
`),re(K(t,"USER.md"),`${n}Notes about the user that this agent should remember.
|
|
7
|
+
`),re(K(t,"MEMORY.md"),`${n}Long-term consolidated memory for this agent.
|
|
8
|
+
`),t}function Tt(s,e){if(!D(e))throw new C(`Invalid agent id "${e}".`);let t=X(s,".vole");je(t,{recursive:!0}),re(K(t,"active-agent"),`${e}
|
|
9
|
+
`)}function _t(s,e){if(!D(e))throw new C(`Invalid agent id "${e}".`);let t=X(s,"agents",e);if(!Ue(t))throw new C(`Agent "${e}" not found at ${t}.`);let n=X(s,"agents",".archive");je(n,{recursive:!0});let r=new Date().toISOString().replace(/[:.]/g,"-"),o=K(n,`${e}-${r}`);return Js(t,o),o}import{readFile as un}from"fs/promises";import{join as mn}from"path";var ke=class{async assemble(e){let t=[];return e.systemInstruction&&t.push({role:"system",content:e.systemInstruction}),e.recentMessages&&t.push(...e.recentMessages),t.push({role:"user",content:e.userMessage}),{modelInput:{messages:t},report:{includedSections:e.systemInstruction?["identity"]:[],omittedSections:["runtime","tooling","safety","skills","workspace"],sections:[]}}}},ve=class{#e;#t;constructor(e={}){this.#e=e.workspacePromptFiles??[],this.#t=e.readWorkspaceFile??(t=>un(t,"utf8"))}async assemble(e){let t=e.promptMode??"full",n=[],r=[];if(t==="none"){let c=e.recentMessages??[];c.length>0&&n.push({name:"conversation_history",included:!0}),n.push({name:"user_message",included:!0});let d=n.filter(u=>u.included).map(u=>u.name),m=n.filter(u=>!u.included).map(u=>u.name);return{modelInput:{messages:[...c.map(u=>({...u})),{role:"user",content:e.userMessage}]},report:{includedSections:d,omittedSections:m,sections:n}}}if(r.push(`<identity>
|
|
10
|
+
${e.systemInstruction}
|
|
11
|
+
</identity>`),n.push({name:"identity",included:!0}),t==="full"){if(e.runtime?(r.push("",`<runtime>
|
|
12
|
+
- Mode: ${e.runtime.mode}
|
|
13
|
+
- Workspace: ${e.runtime.workspace}
|
|
14
|
+
- Date: ${e.runtime.currentDate}
|
|
15
|
+
</runtime>`),n.push({name:"runtime",included:!0})):n.push({name:"runtime",included:!1,reason:"No runtime metadata provided."}),e.currentDateTime!==void 0&&e.currentDateTime.length>0?(r.push("",`<current-date>
|
|
16
|
+
${e.currentDateTime}
|
|
17
|
+
</current-date>`),n.push({name:"current_date",included:!0})):n.push({name:"current_date",included:!1,reason:"No currentDateTime provided."}),e.tools!==void 0&&e.tools.length>0){let d=e.tools.map(m=>`- ${m.name} [${m.risk}]: ${m.description}`).join(`
|
|
18
|
+
`);r.push("",`<tooling>
|
|
19
|
+
${d}
|
|
20
|
+
</tooling>`),n.push({name:"tooling",included:!0})}else n.push({name:"tooling",included:!1,reason:"No tools registered."});if(e.executionBias!==void 0&&e.executionBias.length>0?(r.push("",`<execution-bias>
|
|
21
|
+
${e.executionBias}
|
|
22
|
+
</execution-bias>`),n.push({name:"execution_bias",included:!0})):n.push({name:"execution_bias",included:!1,reason:"No executionBias provided."}),e.permissionGuidance!==void 0&&e.permissionGuidance.length>0?(r.push("",`<safety>
|
|
23
|
+
${e.permissionGuidance}
|
|
24
|
+
</safety>`),n.push({name:"safety",included:!0})):n.push({name:"safety",included:!1,reason:"No permission guidance provided."}),e.reasoningPolicy!==void 0&&e.reasoningPolicy.length>0?(r.push("",`<reasoning>
|
|
25
|
+
${e.reasoningPolicy}
|
|
26
|
+
</reasoning>`),n.push({name:"reasoning",included:!0})):n.push({name:"reasoning",included:!1,reason:"No reasoningPolicy provided."}),e.replyTagsPolicy!==void 0&&e.replyTagsPolicy.length>0?(r.push("",`<reply-tags>
|
|
27
|
+
${e.replyTagsPolicy}
|
|
28
|
+
</reply-tags>`),n.push({name:"reply_tags",included:!0})):n.push({name:"reply_tags",included:!1,reason:"No replyTagsPolicy provided."}),e.skillIndex!==void 0&&e.skillIndex.length>0){let d=e.skillIndex.map(m=>`- ${m.name}: ${m.description}`).join(`
|
|
29
|
+
`);r.push("",`<skills>
|
|
30
|
+
${d}
|
|
31
|
+
</skills>`),n.push({name:"skills",included:!0})}else n.push({name:"skills",included:!1,reason:"No skills loaded."});let c=await this.#s(e.runtime?.workspace);c.length>0?(r.push("",`<workspace>${c.join(`
|
|
32
|
+
`)}
|
|
33
|
+
</workspace>`),n.push({name:"workspace",included:!0})):this.#e.length>0&&n.push({name:"workspace",included:!1,reason:"No workspace prompt files found."}),e.documentationPolicy!==void 0&&e.documentationPolicy.length>0?(r.push("",`<documentation>
|
|
34
|
+
${e.documentationPolicy}
|
|
35
|
+
</documentation>`),n.push({name:"documentation",included:!0})):n.push({name:"documentation",included:!1,reason:"No documentationPolicy provided."}),e.selfUpdatePolicy!==void 0&&e.selfUpdatePolicy.length>0?(r.push("",`<self-update>
|
|
36
|
+
${e.selfUpdatePolicy}
|
|
37
|
+
</self-update>`),n.push({name:"self_update",included:!0})):n.push({name:"self_update",included:!1,reason:"No selfUpdatePolicy provided."})}let o=e.recentMessages??[];o.length>0&&n.push({name:"conversation_history",included:!0}),n.push({name:"user_message",included:!0});let i=n.filter(c=>c.included).map(c=>c.name),a=n.filter(c=>!c.included).map(c=>c.name);return{modelInput:{messages:[{role:"system",content:r.join(`
|
|
38
|
+
`)},...o.map(c=>({...c})),{role:"user",content:e.userMessage}]},report:{includedSections:i,omittedSections:a,sections:n}}}async#s(e){if(e===void 0||this.#e.length===0)return[];let t=[];for(let n of this.#e)try{let o=(await this.#t(mn(e,n))).trim();o.length>0&&t.push("",`### ${n}`,o)}catch(r){if(fn(r)&&r.code==="ENOENT")continue;throw r}return t}};function fn(s){return s instanceof Error&&"code"in s}var pn=["off","minimal","low","medium","high","xhigh","adaptive","max"],hn=/\/think:([a-zA-Z]+)/g,It=/(?:^|\s)\/stop(?:\s|$)/g,bt=/(?:^|\s)\/compact(?:\s|$)/g;function At(s){let e={stop:!1,compact:!1},t=s;return t=t.replace(hn,(n,r)=>{let o=r.toLowerCase();return pn.includes(o)&&(e.think=o),""}),It.test(t)&&(e.stop=!0,t=t.replace(It," ")),bt.test(t)&&(e.compact=!0,t=t.replace(bt," ")),{cleanedMessage:t.replace(/\s+/g," ").trim(),directives:e}}var Ke="Before this conversation is compressed, take this opportunity to record any durable facts the user will care about across sessions. Prefer the append_daily_memory tool when it is available. Skip if there is nothing worth preserving.",He={maxTokens:6e4,maxMessages:400,keepRecent:12,summarySystemPrompt:"You are a context distiller for an AI agent. The conversation history has grown too long and must be reduced. Extract only what the agent needs to continue working: tools called and their key outcomes, decisions reached, important facts discovered, files created or modified, errors encountered, and the current task state. Discard pleasantries, repetition, and details that no longer affect the agent's ability to proceed. Output concise factual statements only.",memoryFlush:{enabled:!0,prompt:Ke}};function Ve(s){let e=0;for(let t of s)typeof t.content=="string"&&(e+=t.content.length),t.toolCalls!==void 0&&(e+=JSON.stringify(t.toolCalls).length),t.toolCallId!==void 0&&(e+=t.toolCallId.length);return Math.ceil(e/4)}async function Rt(s,e,t){let n={...He,...t};if(!(Ve(s)>n.maxTokens||s.length>n.maxMessages))return s;let o=s[0]?.role==="system"?s[0]:void 0,i=o!==void 0?s.slice(1):s,a=i.slice(0,i.length-n.keepRecent),c=i.slice(-n.keepRecent);if(a.length===0)return s;let d=a.map(gn),m=[...o!==void 0?[o]:[],...d,...c],u=d.map(p=>`${p.role.toUpperCase()}: ${p.content??"(tool call)"}`).join(`
|
|
39
|
+
`);try{let p=await e.generate({messages:[{role:"system",content:n.summarySystemPrompt},{role:"user",content:`Conversation to distil:
|
|
40
|
+
|
|
41
|
+
${u}`}]});return p.type!=="message"||!p.content?m:[...o!==void 0?[o]:[],{role:"system",content:`Conversation summary:
|
|
42
|
+
${p.content}`},...c]}catch{return m}}function gn(s){if(s.role!=="tool"||s.content===null)return s;let e;try{e=JSON.parse(s.content)}catch{return s.content.length>400?{...s,content:`${s.content.slice(0,400)}
|
|
43
|
+
[${s.content.length-400} chars omitted]`}:s}let t={};return"ok"in e&&(t.ok=e.ok),"summary"in e&&typeof e.summary=="string"&&(t.summary=e.summary),"exitCode"in e&&(t.exitCode=e.exitCode),"error"in e&&(t.error=e.error),"type"in e&&(t.type=e.type),"result"in e&&typeof e.result=="string"&&e.result.length<=200&&(t.result=e.result),{...s,content:JSON.stringify(t)}}import yn from"@anthropic-ai/sdk";function $t(s){return"generateStream"in s&&typeof s.generateStream=="function"}var Ee=class{#e;#t;#s;#n;#r;#o;constructor(e){this.#e=e.baseURL.replace(/\/+$/,""),this.#t=e.apiKey,this.#s=e.model,this.#n=e.temperature,this.#r=e.maxTokens,this.#o=e.fetch??fetch}async generate(e){try{let t=await this.#o(`${this.#e}/chat/completions`,{method:"POST",headers:this.#c(),body:JSON.stringify(this.#a(e))});if(!t.ok)return{type:"error",category:this.#d(t.status),message:`Provider request failed with status ${t.status}.`,recoverable:t.status===408||t.status===409||t.status===429||t.status>=500};let n=await t.json(),r=n.choices?.[0],o=r?.finish_reason,i=r?.message,a=i?.tool_calls;if(o==="tool_calls"&&a!==void 0&&a.length>0){let c=i?.content??"";return{type:"tool_calls",calls:a.map(d=>({id:d.id,name:d.function.name,input:qe(d.function.arguments)})),...c?{text:c}:{},...n.usage?{usage:this.#m(n.usage)}:{}}}return{type:"message",content:i?.content??"",...n.usage?{usage:this.#m(n.usage)}:{}}}catch{return{type:"error",category:"network",message:"Provider network request failed.",recoverable:!0}}}async*generateStream(e){try{let t=await this.#o(`${this.#e}/chat/completions`,{method:"POST",headers:this.#c(),body:JSON.stringify({...this.#a(e),stream:!0})});if(!t.ok){yield{type:"error",category:this.#d(t.status),message:`Provider request failed with status ${t.status}.`,recoverable:t.status===408||t.status===409||t.status===429||t.status>=500};return}if(t.body===null){yield{type:"error",category:"network",message:"No response body for streaming request.",recoverable:!0};return}let n=new Map,r="",o,i=null;for await(let a of wn(t.body)){if(a==="[DONE]")break;let c;try{c=JSON.parse(a)}catch{continue}let d=c.choices?.[0];if(d!==void 0){d.finish_reason!==null&&d.finish_reason!==void 0&&(i=d.finish_reason);let m=d.delta;if(m!==void 0&&(m.content&&(r+=m.content,yield{type:"token_delta",delta:m.content}),m.tool_calls))for(let u of m.tool_calls){n.has(u.index)||n.set(u.index,{id:"",name:"",arguments:""});let p=n.get(u.index);u.id&&(p.id=u.id),u.function?.name&&(p.name=u.function.name),u.function?.arguments&&(p.arguments+=u.function.arguments)}}c.usage&&(o=this.#m(c.usage))}i==="tool_calls"&&n.size>0?yield{type:"tool_calls",calls:Array.from(n.entries()).sort(([c],[d])=>c-d).map(([,c])=>({id:c.id,name:c.name,input:qe(c.arguments)})),...r?{text:r}:{},...o!==void 0?{usage:o}:{}}:yield{type:"message_done",content:r,...o!==void 0?{usage:o}:{}}}catch{yield{type:"error",category:"network",message:"Provider network request failed.",recoverable:!0}}}#c(){return{"content-type":"application/json",...this.#t?{authorization:`Bearer ${this.#t}`}:{}}}#a(e){return{model:this.#s,messages:e.messages.map(t=>this.#u(t)),...e.tools!==void 0&&e.tools.length>0?{tools:e.tools}:{},...this.#n===void 0?{}:{temperature:this.#n},...this.#r===void 0?{}:{max_tokens:this.#r}}}#u(e){return e.role==="tool"?{role:"tool",tool_call_id:e.toolCallId??"",content:e.content??""}:e.role==="assistant"&&e.toolCalls!==void 0&&e.toolCalls.length>0?{role:"assistant",content:e.content,tool_calls:e.toolCalls.map(t=>({id:t.id,type:"function",function:{name:t.name,arguments:typeof t.input=="string"?t.input:JSON.stringify(t.input)}}))}:{role:e.role,content:e.content}}#d(e){return e===401||e===403?"authentication":e===429?"rate_limit":e===400||e===422?"invalid_request":e===404||e===503?"model_unavailable":"unknown"}#m(e){return{...e.prompt_tokens===void 0?{}:{inputTokens:e.prompt_tokens},...e.completion_tokens===void 0?{}:{outputTokens:e.completion_tokens},...e.total_tokens===void 0?{}:{totalTokens:e.total_tokens}}}};async function*wn(s){let e=s.getReader(),t=new TextDecoder,n="";try{for(;;){let{done:r,value:o}=await e.read();if(r)break;n+=t.decode(o,{stream:!0});let i=n.split(`
|
|
44
|
+
`);n=i.pop()??"";for(let a of i){let c=a.trim();c.startsWith("data: ")&&(yield c.slice(6))}}n+=t.decode();for(let r of n.split(`
|
|
45
|
+
`)){let o=r.trim();o.startsWith("data: ")&&(yield o.slice(6))}}finally{e.releaseLock()}}function qe(s){try{return JSON.parse(s)}catch{return s}}var Q=class{requests=[];#e;constructor(e){this.#e=[...e]}async generate(e){return this.requests.push(e),this.#e.shift()??{type:"error",category:"unknown",message:"FakeModelProvider has no queued output.",recoverable:!1}}};var kn={minimal:1024,low:2048,medium:4096,high:8192,max:16384},Se=class{#e;#t;#s;#n;#r;#o;constructor(e){if(this.#s=e.model,this.#n=e.maxTokens??4096,this.#r=e.temperature,this.#o=e.thinkingBudget,e.client!==void 0||e.streamClient!==void 0)this.#e=e.client??{messages:{create:async()=>{throw new Error("No client provided.")}}},this.#t=e.streamClient;else{let t=new yn({apiKey:e.apiKey});this.#e=t,this.#t={messages:{stream:n=>t.messages.create({...n,stream:!0})}}}}#c(){let e=this.#o;return e===void 0||e==="off"?void 0:e==="adaptive"?{type:"adaptive"}:{type:"enabled",budget_tokens:kn[e]}}async generate(e){try{let{system:t,messages:n}=xt(e.messages),r=t!==void 0?[{type:"text",text:t,cache_control:{type:"ephemeral"}}]:void 0,o=this.#c(),i=await this.#e.messages.create({model:this.#s,max_tokens:this.#n,...r!==void 0?{system:r}:{},messages:n,...e.tools!==void 0&&e.tools.length>0?{tools:Ct(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}}),a=i.content.filter(vn);if(i.stop_reason==="tool_use"&&a.length>0){let d=i.content.find(Ot);return{type:"tool_calls",calls:a.map(m=>({id:m.id,name:m.name,input:m.input})),...d?.text?{text:d.text}:{},usage:{inputTokens:i.usage.input_tokens,outputTokens:i.usage.output_tokens}}}return{type:"message",content:i.content.find(Ot)?.text??"",usage:{inputTokens:i.usage.input_tokens,outputTokens:i.usage.output_tokens}}}catch(t){return Mt(t)}}async*generateStream(e){if(this.#t===void 0){let t=await this.generate(e);t.type==="message"?(yield{type:"token_delta",delta:t.content},yield{type:"message_done",content:t.content,...t.usage?{usage:t.usage}:{}}):t.type==="tool_calls"?yield{type:"tool_calls",calls:t.calls,...t.usage?{usage:t.usage}:{}}:yield{type:"error",category:t.category,message:t.message,recoverable:t.recoverable};return}try{let{system:t,messages:n}=xt(e.messages),r=t!==void 0?[{type:"text",text:t,cache_control:{type:"ephemeral"}}]:void 0,o=this.#c(),i={model:this.#s,max_tokens:this.#n,...r!==void 0?{system:r}:{},messages:n,...e.tools!==void 0&&e.tools.length>0?{tools:Ct(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}},a=await this.#t.messages.stream(i),c="",d=0,m=0,u=null,p=new Map;for await(let f of a)if(f.type==="message_start")d=f.message.usage.input_tokens;else if(f.type==="content_block_start")f.content_block.type==="tool_use"&&p.set(f.index,{id:f.content_block.id??"",name:f.content_block.name??"",inputJson:""});else if(f.type==="content_block_delta"){if(f.delta.type==="text_delta")c+=f.delta.text,yield{type:"token_delta",delta:f.delta.text};else if(f.delta.type==="input_json_delta"){let l=p.get(f.index);l!==void 0&&(l.inputJson+=f.delta.partial_json)}}else f.type==="message_delta"&&(m=f.usage.output_tokens,u=f.delta.stop_reason);let h={inputTokens:d,outputTokens:m};u==="tool_use"&&p.size>0?yield{type:"tool_calls",calls:Array.from(p.entries()).sort(([l],[g])=>l-g).map(([,l])=>({id:l.id,name:l.name,input:qe(l.inputJson)})),...c?{text:c}:{},usage:h}:yield{type:"message_done",content:c,usage:h}}catch(t){yield Mt(t)}}};function xt(s){let e,t=[],n=0;for(;n<s.length;){let r=s[n];if(r===void 0)break;if(r.role==="system"){e=r.content??void 0,n++;continue}if(r.role==="tool"){let o=[];for(;n<s.length;){let i=s[n];if(i===void 0||i.role!=="tool")break;o.push({type:"tool_result",tool_use_id:i.toolCallId??"",content:i.content??""}),n++}t.push({role:"user",content:o});continue}if(r.role==="assistant"){if(r.toolCalls!==void 0&&r.toolCalls.length>0){let o=[...r.content?[{type:"text",text:r.content}]:[],...r.toolCalls.map(i=>({type:"tool_use",id:i.id,name:i.name,input:i.input}))];t.push({role:"assistant",content:o})}else t.push({role:"assistant",content:r.content??""});n++;continue}t.push({role:"user",content:r.content??""}),n++}return{system:e,messages:t}}function Ct(s){return s.map(e=>({name:e.function.name,description:e.function.description,input_schema:{type:"object",...e.function.parameters.properties!==void 0?{properties:e.function.parameters.properties}:{},...e.function.parameters.required!==void 0?{required:e.function.parameters.required}:{}}}))}function vn(s){return s.type==="tool_use"&&typeof s.id=="string"&&typeof s.name=="string"}function Ot(s){return s.type==="text"&&typeof s.text=="string"}function Mt(s){if(typeof s=="object"&&s!==null&&"status"in s&&typeof s.status=="number"){let e=s;return{type:"error",category:En(e.status),message:e.message??`Anthropic API error ${e.status}.`,recoverable:e.status===429||e.status>=500}}return{type:"error",category:"network",message:"Provider network request failed.",recoverable:!0}}function En(s){return s===401||s===403?"authentication":s===429?"rate_limit":s===400?"invalid_request":s===404?"model_unavailable":s===413||s===422?"context_length":"unknown"}import{exec as Io}from"child_process";import{resolve as Ao,sep as Ro}from"path";import{Worker as Co}from"worker_threads";var Te=class{evaluate(e){let t=e.action.risk;return t==="blocked"?{decision:"deny",risk:t,reason:"Blocked actions are denied."}:e.mode==="observe"?{decision:"ask",risk:t,reason:"Observe mode asks before external actions."}:e.mode==="auto"?t==="high"?{decision:"ask",risk:t,reason:"High-risk action requires approval in auto mode."}:{decision:"allow",risk:t,reason:"Low and medium-risk actions are allowed in auto mode."}:t==="low"?{decision:"allow",risk:t,reason:"Low-risk action is allowed in confirm mode."}:{decision:"ask",risk:t,reason:"Medium and high-risk actions require approval in confirm mode."}}};var Oo=String.raw`
|
|
46
|
+
const { parentPort, workerData } = require('node:worker_threads');
|
|
47
|
+
async function main() {
|
|
48
|
+
const start = Date.now();
|
|
49
|
+
try {
|
|
50
|
+
const fn = new Function('return (async () => { ' + workerData.command + ' })()');
|
|
51
|
+
const result = await fn();
|
|
52
|
+
parentPort.postMessage({
|
|
53
|
+
ok: true,
|
|
54
|
+
stdout: result === undefined ? '' : String(result),
|
|
55
|
+
durationMs: Date.now() - start
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
parentPort.postMessage({
|
|
59
|
+
ok: false,
|
|
60
|
+
stderr: error && error.message ? String(error.message) : String(error),
|
|
61
|
+
durationMs: Date.now() - start
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
main();
|
|
66
|
+
`;import{exec as Sn}from"child_process";import{readdir as Lt,readFile as Xe,stat as Tn,writeFile as _e,mkdir as Dt}from"fs/promises";import{resolve as F,relative as Ft,basename as Ut,extname as jt,dirname as Bt,join as _n}from"path";function Yt(){return{name:"read_file",description:"Read a UTF-8 file inside the workspace.",inputSchema:{type:"object",properties:{path:{type:"string"}},required:["path"]},risk:"low",async execute(s,e){let t=Ht(s);if(t===void 0)return H("Tool input must include a string path.");let n=Ge(e.workspaceRoot,t);if(n===void 0)return ie();if(Ie(n.absolutePath))return be();try{return{ok:!0,content:await Xe(n.absolutePath,"utf8"),summary:`Read file ${n.displayPath}.`}}catch(r){return Z(r)}}}}function Kt(){return{name:"list_directory",description:"List entries in a workspace directory.",inputSchema:{type:"object",properties:{path:{type:"string"}},required:["path"]},risk:"low",async execute(s,e){let t=Ht(s);if(t===void 0)return H("Tool input must include a string path.");let n=Ge(e.workspaceRoot,t);if(n===void 0)return ie();try{return{ok:!0,entries:(await Lt(n.absolutePath,{withFileTypes:!0})).map(o=>({name:o.name,type:o.isDirectory()?"directory":o.isFile()?"file":"other"})).sort((o,i)=>o.name.localeCompare(i.name)),summary:`Listed directory ${n.displayPath}.`}}catch(r){return Z(r)}}}}function Ht(s){if(typeof s!="object"||s===null||!("path"in s))return;let e=s.path;return typeof e=="string"?e:void 0}function Ge(s,e){let t=F(s),n=F(t,e),r=Ft(t,n);if(!(r.startsWith("..")||r===".."||n!==t&&r===""))return{absolutePath:n,displayPath:r===""?".":r}}function H(s){return{ok:!1,error:{code:"invalid_input",message:s}}}function ie(){return{ok:!1,error:{code:"path_outside_workspace",message:"Tool path must stay inside the workspace."}}}function Z(s){return{ok:!1,error:{code:typeof s=="object"&&s!==null&&"code"in s?String(s.code):"fs_error",message:"File system operation failed."}}}function Ie(s){let e=Ut(s).toLowerCase();if(e===".env"||e.startsWith(".env.")||e===".netrc")return!0;let t=jt(e);return t===".key"||t===".pem"||t===".p12"||t===".pfx"?!0:e==="id_rsa"||e==="id_ed25519"||e==="id_ecdsa"||e==="id_dsa"}function be(){return{ok:!1,error:{code:"path_not_permitted",message:"Tool path is not permitted."}}}function In(s){if(typeof s!="object"||s===null)return;let e=s.path,t=s.content;return typeof e=="string"&&typeof t=="string"?{path:e,content:t}:void 0}var bn=3e4,We=4e3,An=[/\brm\b.*-[a-zA-Z]*r[a-zA-Z]*.*\s+\/\s*$/,/\brm\b.*-[a-zA-Z]*r[a-zA-Z]*.*\s+~\/?$/,/:\(\)\s*\{/,/[|>]\s*\/dev\/(sd|hd|nvme|vd)[a-z0-9]?/,/\b(mkfs(\.[a-z0-9]+)?|fdisk|parted|shred)\b/];function Rn(s){return An.some(e=>e.test(s))}function Nt(s){return s.length<=We?s:`${s.slice(0,We)}
|
|
67
|
+
[truncated ${s.length-We} characters]`}function xn(s,e,t){return new Promise(n=>{let r=Date.now();Sn(s,{cwd:e,timeout:t},(o,i,a)=>{let c=Date.now()-r;if(o?.killed===!0){n({completed:!1});return}let d=o===null?0:typeof o.code=="number"?o.code:1;n({completed:!0,exitCode:d,stdout:Nt(i),stderr:Nt(a),durationMs:c})})})}function Cn(s){if(typeof s!="object"||s===null)return;let e=s.command;if(typeof e!="string")return;let t=s.timeoutMs;return{command:e,...typeof t=="number"?{timeoutMs:t}:{}}}function On(){return{ok:!1,error:{code:"command_blocked",message:"Command matches a blocked pattern."}}}function Mn(){return{ok:!1,error:{code:"sandbox_rejected",message:"Command rejected: workspace sandbox prevents execution outside workspace."}}}var $n=[/\/\.\.\//,/\bcd\s+\/(\s|$)/,/\bcd\s+~\/?(\s|$)/];function Nn(s){return $n.some(e=>e.test(s))}function Vt(s){return{name:"run_shell",description:"Run a shell command in the workspace directory. Requires approval.",inputSchema:{type:"object",properties:{command:{type:"string"},timeoutMs:{type:"number"}},required:["command"]},risk:"high",async execute(e,t){let n=Cn(e);if(n===void 0)return H("Tool input must include a string command.");if(Rn(n.command))return On();if(s?.sandboxed===!0&&Nn(n.command))return Mn();let r=n.timeoutMs??bn,o=await xn(n.command,t.workspaceRoot,r);return o.completed?{ok:!0,exitCode:o.exitCode,stdout:o.stdout,stderr:o.stderr,durationMs:o.durationMs,summary:`Ran command in ${o.durationMs}ms with exit code ${o.exitCode}.`}:{ok:!1,error:{code:"timeout",message:`Command exceeded ${r}ms timeout.`}}}}}function qt(){return{name:"write_file",description:"Write or overwrite a UTF-8 file inside the workspace. Requires approval.",inputSchema:{type:"object",properties:{path:{type:"string"},content:{type:"string"}},required:["path","content"]},risk:"medium",async execute(s,e){let t=In(s);if(t===void 0)return H("Tool input must include a string path and string content.");let n=Ge(e.workspaceRoot,t.path);if(n===void 0)return ie();if(Ie(n.absolutePath))return be();try{return await Dt(Bt(n.absolutePath),{recursive:!0}),await _e(n.absolutePath,t.content,"utf8"),{ok:!0,summary:`Wrote file ${n.displayPath}.`}}catch(r){return Z(r)}}}}function Pn(s,e){if(e.length===0)return 0;let t=0,n=0;for(;(n=s.indexOf(e,n))!==-1;)t++,n+=e.length;return t}function Wt(){return{name:"edit_file",description:"Make a precise edit to an existing file by replacing an exact string. old_string must appear exactly once in the file unless replace_all is true. Prefer this over write_file when modifying existing content \u2014 it never loses surrounding code.",risk:"medium",inputSchema:{type:"object",properties:{path:{type:"string",description:"File path relative to workspace root."},old_string:{type:"string",description:"The exact string to replace. Must be unique in the file."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"Replace every occurrence. Default false (errors on multiple matches)."}},required:["path","old_string","new_string"]},async execute(s,e){let t=s;if(typeof t.path!="string"||typeof t.old_string!="string"||typeof t.new_string!="string")return H("path, old_string, and new_string must be strings.");let n=t.path,r=t.old_string,o=t.new_string,i=t.replace_all===!0;if(r.length===0)return H("old_string must not be empty.");let a=F(e.workspaceRoot,n);if(!a.startsWith(F(e.workspaceRoot)+"/")&&a!==F(e.workspaceRoot))return ie();if(Ie(a))return be();let c;try{c=await Xe(a,"utf8")}catch(u){return Z(u)}let d=Pn(c,r);if(d===0)return{ok:!1,error:{code:"string_not_found",message:`old_string not found in ${n}.`}};if(d>1&&!i)return{ok:!1,error:{code:"multiple_matches",message:`old_string appears ${d} times in ${n}. Use replace_all: true or add more surrounding context to make it unique.`}};let m=c.split(r).join(o);try{await _e(a,m,"utf8")}catch(u){return Z(u)}return{ok:!0,path:n,replacements:d,summary:`Edited ${n}: ${d} replacement${d===1?"":"s"}.`}}}}function Jt(){return{name:"append_file",description:"Append text to the end of a file. Creates the file (and parent directories) if it does not exist. Use this to add new code, tests, or entries without touching existing content.",risk:"medium",inputSchema:{type:"object",properties:{path:{type:"string",description:"File path relative to workspace root."},content:{type:"string",description:"Text to append."}},required:["path","content"]},async execute(s,e){let t=s;if(typeof t.path!="string"||typeof t.content!="string")return H("path and content must be strings.");let n=t.path,r=t.content,o=F(e.workspaceRoot,n);if(!o.startsWith(F(e.workspaceRoot)+"/")&&o!==F(e.workspaceRoot))return ie();if(Ie(o))return be();try{await Dt(Bt(o),{recursive:!0}),await _e(o,r,{flag:"a"})}catch(i){return Z(i)}return{ok:!0,path:n,summary:`Appended to ${n}.`}}}}var Je=8e3;function Ln(s){try{let e=new URL(s);return e.protocol==="http:"||e.protocol==="https:"?e:void 0}catch{return}}function Dn(s){return s.replace(/<script[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/ /g," ").replace(/\s+/g," ").trim()}function Fn(s){return s.length<=Je?s:`${s.slice(0,Je)}
|
|
68
|
+
[truncated ${s.length-Je} characters]`}function Un(s){if(typeof s!="object"||s===null)return;let e=s.url;return typeof e=="string"?e:void 0}function Xt(s=fetch){return{name:"read_web_page",description:"Read a public web page and return its text content.",inputSchema:{type:"object",properties:{url:{type:"string"}},required:["url"]},risk:"low",async execute(e,t){let n=Un(e);if(n===void 0)return H("Tool input must include a string url.");let r=Ln(n);if(r===void 0)return H("Tool url must use http or https.");try{let o=await s(n);if(!o.ok)return{ok:!1,error:{code:"http_error",message:`Page request failed with status ${o.status}.`}};let i=await o.text(),a=Fn(Dn(i));return{ok:!0,url:n,content:a,summary:`Read web page ${r.hostname}.`}}catch{return{ok:!1,error:{code:"network_error",message:"Web page request failed."}}}}}}function Gt(s){return{name:"update_todos",description:"Update the task list to track progress on multi-step work. Call this when starting a complex task or after completing each step. At most one item may be in_progress at a time.",inputSchema:{type:"object",properties:{todos:{type:"array",items:{type:"object",properties:{content:{type:"string"},status:{type:"string",enum:["pending","in_progress","completed"]}},required:["content","status"]}}},required:["todos"]},risk:"low",async execute(e,t){let n=e;if(!Array.isArray(n.todos))return{ok:!1,error:{code:"invalid_input",message:"todos must be an array."}};let r=[];for(let i of n.todos){if(typeof i!="object"||i===null)return{ok:!1,error:{code:"invalid_input",message:"Each todo must be an object."}};let{content:a,status:c}=i;if(typeof a!="string"||a.length===0)return{ok:!1,error:{code:"invalid_input",message:"Each todo must have a non-empty content string."}};if(c!=="pending"&&c!=="in_progress"&&c!=="completed")return{ok:!1,error:{code:"invalid_input",message:`Invalid status "${String(c)}". Must be pending, in_progress, or completed.`}};r.push({content:a,status:c})}return r.filter(i=>i.status==="in_progress").length>1?{ok:!1,error:{code:"invalid_input",message:"At most one todo may be in_progress at a time."}}:(s?.(r),{ok:!0})}}}function zt(s){return{name:"load_skill",description:"Load the full instructions for a named skill. Call this when you need to follow a skill's detailed guidance. Available skills are listed in the <skills> section.",risk:"low",inputSchema:{type:"object",properties:{name:{type:"string",description:"The exact skill name to load."}},required:["name"]},async execute(e){let{name:t}=e,n=s.get(t);return n===void 0?{ok:!1,error:`Skill "${t}" not found. Check the skills list for available names.`}:{ok:!0,content:n}}}}var jn=new Set(["node_modules",".git","dist","build","coverage",".pnpm-store",".nyc_output",".turbo",".cache"]),Bn=new Set([".png",".jpg",".jpeg",".gif",".svg",".ico",".webp",".avif",".woff",".woff2",".ttf",".eot",".otf",".pdf",".zip",".tar",".gz",".bz2",".7z",".rar",".exe",".bin",".dll",".so",".dylib",".class",".mp3",".mp4",".wav",".ogg",".webm",".flac",".db",".sqlite",".sqlite3"]),Yn=512*1024,Pt=50;async function*Qt(s){let e;try{e=await Lt(s,{withFileTypes:!0})}catch{return}for(let t of e){if(jn.has(t.name))continue;let n=_n(s,t.name);t.isDirectory()?yield*Qt(n):t.isFile()&&!Bn.has(jt(t.name).toLowerCase())&&(yield n)}}function Kn(s,e){let t=Ut(s),r=e.includes("/")?s.replace(/\\/g,"/"):t,o=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*\//g,"(.*/)?").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]");return new RegExp(`^${o}$`).test(r)}function Zt(){return{name:"update_heartbeat",description:"Write current execution status to HEARTBEAT.md in the workspace. Use during long-running background tasks to signal progress and liveness. Status must be one of: running, completed, failed, idle.",risk:"low",inputSchema:{type:"object",properties:{status:{type:"string",enum:["running","completed","failed","idle"],description:"Current execution status."},message:{type:"string",description:"Human-readable progress note or status message."}},required:["status","message"]},async execute(s,e){let t=s,r=["running","completed","failed","idle"].find(d=>d===t.status)??"running",o=typeof t.message=="string"?t.message.trim():"",i=F(e.workspaceRoot,"HEARTBEAT.md"),a=new Date().toISOString(),c=["# Heartbeat","",`**Status**: ${r}`,`**Last updated**: ${a}`,...o.length>0?["",o]:[]];try{return await _e(i,c.join(`
|
|
69
|
+
`)+`
|
|
70
|
+
`),{ok:!0,filePath:"HEARTBEAT.md"}}catch(d){return{ok:!1,error:{code:"write_error",message:d instanceof Error?d.message:"Failed to write HEARTBEAT.md."}}}}}}function es(){return{name:"search_files",description:"Search for a text or regex pattern across files in the workspace. Returns matching file paths, line numbers, and line content. Skips node_modules, .git, dist, and binary files.",risk:"low",inputSchema:{type:"object",properties:{pattern:{type:"string",description:"Text or regex pattern to search for."},path:{type:"string",description:"Directory to search in, relative to workspace root. Defaults to '.' (workspace root)."},include:{type:"string",description:"Glob pattern to filter files, e.g. '*.ts' or '**/*.md'. Defaults to all non-binary files."},case_sensitive:{type:"boolean",description:"Case-sensitive search. Defaults to false."},max_results:{type:"number",description:`Maximum matching lines to return. Defaults to ${Pt}.`}},required:["pattern"]},async execute(s,e){let t=s,n=e.workspaceRoot,r=t.path?F(n,t.path):n,o=t.max_results??Pt,i=t.case_sensitive===!0?"":"i",a;try{a=new RegExp(t.pattern,i)}catch{let p=t.pattern.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");a=new RegExp(p,i)}let c=[],d=0,m=0,u=!1;e:for await(let p of Qt(r)){let h=Ft(n,p).replace(/\\/g,"/");if(t.include!==void 0&&!Kn(h,t.include))continue;let f;try{if((await Tn(p)).size>Yn)continue;f=await Xe(p,"utf8")}catch{continue}d++;let l=f.split(`
|
|
71
|
+
`),g=!1;for(let E=0;E<l.length;E++){if(a.test(l[E])){if(c.length>=o){u=!0;break e}c.push({file:h,line:E+1,content:l[E].trimEnd()}),g=!0}a.lastIndex=0}g&&m++}return{type:"search_files_result",matches:c,truncated:u,matchedFiles:m,searchedFiles:d}}}}var ee=class{#e=[];async append(e){this.#e.push(e)}async listRecent(e={}){return[...e.limit===void 0?this.#e:this.#e.slice(-e.limit)]}async listByRun(e){return this.#e.filter(t=>t.runId===e)}},Hn=12,Vn=2,qn="Low-risk actions run automatically. Medium and high-risk actions require approval. Blocked actions are never permitted.",Wn="Do not restate the plan. Act now: take the first concrete tool action you can.",ss=/\b(?:i(?:'ll| will)|let me|i(?:'m| am)\s+going to|first[, ]+i(?:'ll| will)|next[, ]+i(?:'ll| will)|i can do that)\b/i,Jn=/\b(?:done|finished|implemented|updated|fixed|changed|ran|verified|found|here(?:'s| is) what|blocked by|the blocker is)\b/i,Xn=/^(?:plan|steps?|next steps?)\s*:/im,Gn=/^(?:[-*•]\s+|\d+[.)]\s+)/u,zn=/\b(?:inspect|investigate|check|look(?:\s+into|\s+at)?|read|search|find|debug|fix|patch|update|change|edit|write|implement|run|test|verify|review|analy(?:s|z)e|summari(?:s|z)e|explain|answer|show|share|report|prepare|refactor|deploy)\b/i,Qn=700,V=class{#e;#t;#s;#n;#r;#o;#c;#a;#u;#d;#m;#p;#h;#l;#g;#y;#T;#k;#v;#E;#w=[];constructor(e){this.#e=e.contextAssembler??new ke,this.#t=e.modelProvider,this.#s=e.permissionPolicy??new Te,this.#n=e.approvalResolver,this.#c=e.maxSteps??Hn,this.#T=e.executionContract??"default",this.#a=e.executionContract==="strict-agentic"?e.maxPlanningStallRetries??3:e.maxPlanningStallRetries??Vn,this.#o=e.skillIndex??[];let t=e.systemInstruction??"";this.#u=e.executionContract==="strict-agentic"?`${t}
|
|
72
|
+
|
|
73
|
+
Execution contract: strict-agentic. Act immediately. Do not narrate plans. Call tools now.`:t,this.#d=e.runtime,this.#m=e.preferStreaming??!1,this.#p=e.compaction,this.#h=e.promptMode,this.#l=e.hooks,this.#g=e.taskStore,this.#y=e.depth??0,this.#k=e.createRunId??ts("run"),this.#v=e.createEventId??ts("evt"),this.#E=e.now??(()=>new Date().toISOString());let n=Gt(o=>{this.#w=o}),r=e.tools??[];this.#r=new Map([n,...r].map(o=>[o.name,o]))}async*runTurn(e){let t=this.#k(),n=e.sessionId?{runId:t,sessionId:e.sessionId}:{runId:t},r=[];{if(this.#l?.beforeTurn!==void 0)try{await this.#l.beforeTurn(e)}catch(y){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeTurn hook threw:",y)}let o=y=>(r.push(y),y);yield o(this.#i({...n,type:"run_started",userMessage:e.message}));let i=[];if(this.#g!==void 0&&e.sessionId!==void 0)try{let y=await this.#g.drainPendingForParent(e.sessionId);for(let k of y)i.push({role:"system",content:Zn(k)})}catch(y){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] drainPendingForParent failed:",y)}let a=i.length>0?[...i,...e.recentMessages??[]]:e.recentMessages,c=this.#I(),d=await this.#e.assemble({systemInstruction:this.#u,...this.#d?{runtime:this.#d}:{},...c.length>0?{tools:c}:{},permissionGuidance:qn,...this.#o.length>0?{skillIndex:this.#o}:{},...a?{recentMessages:a}:{},...this.#h!==void 0?{promptMode:this.#h}:{},userMessage:e.message});yield o(this.#i({...n,type:"context_assembled",messageCount:d.modelInput.messages.length,systemInstructionIncluded:d.report.includedSections.includes("identity")}));let m=this.#S(),u=d.modelInput.messages,p=0,h=0,f=!1,l="";this.#w=[];let g=[],E=d.modelInput.messages.at(-1);for(E&&g.push({...E});p<this.#c;){if(e.signal?.aborted){yield o(this.#i({...n,type:"run_failed",error:{message:"Aborted by user.",recoverable:!1}})),await this.#f(r);return}if(this.#p!==void 0){let w={...He,...this.#p},$=w.memoryFlush?.enabled!==!1;if((Ve(u)>w.maxTokens||u.length>w.maxMessages)&&$){let S=await this.#_(u,w.memoryFlush?.prompt??Ke);yield o(this.#i({...n,type:"memory_flush_triggered",executed:S.executed,toolsInvoked:S.toolsInvoked,...S.reason!==void 0?{reason:S.reason}:{}}))}else $||(yield o(this.#i({...n,type:"memory_flush_triggered",executed:!1,toolsInvoked:[],reason:"disabled"})));let I=u.length;u=await Rt(u,this.#t,this.#p);let N=u.length;if(N<I){let S=u.find(B=>B.role==="system"&&typeof B.content=="string"&&B.content.startsWith(`Conversation summary:
|
|
74
|
+
`)),A=S&&typeof S.content=="string"?S.content.slice(22):"";yield o(this.#i({...n,type:"compaction_triggered",messagesBefore:I,messagesAfter:N,summary:A}))}if(this.#l?.onCompaction!==void 0)try{await this.#l.onCompaction(I,N)}catch(S){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] onCompaction hook threw:",S)}}yield o(this.#i({...n,type:"model_request_started",provider:"configured"}));let y={messages:u,...m.length>0?{tools:m}:{},...d.modelInput.options!==void 0?{options:d.modelInput.options}:{}},k;if(this.#m&&$t(this.#t)){let w="",$,O="",I,N;for await(let S of this.#t.generateStream(y)){if(e.signal?.aborted)break;S.type==="token_delta"?yield o(this.#i({...n,type:"token_delta",delta:S.delta})):S.type==="message_done"?(w=S.content,I=S.usage):S.type==="tool_calls"?($=S.calls,O=S.text??"",I=S.usage):S.type==="error"&&(N={category:S.category,message:S.message,recoverable:S.recoverable})}N!==void 0?k={type:"error",category:N.category,message:N.message,recoverable:N.recoverable}:$!==void 0?k={type:"tool_calls",calls:$,...O?{text:O}:{},...I!==void 0?{usage:I}:{}}:k={type:"message",content:w,...I!==void 0?{usage:I}:{}}}else k=await this.#t.generate(y);if(yield o(this.#i({...n,type:"model_request_completed",provider:"configured"})),p++,k.type==="error"){yield o(this.#i({...n,type:"run_failed",error:{message:k.message,recoverable:k.recoverable}})),await this.#f(r);return}if(k.type==="message"){if([...this.#r.keys()].some(O=>O!=="update_todos")&&!f&&nr(k.content)){if(h++,yield o(this.#i({...n,type:"planning_stall_detected",stallCount:h,maxRetries:this.#a})),h>=this.#a){yield o(this.#i({...n,type:"run_failed",error:{message:"Agent stopped after repeated plan-only turns without taking action.",recoverable:!1}})),await this.#f(r);return}u=[...u,{role:"assistant",content:k.content},{role:"user",content:Wn}];continue}h=0,k.content!==""?(g.push({role:"assistant",content:k.content}),yield o(this.#i({...n,type:"assistant_message_created",message:{role:"assistant",content:k.content}}))):l!==""&&(yield o(this.#i({...n,type:"assistant_message_created",message:{role:"assistant",content:l}}))),yield o(this.#i({...n,type:"turn_complete",messages:[...g]})),yield o(this.#i({...n,type:"run_completed"})),await this.#f(r);return}h=0,k.calls.some(w=>w.name!=="update_todos")&&(f=!0),k.text&&(l=k.text);let x={role:"assistant",content:k.text??null,toolCalls:k.calls};u=[...u,x],g.push({...x});let b=[],T=!1,M="";for(let w of k.calls){yield o(this.#i({...n,type:"tool_call_requested",call:w}));let $=this.#r.get(w.name);if($===void 0){let S=`Tool "${w.name}" is not registered.`;yield o(this.#i({...n,type:"tool_failed",callId:w.id,toolName:w.name,error:{message:S}}));let A={role:"tool",toolCallId:w.id,content:`Error: ${S}`};b.push(A),g.push({...A});continue}let O=this.#s.evaluate({mode:tr(this.#d?.mode),action:er(w,$.risk)});if(yield o(this.#i({...n,type:"tool_call_permission_evaluated",callId:w.id,toolName:w.name,decision:O})),O.decision==="deny"){T=!0,M=`Tool call ${w.name} was denied.`;break}if(O.decision==="ask"){yield o(this.#i({...n,type:"approval_requested",callId:w.id,toolName:w.name,decision:O}));let S=this.#n===void 0?{approved:!1,reason:"No approval resolver was configured."}:await this.#n.resolve({call:w,decision:O});if(yield o(this.#i({...n,type:"approval_resolved",callId:w.id,toolName:w.name,resolution:S})),!S.approved){T=!0,M=`Tool call ${w.name} was denied.`;break}}if(this.#l?.beforeToolCall!==void 0){let S;try{S=await this.#l.beforeToolCall(w)}catch(A){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeToolCall hook threw:",A)}if(S==="abort"){let A="Tool call aborted by hook.";yield o(this.#i({...n,type:"tool_failed",callId:w.id,toolName:w.name,error:{message:A}}));let B={role:"tool",toolCallId:w.id,content:`Error: ${A}`};b.push(B),g.push({...B});continue}}yield o(this.#i({...n,type:"tool_started",callId:w.id,toolName:w.name}));let I;try{let S={workspaceRoot:this.#d?.workspace??process.cwd(),parentRecentMessages:u.map(A=>({role:A.role,content:A.content})),...e.sessionId!==void 0?{parentSessionId:e.sessionId}:{},depth:this.#y};I=await $.execute(w.input,S)}catch(S){let A=S instanceof Error?S.message:"Unknown tool execution error.";yield o(this.#i({...n,type:"tool_failed",callId:w.id,toolName:w.name,error:{message:A}}));let B={role:"tool",toolCallId:w.id,content:`Error: ${A}`};b.push(B),g.push({...B});continue}yield o(this.#i({...n,type:"tool_completed",callId:w.id,toolName:w.name,result:I}));let N={role:"tool",toolCallId:w.id,content:JSON.stringify(I)};if(b.push(N),g.push({...N}),this.#l?.afterToolCall!==void 0)try{await this.#l.afterToolCall(w,I)}catch(S){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] afterToolCall hook threw:",S)}}if(T){yield o(this.#i({...n,type:"run_failed",error:{message:M,recoverable:!1}})),await this.#f(r);return}k.calls.some(w=>w.name==="update_todos")&&(yield o(this.#i({...n,type:"todos_updated",todos:[...this.#w]}))),u=[...u,...b]}yield o(this.#i({...n,type:"run_failed",error:{message:`Agent loop reached the step limit of ${this.#c}.`,recoverable:!1}})),await this.#f(r)}}async#_(e,t){let n=this.#S(),r=[...e,{role:"system",content:t}],o;try{o=await this.#t.generate({messages:r,...n.length>0?{tools:n}:{}})}catch{return{executed:!1,toolsInvoked:[],reason:"model_error"}}if(o.type==="error")return{executed:!1,toolsInvoked:[],reason:"model_error"};if(o.type!=="tool_calls")return{executed:!0,toolsInvoked:[]};let i=[],a={workspaceRoot:this.#d?.workspace??process.cwd(),parentRecentMessages:e.map(c=>({role:c.role,content:c.content})),depth:this.#y};for(let c of o.calls){let d=this.#r.get(c.name);if(d!==void 0&&!(d.risk==="high"||d.risk==="blocked"))try{await d.execute(c.input,a),i.push(c.name)}catch{}}return{executed:!0,toolsInvoked:i}}async#f(e){if(this.#l?.afterTurn!==void 0)try{await this.#l.afterTurn(e)}catch(t){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] afterTurn hook threw:",t)}}#I(){return[...this.#r.values()].map(e=>({name:e.name,description:e.description,risk:e.risk}))}#S(){return[...this.#r.values()].map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.inputSchema}}))}#i(e){return{...e,eventId:this.#v(),timestamp:this.#E()}}};function ts(s){return()=>`${s}_${crypto.randomUUID()}`}function Zn(s){let e=[`[subagent #${s.taskId} ${s.status}]`,`goal: ${s.goal}`,`status: ${s.status}`];return s.terminalSummary!==void 0&&s.terminalSummary.length>0&&e.push(`result: ${s.terminalSummary}`),e.push(`completedAt: ${s.completedAt}`),e.join(`
|
|
75
|
+
`)}function er(s,e){return{kind:"tool",name:s.name,summary:`Model requested tool ${s.name}.`,risk:e}}function tr(s){return s==="observe"||s==="auto"?s:"confirm"}function sr(s){let e=s.split(/\r?\n/).map(o=>o.trim()).filter(Boolean);if(e.length===0)return!1;let t=e.filter(o=>Gn.test(o)).length,n=e.some(o=>ss.test(o));return Xn.test(e[0]??"")&&n||t>=2&&n}function nr(s){let e=s.trim();if(!e||e.length>Qn||e.includes("```")||Jn.test(e))return!1;let t=sr(e);return!(!ss.test(e)&&!t||!t&&!zn.test(e))}function ns(s){return s.runtime!==void 0?s:{runtime:s}}function rs(s,e){return{name:"spawn_subagent_async",description:"Spawn a sub-agent to handle a subtask asynchronously. Returns a taskId immediately; the sub-agent runs in the background. Use spawn_subagent for synchronous execution.",risk:"medium",inputSchema:{type:"object",properties:{goal:{type:"string",description:"The complete goal for the sub-agent."},context:{type:"string",description:"Optional background context."},contextMode:{type:"string",enum:["isolated","fork"],description:"isolated (default): empty transcript. fork: copy parent's recent messages."}},required:["goal"]},async execute(t,n){let r=t,o=`task_${crypto.randomUUID()}`;e?.taskStore!==void 0&&await e.taskStore.create({id:o,runtime:"subagent",task:r.goal,status:"queued",...e.parentTaskId!==void 0?{parentId:e.parentTaskId}:{}});let i=r.context!==void 0?`${r.goal}
|
|
76
|
+
|
|
77
|
+
Context:
|
|
78
|
+
${r.context}`:r.goal,a={contextMode:r.contextMode??"isolated",depth:(n?.depth??0)+1,...n?.parentRecentMessages!==void 0?{parentMessages:n.parentRecentMessages}:{},...n?.parentSessionId!==void 0?{parentSessionKey:n.parentSessionId}:{}};return(async()=>{e?.taskStore!==void 0&&await e.taskStore.update(o,{status:"running"});let d=ns(s.create(r.goal,a)),m=d.runtime,u="",p=!1,h={message:i,...d.firstTurnInput??{}};for await(let f of m.runTurn(h))f.type==="assistant_message_created"&&(u=f.message.content),f.type==="run_failed"&&(p=!0);if(e?.taskStore!==void 0){let f=p?"failed":"succeeded",l=/^\s*no_reply\s*$/i.test(u),g=e.parentTaskId!==void 0&&!l?{taskId:o,goal:r.goal,status:f,...u.length>0?{terminalSummary:u}:{},completedAt:new Date().toISOString()}:void 0;await e.taskStore.update(o,{status:f,...u.length>0?{terminalSummary:u}:{},...g!==void 0?{pendingAnnouncement:g}:{}})}})(),{type:"spawn_subagent_async_result",taskId:o,status:"queued"}}}}function os(s){return{name:"check_subagent",description:"Check the status and result of an async sub-agent by taskId. Returns status (queued/running/succeeded/failed) and result when complete. Use after spawn_subagent_async.",risk:"low",inputSchema:{type:"object",properties:{taskId:{type:"string",description:"The taskId returned by spawn_subagent_async."}},required:["taskId"]},async execute(e){let t=e,n=typeof t.taskId=="string"?t.taskId.trim():"";if(n==="")return{ok:!1,error:{code:"invalid_input",message:"taskId is required."}};let r=await s.get(n);return r===void 0?{ok:!1,error:{code:"not_found",message:`No subagent task found with id "${n}".`}}:{type:"check_subagent_result",taskId:r.id,status:r.status,result:r.terminalSummary}}}}function is(s){return{name:"spawn_subagent",description:"Spawn a focused sub-agent to handle a complex subtask and return its result. Use when the current task requires a separate focused execution context.",risk:"medium",inputSchema:{type:"object",properties:{goal:{type:"string",description:"The complete goal for the sub-agent."},context:{type:"string",description:"Optional background context to share."}},required:["goal"]},async execute(e,t){let n=e,r={contextMode:n.contextMode??"isolated",depth:(t?.depth??0)+1,...t?.parentRecentMessages!==void 0?{parentMessages:t.parentRecentMessages}:{},...t?.parentSessionId!==void 0?{parentSessionKey:t.parentSessionId}:{}},o=ns(s.create(n.goal,r)),i=o.runtime,a="",c=!1,d="",m={message:n.goal,...o.firstTurnInput??{}};for await(let u of i.runTurn(m))u.type==="assistant_message_created"&&(a=u.message.content),u.type==="run_failed"&&(c=!0,d=u.error.message);return c?{type:"spawn_subagent_result",ok:!1,error:d}:{type:"spawn_subagent_result",ok:!0,result:a}}}}function as(s){return{name:"subagents",description:"Inspect and control the parent agent's active sub-agents. Commands: list, info, kill, log (reserved), steer (reserved), send (reserved).",risk:"low",inputSchema:{type:"object",properties:{command:{type:"string",enum:["list","info","kill","log","steer","send"],description:"Action to perform."},taskId:{type:"string",description:'Target run id (for info / kill / log / steer / send). Pass "all" to kill to stop every active child.'},message:{type:"string",description:"Message body for steer / send (reserved)."}},required:["command"]},async execute(e,t){let n=e,r=t?.parentSessionId;if(n.command==="list"){let o=s.control.listActiveRuns();return{type:"subagents_result",command:"list",ok:!0,children:r!==void 0?o.filter(a=>a.parentSessionKey===r):o.filter(a=>a.isSubagent)}}if(n.command==="info"){if(n.taskId===void 0||n.taskId==="")return{type:"subagents_result",command:"info",ok:!1,message:"taskId is required for info."};if(s.taskStore===void 0)return{type:"subagents_result",command:"info",ok:!1,message:"No task store configured."};let o=await s.taskStore.get(n.taskId);return o===void 0?{type:"subagents_result",command:"info",ok:!1,message:`No task found with id "${n.taskId}".`}:{type:"subagents_result",command:"info",ok:!0,record:o}}if(n.command==="kill"){if(n.taskId===void 0||n.taskId==="")return{type:"subagents_result",command:"kill",ok:!1,message:'taskId is required (or pass "all").'};let o=[];if(n.taskId==="all"){let i=s.control.listActiveRuns(),a=r!==void 0?i.filter(c=>c.parentSessionKey===r):i.filter(c=>c.isSubagent);for(let c of a)s.control.cancel(c.runId)&&o.push(c.runId)}else s.control.cancel(n.taskId)&&o.push(n.taskId);return{type:"subagents_result",command:"kill",ok:!0,stopped:o}}return{type:"subagents_result",command:n.command,ok:!1,message:`Command "${n.command}" is reserved for a future phase.`}}}}var ae=class{key;maxConcurrent;#e=0;#t=[];constructor(e){if(!Number.isInteger(e.maxConcurrent)||e.maxConcurrent<1)throw new Error(`Lane "${e.key}" maxConcurrent must be a positive integer; got ${e.maxConcurrent}.`);this.key=e.key,this.maxConcurrent=e.maxConcurrent}async enqueue(e){this.#e>=this.maxConcurrent&&await new Promise(t=>this.#t.push(t)),this.#e++;try{return await e()}finally{this.#e--;let t=this.#t.shift();t!==void 0&&t()}}occupancy(){return{active:this.#e,queued:this.#t.length}}},ce={global:16,subagent:8,session:1},Ae=class{global;subagent;#e=new Map;#t;constructor(e={}){this.global=new ae({key:"global",maxConcurrent:e.globalConcurrency??ce.global}),this.subagent=new ae({key:"subagent",maxConcurrent:e.subagentConcurrency??ce.subagent}),this.#t=e.sessionConcurrency??ce.session}sessionLane(e){let t=this.#e.get(e);return t===void 0&&(t=new ae({key:`session:${e}`,maxConcurrent:this.#t}),this.#e.set(e,t)),t}releaseSessionLane(e){let t=this.#e.get(e);if(t===void 0)return!1;let{active:n,queued:r}=t.occupancy();return n===0&&r===0?(this.#e.delete(e),!0):!1}status(){let e=Array.from(this.#e.values()).map(t=>({key:t.key,...t.occupancy()}));return{global:this.global.occupancy(),subagent:this.subagent.occupancy(),sessions:e}}};async function cs(s,e,t){let n=s.sessionLane(e.sessionId),r=()=>n.enqueue(t),o=()=>e.isSubagent===!0?s.subagent.enqueue(r):r();return s.global.enqueue(o)}var ze=class{#e=new Map;register(e){this.#e.set(e.id,e)}unregister(e){this.#e.delete(e)}touch(e){let t=this.#e.get(e);t!==void 0&&this.#e.set(e,{...t,lastActivityAt:new Date().toISOString()})}get(e){return this.#e.get(e)}list(){return Array.from(this.#e.values())}listByAdapter(e){return this.list().filter(t=>t.adapterName===e)}},rr=5,Qe=class extends Error{code="max_children_per_agent_exceeded";parentSessionKey;limit;constructor(e,t){super(`Parent session "${e}" already has ${t} active children (max).`),this.name="ChildLimitExceededError",this.parentSessionKey=e,this.limit=t}},Ze=class extends Error{code="run_timeout";runId;timeoutSeconds;constructor(e,t){super(`Run "${e}" exceeded its ${t}s timeout.`),this.name="RunTimeoutError",this.runId=e,this.timeoutSeconds=t}},et=class{#e=[];#t=[];#s=!1;#n;push(e){if(this.#s)return;let t=this.#t.shift();if(t!==void 0){t.resolve({value:e,done:!1});return}this.#e.push(e)}close(){if(!this.#s)for(this.#s=!0;this.#t.length>0;){let e=this.#t.shift();e!==void 0&&e.resolve({value:void 0,done:!0})}}fail(e){if(!this.#s)for(this.#s=!0,this.#n=e;this.#t.length>0;){let t=this.#t.shift();t!==void 0&&t.reject(e)}}[Symbol.asyncIterator](){return{next:()=>this.#e.length>0?Promise.resolve({value:this.#e.shift(),done:!1}):this.#s?this.#n!==void 0?Promise.reject(this.#n):Promise.resolve({value:void 0,done:!0}):new Promise((e,t)=>{this.#t.push({resolve:e,reject:t})})}}},Re=class extends ze{#e;#t=new Map;#s;#n;constructor(e={}){super(),this.#e=new Ae(e.lanes??{}),this.#s=e.now??(()=>new Date().toISOString()),this.#n=e.maxChildrenPerAgent??rr}submit(e){let t=new et;if(e.isSubagent===!0&&e.parentSessionKey!==void 0&&this.#r(e.parentSessionKey)>=this.#n)return t.fail(new Qe(e.parentSessionKey,this.#n)),t;let n=new AbortController,o={handle:{runId:e.runId,sessionKey:e.sessionKey,agentId:e.agentId,isSubagent:e.isSubagent===!0,startedAt:this.#s(),...e.parentSessionKey!==void 0?{parentSessionKey:e.parentSessionKey}:{}},controller:n};if(this.#t.set(e.runId,o),e.runTimeoutSeconds!==void 0&&e.runTimeoutSeconds>0){let m=e.runTimeoutSeconds*1e3,u=new Ze(e.runId,e.runTimeoutSeconds);o.timeoutHandle=setTimeout(()=>{n.abort(u)},m)}let i=this.#e,a=e.isSubagent===!0?{sessionId:e.sessionKey,isSubagent:!0}:{sessionId:e.sessionKey},c=this.#t,d=()=>{let m=c.get(e.runId);m?.timeoutHandle!==void 0&&clearTimeout(m.timeoutHandle),c.delete(e.runId)};return cs(i,a,async()=>{if(!n.signal.aborted)for await(let m of e.run(n.signal)){if(n.signal.aborted)break;t.push(m)}}).then(()=>{d(),t.close()}).catch(m=>{d(),t.fail(m)}),t}#r(e){let t=0;for(let n of this.#t.values())n.handle.parentSessionKey===e&&t++;return t}cancel(e){let t=this.#t.get(e);return t===void 0?!1:(t.controller.abort(),!0)}status(){return{lanes:this.#e.status(),activeRuns:Array.from(this.#t.values()).map(e=>e.handle)}}get defaultLaneConcurrency(){return ce}};var ds={streaming:!0,approvalPrompts:!0,background:!1};var or={full:{name:"full",description:"All available tools.",allowedTools:[]},coding:{name:"coding",description:"File system, search, and shell tools for coding tasks.",allowedTools:["read_file","list_directory","write_file","edit_file","append_file","run_shell","search_files","load_skill","update_todos","spawn_subagent","spawn_subagent_async","check_subagent","subagents"]},messaging:{name:"messaging",description:"Read-only tools for informational tasks without file writes or shell execution.",allowedTools:["read_file","list_directory","read_web_page","memory_search","memory_get","load_skill","update_todos"]},background:{name:"background",description:"File system tools only for unattended background tasks.",allowedTools:["read_file","list_directory","write_file","memory_search","memory_get","append_daily_memory","update_todos","spawn_subagent","update_heartbeat"]}};function xe(s,e){let t=or[e];return t.allowedTools.length===0?s:s.filter(n=>t.allowedTools.includes(n.name))}import{mkdir as tt,readFile as ir,writeFile as st}from"fs/promises";import{dirname as nt}from"path";var te=class{#e;constructor(e){this.#e=e}async saveRun(e){await tt(nt(this.#e),{recursive:!0}),await st(this.#e,`${JSON.stringify(e)}
|
|
79
|
+
`,{flag:"a"})}async updateRun(e,t){let r=(await this.#t()).map(o=>o.id===e?{...o,...t}:o);await tt(nt(this.#e),{recursive:!0}),await st(this.#e,r.map(o=>JSON.stringify(o)).join(`
|
|
80
|
+
`)+(r.length>0?`
|
|
81
|
+
`:""))}async listRuns(e={}){let t=await this.#t(),n=e.taskName===void 0?t:t.filter(r=>r.taskName===e.taskName);return e.limit===void 0?n:n.slice(-e.limit)}async#t(){let e="";try{e=await ir(this.#e,"utf8")}catch(n){if(ar(n)&&n.code==="ENOENT")return[];throw n}let t=[];for(let n of e.split(`
|
|
82
|
+
`))n.trim()!==""&&t.push(JSON.parse(n));return t}},le=class{#e;constructor(e="confirm"){this.#e=e}async resolve(e){return this.#e==="auto"?{approved:!0,reason:"Auto-approved in background auto mode."}:{approved:!1,reason:`Auto-denied in background ${this.#e} mode: no user is present to approve.`}}};function ar(s){return s instanceof Error&&"code"in s}function de(s,e){if(s==="*")return!0;let t=parseInt(s,10);return!isNaN(t)&&t===e}function cr(s,e){let t=s.trim().split(/\s+/);if(t.length!==5)return!1;let[n,r,o,i,a]=t;return de(n,e.getMinutes())&&de(r,e.getHours())&&de(o,e.getDate())&&de(i,e.getMonth()+1)&&de(a,e.getDay())}async function rt(s,e){await tt(nt(s),{recursive:!0});let t=["# Heartbeat","",`**Status**: ${e.status}`,`**Last updated**: ${e.lastUpdatedAt}`,...e.taskName!==void 0?[`**Task**: ${e.taskName}`]:[],...e.runId!==void 0?[`**Run ID**: ${e.runId}`]:[],...e.message!==void 0?["",e.message]:[]];await st(s,t.join(`
|
|
83
|
+
`)+`
|
|
84
|
+
`)}var Ce=class{#e;#t;#s;#n;#r;#o=new Map;constructor(e,t,n){this.#e=e,this.#t=t,this.#s=n?.checkIntervalMs??3e4,this.#n=n?.getNow??(()=>new Date)}start(){this.#r===void 0&&(this.#r=setInterval(()=>{this.#c()},this.#s),this.#c())}stop(){this.#r!==void 0&&(clearInterval(this.#r),this.#r=void 0)}get isRunning(){return this.#r!==void 0}async#c(){let e=this.#n();for(let t of this.#e){if(!t.cron||!cr(t.cron,e))continue;let n=this.#o.get(t.name)??0,r=Math.floor(e.getTime()/6e4);if(n!==r){this.#o.set(t.name,r);try{await this.#t(t)}catch{}}}}};import{mkdir as dr,readdir as ms,readFile as at,unlink as ls,writeFile as ot}from"fs/promises";import{join as it}from"path";import fr from"better-sqlite3";var Oe=class{#e=new Map;#t=new Map;#s=new Map;#n;#r;#o;constructor(e={}){this.#n=e.createSessionId??$e("sess"),this.#r=e.createMessageId??$e("msg"),this.#o=e.now??(()=>new Date().toISOString())}async createSession(e={}){let t=this.#o(),n={id:this.#n(),...e.title===void 0?{}:{title:e.title},createdAt:t,updatedAt:t};return this.#e.set(n.id,n),this.#t.set(n.id,[]),this.#s.set(n.id,[]),{...n}}async getSession(e){let t=this.#e.get(e);return t===void 0?void 0:{...t}}async listSessions(e={}){let t=[...this.#e.values()].sort(fs);return(e.limit===void 0?t:t.slice(0,e.limit)).map(r=>({...r}))}async appendMessage(e){let t=this.#e.get(e.sessionId);if(t===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=this.#o(),r={id:this.#r(),sessionId:e.sessionId,role:e.role,content:e.content,createdAt:n,...e.toolCalls!==void 0?{toolCalls:e.toolCalls}:{},...e.toolCallId!==void 0?{toolCallId:e.toolCallId}:{}},o=this.#t.get(e.sessionId)??[];return o.push(r),this.#t.set(e.sessionId,o),this.#e.set(e.sessionId,{...t,updatedAt:n}),{...r}}async listMessages(e,t={}){let n=this.#t.get(e)??[];return(t.limit===void 0?n:n.slice(-t.limit)).map(o=>({...o}))}async appendCompactBoundary(e){let t=this.#e.get(e.sessionId);if(t===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=[];if(e.summary){let r=this.#o();n.push({id:this.#r(),sessionId:e.sessionId,role:"system",content:e.summary,createdAt:r}),this.#e.set(e.sessionId,{...t,updatedAt:r})}this.#t.set(e.sessionId,n)}async appendTraceEvent(e){let t=this.#e.get(e.sessionId);if(t===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=this.#o(),r={sessionId:e.sessionId,event:e.event,createdAt:n},o=this.#s.get(e.sessionId)??[];return o.push(r),this.#s.set(e.sessionId,o),this.#e.set(e.sessionId,{...t,updatedAt:n}),Me(r)}async listTraceEvents(e,t={}){let n=this.#s.get(e)??[];return(t.limit===void 0?n:n.slice(-t.limit)).map(o=>Me(o))}},ue=class{#e;#t;#s;#n;#r;constructor(e){this.#e=e.directory,this.#t=e.createSessionId??$e("sess"),this.#s=e.createMessageId??$e("msg"),this.#n=e.now??(()=>new Date().toISOString());let t=e.fileLock??{};this.#r={enabled:t.enabled??!0,acquireTimeoutMs:t.acquireTimeoutMs??ps,retryIntervalMs:t.retryIntervalMs??hs,staleAfterMs:t.staleAfterMs??gs,...t.pid!==void 0?{pid:t.pid}:{},...t.now!==void 0?{now:t.now}:{},...t.isProcessAlive!==void 0?{isProcessAlive:t.isProcessAlive}:{}}}async createSession(e={}){let t=this.#n(),n={id:this.#t(),...e.title===void 0?{}:{title:e.title},createdAt:t,updatedAt:t};return await this.#o(n.id,{type:"session",session:n}),{...n}}async getSession(e){let t=await this.#a(e);return t.session===void 0?void 0:{...t.session}}async listSessions(e={}){let t=await this.#d(),n=[];for(let i of t){let a=await this.getSession(i);a!==void 0&&n.push(a)}let r=n.sort(fs);return(e.limit===void 0?r:r.slice(0,e.limit)).map(i=>({...i}))}async appendMessage(e){if((await this.#a(e.sessionId)).session===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=this.#n(),r={id:this.#s(),sessionId:e.sessionId,role:e.role,content:e.content,createdAt:n,...e.toolCalls!==void 0?{toolCalls:e.toolCalls}:{},...e.toolCallId!==void 0?{toolCallId:e.toolCallId}:{}};return await this.#o(e.sessionId,{type:"message",message:r}),{...r}}async listMessages(e,t={}){let n=await this.#a(e);return(t.limit===void 0?n.messages:n.messages.slice(-t.limit)).map(o=>({...o}))}async appendTraceEvent(e){if((await this.#a(e.sessionId)).session===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n={sessionId:e.sessionId,event:e.event,createdAt:this.#n()};return await this.#o(e.sessionId,{type:"trace",traceEvent:n}),Me(n)}async listTraceEvents(e,t={}){let n=await this.#a(e);return(t.limit===void 0?n.traceEvents:n.traceEvents.slice(-t.limit)).map(o=>Me(o))}async appendCompactBoundary(e){if((await this.#a(e.sessionId)).session===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=this.#n();await this.#o(e.sessionId,{type:"compact_boundary",summary:e.summary,messagesBefore:e.messagesBefore,messagesAfter:e.messagesAfter,createdAt:n})}async#o(e,t){if(await dr(this.#e,{recursive:!0}),this.#r.enabled){let n=await ur(this.#c(e),this.#r);try{await ot(this.#u(e),`${JSON.stringify(t)}
|
|
85
|
+
`,{flag:"a"})}finally{await n.release()}}else await ot(this.#u(e),`${JSON.stringify(t)}
|
|
86
|
+
`,{flag:"a"})}#c(e){return us(e),it(this.#e,`${e}.lock`)}async#a(e){let t="";try{t=await at(this.#u(e),"utf8")}catch(i){if(q(i)&&i.code==="ENOENT")return{messages:[],traceEvents:[]};throw i}let n=[],r=[],o;for(let i of t.split(`
|
|
87
|
+
`)){if(i.trim()==="")continue;let a=JSON.parse(i);a.type==="session"?o=a.session:a.type==="compact_boundary"?(n=[],a.summary&&n.push({id:`cmpct_${a.createdAt}`,sessionId:o?.id??"",role:"system",content:a.summary,createdAt:a.createdAt}),o&&a.createdAt>o.updatedAt&&(o={...o,updatedAt:a.createdAt})):a.type==="message"?(n.push(a.message),o&&a.message.createdAt>o.updatedAt&&(o={...o,updatedAt:a.message.createdAt})):(r.push(a.traceEvent),o&&a.traceEvent.createdAt>o.updatedAt&&(o={...o,updatedAt:a.traceEvent.createdAt}))}return{...o===void 0?{}:{session:o},messages:n,traceEvents:r}}#u(e){return us(e),it(this.#e,`${e}.jsonl`)}async#d(){try{return(await ms(this.#e)).filter(t=>t.endsWith(".jsonl")).map(t=>t.slice(0,-6)).filter(t=>/^[A-Za-z0-9_-]+$/.test(t))}catch(e){if(q(e)&&e.code==="ENOENT")return[];throw e}}};function us(s){if(!/^[A-Za-z0-9_-]+$/.test(s))throw new Error(`Unsafe session id "${s}".`)}function q(s){return s instanceof Error&&"code"in s}function fs(s,e){return e.updatedAt.localeCompare(s.updatedAt)}function Me(s){return{...s,event:structuredClone(s.event)}}function $e(s){return()=>`${s}_${crypto.randomUUID()}`}var ps=6e4,hs=50,gs=6e4;function lr(s){try{return process.kill(s,0),!0}catch(e){return!(q(e)&&e.code==="ESRCH")}}async function ur(s,e={}){let t=e.acquireTimeoutMs??ps,n=e.retryIntervalMs??hs,r=e.staleAfterMs??gs,o=e.pid??process.pid,i=e.now??(()=>Date.now()),a=e.isProcessAlive??lr,c=i(),d={pid:o,startedAt:i()},m=JSON.stringify(d),u=!1,p=async()=>{if(!u){u=!0;try{await ls(s)}catch(h){if(q(h)&&h.code==="ENOENT")return;throw h}}};for(;;){try{return await ot(s,m,{flag:"wx"}),{lockPath:s,release:p}}catch(l){if(!q(l)||l.code!=="EEXIST")throw l}let h;try{let l=await at(s,"utf8");h=JSON.parse(l)}catch(l){(!q(l)||l.code!=="ENOENT"&&!(l instanceof SyntaxError))&&(h=void 0)}let f=!1;if((h===void 0||i()-h.startedAt>r||typeof h.pid=="number"&&!a(h.pid))&&(f=!0),f){try{await ls(s)}catch(l){if(!q(l)||l.code!=="ENOENT")throw l}continue}if(i()-c>t)throw new Error(`Timed out acquiring session file lock at ${s} after ${t}ms (held by pid ${h?.pid??"?"}).`);await new Promise(l=>setTimeout(l,n))}}var mr=`
|
|
88
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
89
|
+
id TEXT PRIMARY KEY,
|
|
90
|
+
title TEXT,
|
|
91
|
+
createdAt TEXT NOT NULL,
|
|
92
|
+
updatedAt TEXT NOT NULL
|
|
93
|
+
);
|
|
94
|
+
CREATE INDEX IF NOT EXISTS sessions_updated_idx ON sessions(updatedAt DESC);
|
|
95
|
+
|
|
96
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
97
|
+
id TEXT PRIMARY KEY,
|
|
98
|
+
sessionId TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
99
|
+
role TEXT NOT NULL,
|
|
100
|
+
content TEXT,
|
|
101
|
+
toolCallsJson TEXT,
|
|
102
|
+
toolCallId TEXT,
|
|
103
|
+
createdAt TEXT NOT NULL
|
|
104
|
+
);
|
|
105
|
+
CREATE INDEX IF NOT EXISTS messages_session_created_idx ON messages(sessionId, createdAt);
|
|
106
|
+
|
|
107
|
+
CREATE TABLE IF NOT EXISTS trace_events (
|
|
108
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
109
|
+
sessionId TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
110
|
+
eventJson TEXT NOT NULL,
|
|
111
|
+
createdAt TEXT NOT NULL
|
|
112
|
+
);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS trace_events_session_created_idx ON trace_events(sessionId, createdAt);
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS compact_boundaries (
|
|
116
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
117
|
+
sessionId TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
118
|
+
summary TEXT NOT NULL,
|
|
119
|
+
messagesBefore INTEGER NOT NULL,
|
|
120
|
+
messagesAfter INTEGER NOT NULL,
|
|
121
|
+
createdAt TEXT NOT NULL
|
|
122
|
+
);
|
|
123
|
+
CREATE INDEX IF NOT EXISTS compact_boundaries_session_created_idx ON compact_boundaries(sessionId, createdAt);
|
|
124
|
+
|
|
125
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
126
|
+
version INTEGER PRIMARY KEY
|
|
127
|
+
);
|
|
128
|
+
`;async function ys(s,e,t={}){let n={sessions:0,messages:0,traceEvents:0,compactBoundaries:0},r;try{r=(await ms(s)).filter(i=>i.endsWith(".jsonl"))}catch(i){if(q(i)&&i.code==="ENOENT")return n;throw i}if(r.length===0)return n;let o=t.dryRun===!0?void 0:new fr(e);o!==void 0&&(o.pragma("journal_mode = WAL"),o.pragma("synchronous = NORMAL"),o.pragma("foreign_keys = ON"),o.exec(mr));try{for(let i of r){let a=await at(it(s,i),"utf8"),c;for(let d of a.split(`
|
|
129
|
+
`)){if(d.trim()==="")continue;let m=JSON.parse(d);m.type==="session"?(c=m.session.id,n.sessions++,o!==void 0&&o.prepare("INSERT OR IGNORE INTO sessions (id, title, createdAt, updatedAt) VALUES (?, ?, ?, ?)").run(m.session.id,m.session.title??null,m.session.createdAt,m.session.updatedAt)):m.type==="message"?(n.messages++,o!==void 0&&o.prepare("INSERT OR IGNORE INTO messages (id, sessionId, role, content, toolCallsJson, toolCallId, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?)").run(m.message.id,m.message.sessionId,m.message.role,m.message.content??null,m.message.toolCalls===void 0?null:JSON.stringify(m.message.toolCalls),m.message.toolCallId??null,m.message.createdAt)):m.type==="trace"?(n.traceEvents++,o!==void 0&&o.prepare("INSERT INTO trace_events (sessionId, eventJson, createdAt) VALUES (?, ?, ?)").run(m.traceEvent.sessionId,JSON.stringify(m.traceEvent.event),m.traceEvent.createdAt)):m.type==="compact_boundary"&&(n.compactBoundaries++,o!==void 0&&c!==void 0&&o.prepare("INSERT INTO compact_boundaries (sessionId, summary, messagesBefore, messagesAfter, createdAt) VALUES (?, ?, ?, ?, ?)").run(c,m.summary,m.messagesBefore,m.messagesAfter,m.createdAt))}}}finally{o?.close()}return n}import{mkdir as pr,readFile as ws,writeFile as hr}from"fs/promises";import{join as si,dirname as gr}from"path";import yr from"better-sqlite3";var U=class{#e;constructor(e){this.#e=e}async#t(){try{return(await ws(this.#e,"utf-8")).split(`
|
|
130
|
+
`).filter(t=>t.trim().length>0).map(t=>JSON.parse(t))}catch{return[]}}async#s(e){await pr(gr(this.#e),{recursive:!0}),await hr(this.#e,e.map(t=>JSON.stringify(t)).join(`
|
|
131
|
+
`)+`
|
|
132
|
+
`,"utf-8")}async create(e){let t=new Date().toISOString(),n={...e,createdAt:t,updatedAt:t},r=await this.#t();return r.push(n),await this.#s(r),n}async update(e,t){let n=await this.#t(),r=n.findIndex(c=>c.id===e);if(r===-1)return;let{clearPendingAnnouncement:o,...i}=t,a={...n[r],...i,updatedAt:new Date().toISOString()};return o===!0&&delete a.pendingAnnouncement,n[r]=a,await this.#s(n),a}async get(e){return(await this.#t()).find(n=>n.id===e)}async list(e){let t=await this.#t();return e?.status!==void 0&&(t=t.filter(n=>n.status===e.status)),e?.parentId!==void 0&&(t=t.filter(n=>n.parentId===e.parentId)),e?.limit!==void 0&&(t=t.slice(-e.limit)),t}async drainPendingForParent(e){let t=await this.#t(),n=[],r=new Date().toISOString(),o=!1;for(let i=0;i<t.length;i++){let a=t[i];if(a.parentId===e&&a.pendingAnnouncement!==void 0){n.push(a.pendingAnnouncement);let c={...a,updatedAt:r};delete c.pendingAnnouncement,t[i]=c,o=!0}}return o&&await this.#s(t),n}};var wr=`
|
|
133
|
+
CREATE TABLE IF NOT EXISTS task_records (
|
|
134
|
+
id TEXT PRIMARY KEY,
|
|
135
|
+
runtime TEXT NOT NULL,
|
|
136
|
+
task TEXT NOT NULL,
|
|
137
|
+
status TEXT NOT NULL,
|
|
138
|
+
progressSummary TEXT,
|
|
139
|
+
terminalSummary TEXT,
|
|
140
|
+
parentId TEXT,
|
|
141
|
+
sessionId TEXT,
|
|
142
|
+
pendingAnnouncementJson TEXT,
|
|
143
|
+
createdAt TEXT NOT NULL,
|
|
144
|
+
updatedAt TEXT NOT NULL
|
|
145
|
+
);
|
|
146
|
+
CREATE INDEX IF NOT EXISTS task_records_status_idx ON task_records(status);
|
|
147
|
+
CREATE INDEX IF NOT EXISTS task_records_parent_idx ON task_records(parentId);
|
|
148
|
+
CREATE INDEX IF NOT EXISTS task_records_runtime_idx ON task_records(runtime);
|
|
149
|
+
CREATE INDEX IF NOT EXISTS task_records_created_idx ON task_records(createdAt);
|
|
150
|
+
|
|
151
|
+
CREATE TABLE IF NOT EXISTS schema_version (version INTEGER PRIMARY KEY);
|
|
152
|
+
`;async function ks(s,e,t={}){let n={taskRecords:0},r;try{r=await ws(s,"utf-8")}catch(a){if(a instanceof Error&&"code"in a&&a.code==="ENOENT")return n;throw a}let o=r.split(`
|
|
153
|
+
`).filter(a=>a.trim().length>0);if(o.length===0)return n;let i=t.dryRun===!0?void 0:new yr(e);i!==void 0&&(i.pragma("journal_mode = WAL"),i.pragma("synchronous = NORMAL"),i.exec(wr));try{for(let a of o){let c=JSON.parse(a);n.taskRecords++,i!==void 0&&i.prepare(`INSERT OR IGNORE INTO task_records (
|
|
154
|
+
id, runtime, task, status, progressSummary, terminalSummary,
|
|
155
|
+
parentId, sessionId, pendingAnnouncementJson, createdAt, updatedAt
|
|
156
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(c.id,c.runtime,c.task,c.status,c.progressSummary??null,c.terminalSummary??null,c.parentId??null,c.sessionId??null,c.pendingAnnouncement===void 0?null:JSON.stringify(c.pendingAnnouncement),c.createdAt,c.updatedAt)}}finally{i?.close()}return n}import{copyFile as kr,mkdir as vs,readFile as me,readdir as vr,writeFile as Er}from"fs/promises";import{homedir as Sr}from"os";import{basename as Tr,join as W}from"path";var _r=[{name:"research",description:"Use when investigating external information, comparing sources, or summarizing findings. Guides web search, source reading, source comparison, and citation-aware output.",body:"Search for relevant sources, read and compare at least two, and summarize findings with source links. Prefer primary sources. Flag conflicting evidence.",source:"built-in",filePath:""},{name:"project-inspector",description:"Use when understanding a codebase, identifying technologies, or summarizing module responsibilities. Guides project structure inspection and technology detection.",body:"Read README, list top-level directories, inspect package files, and summarize each module's role. Identify entry points and dependency boundaries.",source:"built-in",filePath:""},{name:"safe-shell",description:"Use when planning to run shell commands, especially destructive or irreversible ones. Guides shell command risk assessment and command purpose explanation.",body:"State the purpose before running. Prefer read-only commands. Avoid rm -rf, force flags, or piped untrusted input. Confirm intent before destructive operations.",source:"built-in",filePath:""}],se=class{async load(e={}){let t=new Set,n=[],r=a=>{t.has(a.name)||(t.add(a.name),n.push(a))};if(e.workspaceRoot!==void 0){let a=W(e.workspaceRoot,"skills");for(let c of await this.#e(a,"workspace",e))r(c)}let o=e.userSkillsDir??W(Sr(),".vole","skills"),i=await Ir(o,e.readFile);for(let a of await this.#e(o,"user",e,i))r(a);for(let a of _r)r(a);return n}async#e(e,t,n,r){let o=n.readDir??(d=>vr(d)),i=n.readFile??(d=>me(d,"utf8")),a;try{a=await o(e)}catch(d){if(br(d)&&d.code==="ENOENT")return[];throw d}let c=[];for(let d of a){if(d==="skills-index.json")continue;let m=W(e,d,"SKILL.md");if(t==="user"&&r!==void 0){let u=r.skills.find(p=>p.name===d);if(u!==void 0&&u.enabled===!1)continue}try{let u=await i(m),p=ct(u);if(p!==null){let h,f;if(t==="user"){let g=r?.skills.find(E=>E.name===d);h=g?.trusted??!1,f=g?.enabled??!0}let l={...p,source:t,filePath:m,...h!==void 0?{trusted:h}:{},...f!==void 0?{enabled:f}:{}};c.push(l)}}catch{}}return c}};async function Ir(s,e){let t=e??(r=>me(r,"utf8")),n=W(s,"skills-index.json");try{let r=await t(n);return JSON.parse(r)}catch{return}}var ne=class{#e;constructor(e){this.#e=e}async loadManifest(){let e=W(this.#e,"skills-index.json");try{let t=await me(e,"utf8");return JSON.parse(t)}catch{return{skills:[]}}}async saveManifest(e){await vs(this.#e,{recursive:!0});let t=W(this.#e,"skills-index.json");await Er(t,JSON.stringify(e,null,2)+`
|
|
157
|
+
`,"utf8")}async install(e){let t=Tr(e),n=t.endsWith(".md")?t.slice(0,-3):t,r=await me(e,"utf8"),o=ct(r),i=o?.name??n,a=W(this.#e,i);await vs(a,{recursive:!0});let c=W(a,"SKILL.md");await kr(e,c);let d=await this.loadManifest(),m=d.skills.findIndex(p=>p.name===i),u={name:i,filePath:c,installedAt:new Date().toISOString(),...o?.origin!==void 0?{origin:o.origin}:{},trusted:!1,enabled:!0};return m!==-1?d.skills[m]=u:d.skills.push(u),await this.saveManifest(d),u}async enable(e){let t=await this.loadManifest(),n=t.skills.find(r=>r.name===e);if(n===void 0)throw new Error(`Skill "${e}" not found in manifest.`);n.enabled=!0,await this.saveManifest(t)}async disable(e){let t=await this.loadManifest(),n=t.skills.find(r=>r.name===e);if(n===void 0)throw new Error(`Skill "${e}" not found in manifest.`);n.enabled=!1,await this.saveManifest(t)}async trust(e){let t=await this.loadManifest(),n=t.skills.find(r=>r.name===e);if(n===void 0)throw new Error(`Skill "${e}" not found in manifest.`);n.trusted=!0,await this.saveManifest(t)}async review(e){let n=(await this.loadManifest()).skills.find(r=>r.name===e);if(n!==void 0)try{let r=await me(n.filePath,"utf8"),o=ct(r);return o===null?void 0:{...o,source:"user",filePath:n.filePath,trusted:n.trusted,enabled:n.enabled}}catch{return}}async listEntries(){return(await this.loadManifest()).skills}};function ct(s){let e=s.split(`
|
|
158
|
+
`);if(e[0]?.trim()!=="---")return null;let t=e.findIndex((f,l)=>l>0&&f.trim()==="---");if(t===-1)return null;let n=e.slice(1,t),r=e.slice(t+1).join(`
|
|
159
|
+
`).trim(),o={},i={},a=null;for(let f of n){let l=/^\s+-\s+(.+)$/.exec(f);if(l!==null&&a!==null){let y=l[1]?.trim()??"";y.length>0&&(i[a]=[...i[a]??[],y]);continue}let g=f.indexOf(":");if(g===-1){a=null;continue}let E=f.slice(0,g).trim(),v=f.slice(g+1).trim();if(E.length===0){a=null;continue}v===""?a=E:(a=null,o[E]=v)}let{name:c,description:d,version:m,origin:u,permissions:p}=o;if(!c||!d)return null;let h;return p!==void 0&&p.length>0?h=p.split(",").map(f=>f.trim()).filter(f=>f.length>0):i.permissions!==void 0&&(h=i.permissions),{name:c,description:d,body:r,...m!==void 0?{version:m}:{},...u!==void 0?{origin:u}:{},...h!==void 0?{permissions:h}:{}}}function Es(s){return{name:s.name,description:s.description,source:s.source}}function br(s){return s instanceof Error&&"code"in s}import{createHash as li}from"crypto";import{mkdir as Ss,readdir as Ar,readFile as Le,writeFile as Pe,access as Rr}from"fs/promises";import{join as Ne,relative as xr,resolve as j}from"path";import pi from"better-sqlite3";function Cr(s,e){let t=Math.min(s.length,e.length),n=0;for(let r=0;r<t;r++)n+=(s[r]??0)*(e[r]??0);return n}function Or(s,e){let t=new Map;for(let n of s)n.forEach((r,o)=>{let i=o+1,a=1/(e+i),c=t.get(r.key);c?c.score+=a:t.set(r.key,{score:a,record:r.record})});return[...t.values()].sort((n,r)=>r.score-n.score).map(n=>n.record)}function Ts(s,e){let t=e?.embeddingProvider,n=e?.topKVector??10,r=e?.fusionConstant??60;return{name:"memory_search",description:t===void 0?"Search over memory files (MEMORY.md, USER.md, memory/YYYY-MM-DD.md) for relevant content. Returns matching excerpts.":"Hybrid search over memory files (MEMORY.md, USER.md, memory/YYYY-MM-DD.md): combines keyword paragraph match with vector top-K from the configured embedding provider, fused via reciprocal rank fusion.",risk:"low",inputSchema:{type:"object",properties:{query:{type:"string"},maxResults:{type:"number"}},required:["query"]},async execute(o){let i=o,a=typeof i.query=="string"?i.query:"",c=typeof i.maxResults=="number"?i.maxResults:5,d=[],m=Ne(s,"MEMORY.md"),u=Ne(s,"USER.md"),p=Ne(s,"memory");for(let y of[m,u])try{await Rr(y),d.push(y)}catch{}try{let y=await Ar(p,{recursive:!0,withFileTypes:!0});for(let k of y)if(k.isFile()&&k.name.endsWith(".md")){let x=typeof k.parentPath=="string"?k.parentPath:k.path;d.push(Ne(x,k.name))}}catch{}if(d.length===0)return{ok:!0,results:[],total:0};let h=[];for(let y of d){let k;try{k=await Le(y,"utf8")}catch{continue}let x=k.split(/\n\n+/),b=xr(s,y);x.forEach((T,M)=>{let w=T.trim();w.length!==0&&h.push({key:`${b}#${M}`,record:{file:b,excerpt:w}})})}if(h.length===0)return{ok:!0,results:[],total:0};let f=a.toLowerCase().split(/\s+/).filter(y=>y.length>0),l=h.filter(y=>{let k=y.record.excerpt.toLowerCase();return f.some(x=>k.includes(x))});if(t===void 0){let y=l.slice(0,c).map(k=>k.record);return{ok:!0,results:y,total:y.length}}let g=[];try{let y=await t.embed([a,...h.map(x=>x.record.excerpt)]),k=y[0];if(k!==void 0&&y.length===h.length+1){let x=h.map((b,T)=>{let M=y[T+1],w=M===void 0?0:Cr(k,M);return{entry:b,score:w}});x.sort((b,T)=>T.score-b.score),g=x.slice(0,n).map(b=>b.entry)}}catch{g=[]}let v=Or([g,l],r).slice(0,c);return{ok:!0,results:v,total:v.length}}}}function _s(s){return{name:"memory_get",description:"Read the full contents of a specific memory file. Valid paths: MEMORY.md, USER.md, memory/YYYY-MM-DD.md",risk:"low",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path within the memory workspace, e.g. MEMORY.md or memory/2026-05-05.md"}},required:["path"]},async execute(e){let t=e,n=typeof t.path=="string"?t.path:"";if(n.includes(".."))return{ok:!0,error:"Path traversal is not permitted."};if(n.startsWith("/"))return{ok:!0,error:"Absolute paths are not permitted."};if(!n.endsWith(".md"))return{ok:!0,error:"Only .md files are permitted."};let r=j(s),o=j(r,n);if(!o.startsWith(r+"/")&&o!==r)return{ok:!0,error:"Path traversal is not permitted."};try{return{ok:!0,content:await Le(o,"utf8")}}catch{return{ok:!0,error:`File not found: ${n}`}}}}}var Mr=/^## \[(pending|approved|rejected)\]\s+([A-Za-z0-9_.\-]+)\s*$/,$r=/^\*\*Source\*\*:\s*(.*)$/;function Is(s){let e=[],t=s.split(/\r?\n/),n,r=()=>{if(n!==void 0){for(;n.bodyLines.length>0&&n.bodyLines[n.bodyLines.length-1]?.trim()==="";)n.bodyLines.pop();for(;n.bodyLines.length>0&&n.bodyLines[0]?.trim()==="";)n.bodyLines.shift();e.push({id:n.id,status:n.status,...n.source!==void 0?{source:n.source}:{},body:n.bodyLines.join(`
|
|
160
|
+
`).trim()}),n=void 0}};for(let o of t){let i=o.match(Mr);if(i!==null){r();let[,a,c]=i;n={id:c??"",status:a??"pending",bodyLines:[]};continue}if(o.trim()==="---"){r();continue}if(n!==void 0){if(n.source===void 0&&n.bodyLines.length===0){let a=o.match($r);if(a!==null){n.source=(a[1]??"").trim();continue}}n.bodyLines.push(o)}}return r(),e}function Nr(s){let e=["# Dream Entries \u2014 Pending Review",""];for(let t of s)e.push(`## [${t.status}] ${t.id}`),t.source!==void 0&&e.push(`**Source**: ${t.source}`),e.push(""),e.push(t.body.trim()),e.push(""),e.push("---"),e.push("");return e.join(`
|
|
161
|
+
`)}async function dt(s){let e=j(s,"DREAMS.md");try{let t=await Le(e,"utf8");return Is(t)}catch(t){if(bs(t))return[];throw t}}function bs(s){return s instanceof Error&&"code"in s&&s.code==="ENOENT"}async function lt(s,e,t,n){let r=j(s),o=j(r,"DREAMS.md"),i=j(r,"MEMORY.md"),a;try{a=Is(await Le(o,"utf8"))}catch(u){if(bs(u))return;throw u}let c=a.findIndex(u=>u.id===e);if(c===-1)return;let d=a[c],m=[...a.slice(0,c),...a.slice(c+1)];if(t==="approve"){let u=(n?.now?.()??new Date).toISOString(),p=`
|
|
162
|
+
## Promoted from DREAMS.md (${e}, ${u})
|
|
163
|
+
|
|
164
|
+
${d.body}
|
|
165
|
+
`;await Pe(i,p,{flag:"a"})}else{let u=j(r,"DREAMS","archive");await Ss(u,{recursive:!0});let p=`# ${e}
|
|
166
|
+
|
|
167
|
+
Status: rejected
|
|
168
|
+
Archived-At: ${(n?.now?.()??new Date).toISOString()}
|
|
169
|
+
|
|
170
|
+
${d.body}
|
|
171
|
+
`;await Pe(j(u,`${e}.md`),p)}return await Pe(o,Nr(m)),{...d,status:t==="approve"?"approved":"rejected"}}function As(s){return{name:"append_daily_memory",description:"Append a note to today's daily memory file (memory/YYYY-MM-DD.md) in the workspace. Use this to record facts, decisions, or observations worth remembering across sessions.",inputSchema:{type:"object",properties:{content:{type:"string"}},required:["content"]},risk:"medium",async execute(e,t){let n=e;if(typeof n.content!="string"||n.content.trim().length===0)return{ok:!1,error:{code:"invalid_input",message:"content must be a non-empty string."}};let r=s?.getCurrentDate?.()??new Date().toISOString().slice(0,10),o=j(t.workspaceRoot,"memory"),i=j(o,`${r}.md`);try{await Ss(o,{recursive:!0});let c=`
|
|
172
|
+
## ${new Date().toISOString().replace("T"," ").slice(0,16)}
|
|
173
|
+
|
|
174
|
+
${n.content.trim()}
|
|
175
|
+
`;return await Pe(i,c,{flag:"a"}),{ok:!0,filePath:`memory/${r}.md`,summary:`Appended note to memory/${r}.md.`}}catch(a){return{ok:!1,error:{code:"write_error",message:a instanceof Error?a.message:"Failed to write daily memory."}}}}}}var Pi="@vole/cli";async function xs(s){try{return JSON.parse(await ge(s,"utf8"))}catch{return}}async function Fr(s=process.cwd()){let e=s;for(;;)try{return await J(_(e,".git")),e}catch{let t=L(e);if(t===e)return;e=t}}async function R(s={}){let e=s.env??process.env,t=e.HOME??process.env.HOME,n={env:e};t!==void 0&&(n.userConfig=await xs(_(t,".vole","config.json"))),n.projectConfig=await xs(_("vole.config.json"));let r=Be(n);if(r.sessions.directory==="~/.vole/sessions"){let o=await Fr(s.cwd);o!==void 0&&(r.sessions.directory=_(o,".vole","sessions"))}return r}var De=`You are Vole, a capable coding and general-purpose agent.
|
|
176
|
+
|
|
177
|
+
## Tool Call Style
|
|
178
|
+
Do not narrate routine, low-risk tool calls \u2014 just call the tool.
|
|
179
|
+
Narrate only when it genuinely helps: multi-step work, sensitive actions, or when explaining a non-obvious choice.
|
|
180
|
+
Keep narration brief; avoid restating what tool output already shows.
|
|
181
|
+
|
|
182
|
+
## Execution Bias
|
|
183
|
+
- Pure conversational message (greeting, capability question, clarification): reply directly; do not call tools.
|
|
184
|
+
- Actionable request: act in this turn, do not describe what you plan to do.
|
|
185
|
+
- Non-final turn: use tools to advance, or ask for the one decision that blocks safe progress.
|
|
186
|
+
- Continue until done or genuinely blocked; do not end with a plan or promise when tools can move work forward.
|
|
187
|
+
- Weak or empty tool result: vary the query, path, command, or source before concluding.
|
|
188
|
+
- Mutable facts require live checks: files, git state, versions, running processes, package state.
|
|
189
|
+
- Final answer requires evidence: test output, lint result, file inspection, or a named concrete blocker.
|
|
190
|
+
- Longer work: brief progress note, then keep going.
|
|
191
|
+
|
|
192
|
+
## File Editing
|
|
193
|
+
- Modify existing code: edit_file (precise string replacement, preserves surrounding content).
|
|
194
|
+
- Add to end of file: append_file.
|
|
195
|
+
- Create new files or intentional full replacement: write_file.`,G=new Re;async function Ur(s,e,t={}){if((s[0]==="--"?s.slice(1):s).length===0)return Cs(t,{fakeInteractive:!1,resume:!1});let r="",o=null,i=new Pr().name("vole").description("A capable coding and general-purpose agent.").version(e,"-v, --version","Show version number").exitOverride().configureOutput({writeOut:l=>{r+=l},writeErr:l=>{r+=l}}).addHelpText("after","\nRun `vole <command> --help` for command-specific options.");i.command("chat").description("Start an interactive chat session").argument("[extra...]","Slash commands to run after a --fake turn").option("-s, --session <id>","Continue a named session").option("-r, --resume","Continue the most recently updated session").option("--fake <message>","Run one turn with a fake provider and exit").option("--fake-interactive","Interactive chat with a fake provider").action(async(l,g)=>{let E=l.filter(y=>y.startsWith("/"));if(g.fake!==void 0){o=await jr({message:g.fake,slashCommands:E},t);return}if(g.fakeInteractive){let y=typeof g.session=="string"?g.session:void 0;o=await Br(t,{fakeInteractive:!0,resume:!1,...y!==void 0?{sessionId:y}:{}});return}let v=typeof g.session=="string"?g.session:void 0;o=await Cs(t,{fakeInteractive:!1,resume:g.resume===!0,...v!==void 0?{sessionId:v}:{}})}),i.command("sessions").description("List stored chat sessions").action(async()=>{o=await Kr(t)}),i.command("run").description('Run a one-shot background task e.g. vole run "fix the tests"').argument("[goal]","Goal for the task").option("--mode <mode>","Autonomy mode: auto | confirm | observe","confirm").option("--dream","Consolidate daily memory notes into MEMORY.md").action(async(l,g)=>{if(g.dream){o=await zr(t);return}let E=(l??"").trim();if(E===""){o={exitCode:1,stdout:"",stderr:`Missing goal. Usage: vole run "<goal>"
|
|
196
|
+
`};return}let v=g.mode;o=await Ys(E,v==="auto"?"auto":v==="observe"?"observe":"confirm",t)}),i.command("tasks").description("List recent background task runs").option("-n, --limit <n>","Number of runs to show",l=>parseInt(l,10)).action(async l=>{o=await Qr(t,l.limit)});let a=i.command("skills").description("Manage agent skills");a.action(async()=>{o=await no(t)}),a.command("install <path>").description("Install a skill from a local .md file").action(async l=>{o=await ro(l,t)}),a.command("enable <name>").description("Enable a disabled skill").action(async l=>{o=await ut("enable",l,t)}),a.command("disable <name>").description("Disable a skill").action(async l=>{o=await ut("disable",l,t)}),a.command("trust <name>").description("Mark an installed skill as trusted").action(async l=>{o=await ut("trust",l,t)}),a.command("review <name>").description("Show full skill metadata and permissions").action(async l=>{o=await oo(l,t)}),i.command("daemon").description("Start the task scheduler daemon").option("--once","Run all due tasks once and exit").action(async l=>{o=await eo(t,l.once===!0)}),i.command("web").description("Start the Vole web dashboard").option("-p, --port <port>","Port to listen on","3120").option("--no-open","Don't open the browser automatically").action(async l=>{let g=parseInt(l.port,10)||3120,E=l.open!==!1;o=await po(g,E)});let c=i.command("gateway").description("Inspect run admission and active sessions");c.action(async()=>{o=await Os(t)}),c.command("status").description("Show lane occupancy and active runs across processes").action(async()=>{o=await Os(t)}),i.command("compact").description("Print compaction status and how to trigger it in chat").action(async()=>{o=await Xr()}),i.command("doctor").description("Read-only diagnostic checks for workspace, sessions, taskflow, and skills (pass --fix to apply idempotent remediations)").option("--fix","Apply remediations for fixable findings (stale session locks, stuck subagents, orphan TaskFlow rows). Read-only checks (config / workspace / skill files) are never auto-fixed.").action(async l=>{o=await Hr(t,{fix:l.fix===!0})}),i.command("migrate").description("Migrate data between storage backends").command("jsonl-to-sqlite").description("Migrate JSONL sessions + taskflow data into SQLite databases. Defaults to dry-run; pass --apply to actually write.").option("--apply","Write to the SQLite databases. Without this flag, the command only previews counts.").action(async l=>{o=await Jr(t,{apply:l.apply===!0})});let m=i.command("agents").description("Manage per-agent identity directories under <workspace>/agents/");m.action(async()=>{o=await $s(t)}),m.command("list").description("List agents under agents/ and the active default").action(async()=>{o=await $s(t)}),m.command("create <id>").description("Create agents/<id>/ with seed AGENTS.md / SOUL.md / USER.md / MEMORY.md").action(async l=>{o=await Vr(l,t)}),m.command("switch <id>").description("Set .vole/active-agent so subsequent runs use this agent").action(async l=>{o=await qr(l,t)}),m.command("remove <id>").description("Archive agents/<id>/ to agents/.archive/").option("--confirm","Required: confirm that you want to archive the agent").action(async(l,g)=>{o=await Wr(l,t,{confirm:g.confirm===!0})});let p=i.command("memory").description("Inspect and curate workspace memory").command("review").description("Review DREAMS.md candidate entries");p.action(async()=>{o=await Ns(t)}),p.command("list").description("List pending DREAMS.md entries").action(async()=>{o=await Ns(t)}),p.command("approve <id>").description('Promote a DREAMS.md entry into MEMORY.md, or pass "all" to approve every pending entry').action(async l=>{o=await Ps("approve",l,t)}),p.command("reject <id>").description('Archive a DREAMS.md entry to DREAMS/archive/, or pass "all" to reject every pending entry').action(async l=>{o=await Ps("reject",l,t)});let h=i.command("subagents").description("Inspect and control async sub-agents");h.action(async()=>{o=await Ls(t)}),h.command("list").description("List active and recent sub-agent runs").action(async()=>{o=await Ls(t)}),h.command("kill <id>").description('Cancel a sub-agent by taskId, or pass "all" to stop every active one').action(async l=>{o=await Gr(l,t)});let f=i.command("taskflow").description("Inspect cross-session task records");f.action(async()=>{o=await Fs(t,void 0)}),f.command("list").description("List recent task records").option("-n, --limit <n>","Number of records to show",l=>parseInt(l,10)).action(async l=>{o=await Fs(t,l.limit)}),f.command("show <id>").description("Show details of a task").action(async l=>{o=await to(l,t)}),f.command("cancel <id>").description("Mark a task as cancelled").action(async l=>{o=await so(l,t)});try{let l=s[0]==="--"?s.slice(1):s;await i.parseAsync(l,{from:"user"})}catch(l){if(l instanceof Error&&"code"in l){let g=l.code;if(g==="commander.helpDisplayed"||g==="commander.version")return{exitCode:0,stdout:r,stderr:""};if(g==="commander.unknownCommand"){let E=l.message.match(/unknown command '(.+)'/),v=E?E[1]:s[0]??"unknown";return{exitCode:1,stdout:i.helpInformation(),stderr:`Unknown command "${v}".
|
|
197
|
+
`}}return{exitCode:l.exitCode??1,stdout:r,stderr:`${l.message}
|
|
198
|
+
`}}throw l}return o??{exitCode:0,stdout:r,stderr:""}}async function jr(s,e){let{message:t,slashCommands:n}=s;if(t.trim()==="")return{exitCode:1,stdout:"",stderr:"Missing message for `chat --fake`.\n"};let r=await he.createFake(`Fake response to: ${t}`,e),o=await r.sendMessage(t),i=await ao(r,n),a=o.assistantText,c=o.events,d=gt(c).join(`
|
|
199
|
+
`);return{exitCode:c.some(m=>m.type==="run_failed")?1:0,stdout:`Assistant: ${a}
|
|
200
|
+
|
|
201
|
+
Trace:
|
|
202
|
+
${d}
|
|
203
|
+
${i}`,stderr:""}}async function Br(s,e){let t=await he.createFake(n=>`Fake response to: ${n}`,s,{...e.sessionId===void 0?{}:{sessionId:e.sessionId}});return Ks(t,"Vole chat (fake provider)",s)}async function Cs(s,e){let t=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}});if(t.secrets.apiKey===void 0)return{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
204
|
+
`};if(e.resume&&e.sessionId!==void 0)return{exitCode:1,stdout:"",stderr:"Use either `chat --resume` or `chat --session <id>`, not both.\n"};let n=e.resume?await io(t,s):void 0;if(e.resume&&n===void 0)return{exitCode:1,stdout:"",stderr:"No stored sessions to resume. Start one with `vole chat` or `vole chat --session <id>`.\n"};let r=e.sessionId??n;return await Yr(t,s),Ks(await he.createConfigured(t,s,{...r===void 0?{}:{sessionId:r}}),n===void 0?"Vole chat":`Vole chat
|
|
205
|
+
Resumed session: ${n}`,s)}async function Yr(s,e){let t=e.env??process.env;if(t.VOLE_NO_MIGRATION_HINT==="1"||t.VITEST!==void 0||t.NODE_ENV==="test"||e.write===void 0&&process.stdout.isTTY!==!0)return;let n=e.sessionsDirectory?{...s,sessions:{directory:e.sessionsDirectory}}:s,r=P(n,e.env),o=_(r,"sessions.db"),i=_(L(r),"taskflow.jsonl"),a=0;try{a=(await Fe(r)).filter(p=>p.endsWith(".jsonl")).length}catch{a=0}let c=!1;try{await J(o),c=!0}catch{c=!1}let d=!1;try{await J(i),d=!0}catch{d=!1}if(!(a>0||d)||c)return;(e.write??(p=>process.stdout.write(p)))(`[vole] Detected ${a} JSONL session file(s)${d?" + taskflow.jsonl":""}. Run \`vole migrate jsonl-to-sqlite\` to preview a SQLite migration, or \`--apply\` to perform it. Suppress this hint with VOLE_NO_MIGRATION_HINT=1.
|
|
206
|
+
`)}async function Kr(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),n=await ht(e,s,z()).listSessions();return n.length===0?{exitCode:0,stdout:`Sessions:
|
|
207
|
+
No sessions found.
|
|
208
|
+
`,stderr:""}:{exitCode:0,stdout:["Sessions:",...n.map(r=>`${r.id} ${r.updatedAt}${r.title?` ${r.title}`:""}`)].join(`
|
|
209
|
+
`)+`
|
|
210
|
+
`,stderr:""}}async function Os(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),t=s.sessionsDirectory?{...e,sessions:{directory:s.sessionsDirectory}}:e,n=P(t,s.env),r=["Gateway status:",""],o=G.status();if(r.push("In-process (this CLI invocation):"),r.push(` Lanes: global ${o.lanes.global.active}/${G.defaultLaneConcurrency.global} (queued ${o.lanes.global.queued}), subagent ${o.lanes.subagent.active}/${G.defaultLaneConcurrency.subagent} (queued ${o.lanes.subagent.queued}), sessions=${o.lanes.sessions.length}`),o.activeRuns.length===0)r.push(" Active runs: (none)");else{r.push(" Active runs:");for(let a of o.activeRuns)r.push(` ${a.runId} \u2192 ${a.sessionKey}${a.isSubagent?" [subagent]":""} (started ${a.startedAt})`)}r.push(""),r.push(`Cross-process session locks under ${n}:`);let i=[];try{i=(await Fe(n)).filter(c=>c.endsWith(".lock"))}catch(a){if(a instanceof Error&&"code"in a&&a.code==="ENOENT")return r.push(" (sessions directory does not exist yet)"),{exitCode:0,stdout:`${r.join(`
|
|
211
|
+
`)}
|
|
212
|
+
`,stderr:""};throw a}if(i.length===0)r.push(" (no active locks)");else{let a=Date.now();for(let c of i.sort()){let d=c.slice(0,-5),m=_(n,c),u={},p;try{u=JSON.parse(await ge(m,"utf8")),p=await J(m)}catch{r.push(` ${d} \u2014 (lock file unreadable)`);continue}let h=typeof u.pid=="number"?u.pid:void 0,f=h!==void 0?Bs(h):!1,l=typeof u.startedAt=="number"?a-u.startedAt:p?a-p.mtimeMs:void 0,g=l===void 0?"?":`${Math.round(l/100)/10}s`,E=h===void 0?"?":`pid ${h} (${f?"alive":"stale"})`;r.push(` ${d} \u2014 ${E}, held ${g}`)}}return{exitCode:0,stdout:`${r.join(`
|
|
213
|
+
`)}
|
|
214
|
+
`,stderr:""}}function Bs(s){try{return process.kill(s,0),!0}catch(e){return!(e instanceof Error&&"code"in e&&e.code==="ESRCH")}}var Ms=60;async function Hr(s,e={}){let t=[],n;try{n=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}});let u=n.secrets.apiKey!==void 0;t.push({name:"config",level:u?"ok":"warn",summary:u?`provider=${n.model.provider}, model=${n.model.model}`:`provider=${n.model.provider}, model=${n.model.model} (no API key configured)`,details:u?[]:["Set VOLE_API_KEY (or ANTHROPIC_API_KEY / OPENROUTER_API_KEY), or add an apiKey field to ~/.vole/config.json."]})}catch(u){t.push({name:"config",level:"error",summary:"failed to load configuration",details:[u instanceof Error?u.message:String(u)]})}if(n!==void 0){let u=n.workspace.root;try{(await J(u)).isDirectory()?t.push({name:"workspace",level:"ok",summary:u,details:[]}):t.push({name:"workspace",level:"error",summary:`${u} is not a directory`,details:[]})}catch{t.push({name:"workspace",level:"error",summary:`${u} does not exist`,details:["Create the directory or update workspace.root in your config."]})}}let r;if(n!==void 0){let u=s.sessionsDirectory?{...n,sessions:{directory:s.sessionsDirectory}}:n;r=P(u,s.env);let p=[],h=!0;try{p=(await Fe(r)).filter(l=>l.endsWith(".lock"))}catch(f){f instanceof Error&&"code"in f&&f.code==="ENOENT"||t.push({name:"sessions directory",level:"error",summary:`cannot read ${r}`,details:[f instanceof Error?f.message:String(f)]}),h=!1}if(h?t.push({name:"sessions directory",level:"ok",summary:r,details:[]}):t.push({name:"sessions directory",level:"ok",summary:`${r} (will be created on first run)`,details:[]}),h&&p.length>0){let f=[],l=[];for(let g of p.sort()){let E=g.slice(0,-5),v=_(r,g);try{let y=JSON.parse(await ge(v,"utf8"));if(typeof y.pid=="number"&&!Bs(y.pid)){let k=typeof y.startedAt=="number"?`${Math.round((Date.now()-y.startedAt)/1e3)}s`:"?";f.push(`${E} \u2014 pid ${y.pid} (dead), held ${k}`),l.push(v)}}catch{f.push(`${E} \u2014 lock file unreadable`),l.push(v)}}f.length===0?t.push({name:"stale session locks",level:"ok",summary:"all live",details:[]}):t.push({name:"stale session locks",level:"warn",summary:`${f.length} stale lock(s)`,details:f,fix:async()=>{for(let g of l)await Dr(g,{force:!0});return`removed ${l.length} stale lock file(s)`}})}else h&&t.push({name:"stale session locks",level:"ok",summary:"no locks held",details:[]})}if(n!==void 0&&r!==void 0){let u=_(L(r),"taskflow.jsonl"),p=new U(u);try{let h=await p.list(),f=Date.now()-Ms*6e4,l=h.filter(v=>v.runtime==="subagent"&&(v.status==="running"||v.status==="queued")&&Date.parse(v.updatedAt)<f);if(l.length===0)t.push({name:"stale subagents",level:"ok",summary:`none older than ${Ms} minutes`,details:[]});else{let v=l.map(y=>y.id);t.push({name:"stale subagents",level:"warn",summary:`${l.length} stuck subagent(s)`,details:l.map(y=>`${y.id} \u2014 ${y.status} since ${y.updatedAt}`),fix:async()=>{for(let y of v)await p.update(y,{status:"cancelled",terminalSummary:"Cancelled by vole doctor --fix (stale > 60min)"});return`cancelled ${v.length} stuck subagent(s)`}})}let g=new Set(h.map(v=>v.id)),E=h.filter(v=>v.parentId!==void 0&&!g.has(v.parentId));if(E.length===0)t.push({name:"orphan TaskFlow children",level:"ok",summary:"no orphans",details:[]});else{let v=E.map(y=>y.id);t.push({name:"orphan TaskFlow children",level:"warn",summary:`${E.length} orphan(s)`,details:E.map(y=>`${y.id} \u2014 parentId=${y.parentId??"?"} missing`),fix:async()=>{for(let y of v)await p.update(y,{status:"cancelled",terminalSummary:"Cancelled by vole doctor --fix (orphan child)"});return`cancelled ${v.length} orphan child task(s)`}})}}catch(h){t.push({name:"taskflow",level:"error",summary:"failed to read taskflow store",details:[h instanceof Error?h.message:String(h)]})}}if(n!==void 0)try{let u=ye(n,s),h=await new se().load({workspaceRoot:n.workspace.root,userSkillsDir:u}),f=[];for(let l of h)if(l.filePath!=="")try{await J(l.filePath)}catch{f.push(`${l.name} \u2192 missing ${l.filePath}`)}t.push(f.length===0?{name:"skill files",level:"ok",summary:`${h.length} skill(s), all files present`,details:[]}:{name:"skill files",level:"warn",summary:`${f.length} skill(s) point at missing files`,details:f})}catch(u){t.push({name:"skill files",level:"warn",summary:"could not enumerate skills",details:[u instanceof Error?u.message:String(u)]})}let o=[e.fix===!0?"vole doctor --fix:":"vole doctor:",""];for(let u of t){let p=u.level==="ok"?"[OK] ":u.level==="warn"?"[WARN] ":"[ERR] ";o.push(`${p}${u.name}: ${u.summary}`);for(let h of u.details)o.push(` ${h}`)}let i=0,a=0;if(e.fix===!0){let u=["","Remediations:"],p=!1;for(let h of t)if(h.fix!==void 0){p=!0;try{let f=await h.fix();u.push(` ${h.name}: ${f}`),i++}catch(f){let l=f instanceof Error?f.message:String(f);u.push(` ${h.name}: failed \u2014 ${l}`),a++}}p||u.push(" (no auto-fixable findings)"),o.push(...u)}let c=t.filter(u=>u.level==="ok").length,d=t.filter(u=>u.level==="warn").length,m=t.filter(u=>u.level==="error").length;return o.push(""),o.push(`Summary: ${t.length} check(s) \u2014 ${c} ok, ${d} warning(s), ${m} error(s).`),e.fix===!0?o.push(`Remediations: ${i} applied, ${a} failed.`):(d>0||m>0)&&o.push("Hint: run `vole doctor --fix` to apply idempotent remediations (stale locks, stuck subagents, orphan children)."),{exitCode:m>0||a>0?1:0,stdout:`${o.join(`
|
|
215
|
+
`)}
|
|
216
|
+
`,stderr:""}}async function $s(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),t=e.workspace.root,n=we(t),r=vt(t,e),o=["Agents:",""];if(n.length===0)return o.push(" (no agents found under agents/)"),o.push(""),o.push("Create one with `vole agents create <id>`."),{exitCode:0,stdout:`${o.join(`
|
|
217
|
+
`)}
|
|
218
|
+
`,stderr:""};for(let i of n){let a=i===r?" (active)":"",c="";try{let d=Et(t,i),m=Object.keys(d.files);c=m.length>0?` [${m.join(", ")}]`:" [empty]"}catch{c=" [unreadable]"}o.push(` ${i}${a}${c}`)}return o.push(""),o.push(`Active: ${r??"(none)"}`),{exitCode:0,stdout:`${o.join(`
|
|
219
|
+
`)}
|
|
220
|
+
`,stderr:""}}async function Vr(s,e){let t=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}});if(!D(s))return{exitCode:1,stdout:"",stderr:`Invalid agent id "${s}". Use letters, digits, dot, dash, or underscore.
|
|
221
|
+
`};try{let n=St(t.workspace.root,s);return{exitCode:0,stdout:`Created agent ${s} at ${n}.
|
|
222
|
+
`,stderr:""}}catch(n){return{exitCode:1,stdout:"",stderr:`${n instanceof Error?n.message:String(n)}
|
|
223
|
+
`}}}async function qr(s,e){let t=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}});if(!D(s))return{exitCode:1,stdout:"",stderr:`Invalid agent id "${s}".
|
|
224
|
+
`};if(!we(t.workspace.root).includes(s))return{exitCode:1,stdout:"",stderr:`Agent "${s}" not found under agents/. Create it with \`vole agents create ${s}\`.
|
|
225
|
+
`};try{return Tt(t.workspace.root,s),{exitCode:0,stdout:`Active agent set to ${s}.
|
|
226
|
+
`,stderr:""}}catch(r){return{exitCode:1,stdout:"",stderr:`${r instanceof Error?r.message:String(r)}
|
|
227
|
+
`}}}async function Wr(s,e,t){let n=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}});if(!t.confirm)return{exitCode:1,stdout:"",stderr:`Refusing to remove agent "${s}" without --confirm. Archive moves the directory under agents/.archive/.
|
|
228
|
+
`};try{let r=_t(n.workspace.root,s);return{exitCode:0,stdout:`Archived agent ${s} to ${r}.
|
|
229
|
+
`,stderr:""}}catch(r){return{exitCode:1,stdout:"",stderr:`${r instanceof Error?r.message:String(r)}
|
|
230
|
+
`}}}async function Jr(s,e){let t=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),n=s.sessionsDirectory?{...t,sessions:{directory:s.sessionsDirectory}}:t,r=P(n,s.env),o=_(r,"sessions.db"),i=_(L(r),"taskflow.jsonl"),a=_(L(r),"taskflow.db"),c=!e.apply,d=await ys(r,o,{dryRun:c}),m=await ks(i,a,{dryRun:c}),u=[`vole migrate jsonl-to-sqlite (${c?"dry-run":"apply"}):`,"",`Sessions (${r}):`,` sessions: ${d.sessions}`,` messages: ${d.messages}`,` trace events: ${d.traceEvents}`,` compact boundaries: ${d.compactBoundaries}`,` target: ${o}`,"",`Taskflow (${i}):`,` task records: ${m.taskRecords}`,` target: ${a}`,""];return c?u.push("Dry-run only \u2014 no files written. Re-run with --apply to perform the migration."):u.push("Migration complete. JSONL sources are left in place; remove them once you have verified the SQLite copies."),{exitCode:0,stdout:`${u.join(`
|
|
231
|
+
`)}
|
|
232
|
+
`,stderr:""}}async function Ns(s){let t=(await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}})).workspace.root,r=(await dt(t)).filter(i=>i.status==="pending"),o=["DREAMS.md review:",""];if(r.length===0)return o.push(" (no pending entries)"),o.push(""),o.push("Run `vole run --dream` to generate candidate entries."),{exitCode:0,stdout:`${o.join(`
|
|
233
|
+
`)}
|
|
234
|
+
`,stderr:""};for(let i of r){o.push(` ${i.id}${i.source!==void 0?` (source: ${i.source})`:""}`);let a=i.body.split(`
|
|
235
|
+
`).slice(0,3).join(" ").slice(0,120);o.push(` ${a}`),o.push("")}return o.push(`${r.length} pending entr${r.length===1?"y":"ies"}.`),o.push("Approve: vole memory review approve <id> Reject: vole memory review reject <id>"),{exitCode:0,stdout:`${o.join(`
|
|
236
|
+
`)}
|
|
237
|
+
`,stderr:""}}async function Ps(s,e,t){let r=(await R({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}})).workspace.root;if(e==="all"){let a=(await dt(r)).filter(d=>d.status==="pending");if(a.length===0)return{exitCode:0,stdout:`No pending DREAMS.md entries.
|
|
238
|
+
`,stderr:""};let c=[];for(let d of a)await lt(r,d.id,s)!==void 0&&c.push(d.id);return{exitCode:0,stdout:`${s==="approve"?"Approved":"Rejected"}:
|
|
239
|
+
${c.map(d=>` ${d}`).join(`
|
|
240
|
+
`)}
|
|
241
|
+
`,stderr:""}}return await lt(r,e,s)===void 0?{exitCode:1,stdout:"",stderr:`DREAMS.md has no pending entry with id "${e}".
|
|
242
|
+
`}:{exitCode:0,stdout:s==="approve"?`Approved ${e}; appended to MEMORY.md.
|
|
243
|
+
`:`Rejected ${e}; archived to DREAMS/archive/${e}.md.
|
|
244
|
+
`,stderr:""}}async function Xr(){return{exitCode:0,stdout:`${["Compaction:"," Vole compacts the conversation history automatically when the estimated token"," count exceeds the configured maxTokens (default 60000) OR when the message count"," exceeds maxMessages (default 400).",""," Inside an interactive chat, you can hint the model to save durable facts and"," request immediate compaction by including the /compact directive in your message;"," the runtime strips the token before the model sees the message and queues a"," compaction pass on the next turn.",""," Forced standalone compaction (without an active chat session) is Phase 13b work."].join(`
|
|
245
|
+
`)}
|
|
246
|
+
`,stderr:""}}async function Ls(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),t=s.sessionsDirectory?{...e,sessions:{directory:s.sessionsDirectory}}:e,n=_(L(P(t,s.env)),"taskflow.jsonl"),r=new U(n),o=await r.list({runtime:"subagent"}).catch(async()=>(await r.list()).filter(a=>a.runtime==="subagent")),i=["Sub-agent task records:"];if(o.length===0)i.push(" (none)");else for(let a of o.slice(-50)){let c=a.terminalSummary!==void 0?` \u2014 ${a.terminalSummary.slice(0,80)}`:"",d=a.parentId!==void 0?` parent=${a.parentId}`:"";i.push(` ${a.id} ${a.status} ${a.updatedAt}${d}${c}`)}return{exitCode:0,stdout:`${i.join(`
|
|
247
|
+
`)}
|
|
248
|
+
`,stderr:""}}async function Gr(s,e){let t=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}}),n=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,r=_(L(P(n,e.env)),"taskflow.jsonl"),o=new U(r),i=s==="all"?(await o.list()).filter(d=>d.runtime==="subagent"&&(d.status==="running"||d.status==="queued")):o.get(s).then(d=>d===void 0?[]:[d]),a=i instanceof Promise?await i:i,c=[];for(let d of a)await o.update(d.id,{status:"cancelled"}),c.push(d.id);return{exitCode:0,stdout:c.length===0?`No matching sub-agent task to cancel.
|
|
249
|
+
`:`Cancelled:
|
|
250
|
+
${c.map(d=>` ${d}`).join(`
|
|
251
|
+
`)}
|
|
252
|
+
`,stderr:""}}async function zr(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}});return e.secrets.apiKey===void 0?{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
253
|
+
`}:e.memory.longTermFiles!=="write"?{exitCode:1,stdout:"",stderr:`Memory dreaming requires VOLE_LONG_TERM_MEMORY=write
|
|
254
|
+
`}:Ys(`You are a memory consolidation agent. Review the recent daily memory files (memory/YYYY-MM-DD.md) and the current MEMORY.md.
|
|
255
|
+
|
|
256
|
+
Write candidate consolidation entries to DREAMS.md using the write_file tool. DO NOT modify MEMORY.md directly \u2014 every promotion requires the user's explicit approval via \`vole memory review approve <id>\`.
|
|
257
|
+
|
|
258
|
+
DREAMS.md format (append to whatever already exists; preserve existing entries):
|
|
259
|
+
|
|
260
|
+
# Dream Entries \u2014 Pending Review
|
|
261
|
+
|
|
262
|
+
## [pending] <YYYY-MM-DD-NNN>
|
|
263
|
+
**Source**: <comma-separated list of source files>
|
|
264
|
+
|
|
265
|
+
<one short paragraph summarizing the durable fact or pattern>
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
Rules:
|
|
270
|
+
- Each entry id must be unique. Use today's date plus a zero-padded serial (e.g. 2026-05-12-001).
|
|
271
|
+
- One paragraph per entry. Be concise and factual.
|
|
272
|
+
- Do not propose entries that duplicate facts already in MEMORY.md.
|
|
273
|
+
- If there is nothing new worth promoting, write a single header line and stop \u2014 do not invent material.`,"auto",s)}async function Ys(s,e,t){let n=await R({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}});if(n.secrets.apiKey===void 0)return{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
274
|
+
`};let r=t.sessionsDirectory?{...n,sessions:{directory:t.sessionsDirectory}}:n,o=P(r,t.env),i=z(),a=`task_${crypto.randomUUID()}`,c=s.slice(0,40).replace(/\s+/g,"-").replace(/[^A-Za-z0-9-]/g,"").toLowerCase()||"task",d=new Date().toISOString(),m=new ue({directory:o,createSessionId:()=>i}),u=new te(_(o,"task-runs.jsonl")),p={id:a,taskName:c,goal:s,sessionId:i,startedAt:d,status:"running",assistantText:""};await u.saveRun(p);let h=pt(n,t),f=new le(e),l=new Date().toISOString().slice(0,10),g=(()=>{let I=fe(t,n);return n.runtime.toolProfile!==void 0?xe(I,n.runtime.toolProfile):I})(),E=new V({contextAssembler:pe(n),modelProvider:h,systemInstruction:De,runtime:{mode:e,workspace:n.workspace.root,currentDate:l},tools:g,preferStreaming:!1,approvalResolver:f,maxSteps:20,...n.runtime.promptMode!==void 0?{promptMode:n.runtime.promptMode}:{}}),v=[];await m.createSession({title:`task: ${s.slice(0,60)}`});for await(let I of E.runTurn({sessionId:i,message:s}))await m.appendTraceEvent({sessionId:i,event:I}),v.push(I);let y=gt(v),k=v.find(I=>I.type==="assistant_message_created"),x=k?.type==="assistant_message_created"?k.message.content:"No assistant message was produced.",b=v.find(I=>I.type==="run_failed"),T=b?"failed":"completed",M=new Date().toISOString(),w={status:T,assistantText:x,completedAt:M,...b?.type==="run_failed"?{errorMessage:b.error.message}:{}};await u.updateRun(a,w);let $=y.join(`
|
|
275
|
+
`),O=T==="completed"?`Done: ${x}`:`Failed: ${b?.type==="run_failed"?b.error.message:"Unknown error"}`;return{exitCode:T==="completed"?0:1,stdout:`Trace:
|
|
276
|
+
${$}
|
|
277
|
+
|
|
278
|
+
${O}
|
|
279
|
+
`,stderr:""}}async function Qr(s,e){let t=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),n=s.sessionsDirectory?{...t,sessions:{directory:s.sessionsDirectory}}:t,r=P(n,s.env),i=await new te(_(r,"task-runs.jsonl")).listRuns(e!==void 0?{limit:e}:{});return i.length===0?{exitCode:0,stdout:`No task runs found.
|
|
280
|
+
`,stderr:""}:{exitCode:0,stdout:i.map(c=>`${c.id.slice(-8)} ${c.taskName} ${c.status} ${c.startedAt}`).join(`
|
|
281
|
+
`)+`
|
|
282
|
+
`,stderr:""}}async function Zr(s){try{await J(s)}catch{return null}let t=(await Fe(s)).filter(r=>r.endsWith(".task.json")),n=[];for(let r of t){let o=await ge(_(s,r),"utf8");n.push(JSON.parse(o))}return n}async function Ds(s,e,t,n){let r=`run_${crypto.randomUUID()}`,o=z(),i=s.mode??"auto",a={id:r,taskName:s.name,goal:s.goal,sessionId:o,startedAt:new Date().toISOString(),status:"running",assistantText:""};await n.saveRun(a);let c=_(e.workspace.root,"HEARTBEAT.md"),d={status:"running",taskName:s.name,runId:r,lastUpdatedAt:new Date().toISOString()};await rt(c,d);let m=t.fakeModelOutputs?new Q(t.fakeModelOutputs):pt(e,t),u=new le(i),p=new Date().toISOString().slice(0,10),h=(()=>{let T=fe(t,e);return e.runtime.toolProfile!==void 0?xe(T,e.runtime.toolProfile):T})(),f=new V({contextAssembler:pe(e),modelProvider:m,systemInstruction:De,runtime:{mode:i,workspace:e.workspace.root,currentDate:p},tools:h,preferStreaming:!1,approvalResolver:u,...s.maxSteps!==void 0?{maxSteps:s.maxSteps}:{},...e.runtime.promptMode!==void 0?{promptMode:e.runtime.promptMode}:{}}),l=[];for await(let T of f.runTurn({sessionId:o,message:s.goal}))l.push(T);let g=l.find(T=>T.type==="assistant_message_created"),E=g?.type==="assistant_message_created"?g.message.content:"No assistant message was produced.",v=l.find(T=>T.type==="run_failed"),y=v?"failed":"completed",k=new Date().toISOString(),x={status:y,assistantText:E,completedAt:k,...v?.type==="run_failed"?{errorMessage:v.error.message}:{}};await n.updateRun(r,x);let b={status:y,taskName:s.name,runId:r,lastUpdatedAt:k,...v?.type==="run_failed"?{message:`Error: ${v.error.message}`}:{}};await rt(c,b)}async function eo(s,e){let t=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}});if(t.secrets.apiKey===void 0)return{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
283
|
+
`};let n=s.sessionsDirectory?{...t,sessions:{directory:s.sessionsDirectory}}:t,r=P(n,s.env),o=_(L(r),"tasks"),i=new te(_(r,"task-runs.jsonl")),a=await Zr(o);if(a===null)return{exitCode:0,stdout:`No tasks directory found at ${o}.
|
|
284
|
+
`,stderr:""};let c=a.filter(u=>u.cron!==void 0);if(e){let u=new Date,p=[];for(let h of c)p.push(`Running: ${h.name}`),await Ds(h,t,s,i);return p.push("Done."),{exitCode:0,stdout:p.join(`
|
|
285
|
+
`)+`
|
|
286
|
+
`,stderr:""}}let d=async u=>{await Ds(u,t,s,i)},m=new Ce(c,d);return m.start(),new Promise(u=>{let p=()=>{m.stop(),u({exitCode:0,stdout:`Daemon stopped.
|
|
287
|
+
`,stderr:""})};process.once("SIGTERM",p),process.once("SIGINT",p)})}async function ft(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),t=s.sessionsDirectory?{...e,sessions:{directory:s.sessionsDirectory}}:e,n=P(t,s.env);return _(L(n),"taskflow.jsonl")}async function Fs(s,e){let t=await ft(s),r=await new U(t).list(e!==void 0?{limit:e}:{});return r.length===0?{exitCode:0,stdout:`No task records found.
|
|
288
|
+
`,stderr:""}:{exitCode:0,stdout:["Task records:",...r.map(i=>`${i.id.slice(-8)} ${i.status} ${i.runtime} ${i.createdAt} ${i.task.slice(0,60)}`)].join(`
|
|
289
|
+
`)+`
|
|
290
|
+
`,stderr:""}}async function to(s,e){let t=await ft(e),r=await new U(t).get(s);return r===void 0?{exitCode:1,stdout:"",stderr:`Task "${s}" not found.
|
|
291
|
+
`}:{exitCode:0,stdout:[`ID: ${r.id}`,`Runtime: ${r.runtime}`,`Status: ${r.status}`,`Task: ${r.task}`,`Created: ${r.createdAt}`,`Updated: ${r.updatedAt}`,...r.parentId!==void 0?[`Parent: ${r.parentId}`]:[],...r.sessionId!==void 0?[`Session: ${r.sessionId}`]:[],...r.progressSummary!==void 0?[`Progress: ${r.progressSummary}`]:[],...r.terminalSummary!==void 0?[`Terminal summary: ${r.terminalSummary}`]:[]].join(`
|
|
292
|
+
`)+`
|
|
293
|
+
`,stderr:""}}async function so(s,e){let t=await ft(e);return await new U(t).update(s,{status:"cancelled"})===void 0?{exitCode:1,stdout:"",stderr:`Task "${s}" not found.
|
|
294
|
+
`}:{exitCode:0,stdout:`Cancelled: ${s}
|
|
295
|
+
`,stderr:""}}function ye(s,e){let t=e.sessionsDirectory?{...s,sessions:{directory:e.sessionsDirectory}}:s,n=P(t,e.env);return _(L(n),"skills")}async function no(s){let e=await R({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),t=ye(e,s),r=await new se().load({workspaceRoot:e.workspace.root,userSkillsDir:t});return{exitCode:0,stdout:["Skills:",...qs(r)].join(`
|
|
296
|
+
`)+`
|
|
297
|
+
`,stderr:""}}async function ro(s,e){let t=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}}),n=ye(t,e),r=new ne(n);try{return{exitCode:0,stdout:`Installed: ${(await r.install(s)).name}
|
|
298
|
+
`,stderr:""}}catch(o){return{exitCode:1,stdout:"",stderr:`Failed to install skill: ${o instanceof Error?o.message:String(o)}
|
|
299
|
+
`}}}async function ut(s,e,t){let n=await R({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),r=ye(n,t),o=new ne(r);try{return s==="enable"?(await o.enable(e),{exitCode:0,stdout:`Enabled: ${e}
|
|
300
|
+
`,stderr:""}):s==="disable"?(await o.disable(e),{exitCode:0,stdout:`Disabled: ${e}
|
|
301
|
+
`,stderr:""}):(await o.trust(e),{exitCode:0,stdout:`Trusted: ${e}
|
|
302
|
+
`,stderr:""})}catch(i){return{exitCode:1,stdout:"",stderr:`Failed to ${s} skill: ${i instanceof Error?i.message:String(i)}
|
|
303
|
+
`}}}async function oo(s,e){let t=await R({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}}),n=ye(t,e),r=new ne(n),o=await r.review(s);if(o===void 0)return{exitCode:1,stdout:"",stderr:`Skill "${s}" not found.
|
|
304
|
+
`};let a=(await r.listEntries()).find(d=>d.name===s);return{exitCode:0,stdout:[`Name: ${o.name}`,`Source: ${o.source}`,...o.version!==void 0?[`Version: ${o.version}`]:[],...o.origin!==void 0?[`Origin: ${o.origin}`]:[],`Permissions: ${o.permissions!==void 0&&o.permissions.length>0?o.permissions.join(", "):"(none)"}`,`Trusted: ${String(o.trusted??!1)}`,`Enabled: ${String(o.enabled??!0)}`,...a?.installedAt!==void 0?[`Installed: ${a.installedAt}`]:[],"","--- Body ---",o.body].join(`
|
|
305
|
+
`)+`
|
|
306
|
+
`,stderr:""}}async function io(s,e){let t=ht(s,e,z()),[n]=await t.listSessions({limit:1});return n?.id}async function Ks(s,e,t){let n=[],r=(...o)=>{t.write?t.write(`${o.join(`
|
|
307
|
+
`)}
|
|
308
|
+
`):n.push(...o)};for(r(e,"Type /help for commands or /exit to leave.","");;){let o=await t.readLine?.("> ");if(o===void 0)break;let i=o.trim();if(i==="")continue;if(i==="/exit"){r("Goodbye.");break}if(i==="/help"){r(...Vs(),"");continue}if(i==="/clear"){r("(conversation display cleared)","");continue}if(i.startsWith("/")){r(...co(i,await s.runSlashCommand(i)),"");continue}let a=await s.sendMessage(i);a.todosLines.length>0&&r(...a.todosLines,""),a.approvalLines.length>0&&r(...a.approvalLines,""),r(`Assistant: ${a.assistantText}`,"")}return{exitCode:0,stdout:t.write?"":`${n.join(`
|
|
309
|
+
`)}
|
|
310
|
+
`,stderr:""}}var Hs={"/trace":"Recent Trace:","/config":"Config:","/skills":"Skills:","/help":"Commands:"};async function ao(s,e){let t=[];for(let n of e){let r=Hs[n];r!==void 0?t.push(["",r,...await s.runSlashCommand(n)].join(`
|
|
311
|
+
`)):t.push(["",`Unknown slash command: ${n}`].join(`
|
|
312
|
+
`))}return t.length===0?"":`${t.join(`
|
|
313
|
+
`)}
|
|
314
|
+
`}function co(s,e){if(e[0]?.startsWith("Unknown slash command"))return e;let t=Hs[s];return t!==void 0?[t,...e]:e}function Vs(){return["Commands:","/help Show commands","/trace Show recent trace events","/config Show redacted configuration","/skills List loaded skills","/clear Clear conversation display","/exit Leave chat"]}var he=class s{#e;#t;#s;#n;#r;#o;#c;#a;constructor(e,t=oe(Be()),n=new ee,r=z(),o=new Oe({createSessionId:()=>r}),i=12,a=[],c=[],d){this.#e=e,this.#r=t,this.#t=n,this.#s=o,this.#n=r,this.#o=a,this.#c=c,this.#a=d}get sessionId(){return this.#n}async listSessions(e){return this.#s.listSessions(e)}async loadMessages(){return this.#s.listMessages(this.#n)}close(){this.#a?.unregister(this.#n)}static async createFake(e="Fake response to: Hello trace",t={},n={}){let r=oe(await R({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}})),o=[],i=t.fakeModelOutputs?new Q(t.fakeModelOutputs):typeof e=="function"?new mt(e):new Q([{type:"message",content:e}]);return new s(new V({contextAssembler:pe(r),modelProvider:i,systemInstruction:De,runtime:{mode:"confirm",workspace:r.workspace.root,currentDate:new Date().toISOString().slice(0,10)},tools:fe(t,r),approvalResolver:Us(t,o),maxSteps:20,compaction:{}}),r,new ee,n.sessionId??z(),void 0,12,o)}static async createConfigured(e,t={},n={}){let r=n.sessionId??z(),o=new Date().toISOString().slice(0,10),i=[],a=await new se().load({workspaceRoot:e.workspace.root}),c=a.map(Es),d=new Map(a.map(T=>[T.name,T.body])),m=pt(e,t),u=n.approvalResolver??Us(t,i),p=fe(t,e,d),h=1,f=new Set(["spawn_subagent","spawn_subagent_async","subagents"]),l={create:(T,M)=>{let w=M?.depth??1,$=w>=h,O=fe(t,e),I=$?O.filter(A=>!f.has(A.name)):O,N=new V({contextAssembler:pe(oe(e)),modelProvider:m,systemInstruction:`You are Vole, a sub-agent handling: ${T}`,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:I,maxSteps:8,depth:w}),S=M?.contextMode==="fork"&&M.parentMessages?{recentMessages:M.parentMessages.filter(A=>A.role==="user"||A.role==="assistant").map(A=>({role:A.role,content:A.content}))}:void 0;return S!==void 0?{runtime:N,firstTurnInput:S}:N}},g=_(L(P(e,t.env)),"taskflow.jsonl"),E=new U(g),v={listActiveRuns:()=>G.status().activeRuns.map(T=>({runId:T.runId,sessionKey:T.sessionKey,agentId:T.agentId,isSubagent:T.isSubagent,startedAt:T.startedAt,...T.parentSessionKey!==void 0?{parentSessionKey:T.parentSessionKey}:{}})),cancel:T=>G.cancel(T)},y=[...p,is(l),rs(l,{taskStore:E,parentTaskId:r}),os(E),as({control:v,taskStore:E})],k=e.runtime.toolProfile!==void 0?xe(y,e.runtime.toolProfile):y,x=new Date().toISOString(),b={id:r,adapterName:"cli",capabilities:ds,registeredAt:x,lastActivityAt:x};return G.register(b),new s(new V({contextAssembler:pe(e),modelProvider:m,systemInstruction:De,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:k,skillIndex:c,preferStreaming:n.preferStreaming??!1,approvalResolver:u,maxSteps:20,compaction:{},taskStore:E,...e.runtime.promptMode!==void 0?{promptMode:e.runtime.promptMode}:{},...e.runtime.executionContract!==void 0?{executionContract:e.runtime.executionContract}:{}}),oe(e),new ee,r,ht(e,t,r),12,i,a,G)}async sendMessage(e,t={}){let n=[],r=this.#o.length,o=At(e),i=o.cleanedMessage.length>0?o.cleanedMessage:e;if(o.directives.stop&&this.#a!==void 0){for(let l of this.#a.status().activeRuns)l.sessionKey===this.#n&&this.#a.cancel(l.runId);return{assistantText:"Stopped via /stop directive.",approvalLines:[],todosLines:[],events:[]}}await this.#u();let a=(await this.#s.listMessages(this.#n)).map(l=>({role:l.role,content:l.content,...l.toolCalls!==void 0?{toolCalls:l.toolCalls}:{},...l.toolCallId!==void 0?{toolCallId:l.toolCallId}:{}})),c=`run_${crypto.randomUUID()}`,d=this.#n,m=this.#e,u=this.#a;u!==void 0&&t.signal!==void 0&&t.signal.addEventListener("abort",()=>{u.cancel(c)},{once:!0});let p=u!==void 0?u.submit({runId:c,sessionKey:d,agentId:"default",run:async function*(l){for await(let g of m.runTurn({sessionId:d,recentMessages:a,message:i,signal:l}))yield g}}):m.runTurn({sessionId:d,recentMessages:a,message:i,...t.signal!==void 0?{signal:t.signal}:{}});for await(let l of p)if(await this.#t.append(l),await this.#s.appendTraceEvent({sessionId:this.#n,event:l}),n.push(l),t.onEvent?.(l),l.type==="compaction_triggered"&&l.summary&&await this.#s.appendCompactBoundary({sessionId:this.#n,summary:l.summary,messagesBefore:l.messagesBefore,messagesAfter:l.messagesAfter}),l.type==="turn_complete")for(let g of l.messages)await this.#s.appendMessage({sessionId:this.#n,role:g.role,content:g.content??null,...g.toolCalls!==void 0?{toolCalls:g.toolCalls}:{},...g.toolCallId!==void 0?{toolCallId:g.toolCallId}:{}});let h=n.find(l=>l.type==="assistant_message_created");return{assistantText:h?.type==="assistant_message_created"?h.message.content:"No assistant message was produced.",approvalLines:this.#o.slice(r),todosLines:lo(n),events:n}}async runSlashCommand(e){if(e==="/trace"){let t=await this.#s.listTraceEvents(this.#n);return gt(t.map(n=>n.event))}return e==="/config"?uo(this.#r):e==="/skills"?qs(this.#c):e==="/help"?Vs():[`Unknown slash command: ${e}`]}async#u(){await this.#s.getSession(this.#n)===void 0&&await this.#s.createSession({title:this.#n})}};function Us(s,e){return{async resolve(t){e.push("Approval required:",`Tool: ${t.call.name}`,`Risk: ${t.decision.risk}`,`Reason: ${t.decision.reason}`);let n=(await s.readLine?.("Approve once? [y/N/details] "))?.trim().toLowerCase();return n==="y"||n==="yes"?(e.push("Decision: approved once."),{approved:!0,reason:"Approved once from CLI prompt."}):(e.push("Decision: denied"),{approved:!1,reason:"Denied from CLI prompt."})}}}function fe(s,e,t){let n=[Yt(),Kt(),qt(),Wt(),Jt(),Vt(e?.runtime.sandboxed!==void 0?{sandboxed:e.runtime.sandboxed}:void 0),Xt(s.fetch),es()];if(e?.memory.longTermFiles==="write"&&n.push(As()),e?.memory.longTermFiles==="read-only"||e?.memory.longTermFiles==="write"){let r=e.workspace.root;n.push(Ts(r)),n.push(_s(r))}return n.push(Zt()),t!==void 0&&t.size>0&&n.push(zt(t)),n}var mt=class{requests=[];#e;constructor(e){this.#e=e}async generate(e){this.requests.push(e);let t=[...e.messages].reverse().find(n=>n.role==="user")?.content??"";return{type:"message",content:this.#e(t)}}};function pt(s,e){return s.model.provider==="anthropic"?new Se({...s.secrets.apiKey!==void 0?{apiKey:s.secrets.apiKey}:{},model:s.model.model,temperature:s.model.temperature,maxTokens:s.model.maxTokens,...s.model.thinkingBudget!==void 0?{thinkingBudget:s.model.thinkingBudget}:{}}):new Ee({baseURL:s.model.baseURL,...s.secrets.apiKey!==void 0?{apiKey:s.secrets.apiKey}:{},model:s.model.model,temperature:s.model.temperature,maxTokens:s.model.maxTokens,...e.fetch?{fetch:e.fetch}:{}})}function ht(s,e,t){let n=e.sessionsDirectory?{...s,sessions:{directory:e.sessionsDirectory}}:s,r=P(n,e.env);return new ue({directory:r,createSessionId:()=>t})}function pe(s){return new ve({workspacePromptFiles:["AGENTS.md","SOUL.md","TOOLS.md","IDENTITY.md","HEARTBEAT.md","BOOTSTRAP.md","USER.md","MEMORY.md"]})}function z(){return`session_${crypto.randomUUID()}`}function lo(s){let e=[...s].reverse().find(n=>n.type==="todos_updated");if(e?.type!=="todos_updated"||e.todos.length===0)return[];let t=["Todo:"];for(let n of e.todos){let r=n.status==="completed"?"\u2713":n.status==="in_progress"?"\u2192":"\xB7";t.push(` ${r} ${n.content}`)}return t}function qs(s){if(s.length===0)return["No skills loaded."];let e=[],t=[];for(let n of s){let r=n.source==="user"&&n.trusted===!1?" \u26A0 untrusted":"",o=n.version!==void 0?` v${n.version}`:"",i=n.permissions!==void 0&&n.permissions.length>0?` [${n.permissions.join(", ")}]`:"";e.push(`[${n.source}]${r}${o} ${n.name}: ${n.description}${i}`),n.source==="user"&&n.trusted===!1&&t.push(n.name)}if(t.length>0){e.push("");for(let n of t)e.push(`This skill was installed from an external source and has not been trusted. Run \`vole skills trust ${n}\` to trust it.`)}return e}function uo(s){return[`Provider: ${s.model.provider}`,`Model: ${s.model.model}`,`Base URL: ${s.model.baseURL}`,`Default mode: ${s.runtime.defaultMode}`,`Trace verbosity: ${s.trace.verbosity}`,`Long-term memory files: ${s.memory.longTermFiles}`,`Memory writes: ${s.memory.writes}`,`API key: ${s.secrets.apiKey}`]}function mo(s){if("entries"in s&&Array.isArray(s.entries))return s.entries.map(e=>` ${e.type==="directory"?"\u{1F4C1}":"\u{1F4C4}"} ${e.name}`).join(`
|
|
315
|
+
`);if("content"in s&&typeof s.content=="string"){let e=s.content.split(`
|
|
316
|
+
`);return e.length>30?e.slice(0,30).join(`
|
|
317
|
+
`)+`
|
|
318
|
+
\u2026 (${e.length-30} more lines)`:s.content}if("stdout"in s)return[s.stdout,s.stderr].filter(Boolean).join(`
|
|
319
|
+
`)||"(no output)";if("error"in s){let e=s.error;return`Error: ${typeof e=="object"&&e!==null&&"message"in e?e.message:String(e)}`}return JSON.stringify(s,null,2)}function gt(s){return s.map((e,t)=>`${t+1}. ${fo(e)} (${e.type})`)}function fo(s){switch(s.type){case"run_started":return"Received user message";case"context_assembled":return"Assembled context";case"compaction_triggered":return`Compacted context (${s.messagesBefore} \u2192 ${s.messagesAfter} messages)`;case"memory_flush_triggered":return s.executed?`Memory flush ran${s.toolsInvoked.length>0?` (tools: ${s.toolsInvoked.join(", ")})`:""}`:`Memory flush skipped (${s.reason??"unknown"})`;case"todos_updated":return`Updated todos (${s.todos.length} items)`;case"planning_stall_detected":return`Planning stall detected (${s.stallCount}/${s.maxRetries})`;case"model_request_started":return"Started model request";case"token_delta":return`Token delta: "${s.delta.slice(0,20)}${s.delta.length>20?"\u2026":""}"`;case"model_request_completed":return"Completed model request";case"tool_call_requested":return"Requested tool call";case"tool_call_permission_evaluated":return"Evaluated tool permission";case"approval_requested":return"Requested approval";case"approval_resolved":return"Resolved approval";case"tool_started":return`Tool: ${s.toolName}`;case"tool_completed":return`Result [${s.toolName}]:
|
|
320
|
+
${mo(s.result)}`;case"tool_failed":return`Tool failed [${s.toolName}]: ${s.error.message}`;case"assistant_message_created":return"Created assistant message";case"turn_complete":return`Turn complete (${s.messages.length} messages)`;case"run_completed":return"Completed run";case"run_failed":return"Failed run"}}async function po(s,e){let t=L(js(import.meta.url)),n=[{server:_(t,"web","server.js"),cwd:_(t,"web")},{server:_(t,"../../web","dist","server.js"),cwd:_(t,"../../web")}],r;for(let a of n)try{await J(a.server),r=a;break}catch{}if(r===void 0)return{exitCode:1,stdout:"",stderr:`Web app not built. Run first:
|
|
321
|
+
pnpm --filter @vole/web build
|
|
322
|
+
`};let o=`http://localhost:${s}`,i=Rs("node",[r.server],{env:{...process.env,PORT:String(s),VOLE_WEB_ROOT:process.cwd()},stdio:"inherit",cwd:r.cwd});if(process.stdout.write(`Vole web dashboard \u2192 ${o}
|
|
323
|
+
`),process.stdout.write(`Press Ctrl+C to stop.
|
|
324
|
+
`),e){let a=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",c=process.platform==="win32"?["/c","start",o]:[o];setTimeout(()=>{Rs(a,c,{stdio:"ignore",detached:!0}).unref()},800)}return new Promise(a=>{let c=()=>{i.kill(),a({exitCode:0,stdout:`Web server stopped.
|
|
325
|
+
`,stderr:""})};process.once("SIGTERM",c),process.once("SIGINT",c),i.once("exit",d=>a({exitCode:d??0,stdout:"",stderr:""}))})}async function ho(){let s=process.argv.slice(2),[e]=s,t=s.find(d=>d!=="--");if((t==="chat"||t===void 0&&process.stdin.isTTY===!0)&&!s.includes("--help")&&!s.includes("-h")&&!s.includes("--fake")&&!s.includes("--fake-interactive")){let{runInkChat:d}=await import("./app.js");await d({args:s,env:process.env});return}let r=Lr({input:process.stdin,output:process.stdout}),o=r[Symbol.asyncIterator](),i=L(js(import.meta.url)),a="0.0.0";try{let d=await ge(_(i,"../package.json"),"utf8");a=JSON.parse(d).version}catch{}let c=await Ur(s,a,{env:process.env,readLine:async d=>{process.stdout.write(d);let m=await o.next();return m.done?void 0:m.value},write:d=>process.stdout.write(d)});r.close(),process.stdout.write(c.stdout),process.stderr.write(c.stderr),process.exitCode=c.exitCode}ho();export{Be as a,Pi as b,Ur as c,he as d,lo as e,qs as f,uo as g,mo as h,gt as i};
|