vole-agent 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -8
- package/README.zh-CN.md +21 -8
- package/dist/app.js +1 -1
- package/dist/{chunk-EBLG3T72.js → chunk-5IEOV6K2.js} +60 -60
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,8 +28,9 @@ Sessions are stored per-project under `<git-root>/.vole/sessions/` when inside a
|
|
|
28
28
|
## Usage
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
# Interactive chat
|
|
32
|
-
vole
|
|
31
|
+
# Interactive chat (bare `vole` defaults to chat in a real terminal)
|
|
32
|
+
vole
|
|
33
|
+
vole chat # explicit form
|
|
33
34
|
|
|
34
35
|
# Resume previous session
|
|
35
36
|
vole chat --resume
|
|
@@ -48,14 +49,18 @@ vole sessions
|
|
|
48
49
|
|
|
49
50
|
| Command | Description |
|
|
50
51
|
|---|---|
|
|
52
|
+
| `vole` | Bare invocation defaults to interactive chat (when stdin is a TTY) |
|
|
51
53
|
| `vole chat` | Start an interactive chat session |
|
|
52
54
|
| `vole chat --resume` | Resume the most recent session |
|
|
53
55
|
| `vole chat --session <id>` | Resume a specific session |
|
|
54
56
|
| `vole run "<goal>"` | Run a one-shot background task |
|
|
57
|
+
| `vole run --dream` | Consolidate daily memory notes into `MEMORY.md` |
|
|
55
58
|
| `vole web` | Open the web dashboard |
|
|
56
59
|
| `vole sessions` | List stored sessions |
|
|
57
60
|
| `vole tasks` | List background task runs |
|
|
58
|
-
| `vole skills` |
|
|
61
|
+
| `vole skills` | List loaded skills (also `install`/`enable`/`disable`/`trust`/`review` subcommands) |
|
|
62
|
+
| `vole daemon` | Start the cron scheduler daemon (use `--once` for a one-shot run) |
|
|
63
|
+
| `vole taskflow list/show/cancel` | Inspect cross-session task records |
|
|
59
64
|
|
|
60
65
|
## Chat slash commands
|
|
61
66
|
|
|
@@ -89,11 +94,19 @@ Configuration is loaded from (in order of precedence): environment variables →
|
|
|
89
94
|
|
|
90
95
|
| Variable | Default | Description |
|
|
91
96
|
|---|---|---|
|
|
92
|
-
| `
|
|
93
|
-
| `OPENROUTER_API_KEY` | — | OpenRouter
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
+
| `ANTHROPIC_API_KEY` | — | Use Anthropic provider (claude-haiku-4-5) |
|
|
98
|
+
| `OPENROUTER_API_KEY` | — | Use OpenRouter (needs `VOLE_MODEL`) |
|
|
99
|
+
| `VOLE_API_KEY` | — | Generic API key override |
|
|
100
|
+
| `VOLE_BASE_URL` | `https://api.openai.com/v1` | Provider base URL |
|
|
101
|
+
| `VOLE_MODEL` | `gpt-4.1-mini` | Model name |
|
|
102
|
+
| `VOLE_DEFAULT_MODE` | `confirm` | Autonomy mode: `observe` / `confirm` / `auto` |
|
|
103
|
+
| `VOLE_WORKSPACE_ROOT` | `.` | Working directory |
|
|
104
|
+
| `VOLE_LONG_TERM_MEMORY` | `disabled` | Memory policy: `disabled` / `read-only` / `write` |
|
|
105
|
+
| `VOLE_PROMPT_MODE` | `full` | Prompt rendering: `full` / `minimal` / `none` |
|
|
106
|
+
| `VOLE_EXECUTION_CONTRACT` | `default` | Execution discipline: `default` / `strict-agentic` |
|
|
107
|
+
| `VOLE_TOOL_PROFILE` | `full` | Tool capability set: `coding` / `full` / `messaging` / `background` |
|
|
108
|
+
| `VOLE_SANDBOX` | `false` | Restrict shell to workspace root: `true` / `false` |
|
|
109
|
+
| `VOLE_THINKING_BUDGET` | `adaptive` | Anthropic reasoning depth: `off` / `minimal` … `max` / `adaptive` |
|
|
97
110
|
|
|
98
111
|
## License
|
|
99
112
|
|
package/README.zh-CN.md
CHANGED
|
@@ -28,8 +28,9 @@ export OPENROUTER_API_KEY=sk-or-... # OpenRouter
|
|
|
28
28
|
## 使用
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
#
|
|
32
|
-
vole
|
|
31
|
+
# 交互式对话(在真实终端中,直接执行 vole 默认进入 chat)
|
|
32
|
+
vole
|
|
33
|
+
vole chat # 显式形式
|
|
33
34
|
|
|
34
35
|
# 恢复上次会话
|
|
35
36
|
vole chat --resume
|
|
@@ -48,14 +49,18 @@ vole sessions
|
|
|
48
49
|
|
|
49
50
|
| 命令 | 说明 |
|
|
50
51
|
|---|---|
|
|
52
|
+
| `vole` | 无参数调用默认进入交互式聊天(stdin 是真实终端时) |
|
|
51
53
|
| `vole chat` | 开始交互式对话 |
|
|
52
54
|
| `vole chat --resume` | 恢复最近的会话 |
|
|
53
55
|
| `vole chat --session <id>` | 恢复指定会话 |
|
|
54
56
|
| `vole run "<目标>"` | 运行一次性后台任务 |
|
|
57
|
+
| `vole run --dream` | 将日记合并进 `MEMORY.md` |
|
|
55
58
|
| `vole web` | 打开 Web 界面 |
|
|
56
59
|
| `vole sessions` | 列出所有会话 |
|
|
57
60
|
| `vole tasks` | 列出后台任务记录 |
|
|
58
|
-
| `vole skills` |
|
|
61
|
+
| `vole skills` | 列出已加载技能(含 `install`/`enable`/`disable`/`trust`/`review` 子命令) |
|
|
62
|
+
| `vole daemon` | 启动 Cron 调度守护进程(`--once` 仅执行一次) |
|
|
63
|
+
| `vole taskflow list/show/cancel` | 查看跨会话任务记录 |
|
|
59
64
|
|
|
60
65
|
## 对话内指令
|
|
61
66
|
|
|
@@ -89,11 +94,19 @@ vole sessions
|
|
|
89
94
|
|
|
90
95
|
| 变量 | 默认值 | 说明 |
|
|
91
96
|
|---|---|---|
|
|
92
|
-
| `
|
|
93
|
-
| `OPENROUTER_API_KEY` | — | OpenRouter
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
+
| `ANTHROPIC_API_KEY` | — | 使用 Anthropic Provider(claude-haiku-4-5) |
|
|
98
|
+
| `OPENROUTER_API_KEY` | — | 使用 OpenRouter(需配合 `VOLE_MODEL`) |
|
|
99
|
+
| `VOLE_API_KEY` | — | 通用 API Key 覆盖 |
|
|
100
|
+
| `VOLE_BASE_URL` | `https://api.openai.com/v1` | Provider Base URL |
|
|
101
|
+
| `VOLE_MODEL` | `gpt-4.1-mini` | 模型名称 |
|
|
102
|
+
| `VOLE_DEFAULT_MODE` | `confirm` | 自主模式:`observe` / `confirm` / `auto` |
|
|
103
|
+
| `VOLE_WORKSPACE_ROOT` | `.` | 工作目录 |
|
|
104
|
+
| `VOLE_LONG_TERM_MEMORY` | `disabled` | 记忆策略:`disabled` / `read-only` / `write` |
|
|
105
|
+
| `VOLE_PROMPT_MODE` | `full` | 提示词渲染:`full` / `minimal` / `none` |
|
|
106
|
+
| `VOLE_EXECUTION_CONTRACT` | `default` | 执行纪律:`default` / `strict-agentic` |
|
|
107
|
+
| `VOLE_TOOL_PROFILE` | `full` | 工具能力集:`coding` / `full` / `messaging` / `background` |
|
|
108
|
+
| `VOLE_SANDBOX` | `false` | 将 Shell 限制在工作区根目录:`true` / `false` |
|
|
109
|
+
| `VOLE_THINKING_BUDGET` | `adaptive` | Anthropic 推理深度:`off` / `minimal` … `max` / `adaptive` |
|
|
97
110
|
|
|
98
111
|
## 许可证
|
|
99
112
|
|
package/dist/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as le,d as W,h as ae}from"./chunk-
|
|
2
|
+
import{a as le,d as W,h as ae}from"./chunk-5IEOV6K2.js";import{useState as T,useEffect as Se,useCallback as I,useMemo as fe,useRef as Ie}from"react";import{render as Ae,Box as c,Text as o,useInput as O,useApp as ke,useAnimation as Re,useStdout as Ee,Static as Me}from"ink";import _e from"ink-text-input";import{readFile as De,stat as Pe}from"fs/promises";import{dirname as je,join as U}from"path";import{marked as ze}from"marked";import{useRef as Ze}from"react";import{Text as Be}from"ink";import p from"chalk";import{marked as de}from"marked";var ce=!1;function ue(){ce||(ce=!0,de.use({tokenizer:{del(){}}}))}function y(e,l=0,d=!1){switch(e.type){case"heading":{let s=(e.tokens??[]).map(i=>y(i)).join("");return e.depth===1?p.bold.underline(s)+`
|
|
3
3
|
|
|
4
4
|
`:e.depth===2?p.bold(s)+`
|
|
5
5
|
|
|
@@ -1,58 +1,58 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"dotenv/config";import{Command as
|
|
2
|
+
import"dotenv/config";import{Command as yn}from"commander";import{createInterface as wn}from"readline";import{readdir as kn,readFile as Fe,stat as je}from"fs/promises";import{spawn as Rt}from"child_process";import{dirname as B,join as S}from"path";import{fileURLToPath as Dt}from"url";import{join as Bt}from"path";var Vt={baseURL:"https://openrouter.ai/api/v1"},Kt={model:"claude-haiku-4-5-20251001"},E=class extends Error{constructor(e){super(e),this.name="ConfigValidationError"}},Yt={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 xe(t={}){let e=Ht(Yt);return Ke(e,t.userConfig),Ke(e,t.projectConfig),Wt(e,t.env??{}),Gt(e),e}function J(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 Ht(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 Ke(t,e){if(e!==void 0){if(!Ye(e))throw new E("Configuration must be an object.");D(t.model,e.model),D(t.workspace,e.workspace),D(t.runtime,e.runtime),D(t.trace,e.trace),D(t.tools,e.tools),D(t.permissions,e.permissions),D(t.sessions,e.sessions),D(t.memory,e.memory)}}function D(t,e){if(e!==void 0){if(!Ye(e))throw new E("Configuration sections must be objects.");for(let[s,n]of Object.entries(e))s in t&&(t[s]=n)}}function Wt(t,e){e.OPENROUTER_API_KEY!==void 0&&(t.model.provider="openai-compatible",t.model.baseURL=Vt.baseURL,t.model.model="",t.secrets.apiKey=e.OPENROUTER_API_KEY),e.ANTHROPIC_API_KEY!==void 0&&(t.model.provider="anthropic",t.model.model=Kt.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 Gt(t){if(t.model.provider!=="openai-compatible"&&t.model.provider!=="anthropic")throw new E(`Invalid model.provider "${String(t.model.provider)}". Expected openai-compatible or anthropic.`);if(t.model.model.trim().length===0)throw new E("No model configured. Set VOLE_MODEL=<model-name> (e.g. VOLE_MODEL=openai/gpt-4o for OpenRouter).");if(!Jt(t.runtime.defaultMode))throw new E(`Invalid runtime.defaultMode "${String(t.runtime.defaultMode)}". Expected observe, confirm, or auto.`);if(!zt(t.trace.verbosity))throw new E(`Invalid trace.verbosity "${String(t.trace.verbosity)}". Expected explainable or debug.`);if(!Xt(t.memory.longTermFiles))throw new E(`Invalid memory.longTermFiles "${String(t.memory.longTermFiles)}". Expected disabled or read-only.`);if(t.memory.writes!=="disabled")throw new E(`Invalid memory.writes "${String(t.memory.writes)}". Only disabled is supported.`);if(t.runtime.promptMode!==void 0&&!Zt(t.runtime.promptMode))throw new E(`Invalid runtime.promptMode "${String(t.runtime.promptMode)}". Expected full, minimal, or none.`);if(t.runtime.executionContract!==void 0&&!Qt(t.runtime.executionContract))throw new E(`Invalid runtime.executionContract "${String(t.runtime.executionContract)}". Expected default or strict-agentic.`);if(t.runtime.toolProfile!==void 0&&!es(t.runtime.toolProfile))throw new E(`Invalid runtime.toolProfile "${String(t.runtime.toolProfile)}". Expected coding, full, messaging, or background.`);if(t.model.thinkingBudget!==void 0&&!ts(t.model.thinkingBudget))throw new E(`Invalid model.thinkingBudget "${String(t.model.thinkingBudget)}". Expected off, minimal, low, medium, high, max, or adaptive.`)}function Ye(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Jt(t){return t==="observe"||t==="confirm"||t==="auto"}function zt(t){return t==="explainable"||t==="debug"}function Xt(t){return t==="disabled"||t==="read-only"||t==="write"}function Zt(t){return t==="full"||t==="minimal"||t==="none"}function Qt(t){return t==="default"||t==="strict-agentic"}function es(t){return t==="coding"||t==="full"||t==="messaging"||t==="background"}function ts(t){return t==="off"||t==="minimal"||t==="low"||t==="medium"||t==="high"||t==="max"||t==="adaptive"}function L(t,e){let s=t.sessions.directory;if(!s.startsWith("~/"))return s;let n=e?.HOME??process.env.HOME;return n===void 0?s:Bt(n,s.slice(2))}import{readFile as ss}from"fs/promises";import{join as ns}from"path";var ce=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=>ss(s,"utf8"))}async assemble(e){let s=e.promptMode??"full",n=[],r=[];if(s==="none"){let c=e.recentMessages??[];c.length>0&&n.push({name:"conversation_history",included:!0}),n.push({name:"user_message",included:!0});let a=n.filter(u=>u.included).map(u=>u.name),d=n.filter(u=>!u.included).map(u=>u.name);return{modelInput:{messages:[...c.map(u=>({...u})),{role:"user",content:e.userMessage}]},report:{includedSections:a,omittedSections:d,sections:n}}}if(r.push(`<identity>
|
|
3
3
|
${e.systemInstruction}
|
|
4
4
|
</identity>`),n.push({name:"identity",included:!0}),s==="full"){if(e.runtime?(r.push("",`<runtime>
|
|
5
5
|
- Mode: ${e.runtime.mode}
|
|
6
6
|
- Workspace: ${e.runtime.workspace}
|
|
7
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
|
|
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 a=e.tools.map(d=>`- ${d.name} [${d.risk}]: ${d.description}`).join(`
|
|
9
9
|
`);r.push("",`<tooling>
|
|
10
|
-
${
|
|
10
|
+
${a}
|
|
11
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
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
|
|
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 a=e.skillIndex.map(d=>`- ${d.name}: ${d.description}`).join(`
|
|
14
14
|
`);r.push("",`<skills>
|
|
15
|
-
${
|
|
16
|
-
</skills>`),n.push({name:"skills",included:!0})}else n.push({name:"skills",included:!1,reason:"No skills loaded."});let
|
|
15
|
+
${a}
|
|
16
|
+
</skills>`),n.push({name:"skills",included:!0})}else n.push({name:"skills",included:!1,reason:"No skills loaded."});let c=await this.#s(e.runtime?.workspace);c.length>0?(r.push("",`<workspace>${c.join(`
|
|
17
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
|
|
19
|
-
`)},...o.map(
|
|
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 i=n.filter(c=>c.included).map(c=>c.name),l=n.filter(c=>!c.included).map(c=>c.name);return{modelInput:{messages:[{role:"system",content:r.join(`
|
|
19
|
+
`)},...o.map(c=>({...c})),{role:"user",content:e.userMessage}]},report:{includedSections:i,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(ns(e,n))).trim();o.length>0&&s.push("",`### ${n}`,o)}catch(r){if(rs(r)&&r.code==="ENOENT")continue;throw r}return s}};function rs(t){return t instanceof Error&&"code"in t}var os={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 is(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 He(t,e,s){let n={...os,...s};if(!(is(t)>n.maxTokens||t.length>n.maxMessages))return t;let o=t[0]?.role==="system"?t[0]:void 0,i=o!==void 0?t.slice(1):t,l=i.slice(0,i.length-n.keepRecent),c=i.slice(-n.keepRecent);if(l.length===0)return t;let a=l.map(as),d=[...o!==void 0?[o]:[],...a,...c],u=a.map(m=>`${m.role.toUpperCase()}: ${m.content??"(tool call)"}`).join(`
|
|
20
20
|
`);try{let m=await e.generate({messages:[{role:"system",content:n.summarySystemPrompt},{role:"user",content:`Conversation to distil:
|
|
21
21
|
|
|
22
22
|
${u}`}]});return m.type!=="message"||!m.content?d:[...o!==void 0?[o]:[],{role:"system",content:`Conversation summary:
|
|
23
|
-
${m.content}`},...
|
|
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
|
|
25
|
-
`);n=
|
|
26
|
-
`)){let o=r.trim();o.startsWith("data: ")&&(yield o.slice(6))}}finally{e.releaseLock()}}function Se(t){try{return JSON.parse(t)}catch{return t}}var V=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
|
|
27
|
-
[truncated ${t.length-Ce} characters]`}function
|
|
28
|
-
[truncated ${t.length-Te} characters]`}function
|
|
23
|
+
${m.content}`},...c]}catch{return d}}function as(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 cs from"@anthropic-ai/sdk";function Xe(t){return"generateStream"in t&&typeof t.generateStream=="function"}var de=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.#c(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,i=r?.message,l=i?.tool_calls;if(o==="tool_calls"&&l!==void 0&&l.length>0){let c=i?.content??"";return{type:"tool_calls",calls:l.map(a=>({id:a.id,name:a.function.name,input:Se(a.function.arguments)})),...c?{text:c}:{},...n.usage?{usage:this.#m(n.usage)}:{}}}return{type:"message",content:i?.content??"",...n.usage?{usage:this.#m(n.usage)}:{}}}catch{return{type:"error",category:"network",message:"Provider network request failed.",recoverable:!0}}}async*generateStream(e){try{let s=await this.#o(`${this.#e}/chat/completions`,{method:"POST",headers:this.#a(),body:JSON.stringify({...this.#c(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,i=null;for await(let l of ls(s.body)){if(l==="[DONE]")break;let c;try{c=JSON.parse(l)}catch{continue}let a=c.choices?.[0];if(a!==void 0){a.finish_reason!==null&&a.finish_reason!==void 0&&(i=a.finish_reason);let d=a.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)}}c.usage&&(o=this.#m(c.usage))}i==="tool_calls"&&n.size>0?yield{type:"tool_calls",calls:Array.from(n.entries()).sort(([c],[a])=>c-a).map(([,c])=>({id:c.id,name:c.name,input:Se(c.arguments)})),...r?{text:r}:{},...o!==void 0?{usage:o}:{}}:yield{type:"message_done",content:r,...o!==void 0?{usage:o}:{}}}catch{yield{type:"error",category:"network",message:"Provider network request failed.",recoverable:!0}}}#a(){return{"content-type":"application/json",...this.#t?{authorization:`Bearer ${this.#t}`}:{}}}#c(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*ls(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 i=n.split(`
|
|
25
|
+
`);n=i.pop()??"";for(let l of i){let c=l.trim();c.startsWith("data: ")&&(yield c.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 Se(t){try{return JSON.parse(t)}catch{return t}}var V=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 ds={minimal:1024,low:2048,medium:4096,high:8192,max:16384},ue=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 cs({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:ds[e]}}async generate(e){try{let{system:s,messages:n}=We(e.messages),r=s!==void 0?[{type:"text",text:s,cache_control:{type:"ephemeral"}}]:void 0,o=this.#a(),i=await this.#e.messages.create({model:this.#s,max_tokens:this.#n,...r!==void 0?{system:r}:{},messages:n,...e.tools!==void 0&&e.tools.length>0?{tools:Ge(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}}),l=i.content.filter(us);if(i.stop_reason==="tool_use"&&l.length>0){let a=i.content.find(Je);return{type:"tool_calls",calls:l.map(d=>({id:d.id,name:d.name,input:d.input})),...a?.text?{text:a.text}:{},usage:{inputTokens:i.usage.input_tokens,outputTokens:i.usage.output_tokens}}}return{type:"message",content:i.content.find(Je)?.text??"",usage:{inputTokens:i.usage.input_tokens,outputTokens:i.usage.output_tokens}}}catch(s){return ze(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}=We(e.messages),r=s!==void 0?[{type:"text",text:s,cache_control:{type:"ephemeral"}}]:void 0,o=this.#a(),i={model:this.#s,max_tokens:this.#n,...r!==void 0?{system:r}:{},messages:n,...e.tools!==void 0&&e.tools.length>0?{tools:Ge(e.tools)}:{},...this.#r!==void 0?{temperature:this.#r}:{},...o!==void 0?{thinking:o}:{}},l=await this.#t.messages.stream(i),c="",a=0,d=0,u=null,m=new Map;for await(let p of l)if(p.type==="message_start")a=p.message.usage.input_tokens;else if(p.type==="content_block_start")p.content_block.type==="tool_use"&&m.set(p.index,{id:p.content_block.id??"",name:p.content_block.name??"",inputJson:""});else if(p.type==="content_block_delta"){if(p.delta.type==="text_delta")c+=p.delta.text,yield{type:"token_delta",delta:p.delta.text};else if(p.delta.type==="input_json_delta"){let g=m.get(p.index);g!==void 0&&(g.inputJson+=p.delta.partial_json)}}else p.type==="message_delta"&&(d=p.usage.output_tokens,u=p.delta.stop_reason);let h={inputTokens:a,outputTokens:d};u==="tool_use"&&m.size>0?yield{type:"tool_calls",calls:Array.from(m.entries()).sort(([g],[_])=>g-_).map(([,g])=>({id:g.id,name:g.name,input:Se(g.inputJson)})),...c?{text:c}:{},usage:h}:yield{type:"message_done",content:c,usage:h}}catch(s){yield ze(s)}}};function We(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 i=t[n];if(i===void 0||i.role!=="tool")break;o.push({type:"tool_result",tool_use_id:i.toolCallId??"",content:i.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(i=>({type:"tool_use",id:i.id,name:i.name,input:i.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 Ge(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 us(t){return t.type==="tool_use"&&typeof t.id=="string"&&typeof t.name=="string"}function Je(t){return t.type==="text"&&typeof t.text=="string"}function ze(t){if(typeof t=="object"&&t!==null&&"status"in t&&typeof t.status=="number"){let e=t;return{type:"error",category:ms(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 ms(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 me=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 ps}from"child_process";import{access as fs,readdir as Ie,readFile as X,stat as hs,writeFile as Z,mkdir as Ee}from"fs/promises";import{resolve as R,relative as Re,basename as et,extname as tt,dirname as st,join as z}from"path";function nt(){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=ot(t);if(s===void 0)return N("Tool input must include a string path.");let n=Ae(e.workspaceRoot,s);if(n===void 0)return Q();if(pe(n.absolutePath))return fe();try{return{ok:!0,content:await X(n.absolutePath,"utf8"),summary:`Read file ${n.displayPath}.`}}catch(r){return K(r)}}}}function rt(){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=ot(t);if(s===void 0)return N("Tool input must include a string path.");let n=Ae(e.workspaceRoot,s);if(n===void 0)return Q();try{return{ok:!0,entries:(await Ie(n.absolutePath,{withFileTypes:!0})).map(o=>({name:o.name,type:o.isDirectory()?"directory":o.isFile()?"file":"other"})).sort((o,i)=>o.name.localeCompare(i.name)),summary:`Listed directory ${n.displayPath}.`}}catch(r){return K(r)}}}}function ot(t){if(typeof t!="object"||t===null||!("path"in t))return;let e=t.path;return typeof e=="string"?e:void 0}function Ae(t,e){let s=R(t),n=R(s,e),r=Re(s,n);if(!(r.startsWith("..")||r===".."||n!==s&&r===""))return{absolutePath:n,displayPath:r===""?".":r}}function N(t){return{ok:!1,error:{code:"invalid_input",message:t}}}function Q(){return{ok:!1,error:{code:"path_outside_workspace",message:"Tool path must stay inside the workspace."}}}function K(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 pe(t){let e=et(t).toLowerCase();if(e===".env"||e.startsWith(".env.")||e===".netrc")return!0;let s=tt(e);return s===".key"||s===".pem"||s===".p12"||s===".pfx"?!0:e==="id_rsa"||e==="id_ed25519"||e==="id_ecdsa"||e==="id_dsa"}function fe(){return{ok:!1,error:{code:"path_not_permitted",message:"Tool path is not permitted."}}}function gs(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 ys=3e4,Ce=4e3,ws=[/\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 ks(t){return ws.some(e=>e.test(t))}function Ze(t){return t.length<=Ce?t:`${t.slice(0,Ce)}
|
|
27
|
+
[truncated ${t.length-Ce} characters]`}function _s(t,e,s){return new Promise(n=>{let r=Date.now();ps(t,{cwd:e,timeout:s},(o,i,l)=>{let c=Date.now()-r;if(o?.killed===!0){n({completed:!1});return}let a=o===null?0:typeof o.code=="number"?o.code:1;n({completed:!0,exitCode:a,stdout:Ze(i),stderr:Ze(l),durationMs:c})})})}function vs(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 bs(){return{ok:!1,error:{code:"command_blocked",message:"Command matches a blocked pattern."}}}function xs(){return{ok:!1,error:{code:"sandbox_rejected",message:"Command rejected: workspace sandbox prevents execution outside workspace."}}}var Ss=[/\/\.\.\//,/\bcd\s+\/(\s|$)/,/\bcd\s+~\/?(\s|$)/];function Cs(t){return Ss.some(e=>e.test(t))}function it(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=vs(e);if(n===void 0)return N("Tool input must include a string command.");if(ks(n.command))return bs();if(t?.sandboxed===!0&&Cs(n.command))return xs();let r=n.timeoutMs??ys,o=await _s(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 at(){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=gs(t);if(s===void 0)return N("Tool input must include a string path and string content.");let n=Ae(e.workspaceRoot,s.path);if(n===void 0)return Q();if(pe(n.absolutePath))return fe();try{return await Ee(st(n.absolutePath),{recursive:!0}),await Z(n.absolutePath,s.content,"utf8"),{ok:!0,summary:`Wrote file ${n.displayPath}.`}}catch(r){return K(r)}}}}function Ts(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 ct(){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 N("path, old_string, and new_string must be strings.");let n=s.path,r=s.old_string,o=s.new_string,i=s.replace_all===!0;if(r.length===0)return N("old_string must not be empty.");let l=R(e.workspaceRoot,n);if(!l.startsWith(R(e.workspaceRoot)+"/")&&l!==R(e.workspaceRoot))return Q();if(pe(l))return fe();let c;try{c=await X(l,"utf8")}catch(u){return K(u)}let a=Ts(c,r);if(a===0)return{ok:!1,error:{code:"string_not_found",message:`old_string not found in ${n}.`}};if(a>1&&!i)return{ok:!1,error:{code:"multiple_matches",message:`old_string appears ${a} times in ${n}. Use replace_all: true or add more surrounding context to make it unique.`}};let d=c.split(r).join(o);try{await Z(l,d,"utf8")}catch(u){return K(u)}return{ok:!0,path:n,replacements:a,summary:`Edited ${n}: ${a} replacement${a===1?"":"s"}.`}}}}function lt(){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 N("path and content must be strings.");let n=s.path,r=s.content,o=R(e.workspaceRoot,n);if(!o.startsWith(R(e.workspaceRoot)+"/")&&o!==R(e.workspaceRoot))return Q();if(pe(o))return fe();try{await Ee(st(o),{recursive:!0}),await Z(o,r,{flag:"a"})}catch(i){return K(i)}return{ok:!0,path:n,summary:`Appended to ${n}.`}}}}var Te=8e3;function Is(t){try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"?e:void 0}catch{return}}function Es(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 Rs(t){return t.length<=Te?t:`${t.slice(0,Te)}
|
|
28
|
+
[truncated ${t.length-Te} characters]`}function As(t){if(typeof t!="object"||t===null)return;let e=t.url;return typeof e=="string"?e:void 0}function dt(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=As(e);if(n===void 0)return N("Tool input must include a string url.");let r=Is(n);if(r===void 0)return N("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 i=await o.text(),l=Rs(Es(i));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 ut(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 i of n.todos){if(typeof i!="object"||i===null)return{ok:!1,error:{code:"invalid_input",message:"Each todo must be an object."}};let{content:l,status:c}=i;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(c!=="pending"&&c!=="in_progress"&&c!=="completed")return{ok:!1,error:{code:"invalid_input",message:`Invalid status "${String(c)}". Must be pending, in_progress, or completed.`}};r.push({content:l,status:c})}return r.filter(i=>i.status==="in_progress").length>1?{ok:!1,error:{code:"invalid_input",message:"At most one todo may be in_progress at a time."}}:(t?.(r),{ok:!0})}}}function mt(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 pt(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=[],i=z(t,"MEMORY.md"),l=z(t,"USER.md"),c=z(t,"memory");for(let m of[i,l])try{await fs(m),o.push(m)}catch{}try{let m=await Ie(c,{recursive:!0,withFileTypes:!0});for(let h of m)if(h.isFile()&&h.name.endsWith(".md")){let p=typeof h.parentPath=="string"?h.parentPath:h.path;o.push(z(p,h.name))}}catch{}if(o.length===0)return{ok:!0,results:[],total:0};let a=n.toLowerCase().split(/\s+/).filter(m=>m.length>0),d=[];for(let m of o){let h;try{h=await X(m,"utf8")}catch{continue}let p=h.split(/\n\n+/),g=Re(t,m);for(let _ of p){let b=_.toLowerCase();a.some(k=>b.includes(k))&&d.push({file:g,excerpt:_.trim()})}}let u=d.slice(0,r);return{ok:!0,results:u,total:u.length}}}}function ft(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=R(t),o=R(r,n);if(!o.startsWith(r+"/")&&o!==r)return{ok:!0,error:"Path traversal is not permitted."};try{return{ok:!0,content:await X(o,"utf8")}}catch{return{ok:!0,error:`File not found: ${n}`}}}}}function ht(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=R(s.workspaceRoot,"memory"),i=R(o,`${r}.md`);try{await Ee(o,{recursive:!0});let c=`
|
|
29
29
|
## ${new Date().toISOString().replace("T"," ").slice(0,16)}
|
|
30
30
|
|
|
31
31
|
${n.content.trim()}
|
|
32
|
-
`;return await Z(
|
|
32
|
+
`;return await Z(i,c,{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 Ps=new Set(["node_modules",".git","dist","build","coverage",".pnpm-store",".nyc_output",".turbo",".cache"]),Os=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"]),Ms=512*1024,Qe=50;async function*gt(t){let e;try{e=await Ie(t,{withFileTypes:!0})}catch{return}for(let s of e){if(Ps.has(s.name))continue;let n=z(t,s.name);s.isDirectory()?yield*gt(n):s.isFile()&&!Os.has(tt(s.name).toLowerCase())&&(yield n)}}function $s(t,e){let s=et(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 yt(){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(a=>a===s.status)??"running",o=typeof s.message=="string"?s.message.trim():"",i=R(e.workspaceRoot,"HEARTBEAT.md"),l=new Date().toISOString(),c=["# Heartbeat","",`**Status**: ${r}`,`**Last updated**: ${l}`,...o.length>0?["",o]:[]];try{return await Z(i,c.join(`
|
|
33
33
|
`)+`
|
|
34
|
-
`),{ok:!0,filePath:"HEARTBEAT.md"}}catch(
|
|
35
|
-
`),_=!1;for(let b=0;b<
|
|
34
|
+
`),{ok:!0,filePath:"HEARTBEAT.md"}}catch(a){return{ok:!1,error:{code:"write_error",message:a instanceof Error?a.message:"Failed to write HEARTBEAT.md."}}}}}}function wt(){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 ${Qe}.`}},required:["pattern"]},async execute(t,e){let s=t,n=e.workspaceRoot,r=s.path?R(n,s.path):n,o=s.max_results??Qe,i=s.case_sensitive===!0?"":"i",l;try{l=new RegExp(s.pattern,i)}catch{let m=s.pattern.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");l=new RegExp(m,i)}let c=[],a=0,d=0,u=!1;e:for await(let m of gt(r)){let h=Re(n,m).replace(/\\/g,"/");if(s.include!==void 0&&!$s(h,s.include))continue;let p;try{if((await hs(m)).size>Ms)continue;p=await X(m,"utf8")}catch{continue}a++;let g=p.split(`
|
|
35
|
+
`),_=!1;for(let b=0;b<g.length;b++){if(l.test(g[b])){if(c.length>=o){u=!0;break e}c.push({file:h,line:b+1,content:g[b].trimEnd()}),_=!0}l.lastIndex=0}_&&d++}return{type:"search_files_result",matches:c,truncated:u,matchedFiles:d,searchedFiles:a}}}}var Y=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 Ns=12,Ds=2,Ls="Low-risk actions run automatically. Medium and high-risk actions require approval. Blocked actions are never permitted.",Fs="Do not restate the plan. Act now: take the first concrete tool action you can.",_t=/\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,js=/\b(?:done|finished|implemented|updated|fixed|changed|ran|verified|found|here(?:'s| is) what|blocked by|the blocker is)\b/i,Us=/^(?:plan|steps?|next steps?)\s*:/im,qs=/^(?:[-*•]\s+|\d+[.)]\s+)/u,Bs=/\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,Vs=700,F=class{#e;#t;#s;#n;#r;#o;#a;#c;#u;#d;#m;#f;#h;#l;#g;#v;#w;#k;#_;#y=[];constructor(e){this.#e=e.contextAssembler??new ce,this.#t=e.modelProvider,this.#s=e.permissionPolicy??new me,this.#n=e.approvalResolver,this.#a=e.maxSteps??Ns,this.#v=e.executionContract??"default",this.#c=e.executionContract==="strict-agentic"?e.maxPlanningStallRetries??3:e.maxPlanningStallRetries??Ds,this.#o=e.skillIndex??[];let s=e.systemInstruction??"";this.#u=e.executionContract==="strict-agentic"?`${s}
|
|
36
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.#l=e.hooks,this.#g=e.sessionMutex,this.#w=e.createRunId??kt("run"),this.#k=e.createEventId??kt("evt"),this.#_=e.now??(()=>new Date().toISOString());let n=ut(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.#l?.beforeTurn!==void 0)try{await this.#l.beforeTurn(e)}catch(k){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeTurn hook threw:",k)}let
|
|
38
|
-
`)),T=x&&typeof x.content=="string"?x.content.slice(22):"";yield
|
|
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.#l=e.hooks,this.#g=e.sessionMutex,this.#w=e.createRunId??kt("run"),this.#k=e.createEventId??kt("evt"),this.#_=e.now??(()=>new Date().toISOString());let n=ut(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.#l?.beforeTurn!==void 0)try{await this.#l.beforeTurn(e)}catch(k){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeTurn hook threw:",k)}let i=k=>(r.push(k),k);yield i(this.#i({...n,type:"run_started",userMessage:e.message}));let l=this.#b(),c=await this.#e.assemble({systemInstruction:this.#u,...this.#d?{runtime:this.#d}:{},...l.length>0?{tools:l}:{},permissionGuidance:Ls,...this.#o.length>0?{skillIndex:this.#o}:{},...e.recentMessages?{recentMessages:e.recentMessages}:{},...this.#h!==void 0?{promptMode:this.#h}:{},userMessage:e.message});yield i(this.#i({...n,type:"context_assembled",messageCount:c.modelInput.messages.length,systemInstructionIncluded:c.report.includedSections.includes("identity")}));let a=this.#x(),d=c.modelInput.messages,u=0,m=0,h=!1,p="";this.#y=[];let g=[],_=c.modelInput.messages.at(-1);for(_&&g.push({..._});u<this.#a;){if(e.signal?.aborted){yield i(this.#i({...n,type:"run_failed",error:{message:"Aborted by user.",recoverable:!1}})),await this.#p(r);return}if(this.#f!==void 0){let f=d.length;d=await He(d,this.#t,this.#f);let I=d.length;if(I<f){let x=d.find(v=>v.role==="system"&&typeof v.content=="string"&&v.content.startsWith(`Conversation summary:
|
|
38
|
+
`)),T=x&&typeof x.content=="string"?x.content.slice(22):"";yield i(this.#i({...n,type:"compaction_triggered",messagesBefore:f,messagesAfter:I,summary:T}))}if(this.#l?.onCompaction!==void 0)try{await this.#l.onCompaction(f,I)}catch(x){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] onCompaction hook threw:",x)}}yield i(this.#i({...n,type:"model_request_started",provider:"configured"}));let k={messages:d,...a.length>0?{tools:a}:{},...c.modelInput.options!==void 0?{options:c.modelInput.options}:{}},y;if(this.#m&&Xe(this.#t)){let f="",I,x="",T,v;for await(let w of this.#t.generateStream(k)){if(e.signal?.aborted)break;w.type==="token_delta"?yield i(this.#i({...n,type:"token_delta",delta:w.delta})):w.type==="message_done"?(f=w.content,T=w.usage):w.type==="tool_calls"?(I=w.calls,x=w.text??"",T=w.usage):w.type==="error"&&(v={category:w.category,message:w.message,recoverable:w.recoverable})}v!==void 0?y={type:"error",category:v.category,message:v.message,recoverable:v.recoverable}:I!==void 0?y={type:"tool_calls",calls:I,...x?{text:x}:{},...T!==void 0?{usage:T}:{}}:y={type:"message",content:f,...T!==void 0?{usage:T}:{}}}else y=await this.#t.generate(k);if(yield i(this.#i({...n,type:"model_request_completed",provider:"configured"})),u++,y.type==="error"){yield i(this.#i({...n,type:"run_failed",error:{message:y.message,recoverable:y.recoverable}})),await this.#p(r);return}if(y.type==="message"){if([...this.#r.keys()].some(x=>x!=="update_todos")&&!h&&Ws(y.content)){if(m++,yield i(this.#i({...n,type:"planning_stall_detected",stallCount:m,maxRetries:this.#c})),m>=this.#c){yield i(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:y.content},{role:"user",content:Fs}];continue}m=0,y.content!==""?(g.push({role:"assistant",content:y.content}),yield i(this.#i({...n,type:"assistant_message_created",message:{role:"assistant",content:y.content}}))):p!==""&&(yield i(this.#i({...n,type:"assistant_message_created",message:{role:"assistant",content:p}}))),yield i(this.#i({...n,type:"turn_complete",messages:[...g]})),yield i(this.#i({...n,type:"run_completed"})),await this.#p(r);return}m=0,y.calls.some(f=>f.name!=="update_todos")&&(h=!0),y.text&&(p=y.text);let A={role:"assistant",content:y.text??null,toolCalls:y.calls};d=[...d,A],g.push({...A});let M=[],O=!1,C="";for(let f of y.calls){yield i(this.#i({...n,type:"tool_call_requested",call:f}));let I=this.#r.get(f.name);if(I===void 0){let w=`Tool "${f.name}" is not registered.`;yield i(this.#i({...n,type:"tool_failed",callId:f.id,toolName:f.name,error:{message:w}}));let $={role:"tool",toolCallId:f.id,content:`Error: ${w}`};M.push($),g.push({...$});continue}let x=this.#s.evaluate({mode:Ys(this.#d?.mode),action:Ks(f,I.risk)});if(yield i(this.#i({...n,type:"tool_call_permission_evaluated",callId:f.id,toolName:f.name,decision:x})),x.decision==="deny"){O=!0,C=`Tool call ${f.name} was denied.`;break}if(x.decision==="ask"){yield i(this.#i({...n,type:"approval_requested",callId:f.id,toolName:f.name,decision:x}));let w=this.#n===void 0?{approved:!1,reason:"No approval resolver was configured."}:await this.#n.resolve({call:f,decision:x});if(yield i(this.#i({...n,type:"approval_resolved",callId:f.id,toolName:f.name,resolution:w})),!w.approved){O=!0,C=`Tool call ${f.name} was denied.`;break}}if(this.#l?.beforeToolCall!==void 0){let w;try{w=await this.#l.beforeToolCall(f)}catch($){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] beforeToolCall hook threw:",$)}if(w==="abort"){let $="Tool call aborted by hook.";yield i(this.#i({...n,type:"tool_failed",callId:f.id,toolName:f.name,error:{message:$}}));let G={role:"tool",toolCallId:f.id,content:`Error: ${$}`};M.push(G),g.push({...G});continue}}yield i(this.#i({...n,type:"tool_started",callId:f.id,toolName:f.name}));let T;try{T=await I.execute(f.input,{workspaceRoot:this.#d?.workspace??process.cwd()})}catch(w){let $=w instanceof Error?w.message:"Unknown tool execution error.";yield i(this.#i({...n,type:"tool_failed",callId:f.id,toolName:f.name,error:{message:$}}));let G={role:"tool",toolCallId:f.id,content:`Error: ${$}`};M.push(G),g.push({...G});continue}yield i(this.#i({...n,type:"tool_completed",callId:f.id,toolName:f.name,result:T}));let v={role:"tool",toolCallId:f.id,content:JSON.stringify(T)};if(M.push(v),g.push({...v}),this.#l?.afterToolCall!==void 0)try{await this.#l.afterToolCall(f,T)}catch(w){typeof process<"u"&&process.env.NODE_ENV!=="production"&&console.warn("[AgentRuntime] afterToolCall hook threw:",w)}}if(O){yield i(this.#i({...n,type:"run_failed",error:{message:C,recoverable:!1}})),await this.#p(r);return}y.calls.some(f=>f.name==="update_todos")&&(yield i(this.#i({...n,type:"todos_updated",todos:[...this.#y]}))),d=[...d,...M]}yield i(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.#l?.afterTurn!==void 0)try{await this.#l.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 kt(t){return()=>`${t}_${crypto.randomUUID()}`}function Ks(t,e){return{kind:"tool",name:t.name,summary:`Model requested tool ${t.name}.`,risk:e}}function Ys(t){return t==="observe"||t==="auto"?t:"confirm"}function Hs(t){let e=t.split(/\r?\n/).map(o=>o.trim()).filter(Boolean);if(e.length===0)return!1;let s=e.filter(o=>qs.test(o)).length,n=e.some(o=>_t.test(o));return Us.test(e[0]??"")&&n||s>=2&&n}function Ws(t){let e=t.trim();if(!e||e.length>Vs||e.includes("```")||js.test(e))return!1;let s=Hs(e);return!(!_t.test(e)&&!s||!s&&!Bs.test(e))}function vt(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
39
|
|
|
40
40
|
Context:
|
|
41
|
-
${n.context}`:n.goal;return(async()=>{e?.taskStore!==void 0&&await e.taskStore.update(r,{status:"running"});let
|
|
41
|
+
${n.context}`:n.goal;return(async()=>{e?.taskStore!==void 0&&await e.taskStore.update(r,{status:"running"});let l=t.create(n.goal),c="",a=!1;for await(let d of l.runTurn({message:o}))d.type==="assistant_message_created"&&(c=d.message.content),d.type==="run_failed"&&(a=!0);e?.taskStore!==void 0&&await e.taskStore.update(r,{status:a?"failed":"succeeded",...c.length>0?{terminalSummary:c}:{}})})(),{type:"spawn_subagent_async_result",taskId:r,status:"queued"}}}}function bt(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 xt(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="",i=!1,l="";for await(let c of r.runTurn({message:n.goal}))c.type==="assistant_message_created"&&(o=c.message.content),c.type==="run_failed"&&(i=!0,l=c.error.message);return i?{type:"spawn_subagent_result",ok:!1,error:l}:{type:"spawn_subagent_result",ok:!0,result:o}}}}var he=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 St={streaming:!0,approvalPrompts:!0,background:!1};var Gs={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 ge(t,e){let s=Gs[e];return s.allowedTools.length===0?t:t.filter(n=>s.allowedTools.includes(n.name))}import{mkdir as Pe,readFile as Js,writeFile as Oe}from"fs/promises";import{dirname as Me}from"path";var H=class{#e;constructor(e){this.#e=e}async saveRun(e){await Pe(Me(this.#e),{recursive:!0}),await Oe(this.#e,`${JSON.stringify(e)}
|
|
42
42
|
`,{flag:"a"})}async updateRun(e,s){let r=(await this.#t()).map(o=>o.id===e?{...o,...s}:o);await Pe(Me(this.#e),{recursive:!0}),await Oe(this.#e,r.map(o=>JSON.stringify(o)).join(`
|
|
43
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
|
|
45
|
-
`))n.trim()!==""&&s.push(JSON.parse(n));return s}},te=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
|
|
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 Js(this.#e,"utf8")}catch(n){if(zs(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}},te=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 zs(t){return t instanceof Error&&"code"in t}function ee(t,e){if(t==="*")return!0;let s=parseInt(t,10);return!isNaN(s)&&s===e}function Xs(t,e){let s=t.trim().split(/\s+/);if(s.length!==5)return!1;let[n,r,o,i,l]=s;return ee(n,e.getMinutes())&&ee(r,e.getHours())&&ee(o,e.getDate())&&ee(i,e.getMonth()+1)&&ee(l,e.getDay())}async function $e(t,e){await Pe(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 Oe(t,s.join(`
|
|
46
46
|
`)+`
|
|
47
|
-
`)}var ye=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||!
|
|
48
|
-
`,{flag:"a"})}async#o(e){let s="";try{s=await
|
|
49
|
-
`)){if(
|
|
50
|
-
`).filter(s=>s.trim().length>0).map(s=>JSON.parse(s))}catch{return[]}}async#s(e){await
|
|
47
|
+
`)}var ye=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||!Xs(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 Qs,readFile as en,writeFile as tn}from"fs/promises";import{join as sn}from"path";var we=class{#e=new Map;#t=new Map;#s=new Map;#n;#r;#o;constructor(e={}){this.#n=e.createSessionId??_e("sess"),this.#r=e.createMessageId??_e("msg"),this.#o=e.now??(()=>new Date().toISOString())}async createSession(e={}){let 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(Tt);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}),ke(r)}async listTraceEvents(e,s={}){let n=this.#s.get(e)??[];return(s.limit===void 0?n:n.slice(-s.limit)).map(o=>ke(o))}},se=class{#e;#t;#s;#n;constructor(e){this.#e=e.directory,this.#t=e.createSessionId??_e("sess"),this.#s=e.createMessageId??_e("msg"),this.#n=e.now??(()=>new Date().toISOString())}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.#c(),n=[];for(let i of s){let l=await this.getSession(i);l!==void 0&&n.push(l)}let r=n.sort(Tt);return(e.limit===void 0?r:r.slice(0,e.limit)).map(i=>({...i}))}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}),ke(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=>ke(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 tn(this.#a(e),`${JSON.stringify(s)}
|
|
48
|
+
`,{flag:"a"})}async#o(e){let s="";try{s=await en(this.#a(e),"utf8")}catch(i){if(Ct(i)&&i.code==="ENOENT")return{messages:[],traceEvents:[]};throw i}let n=[],r=[],o;for(let i of s.split(`
|
|
49
|
+
`)){if(i.trim()==="")continue;let l=JSON.parse(i);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 nn(e),sn(this.#e,`${e}.jsonl`)}async#c(){try{return(await Qs(this.#e)).filter(s=>s.endsWith(".jsonl")).map(s=>s.slice(0,-6)).filter(s=>/^[A-Za-z0-9_-]+$/.test(s))}catch(e){if(Ct(e)&&e.code==="ENOENT")return[];throw e}}};function nn(t){if(!/^[A-Za-z0-9_-]+$/.test(t))throw new Error(`Unsafe session id "${t}".`)}function Ct(t){return t instanceof Error&&"code"in t}function Tt(t,e){return e.updatedAt.localeCompare(t.updatedAt)}function ke(t){return{...t,event:structuredClone(t.event)}}function _e(t){return()=>`${t}_${crypto.randomUUID()}`}import{mkdir as rn,readFile as on,writeFile as an}from"fs/promises";import{join as gr,dirname as cn}from"path";var U=class{#e;constructor(e){this.#e=e}async#t(){try{return(await on(this.#e,"utf-8")).split(`
|
|
50
|
+
`).filter(s=>s.trim().length>0).map(s=>JSON.parse(s))}catch{return[]}}async#s(e){await rn(cn(this.#e),{recursive:!0}),await an(this.#e,e.map(s=>JSON.stringify(s)).join(`
|
|
51
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(
|
|
53
|
-
`,"utf8")}async install(e){let s=
|
|
54
|
-
`);if(e[0]?.trim()!=="---")return null;let s=e.findIndex((p,
|
|
55
|
-
`).trim(),o={},
|
|
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(i=>i.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 ln,mkdir as It,readFile as ne,readdir as dn,writeFile as un}from"fs/promises";import{homedir as mn}from"os";import{basename as pn,join as j}from"path";var fn=[{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:""}],re=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=j(e.workspaceRoot,"skills");for(let c of await this.#e(l,"workspace",e))r(c)}let o=e.userSkillsDir??j(mn(),".vole","skills"),i=await hn(o,e.readFile);for(let l of await this.#e(o,"user",e,i))r(l);for(let l of fn)r(l);return n}async#e(e,s,n,r){let o=n.readDir??(a=>dn(a)),i=n.readFile??(a=>ne(a,"utf8")),l;try{l=await o(e)}catch(a){if(gn(a)&&a.code==="ENOENT")return[];throw a}let c=[];for(let a of l){if(a==="skills-index.json")continue;let d=j(e,a,"SKILL.md");if(s==="user"&&r!==void 0){let u=r.skills.find(m=>m.name===a);if(u!==void 0&&u.enabled===!1)continue}try{let u=await i(d),m=Ne(u);if(m!==null){let h,p;if(s==="user"){let _=r?.skills.find(b=>b.name===a);h=_?.trusted??!1,p=_?.enabled??!0}let g={...m,source:s,filePath:d,...h!==void 0?{trusted:h}:{},...p!==void 0?{enabled:p}:{}};c.push(g)}}catch{}}return c}};async function hn(t,e){let s=e??(r=>ne(r,"utf8")),n=j(t,"skills-index.json");try{let r=await s(n);return JSON.parse(r)}catch{return}}var W=class{#e;constructor(e){this.#e=e}async loadManifest(){let e=j(this.#e,"skills-index.json");try{let s=await ne(e,"utf8");return JSON.parse(s)}catch{return{skills:[]}}}async saveManifest(e){await It(this.#e,{recursive:!0});let s=j(this.#e,"skills-index.json");await un(s,JSON.stringify(e,null,2)+`
|
|
53
|
+
`,"utf8")}async install(e){let s=pn(e),n=s.endsWith(".md")?s.slice(0,-3):s,r=await ne(e,"utf8"),o=Ne(r),i=o?.name??n,l=j(this.#e,i);await It(l,{recursive:!0});let c=j(l,"SKILL.md");await ln(e,c);let a=await this.loadManifest(),d=a.skills.findIndex(m=>m.name===i),u={name:i,filePath:c,installedAt:new Date().toISOString(),...o?.origin!==void 0?{origin:o.origin}:{},trusted:!1,enabled:!0};return d!==-1?a.skills[d]=u:a.skills.push(u),await this.saveManifest(a),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 ne(n.filePath,"utf8"),o=Ne(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 Ne(t){let e=t.split(`
|
|
54
|
+
`);if(e[0]?.trim()!=="---")return null;let s=e.findIndex((p,g)=>g>0&&p.trim()==="---");if(s===-1)return null;let n=e.slice(1,s),r=e.slice(s+1).join(`
|
|
55
|
+
`).trim(),o={},i={},l=null;for(let p of n){let g=/^\s+-\s+(.+)$/.exec(p);if(g!==null&&l!==null){let y=g[1]?.trim()??"";y.length>0&&(i[l]=[...i[l]??[],y]);continue}let _=p.indexOf(":");if(_===-1){l=null;continue}let b=p.slice(0,_).trim(),k=p.slice(_+1).trim();if(b.length===0){l=null;continue}k===""?l=b:(l=null,o[b]=k)}let{name:c,description:a,version:d,origin:u,permissions:m}=o;if(!c||!a)return null;let h;return m!==void 0&&m.length>0?h=m.split(",").map(p=>p.trim()).filter(p=>p.length>0):i.permissions!==void 0&&(h=i.permissions),{name:c,description:a,body:r,...d!==void 0?{version:d}:{},...u!==void 0?{origin:u}:{},...h!==void 0?{permissions:h}:{}}}function Et(t){return{name:t.name,description:t.description,source:t.source}}function gn(t){return t instanceof Error&&"code"in t}var Ur="@vole/cli";async function At(t){try{return JSON.parse(await Fe(t,"utf8"))}catch{return}}async function _n(t=process.cwd()){let e=t;for(;;)try{return await je(S(e,".git")),e}catch{let s=B(e);if(s===e)return;e=s}}async function P(t={}){let e=t.env??process.env,s=e.HOME??process.env.HOME,n={env:e};s!==void 0&&(n.userConfig=await At(S(s,".vole","config.json"))),n.projectConfig=await At(S("vole.config.json"));let r=xe(n);if(r.sessions.directory==="~/.vole/sessions"){let o=await _n(t.cwd);o!==void 0&&(r.sessions.directory=S(o,".vole","sessions"))}return r}var ve=`You are Vole, a capable coding and general-purpose agent.
|
|
56
56
|
|
|
57
57
|
## Tool Call Style
|
|
58
58
|
Do not narrate routine, low-risk tool calls \u2014 just call the tool.
|
|
@@ -72,76 +72,76 @@ Keep narration brief; avoid restating what tool output already shows.
|
|
|
72
72
|
## File Editing
|
|
73
73
|
- Modify existing code: edit_file (precise string replacement, preserves surrounding content).
|
|
74
74
|
- Add to end of file: append_file.
|
|
75
|
-
- Create new files or intentional full replacement: write_file.`,Pt=new he;async function
|
|
76
|
-
`};return}let
|
|
77
|
-
`}}return{exitCode:
|
|
78
|
-
`}}throw
|
|
79
|
-
`);return{exitCode:
|
|
75
|
+
- Create new files or intentional full replacement: write_file.`,Pt=new he;async function vn(t,e,s={}){if((t[0]==="--"?t.slice(1):t).length===0)return Ot(s,{fakeInteractive:!1,resume:!1});let r="",o=null,i=new yn().name("vole").description("A capable coding and general-purpose agent.").version(e,"-v, --version","Show version number").exitOverride().configureOutput({writeOut:a=>{r+=a},writeErr:a=>{r+=a}}).addHelpText("after","\nRun `vole <command> --help` for command-specific options.");i.command("chat").description("Start an interactive chat session").argument("[extra...]","Slash commands to run after a --fake turn").option("-s, --session <id>","Continue a named session").option("-r, --resume","Continue the most recently updated session").option("--fake <message>","Run one turn with a fake provider and exit").option("--fake-interactive","Interactive chat with a fake provider").action(async(a,d)=>{let u=a.filter(h=>h.startsWith("/"));if(d.fake!==void 0){o=await bn({message:d.fake,slashCommands:u},s);return}if(d.fakeInteractive){let h=typeof d.session=="string"?d.session:void 0;o=await xn(s,{fakeInteractive:!0,resume:!1,...h!==void 0?{sessionId:h}:{}});return}let m=typeof d.session=="string"?d.session:void 0;o=await Ot(s,{fakeInteractive:!1,resume:d.resume===!0,...m!==void 0?{sessionId:m}:{}})}),i.command("sessions").description("List stored chat sessions").action(async()=>{o=await Sn(s)}),i.command("run").description('Run a one-shot background task e.g. vole run "fix the tests"').argument("[goal]","Goal for the task").option("--mode <mode>","Autonomy mode: auto | confirm | observe","confirm").option("--dream","Consolidate daily memory notes into MEMORY.md").action(async(a,d)=>{if(d.dream){o=await Cn(s);return}let u=(a??"").trim();if(u===""){o={exitCode:1,stdout:"",stderr:`Missing goal. Usage: vole run "<goal>"
|
|
76
|
+
`};return}let m=d.mode;o=await Lt(u,m==="auto"?"auto":m==="observe"?"observe":"confirm",s)}),i.command("tasks").description("List recent background task runs").option("-n, --limit <n>","Number of runs to show",a=>parseInt(a,10)).action(async a=>{o=await Tn(s,a.limit)});let l=i.command("skills").description("Manage agent skills");l.action(async()=>{o=await Pn(s)}),l.command("install <path>").description("Install a skill from a local .md file").action(async a=>{o=await On(a,s)}),l.command("enable <name>").description("Enable a disabled skill").action(async a=>{o=await De("enable",a,s)}),l.command("disable <name>").description("Disable a skill").action(async a=>{o=await De("disable",a,s)}),l.command("trust <name>").description("Mark an installed skill as trusted").action(async a=>{o=await De("trust",a,s)}),l.command("review <name>").description("Show full skill metadata and permissions").action(async a=>{o=await Mn(a,s)}),i.command("daemon").description("Start the task scheduler daemon").option("--once","Run all due tasks once and exit").action(async a=>{o=await En(s,a.once===!0)}),i.command("web").description("Start the Vole web dashboard").option("-p, --port <port>","Port to listen on","3120").option("--no-open","Don't open the browser automatically").action(async a=>{let d=parseInt(a.port,10)||3120,u=a.open!==!1;o=await qn(d,u)});let c=i.command("taskflow").description("Inspect cross-session task records");c.action(async()=>{o=await $t(s,void 0)}),c.command("list").description("List recent task records").option("-n, --limit <n>","Number of records to show",a=>parseInt(a,10)).action(async a=>{o=await $t(s,a.limit)}),c.command("show <id>").description("Show details of a task").action(async a=>{o=await Rn(a,s)}),c.command("cancel <id>").description("Mark a task as cancelled").action(async a=>{o=await An(a,s)});try{let a=t[0]==="--"?t.slice(1):t;await i.parseAsync(a,{from:"user"})}catch(a){if(a instanceof Error&&"code"in a){let d=a.code;if(d==="commander.helpDisplayed"||d==="commander.version")return{exitCode:0,stdout:r,stderr:""};if(d==="commander.unknownCommand"){let u=a.message.match(/unknown command '(.+)'/),m=u?u[1]:t[0]??"unknown";return{exitCode:1,stdout:i.helpInformation(),stderr:`Unknown command "${m}".
|
|
77
|
+
`}}return{exitCode:a.exitCode??1,stdout:r,stderr:`${a.message}
|
|
78
|
+
`}}throw a}return o??{exitCode:0,stdout:r,stderr:""}}async function bn(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 ae.createFake(`Fake response to: ${s}`,e),o=await r.sendMessage(s),i=await Nn(r,n),l=o.assistantText,c=o.events,a=Ve(c).join(`
|
|
79
|
+
`);return{exitCode:c.some(d=>d.type==="run_failed")?1:0,stdout:`Assistant: ${l}
|
|
80
80
|
|
|
81
81
|
Trace:
|
|
82
|
-
${
|
|
83
|
-
${
|
|
84
|
-
`};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 $n(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
|
|
82
|
+
${a}
|
|
83
|
+
${i}`,stderr:""}}async function xn(t,e){let s=await ae.createFake(n=>`Fake response to: ${n}`,t,{...e.sessionId===void 0?{}:{sessionId:e.sessionId}});return Ft(s,"Vole chat (fake provider)",t)}async function Ot(t,e){let s=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}});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.
|
|
84
|
+
`};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 $n(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 Ft(await ae.createConfigured(s,t,{...r===void 0?{}:{sessionId:r}}),n===void 0?"Vole chat":`Vole chat
|
|
85
85
|
Resumed session: ${n}`,t)}async function Sn(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),n=await Be(e,t,q()).listSessions();return n.length===0?{exitCode:0,stdout:`Sessions:
|
|
86
86
|
No sessions found.
|
|
87
87
|
`,stderr:""}:{exitCode:0,stdout:["Sessions:",...n.map(r=>`${r.id} ${r.updatedAt}${r.title?` ${r.title}`:""}`)].join(`
|
|
88
88
|
`)+`
|
|
89
89
|
`,stderr:""}}async function Cn(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}});return e.secrets.apiKey===void 0?{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
90
90
|
`}:e.memory.longTermFiles!=="write"?{exitCode:1,stdout:"",stderr:`Memory dreaming requires VOLE_LONG_TERM_MEMORY=write
|
|
91
|
-
`}:
|
|
91
|
+
`}:Lt(`You are a memory consolidation agent.
|
|
92
92
|
Review the recent daily memory files and the current MEMORY.md in the workspace.
|
|
93
93
|
Identify key facts, decisions, and patterns worth preserving long-term.
|
|
94
94
|
Append a consolidation summary to MEMORY.md using the write_file tool.
|
|
95
|
-
Be concise and factual. Do not duplicate what is already in MEMORY.md.`,"auto",t)}async function
|
|
96
|
-
`};let r=s.sessionsDirectory?{...n,sessions:{directory:s.sessionsDirectory}}:n,o=L(r,s.env),
|
|
95
|
+
Be concise and factual. Do not duplicate what is already in MEMORY.md.`,"auto",t)}async function Lt(t,e,s){let n=await P({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}});if(n.secrets.apiKey===void 0)return{exitCode:1,stdout:"",stderr:`No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.
|
|
96
|
+
`};let r=s.sessionsDirectory?{...n,sessions:{directory:s.sessionsDirectory}}:n,o=L(r,s.env),i=q(),l=`task_${crypto.randomUUID()}`,c=t.slice(0,40).replace(/\s+/g,"-").replace(/[^A-Za-z0-9-]/g,"").toLowerCase()||"task",a=new Date().toISOString(),d=new se({directory:o,createSessionId:()=>i}),u=new H(S(o,"task-runs.jsonl")),m={id:l,taskName:c,goal:t,sessionId:i,startedAt:a,status:"running",assistantText:""};await u.saveRun(m);let h=qe(n,s),p=new te(e),g=new Date().toISOString().slice(0,10),_=(()=>{let v=oe(s,n);return n.runtime.toolProfile!==void 0?ge(v,n.runtime.toolProfile):v})(),b=new F({contextAssembler:ie(n),modelProvider:h,systemInstruction:ve,runtime:{mode:e,workspace:n.workspace.root,currentDate:g},tools:_,preferStreaming:!1,approvalResolver:p,maxSteps:20,...n.runtime.promptMode!==void 0?{promptMode:n.runtime.promptMode}:{}}),k=[];await d.createSession({title:`task: ${t.slice(0,60)}`});for await(let v of b.runTurn({sessionId:i,message:t}))await d.appendTraceEvent({sessionId:i,event:v}),k.push(v);let y=Ve(k),A=k.find(v=>v.type==="assistant_message_created"),M=A?.type==="assistant_message_created"?A.message.content:"No assistant message was produced.",O=k.find(v=>v.type==="run_failed"),C=O?"failed":"completed",f=new Date().toISOString(),I={status:C,assistantText:M,completedAt:f,...O?.type==="run_failed"?{errorMessage:O.error.message}:{}};await u.updateRun(l,I);let x=y.join(`
|
|
97
97
|
`),T=C==="completed"?`Done: ${M}`:`Failed: ${O?.type==="run_failed"?O.error.message:"Unknown error"}`;return{exitCode:C==="completed"?0:1,stdout:`Trace:
|
|
98
98
|
${x}
|
|
99
99
|
|
|
100
100
|
${T}
|
|
101
|
-
`,stderr:""}}async function Tn(t,e){let s=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=L(n,t.env),
|
|
102
|
-
`,stderr:""}:{exitCode:0,stdout:
|
|
101
|
+
`,stderr:""}}async function Tn(t,e){let s=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=L(n,t.env),i=await new H(S(r,"task-runs.jsonl")).listRuns(e!==void 0?{limit:e}:{});return i.length===0?{exitCode:0,stdout:`No task runs found.
|
|
102
|
+
`,stderr:""}:{exitCode:0,stdout:i.map(c=>`${c.id.slice(-8)} ${c.taskName} ${c.status} ${c.startedAt}`).join(`
|
|
103
103
|
`)+`
|
|
104
|
-
`,stderr:""}}async function In(t){try{await je(t)}catch{return null}let s=(await
|
|
105
|
-
`};let n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=L(n,t.env),o=S(B(r),"tasks"),
|
|
106
|
-
`,stderr:""};let
|
|
104
|
+
`,stderr:""}}async function In(t){try{await je(t)}catch{return null}let s=(await kn(t)).filter(r=>r.endsWith(".task.json")),n=[];for(let r of s){let o=await Fe(S(t,r),"utf8");n.push(JSON.parse(o))}return n}async function Mt(t,e,s,n){let r=`run_${crypto.randomUUID()}`,o=q(),i=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 c=S(e.workspace.root,"HEARTBEAT.md"),a={status:"running",taskName:t.name,runId:r,lastUpdatedAt:new Date().toISOString()};await $e(c,a);let d=s.fakeModelOutputs?new V(s.fakeModelOutputs):qe(e,s),u=new te(i),m=new Date().toISOString().slice(0,10),h=(()=>{let C=oe(s,e);return e.runtime.toolProfile!==void 0?ge(C,e.runtime.toolProfile):C})(),p=new F({contextAssembler:ie(e),modelProvider:d,systemInstruction:ve,runtime:{mode:i,workspace:e.workspace.root,currentDate:m},tools:h,preferStreaming:!1,approvalResolver:u,...t.maxSteps!==void 0?{maxSteps:t.maxSteps}:{},...e.runtime.promptMode!==void 0?{promptMode:e.runtime.promptMode}:{}}),g=[];for await(let C of p.runTurn({sessionId:o,message:t.goal}))g.push(C);let _=g.find(C=>C.type==="assistant_message_created"),b=_?.type==="assistant_message_created"?_.message.content:"No assistant message was produced.",k=g.find(C=>C.type==="run_failed"),y=k?"failed":"completed",A=new Date().toISOString(),M={status:y,assistantText:b,completedAt:A,...k?.type==="run_failed"?{errorMessage:k.error.message}:{}};await n.updateRun(r,M);let O={status:y,taskName:t.name,runId:r,lastUpdatedAt:A,...k?.type==="run_failed"?{message:`Error: ${k.error.message}`}:{}};await $e(c,O)}async function En(t,e){let s=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}});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.
|
|
105
|
+
`};let n=t.sessionsDirectory?{...s,sessions:{directory:t.sessionsDirectory}}:s,r=L(n,t.env),o=S(B(r),"tasks"),i=new H(S(r,"task-runs.jsonl")),l=await In(o);if(l===null)return{exitCode:0,stdout:`No tasks directory found at ${o}.
|
|
106
|
+
`,stderr:""};let c=l.filter(u=>u.cron!==void 0);if(e){let u=new Date,m=[];for(let h of c)m.push(`Running: ${h.name}`),await Mt(h,s,t,i);return m.push("Done."),{exitCode:0,stdout:m.join(`
|
|
107
107
|
`)+`
|
|
108
|
-
`,stderr:""}}let
|
|
109
|
-
`,stderr:""})};process.once("SIGTERM",m),process.once("SIGINT",m)})}async function Ue(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),s=t.sessionsDirectory?{...e,sessions:{directory:t.sessionsDirectory}}:e,n=L(s,t.env);return S(B(n),"taskflow.jsonl")}async function
|
|
110
|
-
`,stderr:""}:{exitCode:0,stdout:["Task records:",...r.map(
|
|
108
|
+
`,stderr:""}}let a=async u=>{await Mt(u,s,t,i)},d=new ye(c,a);return d.start(),new Promise(u=>{let m=()=>{d.stop(),u({exitCode:0,stdout:`Daemon stopped.
|
|
109
|
+
`,stderr:""})};process.once("SIGTERM",m),process.once("SIGINT",m)})}async function Ue(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),s=t.sessionsDirectory?{...e,sessions:{directory:t.sessionsDirectory}}:e,n=L(s,t.env);return S(B(n),"taskflow.jsonl")}async function $t(t,e){let s=await Ue(t),r=await new U(s).list(e!==void 0?{limit:e}:{});return r.length===0?{exitCode:0,stdout:`No task records found.
|
|
110
|
+
`,stderr:""}:{exitCode:0,stdout:["Task records:",...r.map(i=>`${i.id.slice(-8)} ${i.status} ${i.runtime} ${i.createdAt} ${i.task.slice(0,60)}`)].join(`
|
|
111
111
|
`)+`
|
|
112
112
|
`,stderr:""}}async function Rn(t,e){let s=await Ue(e),r=await new U(s).get(t);return r===void 0?{exitCode:1,stdout:"",stderr:`Task "${t}" not found.
|
|
113
113
|
`}:{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(`
|
|
114
114
|
`)+`
|
|
115
115
|
`,stderr:""}}async function An(t,e){let s=await Ue(e);return await new U(s).update(t,{status:"cancelled"})===void 0?{exitCode:1,stdout:"",stderr:`Task "${t}" not found.
|
|
116
116
|
`}:{exitCode:0,stdout:`Cancelled: ${t}
|
|
117
|
-
`,stderr:""}}function be(t,e){let s=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,n=L(s,e.env);return S(B(n),"skills")}async function Pn(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),s=be(e,t),r=await new re().load({workspaceRoot:e.workspace.root,userSkillsDir:s});return{exitCode:0,stdout:["Skills:",...
|
|
117
|
+
`,stderr:""}}function be(t,e){let s=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,n=L(s,e.env);return S(B(n),"skills")}async function Pn(t){let e=await P({...t.env?{env:t.env}:{},...t.cwd?{cwd:t.cwd}:{}}),s=be(e,t),r=await new re().load({workspaceRoot:e.workspace.root,userSkillsDir:s});return{exitCode:0,stdout:["Skills:",...qt(r)].join(`
|
|
118
118
|
`)+`
|
|
119
119
|
`,stderr:""}}async function On(t,e){let s=await P({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}}),n=be(s,e),r=new W(n);try{return{exitCode:0,stdout:`Installed: ${(await r.install(t)).name}
|
|
120
120
|
`,stderr:""}}catch(o){return{exitCode:1,stdout:"",stderr:`Failed to install skill: ${o instanceof Error?o.message:String(o)}
|
|
121
121
|
`}}}async function De(t,e,s){let n=await P({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}}),r=be(n,s),o=new W(r);try{return t==="enable"?(await o.enable(e),{exitCode:0,stdout:`Enabled: ${e}
|
|
122
122
|
`,stderr:""}):t==="disable"?(await o.disable(e),{exitCode:0,stdout:`Disabled: ${e}
|
|
123
123
|
`,stderr:""}):(await o.trust(e),{exitCode:0,stdout:`Trusted: ${e}
|
|
124
|
-
`,stderr:""})}catch(
|
|
124
|
+
`,stderr:""})}catch(i){return{exitCode:1,stdout:"",stderr:`Failed to ${t} skill: ${i instanceof Error?i.message:String(i)}
|
|
125
125
|
`}}}async function Mn(t,e){let s=await P({...e.env?{env:e.env}:{},...e.cwd?{cwd:e.cwd}:{}}),n=be(s,e),r=new W(n),o=await r.review(t);if(o===void 0)return{exitCode:1,stdout:"",stderr:`Skill "${t}" not found.
|
|
126
|
-
`};let
|
|
126
|
+
`};let l=(await r.listEntries()).find(a=>a.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(`
|
|
127
127
|
`)+`
|
|
128
|
-
`,stderr:""}}async function $n(t,e){let s=Be(t,e,q()),[n]=await s.listSessions({limit:1});return n?.id}async function
|
|
128
|
+
`,stderr:""}}async function $n(t,e){let s=Be(t,e,q()),[n]=await s.listSessions({limit:1});return n?.id}async function Ft(t,e,s){let n=[],r=(...o)=>{s.write?s.write(`${o.join(`
|
|
129
129
|
`)}
|
|
130
|
-
`):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
|
|
130
|
+
`):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 i=o.trim();if(i==="")continue;if(i==="/exit"){r("Goodbye.");break}if(i==="/help"){r(...Ut(),"");continue}if(i==="/clear"){r("(conversation display cleared)","");continue}if(i.startsWith("/")){r(...Dn(i,await t.runSlashCommand(i)),"");continue}let l=await t.sendMessage(i);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(`
|
|
131
131
|
`)}
|
|
132
|
-
`,stderr:""}}var
|
|
132
|
+
`,stderr:""}}var jt={"/trace":"Recent Trace:","/config":"Config:","/skills":"Skills:","/help":"Commands:"};async function Nn(t,e){let s=[];for(let n of e){let r=jt[n];r!==void 0?s.push(["",r,...await t.runSlashCommand(n)].join(`
|
|
133
133
|
`)):s.push(["",`Unknown slash command: ${n}`].join(`
|
|
134
134
|
`))}return s.length===0?"":`${s.join(`
|
|
135
135
|
`)}
|
|
136
|
-
`}function Dn(t,e){if(e[0]?.startsWith("Unknown slash command"))return e;let s=
|
|
136
|
+
`}function Dn(t,e){if(e[0]?.startsWith("Unknown slash command"))return e;let s=jt[t];return s!==void 0?[s,...e]:e}function Ut(){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 ae=class t{#e;#t;#s;#n;#r;#o;#a;#c;constructor(e,s=J(xe()),n=new Y,r=q(),o=new we({createSessionId:()=>r}),i=12,l=[],c=[],a){this.#e=e,this.#r=s,this.#t=n,this.#s=o,this.#n=r,this.#o=l,this.#a=c,this.#c=a}get sessionId(){return this.#n}async listSessions(e){return this.#s.listSessions(e)}async loadMessages(){return this.#s.listMessages(this.#n)}close(){this.#c?.unregister(this.#n)}static async createFake(e="Fake response to: Hello trace",s={},n={}){let r=J(await P({...s.env?{env:s.env}:{},...s.cwd?{cwd:s.cwd}:{}})),o=[],i=s.fakeModelOutputs?new V(s.fakeModelOutputs):typeof e=="function"?new Le(e):new V([{type:"message",content:e}]);return new t(new F({contextAssembler:ie(r),modelProvider:i,systemInstruction:ve,runtime:{mode:"confirm",workspace:r.workspace.root,currentDate:new Date().toISOString().slice(0,10)},tools:oe(s,r),approvalResolver:Nt(s,o),maxSteps:20,compaction:{}}),r,new Y,n.sessionId??q(),void 0,12,o)}static async createConfigured(e,s={},n={}){let r=n.sessionId??q(),o=new Date().toISOString().slice(0,10),i=[],l=await new re().load({workspaceRoot:e.workspace.root}),c=l.map(Et),a=new Map(l.map(A=>[A.name,A.filePath])),d=qe(e,s),u=n.approvalResolver??Nt(s,i),m=oe(s,e,a),h={create:A=>new F({contextAssembler:ie(J(e)),modelProvider:d,systemInstruction:`You are Vole, a sub-agent handling: ${A}`,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:oe(s,e),maxSteps:8})},p=S(B(L(e,s.env)),"taskflow.jsonl"),g=new U(p),_=[...m,xt(h),vt(h,{taskStore:g}),bt(g)],b=e.runtime.toolProfile!==void 0?ge(_,e.runtime.toolProfile):_,k=new Date().toISOString(),y={id:r,adapterName:"cli",capabilities:St,registeredAt:k,lastActivityAt:k};return Pt.register(y),new t(new F({contextAssembler:ie(e),modelProvider:d,systemInstruction:ve,runtime:{mode:e.runtime.defaultMode,workspace:e.workspace.root,currentDate:o},tools:b,skillIndex:c,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}:{}}),J(e),new Y,r,Be(e,s,r),12,i,l,Pt)}async sendMessage(e,s={}){let n=[],r=this.#o.length;await this.#u();let o=(await this.#s.listMessages(this.#n)).map(c=>({role:c.role,content:c.content,...c.toolCalls!==void 0?{toolCalls:c.toolCalls}:{},...c.toolCallId!==void 0?{toolCallId:c.toolCallId}:{}}));for await(let c of this.#e.runTurn({sessionId:this.#n,recentMessages:o,message:e,...s.signal!==void 0?{signal:s.signal}:{}}))if(await this.#t.append(c),await this.#s.appendTraceEvent({sessionId:this.#n,event:c}),n.push(c),s.onEvent?.(c),c.type==="compaction_triggered"&&c.summary&&await this.#s.appendCompactBoundary({sessionId:this.#n,summary:c.summary,messagesBefore:c.messagesBefore,messagesAfter:c.messagesAfter}),c.type==="turn_complete")for(let a of c.messages)await this.#s.appendMessage({sessionId:this.#n,role:a.role,content:a.content??null,...a.toolCalls!==void 0?{toolCalls:a.toolCalls}:{},...a.toolCallId!==void 0?{toolCallId:a.toolCallId}:{}});let i=n.find(c=>c.type==="assistant_message_created");return{assistantText:i?.type==="assistant_message_created"?i.message.content:"No assistant message was produced.",approvalLines:this.#o.slice(r),todosLines:Ln(n),events:n}}async runSlashCommand(e){if(e==="/trace"){let s=await this.#s.listTraceEvents(this.#n);return Ve(s.map(n=>n.event))}return e==="/config"?Fn(this.#r):e==="/skills"?qt(this.#a):e==="/help"?Ut():[`Unknown slash command: ${e}`]}async#u(){await this.#s.getSession(this.#n)===void 0&&await this.#s.createSession({title:this.#n})}};function Nt(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 oe(t,e,s){let n=[nt(),rt(),at(),ct(),lt(),it(e?.runtime.sandboxed!==void 0?{sandboxed:e.runtime.sandboxed}:void 0),dt(t.fetch),wt()];if(e?.memory.longTermFiles==="write"&&n.push(ht()),e?.memory.longTermFiles==="read-only"||e?.memory.longTermFiles==="write"){let r=e.workspace.root;n.push(pt(r)),n.push(ft(r))}return n.push(yt()),s!==void 0&&s.size>0&&n.push(mt(s)),n}var Le=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 qe(t,e){return t.model.provider==="anthropic"?new ue({...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 de({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 Be(t,e,s){let n=e.sessionsDirectory?{...t,sessions:{directory:e.sessionsDirectory}}:t,r=L(n,e.env);return new se({directory:r,createSessionId:()=>s})}function ie(t){return new le({workspacePromptFiles:["AGENTS.md","SOUL.md","TOOLS.md","IDENTITY.md","HEARTBEAT.md","BOOTSTRAP.md","USER.md","MEMORY.md"]})}function q(){return`session_${crypto.randomUUID()}`}function Ln(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 qt(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}`:"",i=n.permissions!==void 0&&n.permissions.length>0?` [${n.permissions.join(", ")}]`:"";e.push(`[${n.source}]${r}${o} ${n.name}: ${n.description}${i}`),n.source==="user"&&n.trusted===!1&&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 Fn(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 jn(t){if("entries"in t&&Array.isArray(t.entries))return t.entries.map(e=>` ${e.type==="directory"?"\u{1F4C1}":"\u{1F4C4}"} ${e.name}`).join(`
|
|
137
137
|
`);if("content"in t&&typeof t.content=="string"){let e=t.content.split(`
|
|
138
138
|
`);return e.length>30?e.slice(0,30).join(`
|
|
139
139
|
`)+`
|
|
140
140
|
\u2026 (${e.length-30} more lines)`:t.content}if("stdout"in t)return[t.stdout,t.stderr].filter(Boolean).join(`
|
|
141
141
|
`)||"(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 Ve(t){return t.map((e,s)=>`${s+1}. ${Un(e)} (${e.type})`)}function Un(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}]:
|
|
142
|
-
${jn(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 qn(t,e){let s=B(
|
|
142
|
+
${jn(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 qn(t,e){let s=B(Dt(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 je(l.server),r=l;break}catch{}if(r===void 0)return{exitCode:1,stdout:"",stderr:`Web app not built. Run first:
|
|
143
143
|
pnpm --filter @vole/web build
|
|
144
|
-
`};let o=`http://localhost:${t}`,
|
|
144
|
+
`};let o=`http://localhost:${t}`,i=Rt("node",[r.server],{env:{...process.env,PORT:String(t),VOLE_WEB_ROOT:process.cwd()},stdio:"inherit",cwd:r.cwd});if(process.stdout.write(`Vole web dashboard \u2192 ${o}
|
|
145
145
|
`),process.stdout.write(`Press Ctrl+C to stop.
|
|
146
|
-
`),e){let
|
|
147
|
-
`,stderr:""})};process.once("SIGTERM",
|
|
146
|
+
`),e){let l=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",c=process.platform==="win32"?["/c","start",o]:[o];setTimeout(()=>{Rt(l,c,{stdio:"ignore",detached:!0}).unref()},800)}return new Promise(l=>{let c=()=>{i.kill(),l({exitCode:0,stdout:`Web server stopped.
|
|
147
|
+
`,stderr:""})};process.once("SIGTERM",c),process.once("SIGINT",c),i.once("exit",a=>l({exitCode:a??0,stdout:"",stderr:""}))})}async function Bn(){let t=process.argv.slice(2),[e]=t,s=t.find(a=>a!=="--");if((s==="chat"||s===void 0&&process.stdin.isTTY===!0)&&!t.includes("--help")&&!t.includes("-h")&&!t.includes("--fake")&&!t.includes("--fake-interactive")){let{runInkChat:a}=await import("./app.js");await a({args:t,env:process.env});return}let r=wn({input:process.stdin,output:process.stdout}),o=r[Symbol.asyncIterator](),i=B(Dt(import.meta.url)),l="0.0.0";try{let a=await Fe(S(i,"../package.json"),"utf8");l=JSON.parse(a).version}catch{}let c=await vn(t,l,{env:process.env,readLine:async a=>{process.stdout.write(a);let d=await o.next();return d.done?void 0:d.value},write:a=>process.stdout.write(a)});r.close(),process.stdout.write(c.stdout),process.stderr.write(c.stderr),process.exitCode=c.exitCode}Bn();export{xe as a,Ur as b,vn as c,ae as d,Ln as e,qt as f,Fn as g,jn as h,Ve as i};
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
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-
|
|
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-5IEOV6K2.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};
|