vole-agent 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +28 -706
- package/dist/chunk-QGVGG7HC.js +146 -0
- package/dist/index.js +1 -20
- package/dist/web/server.js +65 -15674
- package/package.json +1 -1
- package/dist/chunk-ZGGSF3JK.js +0 -4599
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import"dotenv/config";import{Command as hn}from"commander";import{createInterface as gn}from"readline";import{readdir as yn,readFile as Le,stat as Mt}from"fs/promises";import{spawn as Tt}from"child_process";import{dirname as H,join as S}from"path";import{fileURLToPath as Ot}from"url";import{join as jt}from"path";var Ut={baseURL:"https://openrouter.ai/api/v1"},qt={model:"claude-haiku-4-5-20251001"},I=class extends Error{constructor(e){super(e),this.name="ConfigValidationError"}},Bt={model:{provider:"openai-compatible",baseURL:"https://api.openai.com/v1",model:"gpt-4.1-mini",temperature:.2,maxTokens:4096},workspace:{root:"."},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(t={}){let e=Vt(Bt);return Be(e,t.userConfig),Be(e,t.projectConfig),Kt(e,t.env??{}),Yt(e),e}function G(t){return{...t,model:{...t.model},workspace:{...t.workspace},runtime:{...t.runtime},trace:{...t.trace},tools:{...t.tools},permissions:{...t.permissions},sessions:{...t.sessions},memory:{...t.memory},secrets:{apiKey:t.secrets.apiKey===void 0?"missing":"configured"}}}function Vt(t){return{model:{...t.model},workspace:{...t.workspace},runtime:{...t.runtime},trace:{...t.trace},tools:{...t.tools},permissions:{...t.permissions},sessions:{...t.sessions},memory:{...t.memory},secrets:{...t.secrets}}}function Be(t,e){if(e!==void 0){if(!Ve(e))throw new I("Configuration must be an object.");N(t.model,e.model),N(t.workspace,e.workspace),N(t.runtime,e.runtime),N(t.trace,e.trace),N(t.tools,e.tools),N(t.permissions,e.permissions),N(t.sessions,e.sessions),N(t.memory,e.memory)}}function N(t,e){if(e!==void 0){if(!Ve(e))throw new I("Configuration sections must be objects.");for(let[s,n]of Object.entries(e))s in t&&(t[s]=n)}}function Kt(t,e){e.OPENROUTER_API_KEY!==void 0&&(t.model.provider="openai-compatible",t.model.baseURL=Ut.baseURL,t.model.model="",t.secrets.apiKey=e.OPENROUTER_API_KEY),e.ANTHROPIC_API_KEY!==void 0&&(t.model.provider="anthropic",t.model.model=qt.model,t.secrets.apiKey=e.ANTHROPIC_API_KEY),e.VOLE_BASE_URL!==void 0&&(t.model.baseURL=e.VOLE_BASE_URL),e.VOLE_MODEL!==void 0&&(t.model.model=e.VOLE_MODEL),e.VOLE_DEFAULT_MODE!==void 0&&(t.runtime.defaultMode=e.VOLE_DEFAULT_MODE),e.VOLE_WORKSPACE_ROOT!==void 0&&(t.workspace.root=e.VOLE_WORKSPACE_ROOT),e.VOLE_LONG_TERM_MEMORY!==void 0&&(t.memory.longTermFiles=e.VOLE_LONG_TERM_MEMORY),e.VOLE_API_KEY!==void 0&&(t.secrets.apiKey=e.VOLE_API_KEY),e.VOLE_PROMPT_MODE!==void 0&&(t.runtime.promptMode=e.VOLE_PROMPT_MODE),e.VOLE_EXECUTION_CONTRACT!==void 0&&(t.runtime.executionContract=e.VOLE_EXECUTION_CONTRACT),e.VOLE_TOOL_PROFILE!==void 0&&(t.runtime.toolProfile=e.VOLE_TOOL_PROFILE),e.VOLE_SANDBOX!==void 0&&(t.runtime.sandboxed=e.VOLE_SANDBOX==="true"),e.VOLE_THINKING_BUDGET!==void 0&&(t.model.thinkingBudget=e.VOLE_THINKING_BUDGET)}function Yt(t){if(t.model.provider!=="openai-compatible"&&t.model.provider!=="anthropic")throw new I(`Invalid model.provider "${String(t.model.provider)}". Expected openai-compatible or anthropic.`);if(t.model.model.trim().length===0)throw new I("No model configured. Set VOLE_MODEL=<model-name> (e.g. VOLE_MODEL=openai/gpt-4o for OpenRouter).");if(!Ht(t.runtime.defaultMode))throw new I(`Invalid runtime.defaultMode "${String(t.runtime.defaultMode)}". Expected observe, confirm, or auto.`);if(!Wt(t.trace.verbosity))throw new I(`Invalid trace.verbosity "${String(t.trace.verbosity)}". Expected explainable or debug.`);if(!Gt(t.memory.longTermFiles))throw new I(`Invalid memory.longTermFiles "${String(t.memory.longTermFiles)}". Expected disabled or read-only.`);if(t.memory.writes!=="disabled")throw new I(`Invalid memory.writes "${String(t.memory.writes)}". Only disabled is supported.`);if(t.runtime.promptMode!==void 0&&!Jt(t.runtime.promptMode))throw new I(`Invalid runtime.promptMode "${String(t.runtime.promptMode)}". Expected full, minimal, or none.`);if(t.runtime.executionContract!==void 0&&!zt(t.runtime.executionContract))throw new I(`Invalid runtime.executionContract "${String(t.runtime.executionContract)}". Expected default or strict-agentic.`);if(t.runtime.toolProfile!==void 0&&!Xt(t.runtime.toolProfile))throw new I(`Invalid runtime.toolProfile "${String(t.runtime.toolProfile)}". Expected coding, full, messaging, or background.`);if(t.model.thinkingBudget!==void 0&&!Zt(t.model.thinkingBudget))throw new I(`Invalid model.thinkingBudget "${String(t.model.thinkingBudget)}". Expected off, minimal, low, medium, high, max, or adaptive.`)}function Ve(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ht(t){return t==="observe"||t==="confirm"||t==="auto"}function Wt(t){return t==="explainable"||t==="debug"}function Gt(t){return t==="disabled"||t==="read-only"||t==="write"}function Jt(t){return t==="full"||t==="minimal"||t==="none"}function zt(t){return t==="default"||t==="strict-agentic"}function Xt(t){return t==="coding"||t==="full"||t==="messaging"||t==="background"}function Zt(t){return t==="off"||t==="minimal"||t==="low"||t==="medium"||t==="high"||t==="max"||t==="adaptive"}function D(t,e){let s=t.sessions.directory;if(!s.startsWith("~/"))return s;let n=e?.HOME??process.env.HOME;return n===void 0?s:jt(n,s.slice(2))}import{readFile as Qt}from"fs/promises";import{join as es}from"path";var ae=class{async assemble(e){let s=[];return e.systemInstruction&&s.push({role:"system",content:e.systemInstruction}),e.recentMessages&&s.push(...e.recentMessages),s.push({role:"user",content:e.userMessage}),{modelInput:{messages:s},report:{includedSections:e.systemInstruction?["identity"]:[],omittedSections:["runtime","tooling","safety","skills","workspace"],sections:[]}}}},le=class{#e;#t;constructor(e={}){this.#e=e.workspacePromptFiles??[],this.#t=e.readWorkspaceFile??(s=>Qt(s,"utf8"))}async assemble(e){let s=e.promptMode??"full",n=[],r=[];if(s==="none"){let i=e.recentMessages??[];i.length>0&&n.push({name:"conversation_history",included:!0}),n.push({name:"user_message",included:!0});let c=n.filter(u=>u.included).map(u=>u.name),d=n.filter(u=>!u.included).map(u=>u.name);return{modelInput:{messages:[...i.map(u=>({...u})),{role:"user",content:e.userMessage}]},report:{includedSections:c,omittedSections:d,sections:n}}}if(r.push(`<identity>
|
|
3
|
+
${e.systemInstruction}
|
|
4
|
+
</identity>`),n.push({name:"identity",included:!0}),s==="full"){if(e.runtime?(r.push("",`<runtime>
|
|
5
|
+
- Mode: ${e.runtime.mode}
|
|
6
|
+
- Workspace: ${e.runtime.workspace}
|
|
7
|
+
- Date: ${e.runtime.currentDate}
|
|
8
|
+
</runtime>`),n.push({name:"runtime",included:!0})):n.push({name:"runtime",included:!1,reason:"No runtime metadata provided."}),e.tools!==void 0&&e.tools.length>0){let c=e.tools.map(d=>`- ${d.name} [${d.risk}]: ${d.description}`).join(`
|
|
9
|
+
`);r.push("",`<tooling>
|
|
10
|
+
${c}
|
|
11
|
+
</tooling>`),n.push({name:"tooling",included:!0})}else n.push({name:"tooling",included:!1,reason:"No tools registered."});if(e.permissionGuidance!==void 0&&e.permissionGuidance.length>0?(r.push("",`<safety>
|
|
12
|
+
${e.permissionGuidance}
|
|
13
|
+
</safety>`),n.push({name:"safety",included:!0})):n.push({name:"safety",included:!1,reason:"No permission guidance provided."}),e.skillIndex!==void 0&&e.skillIndex.length>0){let c=e.skillIndex.map(d=>`- ${d.name}: ${d.description}`).join(`
|
|
14
|
+
`);r.push("",`<skills>
|
|
15
|
+
${c}
|
|
16
|
+
</skills>`),n.push({name:"skills",included:!0})}else n.push({name:"skills",included:!1,reason:"No skills loaded."});let i=await this.#s(e.runtime?.workspace);i.length>0?(r.push("",`<workspace>${i.join(`
|
|
17
|
+
`)}
|
|
18
|
+
</workspace>`),n.push({name:"workspace",included:!0})):this.#e.length>0&&n.push({name:"workspace",included:!1,reason:"No workspace prompt files found."})}let o=e.recentMessages??[];o.length>0&&n.push({name:"conversation_history",included:!0}),n.push({name:"user_message",included:!0});let a=n.filter(i=>i.included).map(i=>i.name),l=n.filter(i=>!i.included).map(i=>i.name);return{modelInput:{messages:[{role:"system",content:r.join(`
|
|
19
|
+
`)},...o.map(i=>({...i})),{role:"user",content:e.userMessage}]},report:{includedSections:a,omittedSections:l,sections:n}}}async#s(e){if(e===void 0||this.#e.length===0)return[];let s=[];for(let n of this.#e)try{let o=(await this.#t(es(e,n))).trim();o.length>0&&s.push("",`### ${n}`,o)}catch(r){if(ts(r)&&r.code==="ENOENT")continue;throw r}return s}};function ts(t){return t instanceof Error&&"code"in t}var ss={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."};function ns(t){let e=0;for(let s of t)typeof s.content=="string"&&(e+=s.content.length),s.toolCalls!==void 0&&(e+=JSON.stringify(s.toolCalls).length),s.toolCallId!==void 0&&(e+=s.toolCallId.length);return Math.ceil(e/4)}async function Ke(t,e,s){let n={...ss,...s};if(!(ns(t)>n.maxTokens||t.length>n.maxMessages))return t;let o=t[0]?.role==="system"?t[0]:void 0,a=o!==void 0?t.slice(1):t,l=a.slice(0,a.length-n.keepRecent),i=a.slice(-n.keepRecent);if(l.length===0)return t;let c=l.map(rs),d=[...o!==void 0?[o]:[],...c,...i],u=c.map(m=>`${m.role.toUpperCase()}: ${m.content??"(tool call)"}`).join(`
|
|
20
|
+
`);try{let m=await e.generate({messages:[{role:"system",content:n.summarySystemPrompt},{role:"user",content:`Conversation to distil:
|
|
21
|
+
|
|
22
|
+
${u}`}]});return m.type!=="message"||!m.content?d:[...o!==void 0?[o]:[],{role:"system",content:`Conversation summary:
|
|
23
|
+
${m.content}`},...i]}catch{return d}}function rs(t){if(t.role!=="tool"||t.content===null)return t;let e;try{e=JSON.parse(t.content)}catch{return t.content.length>400?{...t,content:`${t.content.slice(0,400)}
|
|
24
|
+
[${t.content.length-400} chars omitted]`}:t}let s={};return"ok"in e&&(s.ok=e.ok),"summary"in e&&typeof e.summary=="string"&&(s.summary=e.summary),"exitCode"in e&&(s.exitCode=e.exitCode),"error"in e&&(s.error=e.error),"type"in e&&(s.type=e.type),"result"in e&&typeof e.result=="string"&&e.result.length<=200&&(s.result=e.result),{...t,content:JSON.stringify(s)}}import os from"@anthropic-ai/sdk";function Ge(t){return"generateStream"in t&&typeof t.generateStream=="function"}var ce=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 s=await this.#o(`${this.#e}/chat/completions`,{method:"POST",headers:this.#a(),body:JSON.stringify(this.#l(e))});if(!s.ok)return{type:"error",category:this.#d(s.status),message:`Provider request failed with status ${s.status}.`,recoverable:s.status===408||s.status===409||s.status===429||s.status>=500};let n=await s.json(),r=n.choices?.[0],o=r?.finish_reason,a=r?.message,l=a?.tool_calls;return o==="tool_calls"&&l!==void 0&&l.length>0?{type:"tool_calls",calls:l.map(i=>({id:i.id,name:i.function.name,input:xe(i.function.arguments)})),...n.usage?{usage:this.#m(n.usage)}:{}}:{type:"message",content:a?.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 s=await this.#o(`${this.#e}/chat/completions`,{method:"POST",headers:this.#a(),body:JSON.stringify({...this.#l(e),stream:!0})});if(!s.ok){yield{type:"error",category:this.#d(s.status),message:`Provider request failed with status ${s.status}.`,recoverable:s.status===408||s.status===409||s.status===429||s.status>=500};return}if(s.body===null){yield{type:"error",category:"network",message:"No response body for streaming request.",recoverable:!0};return}let n=new Map,r="",o,a=null;for await(let l of is(s.body)){if(l==="[DONE]")break;let i;try{i=JSON.parse(l)}catch{continue}let c=i.choices?.[0];if(c!==void 0){c.finish_reason!==null&&c.finish_reason!==void 0&&(a=c.finish_reason);let d=c.delta;if(d!==void 0&&(d.content&&(r+=d.content,yield{type:"token_delta",delta:d.content}),d.tool_calls))for(let u of d.tool_calls){n.has(u.index)||n.set(u.index,{id:"",name:"",arguments:""});let m=n.get(u.index);u.id&&(m.id=u.id),u.function?.name&&(m.name=u.function.name),u.function?.arguments&&(m.arguments+=u.function.arguments)}}i.usage&&(o=this.#m(i.usage))}a==="tool_calls"&&n.size>0?yield{type:"tool_calls",calls:Array.from(n.entries()).sort(([i],[c])=>i-c).map(([,i])=>({id:i.id,name:i.name,input:xe(i.arguments)})),...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}}}#a(){return{"content-type":"application/json",...this.#t?{authorization:`Bearer ${this.#t}`}:{}}}#l(e){return{model:this.#s,messages:e.messages.map(s=>this.#u(s)),...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(s=>({id:s.id,type:"function",function:{name:s.name,arguments:typeof s.input=="string"?s.input:JSON.stringify(s.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*is(t){let e=t.getReader(),s=new TextDecoder,n="";try{for(;;){let{done:r,value:o}=await e.read();if(r)break;n+=s.decode(o,{stream:!0});let a=n.split(`
|
|
25
|
+
`);n=a.pop()??"";for(let l of a){let i=l.trim();i.startsWith("data: ")&&(yield i.slice(6))}}n+=s.decode();for(let r of n.split(`
|
|
26
|
+
`)){let o=r.trim();o.startsWith("data: ")&&(yield o.slice(6))}}finally{e.releaseLock()}}function xe(t){try{return JSON.parse(t)}catch{return t}}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 as={minimal:1024,low:2048,medium:4096,high:8192,max:16384},de=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 s=new os({apiKey:e.apiKey});this.#e=s,this.#t={messages:{stream:n=>s.messages.create({...n,stream:!0})}}}}#a(){let e=this.#o;return e===void 0||e==="off"?void 0:e==="adaptive"?{type:"adaptive"}:{type:"enabled",budget_tokens:as[e]}}async generate(e){try{let{system:s,messages:n}=Ye(e.messages),r=s!==void 0?[{type:"text",text:s,cache_control:{type:"ephemeral"}}]:void 0,o=this.#a(),a=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:He(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}}),l=a.content.filter(ls);return a.stop_reason==="tool_use"&&l.length>0?{type:"tool_calls",calls:l.map(c=>({id:c.id,name:c.name,input:c.input})),usage:{inputTokens:a.usage.input_tokens,outputTokens:a.usage.output_tokens}}:{type:"message",content:a.content.find(cs)?.text??"",usage:{inputTokens:a.usage.input_tokens,outputTokens:a.usage.output_tokens}}}catch(s){return We(s)}}async*generateStream(e){if(this.#t===void 0){let s=await this.generate(e);s.type==="message"?(yield{type:"token_delta",delta:s.content},yield{type:"message_done",content:s.content,...s.usage?{usage:s.usage}:{}}):s.type==="tool_calls"?yield{type:"tool_calls",calls:s.calls,...s.usage?{usage:s.usage}:{}}:yield{type:"error",category:s.category,message:s.message,recoverable:s.recoverable};return}try{let{system:s,messages:n}=Ye(e.messages),r=s!==void 0?[{type:"text",text:s,cache_control:{type:"ephemeral"}}]:void 0,o=this.#a(),a={model:this.#s,max_tokens:this.#n,...r!==void 0?{system:r}:{},messages:n,...e.tools!==void 0&&e.tools.length>0?{tools:He(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}},l=await this.#t.messages.stream(a),i="",c=0,d=0,u=null,m=new Map;for await(let f of l)if(f.type==="message_start")c=f.message.usage.input_tokens;else if(f.type==="content_block_start")f.content_block.type==="tool_use"&&m.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")i+=f.delta.text,yield{type:"token_delta",delta:f.delta.text};else if(f.delta.type==="input_json_delta"){let h=m.get(f.index);h!==void 0&&(h.inputJson+=f.delta.partial_json)}}else f.type==="message_delta"&&(d=f.usage.output_tokens,u=f.delta.stop_reason);let y={inputTokens:c,outputTokens:d};u==="tool_use"&&m.size>0?yield{type:"tool_calls",calls:Array.from(m.entries()).sort(([h],[v])=>h-v).map(([,h])=>({id:h.id,name:h.name,input:xe(h.inputJson)})),usage:y}:yield{type:"message_done",content:i,usage:y}}catch(s){yield We(s)}}};function Ye(t){let e,s=[],n=0;for(;n<t.length;){let r=t[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<t.length;){let a=t[n];if(a===void 0||a.role!=="tool")break;o.push({type:"tool_result",tool_use_id:a.toolCallId??"",content:a.content??""}),n++}s.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(a=>({type:"tool_use",id:a.id,name:a.name,input:a.input}))];s.push({role:"assistant",content:o})}else s.push({role:"assistant",content:r.content??""});n++;continue}s.push({role:"user",content:r.content??""}),n++}return{system:e,messages:s}}function He(t){return t.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 ls(t){return t.type==="tool_use"&&typeof t.id=="string"&&typeof t.name=="string"}function cs(t){return t.type==="text"&&typeof t.text=="string"}function We(t){if(typeof t=="object"&&t!==null&&"status"in t&&typeof t.status=="number"){let e=t;return{type:"error",category:ds(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 ds(t){return t===401||t===403?"authentication":t===429?"rate_limit":t===400?"invalid_request":t===404?"model_unavailable":t===413||t===422?"context_length":"unknown"}var ue=class{evaluate(e){let s=e.action.risk;return s==="blocked"?{decision:"deny",risk:s,reason:"Blocked actions are denied."}:e.mode==="observe"?{decision:"ask",risk:s,reason:"Observe mode asks before external actions."}:e.mode==="auto"?s==="high"?{decision:"ask",risk:s,reason:"High-risk action requires approval in auto mode."}:{decision:"allow",risk:s,reason:"Low and medium-risk actions are allowed in auto mode."}:s==="low"?{decision:"allow",risk:s,reason:"Low-risk action is allowed in confirm mode."}:{decision:"ask",risk:s,reason:"Medium and high-risk actions require approval in confirm mode."}}};import{exec as us}from"child_process";import{access as ms,readdir as Te,readFile as z,stat as ps,writeFile as X,mkdir as Ie}from"fs/promises";import{resolve as E,relative as Ee,basename as Xe,extname as Ze,dirname as Qe,join as J}from"path";function et(){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(t,e){let s=st(t);if(s===void 0)return O("Tool input must include a string path.");let n=Re(e.workspaceRoot,s);if(n===void 0)return Z();if(me(n.absolutePath))return pe();try{return{ok:!0,content:await z(n.absolutePath,"utf8"),summary:`Read file ${n.displayPath}.`}}catch(r){return B(r)}}}}function tt(){return{name:"list_directory",description:"List entries in a workspace directory.",inputSchema:{type:"object",properties:{path:{type:"string"}},required:["path"]},risk:"low",async execute(t,e){let s=st(t);if(s===void 0)return O("Tool input must include a string path.");let n=Re(e.workspaceRoot,s);if(n===void 0)return Z();try{return{ok:!0,entries:(await Te(n.absolutePath,{withFileTypes:!0})).map(o=>({name:o.name,type:o.isDirectory()?"directory":o.isFile()?"file":"other"})).sort((o,a)=>o.name.localeCompare(a.name)),summary:`Listed directory ${n.displayPath}.`}}catch(r){return B(r)}}}}function st(t){if(typeof t!="object"||t===null||!("path"in t))return;let e=t.path;return typeof e=="string"?e:void 0}function Re(t,e){let s=E(t),n=E(s,e),r=Ee(s,n);if(!(r.startsWith("..")||r===".."||n!==s&&r===""))return{absolutePath:n,displayPath:r===""?".":r}}function O(t){return{ok:!1,error:{code:"invalid_input",message:t}}}function Z(){return{ok:!1,error:{code:"path_outside_workspace",message:"Tool path must stay inside the workspace."}}}function B(t){return{ok:!1,error:{code:typeof t=="object"&&t!==null&&"code"in t?String(t.code):"fs_error",message:"File system operation failed."}}}function me(t){let e=Xe(t).toLowerCase();if(e===".env"||e.startsWith(".env.")||e===".netrc")return!0;let s=Ze(e);return s===".key"||s===".pem"||s===".p12"||s===".pfx"?!0:e==="id_rsa"||e==="id_ed25519"||e==="id_ecdsa"||e==="id_dsa"}function pe(){return{ok:!1,error:{code:"path_not_permitted",message:"Tool path is not permitted."}}}function fs(t){if(typeof t!="object"||t===null)return;let e=t.path,s=t.content;return typeof e=="string"&&typeof s=="string"?{path:e,content:s}:void 0}var hs=3e4,Se=4e3,gs=[/\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 ys(t){return gs.some(e=>e.test(t))}function Je(t){return t.length<=Se?t:`${t.slice(0,Se)}
|
|
27
|
+
[truncated ${t.length-Se} characters]`}function ws(t,e,s){return new Promise(n=>{let r=Date.now();us(t,{cwd:e,timeout:s},(o,a,l)=>{let i=Date.now()-r;if(o?.killed===!0){n({completed:!1});return}let c=o===null?0:typeof o.code=="number"?o.code:1;n({completed:!0,exitCode:c,stdout:Je(a),stderr:Je(l),durationMs:i})})})}function ks(t){if(typeof t!="object"||t===null)return;let e=t.command;if(typeof e!="string")return;let s=t.timeoutMs;return{command:e,...typeof s=="number"?{timeoutMs:s}:{}}}function _s(){return{ok:!1,error:{code:"command_blocked",message:"Command matches a blocked pattern."}}}function vs(){return{ok:!1,error:{code:"sandbox_rejected",message:"Command rejected: workspace sandbox prevents execution outside workspace."}}}var bs=[/\/\.\.\//,/\bcd\s+\/(\s|$)/,/\bcd\s+~\/?(\s|$)/];function xs(t){return bs.some(e=>e.test(t))}function nt(t){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,s){let n=ks(e);if(n===void 0)return O("Tool input must include a string command.");if(ys(n.command))return _s();if(t?.sandboxed===!0&&xs(n.command))return vs();let r=n.timeoutMs??hs,o=await ws(n.command,s.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 rt(){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(t,e){let s=fs(t);if(s===void 0)return O("Tool input must include a string path and string content.");let n=Re(e.workspaceRoot,s.path);if(n===void 0)return Z();if(me(n.absolutePath))return pe();try{return await Ie(Qe(n.absolutePath),{recursive:!0}),await X(n.absolutePath,s.content,"utf8"),{ok:!0,summary:`Wrote file ${n.displayPath}.`}}catch(r){return B(r)}}}}function Ss(t,e){if(e.length===0)return 0;let s=0,n=0;for(;(n=t.indexOf(e,n))!==-1;)s++,n+=e.length;return s}function ot(){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(t,e){let s=t;if(typeof s.path!="string"||typeof s.old_string!="string"||typeof s.new_string!="string")return O("path, old_string, and new_string must be strings.");let n=s.path,r=s.old_string,o=s.new_string,a=s.replace_all===!0;if(r.length===0)return O("old_string must not be empty.");let l=E(e.workspaceRoot,n);if(!l.startsWith(E(e.workspaceRoot)+"/")&&l!==E(e.workspaceRoot))return Z();if(me(l))return pe();let i;try{i=await z(l,"utf8")}catch(u){return B(u)}let c=Ss(i,r);if(c===0)return{ok:!1,error:{code:"string_not_found",message:`old_string not found in ${n}.`}};if(c>1&&!a)return{ok:!1,error:{code:"multiple_matches",message:`old_string appears ${c} times in ${n}. Use replace_all: true or add more surrounding context to make it unique.`}};let d=i.split(r).join(o);try{await X(l,d,"utf8")}catch(u){return B(u)}return{ok:!0,path:n,replacements:c,summary:`Edited ${n}: ${c} replacement${c===1?"":"s"}.`}}}}function it(){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(t,e){let s=t;if(typeof s.path!="string"||typeof s.content!="string")return O("path and content must be strings.");let n=s.path,r=s.content,o=E(e.workspaceRoot,n);if(!o.startsWith(E(e.workspaceRoot)+"/")&&o!==E(e.workspaceRoot))return Z();if(me(o))return pe();try{await Ie(Qe(o),{recursive:!0}),await X(o,r,{flag:"a"})}catch(a){return B(a)}return{ok:!0,path:n,summary:`Appended to ${n}.`}}}}var Ce=8e3;function Cs(t){try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"?e:void 0}catch{return}}function Ts(t){return t.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 Is(t){return t.length<=Ce?t:`${t.slice(0,Ce)}
|
|
28
|
+
[truncated ${t.length-Ce} characters]`}function Es(t){if(typeof t!="object"||t===null)return;let e=t.url;return typeof e=="string"?e:void 0}function at(t=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,s){let n=Es(e);if(n===void 0)return O("Tool input must include a string url.");let r=Cs(n);if(r===void 0)return O("Tool url must use http or https.");try{let o=await t(n);if(!o.ok)return{ok:!1,error:{code:"http_error",message:`Page request failed with status ${o.status}.`}};let a=await o.text(),l=Is(Ts(a));return{ok:!0,url:n,content:l,summary:`Read web page ${r.hostname}.`}}catch{return{ok:!1,error:{code:"network_error",message:"Web page request failed."}}}}}}function lt(t){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,s){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 a of n.todos){if(typeof a!="object"||a===null)return{ok:!1,error:{code:"invalid_input",message:"Each todo must be an object."}};let{content:l,status:i}=a;if(typeof l!="string"||l.length===0)return{ok:!1,error:{code:"invalid_input",message:"Each todo must have a non-empty content string."}};if(i!=="pending"&&i!=="in_progress"&&i!=="completed")return{ok:!1,error:{code:"invalid_input",message:`Invalid status "${String(i)}". Must be pending, in_progress, or completed.`}};r.push({content:l,status:i})}return r.filter(a=>a.status==="in_progress").length>1?{ok:!1,error:{code:"invalid_input",message:"At most one todo may be in_progress at a time."}}:(t?.(r),{ok:!0})}}}function ct(t){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:s}=e,n=t.get(s);if(n===void 0)return{ok:!1,error:`Skill "${s}" not found. Check the skills list for available names.`};try{let{readFile:r}=await import("fs/promises");return{ok:!0,content:await r(n,"utf-8")}}catch{return{ok:!1,error:`Could not read skill file for "${s}".`}}}}}function dt(t){return{name:"memory_search",description:"Search over memory files (MEMORY.md, USER.md, memory/YYYY-MM-DD.md) for relevant content. Returns matching excerpts.",risk:"low",inputSchema:{type:"object",properties:{query:{type:"string"},maxResults:{type:"number"}},required:["query"]},async execute(e){let s=e,n=typeof s.query=="string"?s.query:"",r=typeof s.maxResults=="number"?s.maxResults:5,o=[],a=J(t,"MEMORY.md"),l=J(t,"USER.md"),i=J(t,"memory");for(let u of[a,l])try{await ms(u),o.push(u)}catch{}try{let u=await Te(i,{recursive:!0,withFileTypes:!0});for(let m of u)if(m.isFile()&&m.name.endsWith(".md")){let y=typeof m.parentPath=="string"?m.parentPath:m.path;o.push(J(y,m.name))}}catch{}if(o.length===0)return{ok:!0,results:[],total:0};let c=n.toLowerCase().split(/\s+/).filter(u=>u.length>0),d=[];for(let u of o){let m;try{m=await z(u,"utf8")}catch{continue}let y=m.split(/\n\n+/),f=Ee(t,u);for(let h of y){let v=h.toLowerCase();if(c.some(w=>v.includes(w))&&(d.push({file:f,excerpt:h.trim()}),d.length>=r))break}if(d.length>=r)break}return{ok:!0,results:d,total:d.length}}}}function ut(t){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 s=e,n=typeof s.path=="string"?s.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=E(t),o=E(r,n);if(!o.startsWith(r+"/")&&o!==r)return{ok:!0,error:"Path traversal is not permitted."};try{return{ok:!0,content:await z(o,"utf8")}}catch{return{ok:!0,error:`File not found: ${n}`}}}}}function mt(t){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,s){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=t?.getCurrentDate?.()??new Date().toISOString().slice(0,10),o=E(s.workspaceRoot,"memory"),a=E(o,`${r}.md`);try{await Ie(o,{recursive:!0});let i=`
|
|
29
|
+
## ${new Date().toISOString().replace("T"," ").slice(0,16)}
|
|
30
|
+
|
|
31
|
+
${n.content.trim()}
|
|
32
|
+
`;return await X(a,i,{flag:"a"}),{ok:!0,filePath:`memory/${r}.md`,summary:`Appended note to memory/${r}.md.`}}catch(l){return{ok:!1,error:{code:"write_error",message:l instanceof Error?l.message:"Failed to write daily memory."}}}}}}var Rs=new Set(["node_modules",".git","dist","build","coverage",".pnpm-store",".nyc_output",".turbo",".cache"]),As=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"]),Ps=512*1024,ze=50;async function*pt(t){let e;try{e=await Te(t,{withFileTypes:!0})}catch{return}for(let s of e){if(Rs.has(s.name))continue;let n=J(t,s.name);s.isDirectory()?yield*pt(n):s.isFile()&&!As.has(Ze(s.name).toLowerCase())&&(yield n)}}function Ms(t,e){let s=Xe(t),r=e.includes("/")?t.replace(/\\/g,"/"):s,o=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*\//g,"(.*/)?").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]");return new RegExp(`^${o}$`).test(r)}function ft(){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(t,e){let s=t,r=["running","completed","failed","idle"].find(c=>c===s.status)??"running",o=typeof s.message=="string"?s.message.trim():"",a=E(e.workspaceRoot,"HEARTBEAT.md"),l=new Date().toISOString(),i=["# Heartbeat","",`**Status**: ${r}`,`**Last updated**: ${l}`,...o.length>0?["",o]:[]];try{return await X(a,i.join(`
|
|
33
|
+
`)+`
|
|
34
|
+
`),{ok:!0,filePath:"HEARTBEAT.md"}}catch(c){return{ok:!1,error:{code:"write_error",message:c instanceof Error?c.message:"Failed to write HEARTBEAT.md."}}}}}}function ht(){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 ${ze}.`}},required:["pattern"]},async execute(t,e){let s=t,n=e.workspaceRoot,r=s.path?E(n,s.path):n,o=s.max_results??ze,a=s.case_sensitive===!0?"":"i",l;try{l=new RegExp(s.pattern,a)}catch{let m=s.pattern.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");l=new RegExp(m,a)}let i=[],c=0,d=0,u=!1;e:for await(let m of pt(r)){let y=Ee(n,m).replace(/\\/g,"/");if(s.include!==void 0&&!Ms(y,s.include))continue;let f;try{if((await ps(m)).size>Ps)continue;f=await z(m,"utf8")}catch{continue}c++;let h=f.split(`
|
|
35
|
+
`),v=!1;for(let w=0;w<h.length;w++){if(l.test(h[w])){if(i.length>=o){u=!0;break e}i.push({file:y,line:w+1,content:h[w].trimEnd()}),v=!0}l.lastIndex=0}v&&d++}return{type:"search_files_result",matches:i,truncated:u,matchedFiles:d,searchedFiles:c}}}}var V=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(s=>s.runId===e)}};var Os=12,$s=2,Ns="Low-risk actions run automatically. Medium and high-risk actions require approval. Blocked actions are never permitted.",Ds="Do not restate the plan. Act now: take the first concrete tool action you can.",yt=/\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,Ls=/\b(?:done|finished|implemented|updated|fixed|changed|ran|verified|found|here(?:'s| is) what|blocked by|the blocker is)\b/i,Fs=/^(?:plan|steps?|next steps?)\s*:/im,js=/^(?:[-*•]\s+|\d+[.)]\s+)/u,Us=/\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,qs=700,L=class{#e;#t;#s;#n;#r;#o;#a;#l;#u;#d;#m;#f;#h;#c;#g;#v;#w;#k;#_;#y=[];constructor(e){this.#e=e.contextAssembler??new ae,this.#t=e.modelProvider,this.#s=e.permissionPolicy??new ue,this.#n=e.approvalResolver,this.#a=e.maxSteps??Os,this.#v=e.executionContract??"default",this.#l=e.executionContract==="strict-agentic"?e.maxPlanningStallRetries??3:e.maxPlanningStallRetries??$s,this.#o=e.skillIndex??[];let s=e.systemInstruction??"";this.#u=e.executionContract==="strict-agentic"?`${s}
|
|
36
|
+
|
|
37
|
+
Execution contract: strict-agentic. Act immediately. Do not narrate plans. Call tools now.`:s,this.#d=e.runtime,this.#m=e.preferStreaming??!1,this.#f=e.compaction,this.#h=e.promptMode,this.#c=e.hooks,this.#g=e.sessionMutex,this.#w=e.createRunId??gt("run"),this.#k=e.createEventId??gt("evt"),this.#_=e.now??(()=>new Date().toISOString());let n=lt(o=>{this.#y=o}),r=e.tools??[];this.#r=new Map([n,...r].map(o=>[o.name,o]))}async*runTurn(e){let s=this.#w(),n=e.sessionId?{runId:s,sessionId:e.sessionId}:{runId:s},r=[],o=this.#g?await this.#g.acquire(e.sessionId??"global"):void 0;try{if(this.#c?.beforeTurn!==void 0)try{await this.#c.beforeTurn(e)}catch(w){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeTurn hook threw:",w)}let a=w=>(r.push(w),w);yield a(this.#i({...n,type:"run_started",userMessage:e.message}));let l=this.#b(),i=await this.#e.assemble({systemInstruction:this.#u,...this.#d?{runtime:this.#d}:{},...l.length>0?{tools:l}:{},permissionGuidance:Ns,...this.#o.length>0?{skillIndex:this.#o}:{},...e.recentMessages?{recentMessages:e.recentMessages}:{},...this.#h!==void 0?{promptMode:this.#h}:{},userMessage:e.message});yield a(this.#i({...n,type:"context_assembled",messageCount:i.modelInput.messages.length,systemInstructionIncluded:i.report.includedSections.includes("identity")}));let c=this.#x(),d=i.modelInput.messages,u=0,m=0,y=!1;this.#y=[];let f=[],h=i.modelInput.messages.at(-1);for(h&&f.push({...h});u<this.#a;){if(e.signal?.aborted){yield a(this.#i({...n,type:"run_failed",error:{message:"Aborted by user.",recoverable:!1}})),await this.#p(r);return}if(this.#f!==void 0){let p=d.length;d=await Ke(d,this.#t,this.#f);let C=d.length;if(C<p){let k=d.find(b=>b.role==="system"&&typeof b.content=="string"&&b.content.startsWith(`Conversation summary:
|
|
38
|
+
`)),T=k&&typeof k.content=="string"?k.content.slice(22):"";yield a(this.#i({...n,type:"compaction_triggered",messagesBefore:p,messagesAfter:C,summary:T}))}if(this.#c?.onCompaction!==void 0)try{await this.#c.onCompaction(p,C)}catch(k){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] onCompaction hook threw:",k)}}yield a(this.#i({...n,type:"model_request_started",provider:"configured"}));let w={messages:d,...c.length>0?{tools:c}:{},...i.modelInput.options!==void 0?{options:i.modelInput.options}:{}},g;if(this.#m&&Ge(this.#t)){let p="",C,k,T;for await(let b of this.#t.generateStream(w)){if(e.signal?.aborted)break;b.type==="token_delta"?yield a(this.#i({...n,type:"token_delta",delta:b.delta})):b.type==="message_done"?(p=b.content,k=b.usage):b.type==="tool_calls"?(C=b.calls,k=b.usage):b.type==="error"&&(T={category:b.category,message:b.message,recoverable:b.recoverable})}T!==void 0?g={type:"error",category:T.category,message:T.message,recoverable:T.recoverable}:C!==void 0?g={type:"tool_calls",calls:C,...k!==void 0?{usage:k}:{}}:g={type:"message",content:p,...k!==void 0?{usage:k}:{}}}else g=await this.#t.generate(w);if(yield a(this.#i({...n,type:"model_request_completed",provider:"configured"})),u++,g.type==="error"){yield a(this.#i({...n,type:"run_failed",error:{message:g.message,recoverable:g.recoverable}})),await this.#p(r);return}if(g.type==="message"){if([...this.#r.keys()].some(k=>k!=="update_todos")&&!y&&Ys(g.content)){if(m++,yield a(this.#i({...n,type:"planning_stall_detected",stallCount:m,maxRetries:this.#l})),m>=this.#l){yield a(this.#i({...n,type:"run_failed",error:{message:"Agent stopped after repeated plan-only turns without taking action.",recoverable:!1}})),await this.#p(r);return}d=[...d,{role:"assistant",content:g.content},{role:"user",content:Ds}];continue}m=0,f.push({role:"assistant",content:g.content}),yield a(this.#i({...n,type:"assistant_message_created",message:{role:"assistant",content:g.content}})),yield a(this.#i({...n,type:"turn_complete",messages:[...f]})),yield a(this.#i({...n,type:"run_completed"})),await this.#p(r);return}m=0,g.calls.some(p=>p.name!=="update_todos")&&(y=!0);let R={role:"assistant",content:null,toolCalls:g.calls};d=[...d,R],f.push({...R});let x=[],$=!1,P="";for(let p of g.calls){yield a(this.#i({...n,type:"tool_call_requested",call:p}));let C=this.#r.get(p.name);if(C===void 0){let _=`Tool "${p.name}" is not registered.`;yield a(this.#i({...n,type:"tool_failed",callId:p.id,toolName:p.name,error:{message:_}}));let M={role:"tool",toolCallId:p.id,content:`Error: ${_}`};x.push(M),f.push({...M});continue}let k=this.#s.evaluate({mode:Vs(this.#d?.mode),action:Bs(p,C.risk)});if(yield a(this.#i({...n,type:"tool_call_permission_evaluated",callId:p.id,toolName:p.name,decision:k})),k.decision==="deny"){$=!0,P=`Tool call ${p.name} was denied.`;break}if(k.decision==="ask"){yield a(this.#i({...n,type:"approval_requested",callId:p.id,toolName:p.name,decision:k}));let _=this.#n===void 0?{approved:!1,reason:"No approval resolver was configured."}:await this.#n.resolve({call:p,decision:k});if(yield a(this.#i({...n,type:"approval_resolved",callId:p.id,toolName:p.name,resolution:_})),!_.approved){$=!0,P=`Tool call ${p.name} was denied.`;break}}if(this.#c?.beforeToolCall!==void 0){let _;try{_=await this.#c.beforeToolCall(p)}catch(M){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeToolCall hook threw:",M)}if(_==="abort"){let M="Tool call aborted by hook.";yield a(this.#i({...n,type:"tool_failed",callId:p.id,toolName:p.name,error:{message:M}}));let W={role:"tool",toolCallId:p.id,content:`Error: ${M}`};x.push(W),f.push({...W});continue}}yield a(this.#i({...n,type:"tool_started",callId:p.id,toolName:p.name}));let T;try{T=await C.execute(p.input,{workspaceRoot:this.#d?.workspace??process.cwd()})}catch(_){let M=_ instanceof Error?_.message:"Unknown tool execution error.";yield a(this.#i({...n,type:"tool_failed",callId:p.id,toolName:p.name,error:{message:M}}));let W={role:"tool",toolCallId:p.id,content:`Error: ${M}`};x.push(W),f.push({...W});continue}yield a(this.#i({...n,type:"tool_completed",callId:p.id,toolName:p.name,result:T}));let b={role:"tool",toolCallId:p.id,content:JSON.stringify(T)};if(x.push(b),f.push({...b}),this.#c?.afterToolCall!==void 0)try{await this.#c.afterToolCall(p,T)}catch(_){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] afterToolCall hook threw:",_)}}if($){yield a(this.#i({...n,type:"run_failed",error:{message:P,recoverable:!1}})),await this.#p(r);return}g.calls.some(p=>p.name==="update_todos")&&(yield a(this.#i({...n,type:"todos_updated",todos:[...this.#y]}))),d=[...d,...x]}yield a(this.#i({...n,type:"run_failed",error:{message:`Agent loop reached the step limit of ${this.#a}.`,recoverable:!1}})),await this.#p(r)}finally{o?.()}}async#p(e){if(this.#c?.afterTurn!==void 0)try{await this.#c.afterTurn(e)}catch(s){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] afterTurn hook threw:",s)}}#b(){return[...this.#r.values()].map(e=>({name:e.name,description:e.description,risk:e.risk}))}#x(){return[...this.#r.values()].map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.inputSchema}}))}#i(e){return{...e,eventId:this.#k(),timestamp:this.#_()}}};function gt(t){return()=>`${t}_${crypto.randomUUID()}`}function Bs(t,e){return{kind:"tool",name:t.name,summary:`Model requested tool ${t.name}.`,risk:e}}function Vs(t){return t==="observe"||t==="auto"?t:"confirm"}function Ks(t){let e=t.split(/\r?\n/).map(o=>o.trim()).filter(Boolean);if(e.length===0)return!1;let s=e.filter(o=>js.test(o)).length,n=e.some(o=>yt.test(o));return Fs.test(e[0]??"")&&n||s>=2&&n}function Ys(t){let e=t.trim();if(!e||e.length>qs||e.includes("```")||Ls.test(e))return!1;let s=Ks(e);return!(!yt.test(e)&&!s||!s&&!Us.test(e))}function wt(t,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."}},required:["goal"]},async execute(s){let n=s,r=`task_${crypto.randomUUID()}`;e?.taskStore!==void 0&&await e.taskStore.create({id:r,runtime:"subagent",task:n.goal,status:"queued",...e.parentTaskId!==void 0?{parentId:e.parentTaskId}:{}});let o=n.context!==void 0?`${n.goal}
|
|
39
|
+
|
|
40
|
+
Context:
|
|
41
|
+
${n.context}`:n.goal;return(async()=>{e?.taskStore!==void 0&&await e.taskStore.update(r,{status:"running"});let l=t.create(n.goal),i="",c=!1;for await(let d of l.runTurn({message:o}))d.type==="assistant_message_created"&&(i=d.message.content),d.type==="run_failed"&&(c=!0);e?.taskStore!==void 0&&await e.taskStore.update(r,{status:c?"failed":"succeeded",...i.length>0?{terminalSummary:i}:{}})})(),{type:"spawn_subagent_async_result",taskId:r,status:"queued"}}}}function kt(t){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 s=e,n=typeof s.taskId=="string"?s.taskId.trim():"";if(n==="")return{ok:!1,error:{code:"invalid_input",message:"taskId is required."}};let r=await t.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 _t(t){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,s){let n=e,r=t.create(n.goal),o="",a=!1,l="";for await(let i of r.runTurn({message:n.goal}))i.type==="assistant_message_created"&&(o=i.message.content),i.type==="run_failed"&&(a=!0,l=i.error.message);return a?{type:"spawn_subagent_result",ok:!1,error:l}:{type:"spawn_subagent_result",ok:!0,result:o}}}}var fe=class{#e=new Map;register(e){this.#e.set(e.id,e)}unregister(e){this.#e.delete(e)}touch(e){let s=this.#e.get(e);s!==void 0&&this.#e.set(e,{...s,lastActivityAt:new Date().toISOString()})}get(e){return this.#e.get(e)}list(){return Array.from(this.#e.values())}listByAdapter(e){return this.list().filter(s=>s.adapterName===e)}};var vt={streaming:!0,approvalPrompts:!0,background:!1};var Hs={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"]},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 he(t,e){let s=Hs[e];return s.allowedTools.length===0?t:t.filter(n=>s.allowedTools.includes(n.name))}import{mkdir as Ae,readFile as Ws,writeFile as Pe}from"fs/promises";import{dirname as Me}from"path";var K=class{#e;constructor(e){this.#e=e}async saveRun(e){await Ae(Me(this.#e),{recursive:!0}),await Pe(this.#e,`${JSON.stringify(e)}
|
|
42
|
+
`,{flag:"a"})}async updateRun(e,s){let r=(await this.#t()).map(o=>o.id===e?{...o,...s}:o);await Ae(Me(this.#e),{recursive:!0}),await Pe(this.#e,r.map(o=>JSON.stringify(o)).join(`
|
|
43
|
+
`)+(r.length>0?`
|
|
44
|
+
`:""))}async listRuns(e={}){let s=await this.#t(),n=e.taskName===void 0?s:s.filter(r=>r.taskName===e.taskName);return e.limit===void 0?n:n.slice(-e.limit)}async#t(){let e="";try{e=await Ws(this.#e,"utf8")}catch(n){if(Gs(n)&&n.code==="ENOENT")return[];throw n}let s=[];for(let n of e.split(`
|
|
45
|
+
`))n.trim()!==""&&s.push(JSON.parse(n));return s}},ee=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 Gs(t){return t instanceof Error&&"code"in t}function Q(t,e){if(t==="*")return!0;let s=parseInt(t,10);return!isNaN(s)&&s===e}function Js(t,e){let s=t.trim().split(/\s+/);if(s.length!==5)return!1;let[n,r,o,a,l]=s;return Q(n,e.getMinutes())&&Q(r,e.getHours())&&Q(o,e.getDate())&&Q(a,e.getMonth()+1)&&Q(l,e.getDay())}async function Oe(t,e){await Ae(Me(t),{recursive:!0});let s=["# 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 Pe(t,s.join(`
|
|
46
|
+
`)+`
|
|
47
|
+
`)}var ge=class{#e;#t;#s;#n;#r;#o=new Map;constructor(e,s,n){this.#e=e,this.#t=s,this.#s=n?.checkIntervalMs??3e4,this.#n=n?.getNow??(()=>new Date)}start(){this.#r===void 0&&(this.#r=setInterval(()=>{this.#a()},this.#s),this.#a())}stop(){this.#r!==void 0&&(clearInterval(this.#r),this.#r=void 0)}get isRunning(){return this.#r!==void 0}async#a(){let e=this.#n();for(let s of this.#e){if(!s.cron||!Js(s.cron,e))continue;let n=this.#o.get(s.name)??0,r=Math.floor(e.getTime()/6e4);if(n!==r){this.#o.set(s.name,r);try{await this.#t(s)}catch{}}}}};import{mkdir as zs,readdir as Xs,readFile as Zs,writeFile as Qs}from"fs/promises";import{join as en}from"path";var ye=class{#e=new Map;#t=new Map;#s=new Map;#n;#r;#o;constructor(e={}){this.#n=e.createSessionId??ke("sess"),this.#r=e.createMessageId??ke("msg"),this.#o=e.now??(()=>new Date().toISOString())}async createSession(e={}){let s=this.#o(),n={id:this.#n(),...e.title===void 0?{}:{title:e.title},createdAt:s,updatedAt:s};return this.#e.set(n.id,n),this.#t.set(n.id,[]),this.#s.set(n.id,[]),{...n}}async getSession(e){let s=this.#e.get(e);return s===void 0?void 0:{...s}}async listSessions(e={}){let s=[...this.#e.values()].sort(xt);return(e.limit===void 0?s:s.slice(0,e.limit)).map(r=>({...r}))}async appendMessage(e){let s=this.#e.get(e.sessionId);if(s===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,{...s,updatedAt:n}),{...r}}async listMessages(e,s={}){let n=this.#t.get(e)??[];return(s.limit===void 0?n:n.slice(-s.limit)).map(o=>({...o}))}async appendCompactBoundary(e){let s=this.#e.get(e.sessionId);if(s===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,{...s,updatedAt:r})}this.#t.set(e.sessionId,n)}async appendTraceEvent(e){let s=this.#e.get(e.sessionId);if(s===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,{...s,updatedAt:n}),we(r)}async listTraceEvents(e,s={}){let n=this.#s.get(e)??[];return(s.limit===void 0?n:n.slice(-s.limit)).map(o=>we(o))}},te=class{#e;#t;#s;#n;constructor(e){this.#e=e.directory,this.#t=e.createSessionId??ke("sess"),this.#s=e.createMessageId??ke("msg"),this.#n=e.now??(()=>new Date().toISOString())}async createSession(e={}){let s=this.#n(),n={id:this.#t(),...e.title===void 0?{}:{title:e.title},createdAt:s,updatedAt:s};return await this.#r(n.id,{type:"session",session:n}),{...n}}async getSession(e){let s=await this.#o(e);return s.session===void 0?void 0:{...s.session}}async listSessions(e={}){let s=await this.#l(),n=[];for(let a of s){let l=await this.getSession(a);l!==void 0&&n.push(l)}let r=n.sort(xt);return(e.limit===void 0?r:r.slice(0,e.limit)).map(a=>({...a}))}async appendMessage(e){if((await this.#o(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.#r(e.sessionId,{type:"message",message:r}),{...r}}async listMessages(e,s={}){let n=await this.#o(e);return(s.limit===void 0?n.messages:n.messages.slice(-s.limit)).map(o=>({...o}))}async appendTraceEvent(e){if((await this.#o(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.#r(e.sessionId,{type:"trace",traceEvent:n}),we(n)}async listTraceEvents(e,s={}){let n=await this.#o(e);return(s.limit===void 0?n.traceEvents:n.traceEvents.slice(-s.limit)).map(o=>we(o))}async appendCompactBoundary(e){if((await this.#o(e.sessionId)).session===void 0)throw new Error(`Unknown session "${e.sessionId}".`);let n=this.#n();await this.#r(e.sessionId,{type:"compact_boundary",summary:e.summary,messagesBefore:e.messagesBefore,messagesAfter:e.messagesAfter,createdAt:n})}async#r(e,s){await zs(this.#e,{recursive:!0}),await Qs(this.#a(e),`${JSON.stringify(s)}
|
|
48
|
+
`,{flag:"a"})}async#o(e){let s="";try{s=await Zs(this.#a(e),"utf8")}catch(a){if(bt(a)&&a.code==="ENOENT")return{messages:[],traceEvents:[]};throw a}let n=[],r=[],o;for(let a of s.split(`
|
|
49
|
+
`)){if(a.trim()==="")continue;let l=JSON.parse(a);l.type==="session"?o=l.session:l.type==="compact_boundary"?(n=[],l.summary&&n.push({id:`cmpct_${l.createdAt}`,sessionId:o?.id??"",role:"system",content:l.summary,createdAt:l.createdAt}),o&&l.createdAt>o.updatedAt&&(o={...o,updatedAt:l.createdAt})):l.type==="message"?(n.push(l.message),o&&l.message.createdAt>o.updatedAt&&(o={...o,updatedAt:l.message.createdAt})):(r.push(l.traceEvent),o&&l.traceEvent.createdAt>o.updatedAt&&(o={...o,updatedAt:l.traceEvent.createdAt}))}return{...o===void 0?{}:{session:o},messages:n,traceEvents:r}}#a(e){return tn(e),en(this.#e,`${e}.jsonl`)}async#l(){try{return(await Xs(this.#e)).filter(s=>s.endsWith(".jsonl")).map(s=>s.slice(0,-6)).filter(s=>/^[A-Za-z0-9_-]+$/.test(s))}catch(e){if(bt(e)&&e.code==="ENOENT")return[];throw e}}};function tn(t){if(!/^[A-Za-z0-9_-]+$/.test(t))throw new Error(`Unsafe session id "${t}".`)}function bt(t){return t instanceof Error&&"code"in t}function xt(t,e){return e.updatedAt.localeCompare(t.updatedAt)}function we(t){return{...t,event:structuredClone(t.event)}}function ke(t){return()=>`${t}_${crypto.randomUUID()}`}import{mkdir as sn,readFile as nn,writeFile as rn}from"fs/promises";import{join as hr,dirname as on}from"path";var j=class{#e;constructor(e){this.#e=e}async#t(){try{return(await nn(this.#e,"utf-8")).split(`
|
|
50
|
+
`).filter(s=>s.trim().length>0).map(s=>JSON.parse(s))}catch{return[]}}async#s(e){await sn(on(this.#e),{recursive:!0}),await rn(this.#e,e.map(s=>JSON.stringify(s)).join(`
|
|
51
|
+
`)+`
|
|
52
|
+
`,"utf-8")}async create(e){let s=new Date().toISOString(),n={...e,createdAt:s,updatedAt:s},r=await this.#t();return r.push(n),await this.#s(r),n}async update(e,s){let n=await this.#t(),r=n.findIndex(a=>a.id===e);if(r===-1)return;let o={...n[r],...s,updatedAt:new Date().toISOString()};return n[r]=o,await this.#s(n),o}async get(e){return(await this.#t()).find(n=>n.id===e)}async list(e){let s=await this.#t();return e?.status!==void 0&&(s=s.filter(n=>n.status===e.status)),e?.parentId!==void 0&&(s=s.filter(n=>n.parentId===e.parentId)),e?.limit!==void 0&&(s=s.slice(-e.limit)),s}};import{copyFile as an,mkdir as St,readFile as se,readdir as ln,writeFile as cn}from"fs/promises";import{homedir as dn}from"os";import{basename as un,join as F}from"path";var mn=[{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:""}],ne=class{async load(e={}){let s=new Set,n=[],r=l=>{s.has(l.name)||(s.add(l.name),n.push(l))};if(e.workspaceRoot!==void 0){let l=F(e.workspaceRoot,"skills");for(let i of await this.#e(l,"workspace",e))r(i)}let o=e.userSkillsDir??F(dn(),".vole","skills"),a=await pn(o,e.readFile);for(let l of await this.#e(o,"user",e,a))r(l);for(let l of mn)r(l);return n}async#e(e,s,n,r){let o=n.readDir??(c=>ln(c)),a=n.readFile??(c=>se(c,"utf8")),l;try{l=await o(e)}catch(c){if(fn(c)&&c.code==="ENOENT")return[];throw c}let i=[];for(let c of l){if(c==="skills-index.json")continue;let d=F(e,c,"SKILL.md");if(s==="user"&&r!==void 0){let u=r.skills.find(m=>m.name===c);if(u!==void 0&&u.enabled===!1)continue}try{let u=await a(d),m=$e(u);if(m!==null){let y,f;if(s==="user"){let v=r?.skills.find(w=>w.name===c);y=v?.trusted??!1,f=v?.enabled??!0}let h={...m,source:s,filePath:d,...y!==void 0?{trusted:y}:{},...f!==void 0?{enabled:f}:{}};i.push(h)}}catch{}}return i}};async function pn(t,e){let s=e??(r=>se(r,"utf8")),n=F(t,"skills-index.json");try{let r=await s(n);return JSON.parse(r)}catch{return}}var Y=class{#e;constructor(e){this.#e=e}async loadManifest(){let e=F(this.#e,"skills-index.json");try{let s=await se(e,"utf8");return JSON.parse(s)}catch{return{skills:[]}}}async saveManifest(e){await St(this.#e,{recursive:!0});let s=F(this.#e,"skills-index.json");await cn(s,JSON.stringify(e,null,2)+`
|
|
53
|
+
`,"utf8")}async install(e){let s=un(e),n=s.endsWith(".md")?s.slice(0,-3):s,r=await se(e,"utf8"),o=$e(r),a=o?.name??n,l=F(this.#e,a);await St(l,{recursive:!0});let i=F(l,"SKILL.md");await an(e,i);let c=await this.loadManifest(),d=c.skills.findIndex(m=>m.name===a),u={name:a,filePath:i,installedAt:new Date().toISOString(),...o?.origin!==void 0?{origin:o.origin}:{},trusted:!1,enabled:!0};return d!==-1?c.skills[d]=u:c.skills.push(u),await this.saveManifest(c),u}async enable(e){let s=await this.loadManifest(),n=s.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(s)}async disable(e){let s=await this.loadManifest(),n=s.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(s)}async trust(e){let s=await this.loadManifest(),n=s.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(s)}async review(e){let n=(await this.loadManifest()).skills.find(r=>r.name===e);if(n!==void 0)try{let r=await se(n.filePath,"utf8"),o=$e(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 $e(t){let e=t.split(`
|
|
54
|
+
`);if(e[0]?.trim()!=="---")return null;let s=e.findIndex((f,h)=>h>0&&f.trim()==="---");if(s===-1)return null;let n=e.slice(1,s),r=e.slice(s+1).join(`
|
|
55
|
+
`).trim(),o={},a={},l=null;for(let f of n){let h=/^\s+-\s+(.+)$/.exec(f);if(h!==null&&l!==null){let R=h[1]?.trim()??"";R.length>0&&(a[l]=[...a[l]??[],R]);continue}let v=f.indexOf(":");if(v===-1){l=null;continue}let w=f.slice(0,v).trim(),g=f.slice(v+1).trim();if(w.length===0){l=null;continue}g===""?l=w:(l=null,o[w]=g)}let{name:i,description:c,version:d,origin:u,permissions:m}=o;if(!i||!c)return null;let y;return m!==void 0&&m.length>0?y=m.split(",").map(f=>f.trim()).filter(f=>f.length>0):a.permissions!==void 0&&(y=a.permissions),{name:i,description:c,body:r,...d!==void 0?{version:d}:{},...u!==void 0?{origin:u}:{},...y!==void 0?{permissions:y}:{}}}function Ct(t){return{name:t.name,description:t.description,source:t.source}}function fn(t){return t instanceof Error&&"code"in t}var jr="@vole/cli";async function It(t){try{return JSON.parse(await Le(t,"utf8"))}catch{return}}async function A(t={}){let e=t.env??process.env,s=e.HOME??process.env.HOME,n={env:e};return s!==void 0&&(n.userConfig=await It(S(s,".vole","config.json"))),n.projectConfig=await It(S("vole.config.json")),be(n)}var _e=`You are Vole, a capable coding and general-purpose agent.
|
|
56
|
+
|
|
57
|
+
## Tool Call Style
|
|
58
|
+
Do not narrate routine, low-risk tool calls \u2014 just call the tool.
|
|
59
|
+
Narrate only when it genuinely helps: multi-step work, sensitive actions, or when explaining a non-obvious choice.
|
|
60
|
+
Keep narration brief; avoid restating what tool output already shows.
|
|
61
|
+
|
|
62
|
+
## Execution Bias
|
|
63
|
+
- Actionable request: act in this turn, do not describe what you plan to do.
|
|
64
|
+
- Non-final turn: use tools to advance, or ask for the one decision that blocks safe progress.
|
|
65
|
+
- Continue until done or genuinely blocked; do not end with a plan or promise when tools can move work forward.
|
|
66
|
+
- Weak or empty tool result: vary the query, path, command, or source before concluding.
|
|
67
|
+
- Mutable facts require live checks: files, git state, versions, running processes, package state.
|
|
68
|
+
- Final answer requires evidence: test output, lint result, file inspection, or a named concrete blocker.
|
|
69
|
+
- Longer work: brief progress note, then keep going.
|
|
70
|
+
|
|
71
|
+
## File Editing
|
|
72
|
+
- Modify existing code: edit_file (precise string replacement, preserves surrounding content).
|
|
73
|
+
- Add to end of file: append_file.
|
|
74
|
+
- Create new files or intentional full replacement: write_file.`,Et=new fe;async function wn(t,e,s={}){let n="",r=null,o=new hn().name("vole").description("A capable coding and general-purpose agent.").version(e,"-v, --version","Show version number").exitOverride().configureOutput({writeOut:i=>{n+=i},writeErr:i=>{n+=i}}).addHelpText("after","\nRun `vole <command> --help` for command-specific options.");o.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(i,c)=>{let d=i.filter(m=>m.startsWith("/"));if(c.fake!==void 0){r=await kn({message:c.fake,slashCommands:d},s);return}if(c.fakeInteractive){let m=typeof c.session=="string"?c.session:void 0;r=await _n(s,{fakeInteractive:!0,resume:!1,...m!==void 0?{sessionId:m}:{}});return}let u=typeof c.session=="string"?c.session:void 0;r=await vn(s,{fakeInteractive:!1,resume:c.resume===!0,...u!==void 0?{sessionId:u}:{}})}),o.command("sessions").description("List stored chat sessions").action(async()=>{r=await bn(s)}),o.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(i,c)=>{if(c.dream){r=await xn(s);return}let d=(i??"").trim();if(d===""){r={exitCode:1,stdout:"",stderr:`Missing goal. Usage: vole run "<goal>"
|
|
75
|
+
`};return}let u=c.mode;r=await $t(d,u==="auto"?"auto":u==="observe"?"observe":"confirm",s)}),o.command("tasks").description("List recent background task runs").option("-n, --limit <n>","Number of runs to show",i=>parseInt(i,10)).action(async i=>{r=await Sn(s,i.limit)});let a=o.command("skills").description("Manage agent skills");a.action(async()=>{r=await Rn(s)}),a.command("install <path>").description("Install a skill from a local .md file").action(async i=>{r=await An(i,s)}),a.command("enable <name>").description("Enable a disabled skill").action(async i=>{r=await Ne("enable",i,s)}),a.command("disable <name>").description("Disable a skill").action(async i=>{r=await Ne("disable",i,s)}),a.command("trust <name>").description("Mark an installed skill as trusted").action(async i=>{r=await Ne("trust",i,s)}),a.command("review <name>").description("Show full skill metadata and permissions").action(async i=>{r=await Pn(i,s)}),o.command("daemon").description("Start the task scheduler daemon").option("--once","Run all due tasks once and exit").action(async i=>{r=await Tn(s,i.once===!0)}),o.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 i=>{let c=parseInt(i.port,10)||3120,d=i.open!==!1;r=await Un(c,d)});let l=o.command("taskflow").description("Inspect cross-session task records");l.action(async()=>{r=await At(s,void 0)}),l.command("list").description("List recent task records").option("-n, --limit <n>","Number of records to show",i=>parseInt(i,10)).action(async i=>{r=await At(s,i.limit)}),l.command("show <id>").description("Show details of a task").action(async i=>{r=await In(i,s)}),l.command("cancel <id>").description("Mark a task as cancelled").action(async i=>{r=await En(i,s)});try{let i=t[0]==="--"?t.slice(1):t;await o.parseAsync(i,{from:"user"})}catch(i){if(i instanceof Error&&"code"in i){let c=i.code;if(c==="commander.helpDisplayed"||c==="commander.version")return{exitCode:0,stdout:n,stderr:""};if(c==="commander.unknownCommand"){let d=i.message.match(/unknown command '(.+)'/),u=d?d[1]:t[0]??"unknown";return{exitCode:1,stdout:o.helpInformation(),stderr:`Unknown command "${u}".
|
|
76
|
+
`}}return{exitCode:i.exitCode??1,stdout:n,stderr:`${i.message}
|
|
77
|
+
`}}throw i}return r??{exitCode:0,stdout:n,stderr:""}}async function kn(t,e){let{message:s,slashCommands:n}=t;if(s.trim()==="")return{exitCode:1,stdout:"",stderr:"Missing message for `chat --fake`.\n"};let r=await ie.createFake(`Fake response to: ${s}`,e),o=await r.sendMessage(s),a=await On(r,n),l=o.assistantText,i=o.events,c=qe(i).join(`
|
|
78
|
+
`);return{exitCode:i.some(d=>d.type==="run_failed")?1:0,stdout:`Assistant: ${l}
|
|
79
|
+
|
|
80
|
+
Trace:
|
|
81
|
+
${c}
|
|
82
|
+
${a}`,stderr:""}}async function _n(t,e){let s=await ie.createFake(n=>`Fake response to: ${n}`,t,{...e.sessionId===void 0?{}:{sessionId:e.sessionId}});return Nt(s,"Vole chat (fake provider)",t)}async function vn(t,e){let s=await A(t.env?{env:t.env}:{});if(s.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.
|
|
83
|
+
`};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 Mn(s,t):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 Nt(await ie.createConfigured(s,t,{...r===void 0?{}:{sessionId:r}}),n===void 0?"Vole chat":`Vole chat
|
|
84
|
+
Resumed session: ${n}`,t)}async function bn(t){let e=await A(t.env?{env:t.env}:{}),n=await Ue(e,t,U()).listSessions();return n.length===0?{exitCode:0,stdout:`Sessions:
|
|
85
|
+
No sessions found.
|
|
86
|
+
`,stderr:""}:{exitCode:0,stdout:["Sessions:",...n.map(r=>`${r.id} ${r.updatedAt}${r.title?` ${r.title}`:""}`)].join(`
|
|
87
|
+
`)+`
|
|
88
|
+
`,stderr:""}}async function xn(t){let e=await A(t.env?{env:t.env}:{});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.
|
|
89
|
+
`}:e.memory.longTermFiles!=="write"?{exitCode:1,stdout:"",stderr:`Memory dreaming requires VOLE_LONG_TERM_MEMORY=write
|
|
90
|
+
`}:$t(`You are a memory consolidation agent.
|
|
91
|
+
Review the recent daily memory files and the current MEMORY.md in the workspace.
|
|
92
|
+
Identify key facts, decisions, and patterns worth preserving long-term.
|
|
93
|
+
Append a consolidation summary to MEMORY.md using the write_file tool.
|
|
94
|
+
Be concise and factual. Do not duplicate what is already in MEMORY.md.`,"auto",t)}async function $t(t,e,s){let n=await A(s.env?{env:s.env}:{});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.
|
|
95
|
+
`};let r=s.sessionsDirectory?{...n,sessions:{directory:s.sessionsDirectory}}:n,o=D(r,s.env),a=U(),l=`task_${crypto.randomUUID()}`,i=t.slice(0,40).replace(/\s+/g,"-").replace(/[^A-Za-z0-9-]/g,"").toLowerCase()||"task",c=new Date().toISOString(),d=new te({directory:o,createSessionId:()=>a}),u=new K(S(o,"task-runs.jsonl")),m={id:l,taskName:i,goal:t,sessionId:a,startedAt:c,status:"running",assistantText:""};await u.saveRun(m);let y=je(n,s),f=new ee(e),h=new Date().toISOString().slice(0,10),v=(()=>{let _=re(s,n);return n.runtime.toolProfile!==void 0?he(_,n.runtime.toolProfile):_})(),w=new L({contextAssembler:oe(n,h),modelProvider:y,systemInstruction:_e,runtime:{mode:e,workspace:n.workspace.root,currentDate:h},tools:v,preferStreaming:!1,approvalResolver:f,maxSteps:20,...n.runtime.promptMode!==void 0?{promptMode:n.runtime.promptMode}:{}}),g=[];await d.createSession({title:`task: ${t.slice(0,60)}`});for await(let _ of w.runTurn({sessionId:a,message:t}))await d.appendTraceEvent({sessionId:a,event:_}),g.push(_);let R=qe(g),x=g.find(_=>_.type==="assistant_message_created"),$=x?.type==="assistant_message_created"?x.message.content:"No assistant message was produced.",P=g.find(_=>_.type==="run_failed"),p=P?"failed":"completed",C=new Date().toISOString(),k={status:p,assistantText:$,completedAt:C,...P?.type==="run_failed"?{errorMessage:P.error.message}:{}};await u.updateRun(l,k);let T=R.join(`
|
|
96
|
+
`),b=p==="completed"?`Done: ${$}`:`Failed: ${P?.type==="run_failed"?P.error.message:"Unknown error"}`;return{exitCode:p==="completed"?0:1,stdout:`Trace:
|
|
97
|
+
${T}
|
|
98
|
+
|
|
99
|
+
${b}
|
|
100
|
+
`,stderr:""}}async function Sn(t,e){let s=await A(t.env?{env:t.env}:{}),n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=D(n,t.env),a=await new K(S(r,"task-runs.jsonl")).listRuns(e!==void 0?{limit:e}:{});return a.length===0?{exitCode:0,stdout:`No task runs found.
|
|
101
|
+
`,stderr:""}:{exitCode:0,stdout:a.map(i=>`${i.id.slice(-8)} ${i.taskName} ${i.status} ${i.startedAt}`).join(`
|
|
102
|
+
`)+`
|
|
103
|
+
`,stderr:""}}async function Cn(t){try{await Mt(t)}catch{return null}let s=(await yn(t)).filter(r=>r.endsWith(".task.json")),n=[];for(let r of s){let o=await Le(S(t,r),"utf8");n.push(JSON.parse(o))}return n}async function Rt(t,e,s,n){let r=`run_${crypto.randomUUID()}`,o=U(),a=t.mode??"auto",l={id:r,taskName:t.name,goal:t.goal,sessionId:o,startedAt:new Date().toISOString(),status:"running",assistantText:""};await n.saveRun(l);let i=S(e.workspace.root,"HEARTBEAT.md"),c={status:"running",taskName:t.name,runId:r,lastUpdatedAt:new Date().toISOString()};await Oe(i,c);let d=s.fakeModelOutputs?new q(s.fakeModelOutputs):je(e,s),u=new ee(a),m=new Date().toISOString().slice(0,10),y=(()=>{let p=re(s,e);return e.runtime.toolProfile!==void 0?he(p,e.runtime.toolProfile):p})(),f=new L({contextAssembler:oe(e,m),modelProvider:d,systemInstruction:_e,runtime:{mode:a,workspace:e.workspace.root,currentDate:m},tools:y,preferStreaming:!1,approvalResolver:u,...t.maxSteps!==void 0?{maxSteps:t.maxSteps}:{},...e.runtime.promptMode!==void 0?{promptMode:e.runtime.promptMode}:{}}),h=[];for await(let p of f.runTurn({sessionId:o,message:t.goal}))h.push(p);let v=h.find(p=>p.type==="assistant_message_created"),w=v?.type==="assistant_message_created"?v.message.content:"No assistant message was produced.",g=h.find(p=>p.type==="run_failed"),R=g?"failed":"completed",x=new Date().toISOString(),$={status:R,assistantText:w,completedAt:x,...g?.type==="run_failed"?{errorMessage:g.error.message}:{}};await n.updateRun(r,$);let P={status:R,taskName:t.name,runId:r,lastUpdatedAt:x,...g?.type==="run_failed"?{message:`Error: ${g.error.message}`}:{}};await Oe(i,P)}async function Tn(t,e){let s=await A(t.env?{env:t.env}:{});if(s.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.
|
|
104
|
+
`};let n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=D(n,t.env),o=S(H(r),"tasks"),a=new K(S(r,"task-runs.jsonl")),l=await Cn(o);if(l===null)return{exitCode:0,stdout:`No tasks directory found at ${o}.
|
|
105
|
+
`,stderr:""};let i=l.filter(u=>u.cron!==void 0);if(e){let u=new Date,m=[];for(let y of i)m.push(`Running: ${y.name}`),await Rt(y,s,t,a);return m.push("Done."),{exitCode:0,stdout:m.join(`
|
|
106
|
+
`)+`
|
|
107
|
+
`,stderr:""}}let c=async u=>{await Rt(u,s,t,a)},d=new ge(i,c);return d.start(),new Promise(u=>{let m=()=>{d.stop(),u({exitCode:0,stdout:`Daemon stopped.
|
|
108
|
+
`,stderr:""})};process.once("SIGTERM",m),process.once("SIGINT",m)})}async function Fe(t){let e=await A(t.env?{env:t.env}:{}),s=t.sessionsDirectory?{...e,sessions:{directory:t.sessionsDirectory}}:e,n=D(s,t.env);return S(H(n),"taskflow.jsonl")}async function At(t,e){let s=await Fe(t),r=await new j(s).list(e!==void 0?{limit:e}:{});return r.length===0?{exitCode:0,stdout:`No task records found.
|
|
109
|
+
`,stderr:""}:{exitCode:0,stdout:["Task records:",...r.map(a=>`${a.id.slice(-8)} ${a.status} ${a.runtime} ${a.createdAt} ${a.task.slice(0,60)}`)].join(`
|
|
110
|
+
`)+`
|
|
111
|
+
`,stderr:""}}async function In(t,e){let s=await Fe(e),r=await new j(s).get(t);return r===void 0?{exitCode:1,stdout:"",stderr:`Task "${t}" not found.
|
|
112
|
+
`}:{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(`
|
|
113
|
+
`)+`
|
|
114
|
+
`,stderr:""}}async function En(t,e){let s=await Fe(e);return await new j(s).update(t,{status:"cancelled"})===void 0?{exitCode:1,stdout:"",stderr:`Task "${t}" not found.
|
|
115
|
+
`}:{exitCode:0,stdout:`Cancelled: ${t}
|
|
116
|
+
`,stderr:""}}function ve(t,e){let s=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,n=D(s,e.env);return S(H(n),"skills")}async function Rn(t){let e=await A(t.env?{env:t.env}:{}),s=ve(e,t),r=await new ne().load({workspaceRoot:e.workspace.root,userSkillsDir:s});return{exitCode:0,stdout:["Skills:",...Ft(r)].join(`
|
|
117
|
+
`)+`
|
|
118
|
+
`,stderr:""}}async function An(t,e){let s=await A(e.env?{env:e.env}:{}),n=ve(s,e),r=new Y(n);try{return{exitCode:0,stdout:`Installed: ${(await r.install(t)).name}
|
|
119
|
+
`,stderr:""}}catch(o){return{exitCode:1,stdout:"",stderr:`Failed to install skill: ${o instanceof Error?o.message:String(o)}
|
|
120
|
+
`}}}async function Ne(t,e,s){let n=await A(s.env?{env:s.env}:{}),r=ve(n,s),o=new Y(r);try{return t==="enable"?(await o.enable(e),{exitCode:0,stdout:`Enabled: ${e}
|
|
121
|
+
`,stderr:""}):t==="disable"?(await o.disable(e),{exitCode:0,stdout:`Disabled: ${e}
|
|
122
|
+
`,stderr:""}):(await o.trust(e),{exitCode:0,stdout:`Trusted: ${e}
|
|
123
|
+
`,stderr:""})}catch(a){return{exitCode:1,stdout:"",stderr:`Failed to ${t} skill: ${a instanceof Error?a.message:String(a)}
|
|
124
|
+
`}}}async function Pn(t,e){let s=await A(e.env?{env:e.env}:{}),n=ve(s,e),r=new Y(n),o=await r.review(t);if(o===void 0)return{exitCode:1,stdout:"",stderr:`Skill "${t}" not found.
|
|
125
|
+
`};let l=(await r.listEntries()).find(c=>c.name===t);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)}`,...l?.installedAt!==void 0?[`Installed: ${l.installedAt}`]:[],"","--- Body ---",o.body].join(`
|
|
126
|
+
`)+`
|
|
127
|
+
`,stderr:""}}async function Mn(t,e){let s=Ue(t,e,U()),[n]=await s.listSessions({limit:1});return n?.id}async function Nt(t,e,s){let n=[],r=(...o)=>{s.write?s.write(`${o.join(`
|
|
128
|
+
`)}
|
|
129
|
+
`):n.push(...o)};for(r(e,"Type /help for commands or /exit to leave.","");;){let o=await s.readLine?.("> ");if(o===void 0)break;let a=o.trim();if(a==="")continue;if(a==="/exit"){r("Goodbye.");break}if(a==="/help"){r(...Lt(),"");continue}if(a==="/clear"){r("(conversation display cleared)","");continue}if(a.startsWith("/")){r(...$n(a,await t.runSlashCommand(a)),"");continue}let l=await t.sendMessage(a);l.todosLines.length>0&&r(...l.todosLines,""),l.approvalLines.length>0&&r(...l.approvalLines,""),r(`Assistant: ${l.assistantText}`,"")}return{exitCode:0,stdout:s.write?"":`${n.join(`
|
|
130
|
+
`)}
|
|
131
|
+
`,stderr:""}}var Dt={"/trace":"Recent Trace:","/config":"Config:","/skills":"Skills:","/help":"Commands:"};async function On(t,e){let s=[];for(let n of e){let r=Dt[n];r!==void 0?s.push(["",r,...await t.runSlashCommand(n)].join(`
|
|
132
|
+
`)):s.push(["",`Unknown slash command: ${n}`].join(`
|
|
133
|
+
`))}return s.length===0?"":`${s.join(`
|
|
134
|
+
`)}
|
|
135
|
+
`}function $n(t,e){if(e[0]?.startsWith("Unknown slash command"))return e;let s=Dt[t];return s!==void 0?[s,...e]:e}function Lt(){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 ie=class t{#e;#t;#s;#n;#r;#o;#a;#l;constructor(e,s=G(be()),n=new V,r=U(),o=new ye({createSessionId:()=>r}),a=12,l=[],i=[],c){this.#e=e,this.#r=s,this.#t=n,this.#s=o,this.#n=r,this.#o=l,this.#a=i,this.#l=c}get sessionId(){return this.#n}async listSessions(e){return this.#s.listSessions(e)}async loadMessages(){return this.#s.listMessages(this.#n)}close(){this.#l?.unregister(this.#n)}static async createFake(e="Fake response to: Hello trace",s={},n={}){let r=G(await A(s.env?{env:s.env}:{})),o=[],a=s.fakeModelOutputs?new q(s.fakeModelOutputs):typeof e=="function"?new De(e):new q([{type:"message",content:e}]);return new t(new L({contextAssembler:oe(r,new Date().toISOString().slice(0,10)),modelProvider:a,systemInstruction:_e,runtime:{mode:"confirm",workspace:r.workspace.root,currentDate:new Date().toISOString().slice(0,10)},tools:re(s,r),approvalResolver:Pt(s,o),maxSteps:20,compaction:{}}),r,new V,n.sessionId??U(),void 0,12,o)}static async createConfigured(e,s={},n={}){let r=n.sessionId??U(),o=new Date().toISOString().slice(0,10),a=[],l=await new ne().load({workspaceRoot:e.workspace.root}),i=l.map(Ct),c=new Map(l.map(x=>[x.name,x.filePath])),d=je(e,s),u=n.approvalResolver??Pt(s,a),m=re(s,e,c),y={create:x=>new L({contextAssembler:oe(G(e),o),modelProvider:d,systemInstruction:`You are Vole, a sub-agent handling: ${x}`,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:re(s,e),maxSteps:8})},f=S(H(D(e,s.env)),"taskflow.jsonl"),h=new j(f),v=[...m,_t(y),wt(y,{taskStore:h}),kt(h)],w=e.runtime.toolProfile!==void 0?he(v,e.runtime.toolProfile):v,g=new Date().toISOString(),R={id:r,adapterName:"cli",capabilities:vt,registeredAt:g,lastActivityAt:g};return Et.register(R),new t(new L({contextAssembler:oe(e,o),modelProvider:d,systemInstruction:_e,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:w,skillIndex:i,preferStreaming:n.preferStreaming??!1,approvalResolver:u,maxSteps:20,compaction:{},...e.runtime.promptMode!==void 0?{promptMode:e.runtime.promptMode}:{},...e.runtime.executionContract!==void 0?{executionContract:e.runtime.executionContract}:{}}),G(e),new V,r,Ue(e,s,r),12,a,l,Et)}async sendMessage(e,s={}){let n=[],r=this.#o.length;await this.#u();let o=(await this.#s.listMessages(this.#n)).map(i=>({role:i.role,content:i.content,...i.toolCalls!==void 0?{toolCalls:i.toolCalls}:{},...i.toolCallId!==void 0?{toolCallId:i.toolCallId}:{}}));for await(let i of this.#e.runTurn({sessionId:this.#n,recentMessages:o,message:e,...s.signal!==void 0?{signal:s.signal}:{}}))if(await this.#t.append(i),await this.#s.appendTraceEvent({sessionId:this.#n,event:i}),n.push(i),s.onEvent?.(i),i.type==="compaction_triggered"&&i.summary&&await this.#s.appendCompactBoundary({sessionId:this.#n,summary:i.summary,messagesBefore:i.messagesBefore,messagesAfter:i.messagesAfter}),i.type==="turn_complete")for(let c of i.messages)await this.#s.appendMessage({sessionId:this.#n,role:c.role,content:c.content??null,...c.toolCalls!==void 0?{toolCalls:c.toolCalls}:{},...c.toolCallId!==void 0?{toolCallId:c.toolCallId}:{}});let a=n.find(i=>i.type==="assistant_message_created");return{assistantText:a?.type==="assistant_message_created"?a.message.content:"No assistant message was produced.",approvalLines:this.#o.slice(r),todosLines:Dn(n),events:n}}async runSlashCommand(e){if(e==="/trace"){let s=await this.#s.listTraceEvents(this.#n);return qe(s.map(n=>n.event))}return e==="/config"?Ln(this.#r):e==="/skills"?Ft(this.#a):e==="/help"?Lt():[`Unknown slash command: ${e}`]}async#u(){await this.#s.getSession(this.#n)===void 0&&await this.#s.createSession({title:this.#n})}};function Pt(t,e){return{async resolve(s){e.push("Approval required:",`Tool: ${s.call.name}`,`Risk: ${s.decision.risk}`,`Reason: ${s.decision.reason}`);let n=(await t.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 re(t,e,s){let n=[et(),tt(),rt(),ot(),it(),nt(e?.runtime.sandboxed!==void 0?{sandboxed:e.runtime.sandboxed}:void 0),at(t.fetch),ht()];if(e?.memory.longTermFiles==="write"&&n.push(mt()),e?.memory.longTermFiles==="read-only"||e?.memory.longTermFiles==="write"){let r=e.workspace.root;n.push(dt(r)),n.push(ut(r))}return n.push(ft()),s!==void 0&&s.size>0&&n.push(ct(s)),n}var De=class{requests=[];#e;constructor(e){this.#e=e}async generate(e){this.requests.push(e);let s=[...e.messages].reverse().find(n=>n.role==="user")?.content??"";return{type:"message",content:this.#e(s)}}};function je(t,e){return t.model.provider==="anthropic"?new de({...t.secrets.apiKey!==void 0?{apiKey:t.secrets.apiKey}:{},model:t.model.model,temperature:t.model.temperature,maxTokens:t.model.maxTokens,...t.model.thinkingBudget!==void 0?{thinkingBudget:t.model.thinkingBudget}:{}}):new ce({baseURL:t.model.baseURL,...t.secrets.apiKey!==void 0?{apiKey:t.secrets.apiKey}:{},model:t.model.model,temperature:t.model.temperature,maxTokens:t.model.maxTokens,...e.fetch?{fetch:e.fetch}:{}})}function Ue(t,e,s){let n=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,r=D(n,e.env);return new te({directory:r,createSessionId:()=>s})}function oe(t,e){let s=["AGENTS.md","SOUL.md","TOOLS.md","IDENTITY.md","HEARTBEAT.md","BOOTSTRAP.md"];return t.memory.longTermFiles==="read-only"&&s.push("USER.md","MEMORY.md",`memory/${e}.md`,`memory/${Nn(e)}.md`),new le({workspacePromptFiles:s})}function Nn(t){let e=new Date(`${t}T00:00:00.000Z`);return e.setUTCDate(e.getUTCDate()-1),e.toISOString().slice(0,10)}function U(){return`session_${crypto.randomUUID()}`}function Dn(t){let e=[...t].reverse().find(n=>n.type==="todos_updated");if(e?.type!=="todos_updated"||e.todos.length===0)return[];let s=["Todo:"];for(let n of e.todos){let r=n.status==="completed"?"\u2713":n.status==="in_progress"?"\u2192":"\xB7";s.push(` ${r} ${n.content}`)}return s}function Ft(t){if(t.length===0)return["No skills loaded."];let e=[],s=[];for(let n of t){let r=n.source==="user"&&n.trusted===!1?" \u26A0 untrusted":"",o=n.version!==void 0?` v${n.version}`:"",a=n.permissions!==void 0&&n.permissions.length>0?` [${n.permissions.join(", ")}]`:"";e.push(`[${n.source}]${r}${o} ${n.name}: ${n.description}${a}`),n.source==="user"&&n.trusted===!1&&s.push(n.name)}if(s.length>0){e.push("");for(let n of s)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 Ln(t){return[`Provider: ${t.model.provider}`,`Model: ${t.model.model}`,`Base URL: ${t.model.baseURL}`,`Default mode: ${t.runtime.defaultMode}`,`Trace verbosity: ${t.trace.verbosity}`,`Long-term memory files: ${t.memory.longTermFiles}`,`Memory writes: ${t.memory.writes}`,`API key: ${t.secrets.apiKey}`]}function Fn(t){if("entries"in t&&Array.isArray(t.entries))return t.entries.map(e=>` ${e.type==="directory"?"\u{1F4C1}":"\u{1F4C4}"} ${e.name}`).join(`
|
|
136
|
+
`);if("content"in t&&typeof t.content=="string"){let e=t.content.split(`
|
|
137
|
+
`);return e.length>30?e.slice(0,30).join(`
|
|
138
|
+
`)+`
|
|
139
|
+
\u2026 (${e.length-30} more lines)`:t.content}if("stdout"in t)return[t.stdout,t.stderr].filter(Boolean).join(`
|
|
140
|
+
`)||"(no output)";if("error"in t){let e=t.error;return`Error: ${typeof e=="object"&&e!==null&&"message"in e?e.message:String(e)}`}return JSON.stringify(t,null,2)}function qe(t){return t.map((e,s)=>`${s+1}. ${jn(e)} (${e.type})`)}function jn(t){switch(t.type){case"run_started":return"Received user message";case"context_assembled":return"Assembled context";case"compaction_triggered":return`Compacted context (${t.messagesBefore} \u2192 ${t.messagesAfter} messages)`;case"todos_updated":return`Updated todos (${t.todos.length} items)`;case"planning_stall_detected":return`Planning stall detected (${t.stallCount}/${t.maxRetries})`;case"model_request_started":return"Started model request";case"token_delta":return`Token delta: "${t.delta.slice(0,20)}${t.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: ${t.toolName}`;case"tool_completed":return`Result [${t.toolName}]:
|
|
141
|
+
${Fn(t.result)}`;case"tool_failed":return`Tool failed [${t.toolName}]: ${t.error.message}`;case"assistant_message_created":return"Created assistant message";case"turn_complete":return`Turn complete (${t.messages.length} messages)`;case"run_completed":return"Completed run";case"run_failed":return"Failed run"}}async function Un(t,e){let s=H(Ot(import.meta.url)),n=[{server:S(s,"web","server.js"),cwd:S(s,"web")},{server:S(s,"../../web","dist","server.js"),cwd:S(s,"../../web")}],r;for(let l of n)try{await Mt(l.server),r=l;break}catch{}if(r===void 0)return{exitCode:1,stdout:"",stderr:`Web app not built. Run first:
|
|
142
|
+
pnpm --filter @vole/web build
|
|
143
|
+
`};let o=`http://localhost:${t}`,a=Tt("node",[r.server],{env:{...process.env,PORT:String(t)},stdio:"inherit",cwd:r.cwd});if(process.stdout.write(`Vole web dashboard \u2192 ${o}
|
|
144
|
+
`),process.stdout.write(`Press Ctrl+C to stop.
|
|
145
|
+
`),e){let l=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",i=process.platform==="win32"?["/c","start",o]:[o];setTimeout(()=>{Tt(l,i,{stdio:"ignore",detached:!0}).unref()},800)}return new Promise(l=>{let i=()=>{a.kill(),l({exitCode:0,stdout:`Web server stopped.
|
|
146
|
+
`,stderr:""})};process.once("SIGTERM",i),process.once("SIGINT",i),a.once("exit",c=>l({exitCode:c??0,stdout:"",stderr:""}))})}async function qn(){let t=process.argv.slice(2),[e]=t;if(t.find(i=>i!=="--")==="chat"&&!t.includes("--help")&&!t.includes("-h")&&!t.includes("--fake")&&!t.includes("--fake-interactive")){let{runInkChat:i}=await import("./app.js");await i({args:t,env:process.env});return}let n=gn({input:process.stdin,output:process.stdout}),r=n[Symbol.asyncIterator](),o=H(Ot(import.meta.url)),a="0.0.0";try{let i=await Le(S(o,"../package.json"),"utf8");a=JSON.parse(i).version}catch{}let l=await wn(t,a,{env:process.env,readLine:async i=>{process.stdout.write(i);let c=await r.next();return c.done?void 0:c.value},write:i=>process.stdout.write(i)});n.close(),process.stdout.write(l.stdout),process.stderr.write(l.stderr),process.exitCode=l.exitCode}qn();export{be as a,jr as b,wn as c,ie as d,Dn as e,Ft as f,Ln as g,Fn as h,qe as i};
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
CliChatSession,
|
|
4
|
-
cliPackageName,
|
|
5
|
-
renderCompactTrace,
|
|
6
|
-
renderRedactedConfig,
|
|
7
|
-
renderSkillIndex,
|
|
8
|
-
renderTodosProgress,
|
|
9
|
-
renderToolResult,
|
|
10
|
-
runCli
|
|
11
|
-
} from "./chunk-ZGGSF3JK.js";
|
|
12
|
-
export {
|
|
13
|
-
CliChatSession,
|
|
14
|
-
cliPackageName,
|
|
15
|
-
renderCompactTrace,
|
|
16
|
-
renderRedactedConfig,
|
|
17
|
-
renderSkillIndex,
|
|
18
|
-
renderTodosProgress,
|
|
19
|
-
renderToolResult,
|
|
20
|
-
runCli
|
|
21
|
-
};
|
|
2
|
+
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h}from"./chunk-QGVGG7HC.js";export{c as CliChatSession,a as cliPackageName,h as renderCompactTrace,f as renderRedactedConfig,e as renderSkillIndex,d as renderTodosProgress,g as renderToolResult,b as runCli};
|