@memo-code/memo 0.6.32 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,6 +55,9 @@ memo
55
55
  - Plain mode (non-TTY): `echo "your prompt" | memo` (plain text output; useful for scripts).
56
56
  - Dangerous mode: `memo --dangerous` or `memo -d` (skip tool approvals; use carefully).
57
57
  - Version: `memo --version` or `memo -v`.
58
+ - Startup project guidance: if `AGENTS.md` exists in the startup root, Memo appends it to the system prompt automatically.
59
+ - MCP activation selection: when MCP servers are configured, startup shows a multi-select to activate servers for this run.
60
+ - Session titles: Memo generates a short title from the first user prompt and uses it in history/resume lists.
58
61
 
59
62
  ## Configuration
60
63
 
@@ -89,6 +92,10 @@ args = []
89
92
  type = "streamable_http"
90
93
  url = "https://your-mcp-server.com/mcp"
91
94
  # headers = { Authorization = "Bearer xxx" }
95
+
96
+ # Optional: default active MCP servers at startup
97
+ active_mcp_servers = ["local_tools", "remote"]
98
+ # Optional: use [] to start with no MCP servers active
92
99
  ```
93
100
 
94
101
  You can also manage MCP configs via CLI (aligned with Codex CLI style):
@@ -112,7 +119,7 @@ memo mcp remove remote
112
119
 
113
120
  - `exec_command` / `write_stdin`: execute shell commands (default shell family)
114
121
  - `shell` / `shell_command`: compatibility shell variants (feature/env controlled)
115
- - `apply_patch`: structured file edits
122
+ - `apply_patch`: direct string-replacement edits (single or batch)
116
123
  - `read_file` / `list_dir` / `grep_files`: file read and retrieval
117
124
  - `list_mcp_resources` / `list_mcp_resource_templates` / `read_mcp_resource`: MCP resource access
118
125
  - `update_plan`: structured task plan updates
@@ -128,9 +135,10 @@ Memo includes a tool-approval mechanism to reduce risky operations:
128
135
  - **Auto-approve**: safe read tools (`read_file`, `list_dir`, `grep_files`, `webfetch`, `get_memory`, etc.)
129
136
  - **Manual approval**: risky tools (`apply_patch`, `exec_command`, etc.)
130
137
  - **Approval options**:
131
- - `once`: approve current operation only
132
- - `session`: approve all matching operations for this session
133
- - `deny`: reject operation
138
+ - `once`: approve this tool until current turn ends
139
+ - `session`: approve this tool for the current session
140
+ - `deny`: deny this tool until you re-approve it
141
+ - **Approval reminders (TUI)**: when approval is required, Memo rings the terminal bell and attempts a desktop notification.
134
142
  - **Dangerous mode**: `--dangerous` skips all approvals (trusted scenarios only)
135
143
 
136
144
  ## Session History
@@ -200,6 +208,7 @@ memo-cli/
200
208
  - `resume` history: type `resume` to list and load past sessions for current directory.
201
209
  - Exit and clear: `exit` / `/exit`, `Ctrl+L` for new session, `Esc Esc` to cancel current run or clear input.
202
210
  - **Tool approval**: risky operations open an approval dialog with `once`/`session`/`deny`.
211
+ - **Approval reminder**: risky approval prompts ring a bell and attempt a desktop notification in interactive TUI.
203
212
 
204
213
  > Session logs are written only when a session contains user messages, to avoid empty files.
205
214
 
@@ -213,7 +222,7 @@ memo-cli/
213
222
 
214
223
  ## Related Docs
215
224
 
216
- - [User Guide](./web/content/docs/README.md) - User-facing docs by module
225
+ - [User Guide](./site/content/docs/README.md) - User-facing docs by module
217
226
  - [Core Architecture](./docs/core.md) - Core implementation details
218
227
  - [TUI Rewrite Design](./docs/tui-rewrite-design.md) - Codex-aligned TUI architecture and migration notes
219
228
  - [CLI Adaptation History](./docs/cli-update.md) - Historical migration notes (Tool Use API)
package/README.zh.md CHANGED
@@ -51,6 +51,9 @@ memo
51
51
  - 非交互纯文本模式(非 TTY):`echo "你的问题" | memo`(适合脚本)。
52
52
  - 危险模式:`memo --dangerous` 或 `memo -d`(跳过工具审批,谨慎使用)。
53
53
  - 查看版本:`memo --version` 或 `memo -v`。
54
+ - 启动目录约定:若启动根目录存在 `AGENTS.md`,Memo 会自动将其拼接进系统提示词。
55
+ - MCP 启动选择:当配置了 MCP server 时,启动会弹出多选以决定本次会话激活哪些 server。
56
+ - 会话标题:Memo 会基于首条用户输入生成简短标题,并在历史/恢复列表中展示。
54
57
 
55
58
  ## 配置文件
56
59
 
@@ -85,6 +88,10 @@ args = []
85
88
  type = "streamable_http"
86
89
  url = "https://your-mcp-server.com/mcp"
87
90
  # headers = { Authorization = "Bearer xxx" }
91
+
92
+ # 可选:启动时默认激活的 MCP server
93
+ active_mcp_servers = ["local_tools", "remote"]
94
+ # 可选:设为 [] 表示启动时不激活任何 MCP server
88
95
  ```
89
96
 
90
97
  也可以通过 CLI 管理 MCP 配置(对齐 Codex CLI 风格):
@@ -124,9 +131,10 @@ memo mcp remove remote
124
131
  - **自动审批**:读类工具(如 `read_file`、`list_dir`、`grep_files`、`webfetch` 等)
125
132
  - **手动审批**:高风险工具(如 `apply_patch`、`exec_command`、`write_stdin`)
126
133
  - **审批选项**:
127
- - `once`:仅批准当前操作
128
- - `session`:批准本次会话中的所有同类操作
129
- - `deny`:拒绝操作
134
+ - `once`:批准该工具直到当前 turn 结束
135
+ - `session`:在本次会话内批准该工具
136
+ - `deny`:拒绝该工具,直到再次批准
137
+ - **审批提醒(TUI)**:当需要审批时,Memo 会触发终端提示音,并尝试发送桌面通知。
130
138
  - **危险模式**:`--dangerous` 参数跳过所有审批(仅限信任场景)
131
139
 
132
140
  ## 会话历史
@@ -196,6 +204,7 @@ memo-cli/
196
204
  - `resume` 历史:输入 `resume` 查看并加载本目录的历史会话。
197
205
  - 退出与清屏:`exit` / `/exit`,`Ctrl+L` 新会话,`Esc Esc` 取消运行或清空输入。
198
206
  - **工具审批**:危险操作会弹出审批对话框,可选择 `once`/`session`/`deny`。
207
+ - **审批提醒**:交互式 TUI 中出现审批请求时,会触发提示音并尝试发送桌面通知。
199
208
 
200
209
  > 仅当会话包含用户消息时才写入 `sessions/` JSONL 日志,避免空会话文件。
201
210
 
@@ -209,7 +218,7 @@ memo-cli/
209
218
 
210
219
  ## 相关文档
211
220
 
212
- - [用户指南](./web/content/docs/README.md) - 面向使用者的分模块说明
221
+ - [用户指南](./site/content/docs/README.md) - 面向使用者的分模块说明
213
222
  - [Core 架构](./docs/core.md) - 核心实现详解
214
223
  - [TUI 重构设计](./docs/tui-rewrite-design.md) - 对标 Codex 的 TUI 架构与迁移说明
215
224
  - [CLI 适配更新](./docs/cli-update.md) - Tool Use API 迁移说明
package/dist/index.js CHANGED
@@ -1,70 +1,101 @@
1
1
  #!/usr/bin/env node
2
- var Rr=Object.create;var mn=Object.defineProperty;var Ir=Object.getOwnPropertyDescriptor;var Or=Object.getOwnPropertyNames;var Lr=Object.getPrototypeOf,$r=Object.prototype.hasOwnProperty;var Nr=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Dr=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Or(e))!$r.call(t,s)&&s!==n&&mn(t,s,{get:()=>e[s],enumerable:!(o=Ir(e,s))||o.enumerable});return t};var Ur=(t,e,n)=>(n=t!=null?Rr(Lr(t)):{},Dr(e||!t||!t.__esModule?mn(n,"default",{value:t,enumerable:!0}):n,t));var Pn=Nr((su,Mn)=>{"use strict";function xn(t){return Array.isArray(t)?t:[t]}var $t="",Cn=" ",Ot="\\",ms=/^\s+$/,ds=/(?:[^\\]|^)\\$/,fs=/^\\!/,gs=/^\\#/,hs=/\r?\n/g,ys=/^\.*\/|^\.+$/,Lt="/",wn="node-ignore";typeof Symbol<"u"&&(wn=Symbol.for("node-ignore"));var En=wn,Ts=(t,e,n)=>Object.defineProperty(t,e,{value:n}),_s=/([0-z])-([0-z])/g,bn=()=>!1,Ss=t=>t.replace(_s,(e,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?e:$t),vs=t=>{let{length:e}=t;return t.slice(0,e-e%2)},xs=[[/^\uFEFF/,()=>$t],[/((?:\\\\)*?)(\\?\s+)$/,(t,e,n)=>e+(n.indexOf("\\")===0?Cn:$t)],[/(\\+?)\s/g,(t,e)=>{let{length:n}=e;return e.slice(0,n-n%2)+Cn}],[/[\\$.|*+(){^]/g,t=>`\\${t}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(t,e,n)=>e+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(t,e,n)=>{let o=n.replace(/\\\*/g,"[^\\/]*");return e+o}],[/\\\\\\(?=[$.|*+(){^])/g,()=>Ot],[/\\\\/g,()=>Ot],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(t,e,n,o,s)=>e===Ot?`\\[${n}${vs(o)}${s}`:s==="]"&&o.length%2===0?`[${Ss(n)}${o}]`:"[]"],[/(?:[^*])$/,t=>/\/$/.test(t)?`${t}$`:`${t}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(t,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`]],An=Object.create(null),Cs=(t,e)=>{let n=An[t];return n||(n=xs.reduce((o,[s,r])=>o.replace(s,r.bind(t)),t),An[t]=n),e?new RegExp(n,"i"):new RegExp(n)},Ut=t=>typeof t=="string",Es=t=>t&&Ut(t)&&!ms.test(t)&&!ds.test(t)&&t.indexOf("#")!==0,As=t=>t.split(hs),Nt=class{constructor(e,n,o,s){this.origin=e,this.pattern=n,this.negative=o,this.regex=s}},ws=(t,e)=>{let n=t,o=!1;t.indexOf("!")===0&&(o=!0,t=t.substr(1)),t=t.replace(fs,"!").replace(gs,"#");let s=Cs(t,e);return new Nt(n,t,o,s)},bs=(t,e)=>{throw new e(t)},ye=(t,e,n)=>Ut(t)?t?ye.isNotRelative(t)?n(`path should be a \`path.relative()\`d string, but got "${e}"`,RangeError):!0:n("path must not be empty",TypeError):n(`path must be a string, but got \`${e}\``,TypeError),kn=t=>ys.test(t);ye.isNotRelative=kn;ye.convert=t=>t;var Dt=class{constructor({ignorecase:e=!0,ignoreCase:n=e,allowRelativePaths:o=!1}={}){Ts(this,En,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=o,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[En]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(Es(e)){let n=ws(e,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(e){return this._added=!1,xn(Ut(e)?As(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,n){let o=!1,s=!1;return this._rules.forEach(r=>{let{negative:i}=r;if(s===i&&o!==s||i&&!o&&!s&&!n)return;r.regex.test(e)&&(o=!i,s=i)}),{ignored:o,unignored:s}}_test(e,n,o,s){let r=e&&ye.convert(e);return ye(r,e,this._allowRelativePaths?bn:bs),this._t(r,n,o,s)}_t(e,n,o,s){if(e in n)return n[e];if(s||(s=e.split(Lt)),s.pop(),!s.length)return n[e]=this._testOne(e,o);let r=this._t(s.join(Lt)+Lt,n,o,s);return n[e]=r.ignored?r:this._testOne(e,o)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return xn(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},rt=t=>new Dt(t),ks=t=>ye(t&&ye.convert(t),t,bn);rt.isPathValid=ks;rt.default=rt;Mn.exports=rt;if(typeof process<"u"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let t=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");ye.convert=t;let e=/^[a-z]:\//i;ye.isNotRelative=n=>e.test(n)||kn(n)}});import{randomUUID as _r}from"crypto";import{createInterface as fc}from"readline/promises";import{stdin as gc,stdout as hc}from"process";import{render as yc}from"ink";import Hr from"os";import{readFile as Fr}from"fs/promises";import{join as jr,dirname as Br}from"path";import{fileURLToPath as Wr}from"url";var zr=/{{\s*([\w.-]+)\s*}}/g;function qr(t,e){return t.replace(zr,(n,o)=>e[o]??"")}function Kr(){try{return Hr.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}async function dn(){let t=Br(Wr(import.meta.url)),e=jr(t,"prompt.md"),n=await Fr(e,"utf-8"),o={date:new Date().toISOString(),user:Kr(),pwd:process.cwd()};return qr(n,o)}import{appendFile as Vr,mkdir as Gr}from"fs/promises";import{dirname as Xr}from"path";var ot=class{constructor(e){this.filePath=e}ready=!1;async append(e){this.ready||(await Gr(Xr(this.filePath),{recursive:!0}),this.ready=!0),await Vr(this.filePath,`${JSON.stringify(e)}
3
- `,"utf8")}async flush(){return Promise.resolve()}};function fn(t){return{ts:new Date().toISOString(),sessionId:t.sessionId,turn:t.turn,step:t.step,type:t.type,content:t.content,role:t.role,meta:t.meta}}import{z as ge}from"zod";function O(t){let{inputSchema:e,execute:n,...o}=t,s=e.toJSONSchema?.(),{$schema:r,...i}=s??{};return{...o,source:"native",inputSchema:i,validateInput:l=>{let a=e.safeParse(l);if(!a.success){let c=a.error.issues[0]?.message??"invalid input";return{ok:!1,error:`${t.name} invalid input: ${c}`}}return{ok:!0,data:a.data}},execute:n}}function p(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}import{spawn as Jr}from"child_process";import{EventEmitter as Yr}from"events";import{resolve as Zr}from"path";var Qr=1e4,es=250,ts=2e3,gn=64;function ns(t){return Math.ceil(t.length/4)}function os(){return Math.random().toString(16).slice(2)||String(Date.now())}function rs(t){let e=t.login,n=t.shell?.trim();if(process.platform==="win32"){let s=n||"powershell.exe";return s.toLowerCase().includes("powershell")?{file:s,args:["-NoProfile","-Command",t.cmd]}:{file:s,args:[e?"-lc":"-c",t.cmd]}}return{file:n||process.env.SHELL||"/bin/bash",args:[e?"-lc":"-c",t.cmd]}}function ss(t,e){let o=(typeof e=="number"&&e>0?Math.floor(e):ts)*4,s=ns(t);return t.length<=o?{output:t,originalTokenCount:s}:{output:t.slice(0,o),originalTokenCount:s}}function is(t){let e=[];return e.push(`Chunk ID: ${t.chunkId}`),e.push(`Wall time: ${t.wallTimeSeconds.toFixed(4)} seconds`),t.exitCode!==null?e.push(`Process exited with code ${t.exitCode}`):e.push(`Process running with session ID ${t.sessionId}`),e.push(`Original token count: ${t.originalTokenCount}`),e.push("Output:"),e.push(t.output),e.join(`
4
- `)}function hn(t,e){return typeof t!="number"||Number.isNaN(t)?e:t<0?0:Math.floor(t)}async function yn(t,e){e<=0||t.exited||await Promise.race([new Promise(n=>{let o=setTimeout(()=>{r(),n()},e),s=()=>{clearTimeout(o),r(),n()},r=()=>{t.eventBus.off("exit",s)};t.eventBus.on("exit",s)})])}var Pt=class{sessions=new Map;nextId=1;cleanupSessions(){if(this.sessions.size<=gn)return;let e=Array.from(this.sessions.values()).filter(n=>n.exited).sort((n,o)=>n.startedAtMs-o.startedAtMs);for(let n of e){if(this.sessions.size<=gn)break;this.sessions.delete(n.id)}}async start(e){let n=e.cmd.trim();if(!n)throw new Error("cmd must not be empty");let o=this.nextId++,s=Date.now(),r=rs({cmd:n,shell:e.shell,login:e.login!==!1}),i=e.workdir?.trim()?Zr(process.cwd(),e.workdir.trim()):process.cwd(),l=Jr(r.file,r.args,{cwd:i,env:process.env,stdio:["pipe","pipe","pipe"],shell:!1}),a={id:o,output:"",readOffset:0,startedAtMs:s,exited:!1,exitCode:null,eventBus:new Yr,proc:l},c=(m,d)=>{let h=typeof d=="string"?d:d.toString("utf8");a.output+=m?`${m}${h}`:h,a.eventBus.emit("output")};l.stdout?.on("data",m=>c("",m)),l.stderr?.on("data",m=>c("",m)),l.on("error",m=>{a.output+=`
5
- [exec error] ${m.message}`,a.eventBus.emit("output")}),l.on("close",m=>{a.exited=!0,a.exitCode=typeof m=="number"?m:-1,a.eventBus.emit("exit")}),this.sessions.set(o,a),this.cleanupSessions();let u=hn(e.yield_time_ms,Qr);return await yn(a,u),this.buildResponseText(a,e.max_output_tokens)}async write(e){let n=this.sessions.get(e.session_id);if(!n)throw new Error(`session_id ${e.session_id} not found`);!n.exited&&e.chars&&e.chars.length>0&&n.proc.stdin?.write(e.chars);let o=hn(e.yield_time_ms,es);return await yn(n,o),this.buildResponseText(n,e.max_output_tokens)}buildResponseText(e,n){let o=e.output.slice(e.readOffset);e.readOffset=e.output.length;let s=ss(o,n),r={sessionId:e.id,chunkId:os(),wallTimeSeconds:(Date.now()-e.startedAtMs)/1e3,exitCode:e.exited?e.exitCode:null,output:s.output,originalTokenCount:s.originalTokenCount};return is(r)}},Tn=new Pt;async function Oe(t){return Tn.start(t)}async function _n(t){return Tn.write(t)}var as=ge.object({command:ge.array(ge.string().min(1)).min(1,"command \u4E0D\u80FD\u4E3A\u7A7A"),workdir:ge.string().optional(),timeout_ms:ge.number().int().positive().optional(),sandbox_permissions:ge.enum(["use_default","require_escalated"]).optional(),justification:ge.string().optional(),prefix_rule:ge.array(ge.string().min(1)).optional()}).strict();function ls(t){return t.map(e=>/^[A-Za-z0-9_./:@%+-]+$/.test(e)?e:JSON.stringify(e)).join(" ")}var Sn=O({name:"shell",description:"Runs a shell command (argv form) and returns output.",inputSchema:as,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:t,workdir:e,timeout_ms:n})=>{try{let o=await Oe({cmd:ls(t),workdir:e,login:!1,yield_time_ms:n});return p(o)}catch(o){return p(`shell failed: ${o.message}`,!0)}}});import{z as he}from"zod";var cs=he.object({command:he.string().min(1,"command \u4E0D\u80FD\u4E3A\u7A7A"),workdir:he.string().optional(),login:he.boolean().optional(),timeout_ms:he.number().int().positive().optional(),sandbox_permissions:he.enum(["use_default","require_escalated"]).optional(),justification:he.string().optional(),prefix_rule:he.array(he.string().min(1)).optional()}).strict(),vn=O({name:"shell_command",description:"Runs a shell command and returns its output. Always set workdir when possible.",inputSchema:cs,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:t,workdir:e,login:n,timeout_ms:o})=>{try{let s=await Oe({cmd:t,workdir:e,login:n,yield_time_ms:o});return p(s)}catch(s){return p(`shell_command failed: ${s.message}`,!0)}}});import{z as oe}from"zod";var us=oe.object({cmd:oe.string().min(1,"cmd \u4E0D\u80FD\u4E3A\u7A7A"),workdir:oe.string().optional(),shell:oe.string().optional(),login:oe.boolean().optional(),tty:oe.boolean().optional(),yield_time_ms:oe.number().int().nonnegative().optional(),max_output_tokens:oe.number().int().positive().optional(),sandbox_permissions:oe.enum(["use_default","require_escalated"]).optional(),justification:oe.string().optional(),prefix_rule:oe.array(oe.string().min(1)).optional()}).strict(),Rt=O({name:"exec_command",description:"Runs a command in a PTY-like managed session, returning output or a session ID for ongoing interaction.",inputSchema:us,supportsParallelToolCalls:!0,isMutating:!0,execute:async t=>{try{let e=await Oe(t);return p(e)}catch(e){return p(`exec_command failed: ${e.message}`,!0)}}});import{z as Be}from"zod";var ps=Be.object({session_id:Be.number().int().positive(),chars:Be.string().optional(),yield_time_ms:Be.number().int().nonnegative().optional(),max_output_tokens:Be.number().int().positive().optional()}).strict(),It=O({name:"write_stdin",description:"Writes characters to an existing unified exec session and returns recent output.",inputSchema:ps,supportsParallelToolCalls:!1,isMutating:!0,execute:async t=>{try{let e=await _n(t);return p(e)}catch(e){return p(`write_stdin failed: ${e.message}`,!0)}}});import{mkdir as On,readFile as Hs,rm as Ln,writeFile as Ht}from"fs/promises";import{dirname as $n}from"path";import{z as Nn}from"zod";var $s=Ur(Pn(),1);import{normalize as Ms,resolve as Ps,dirname as au,join as Rs,relative as Is,isAbsolute as Os}from"path";import{homedir as Ls}from"os";import{existsSync as uu,statSync as pu}from"fs";import{readFile as du}from"fs/promises";function re(t){return Ms(Ps(t))}function Ns(t,e){let n=Is(e,t);return n===""||!n.startsWith("..")&&!Os(n)}function Ds(){let t=process.env.MEMO_SANDBOX_WRITABLE_ROOTS?.trim();return t?t.split(",").map(e=>e.trim()).filter(Boolean).map(e=>re(e)):[]}function Rn(){let t=new Set;t.add(re(process.cwd()));let e=process.env.MEMO_HOME?.trim()||Rs(Ls(),".memo");t.add(re(e));for(let n of Ds())t.add(n);return Array.from(t)}function Us(t){return Rn().some(n=>Ns(t,n))}function In(t){if(Us(t))return null;let e=Rn();return`sandbox \u62D2\u7EDD\u5199\u5165: ${t} \u4E0D\u5728\u5141\u8BB8\u76EE\u5F55\u5185 (${e.join(", ")})`}var Fs=Nn.object({input:Nn.string().min(1,"patch input \u4E0D\u80FD\u4E3A\u7A7A")}).strict();function js(t){let e=t.replace(/\r/g,"").split(`
6
- `);if(e[0]!=="*** Begin Patch")throw new Error("patch must start with *** Begin Patch");let n=[],o=1;for(;o<e.length;){let s=e[o]??"";if(s==="*** End Patch")break;if(!s){o+=1;continue}if(s.startsWith("*** Add File: ")){let r=s.slice(14).trim();if(!r)throw new Error("Add File requires a path");o+=1;let i=[];for(;o<e.length;){let l=e[o];if(l===void 0||l.startsWith("*** "))break;if(!l.startsWith("+"))throw new Error("Add File lines must start with +");i.push(l.slice(1)),o+=1}n.push({type:"add",file:r,lines:i});continue}if(s.startsWith("*** Delete File: ")){let r=s.slice(17).trim();if(!r)throw new Error("Delete File requires a path");n.push({type:"delete",file:r}),o+=1;continue}if(s.startsWith("*** Update File: ")){let r=s.slice(17).trim();if(!r)throw new Error("Update File requires a path");o+=1;let i,l=e[o];l&&l.startsWith("*** Move to: ")&&(i=l.slice(13).trim(),o+=1);let a=[],c=[];for(;o<e.length;){let u=e[o];if(u===void 0||u.startsWith("*** "))break;if(u.startsWith("@@")){c.length>0&&(a.push(c),c=[]),o+=1;continue}if(u==="*** End of File"){o+=1;continue}if(u.startsWith("+")||u.startsWith("-")||u.startsWith(" ")){c.push(u),o+=1;continue}throw new Error(`Unexpected patch line: ${u}`)}if(c.length>0&&a.push(c),a.length===0)throw new Error(`Update File ${r} has no hunks`);n.push({type:"update",file:r,moveTo:i,hunks:a});continue}throw new Error(`Unexpected patch marker: ${s}`)}if(n.length===0)throw new Error("patch contains no operations");return n}function Bs(t,e){let n=e.filter(r=>r.startsWith(" ")||r.startsWith("-")).map(r=>r.slice(1)).join(`
7
- `),o=e.filter(r=>r.startsWith(" ")||r.startsWith("+")).map(r=>r.slice(1)).join(`
8
- `);if(!n){if(!o)return t;if(!t)return o;let r=t.endsWith(`
9
- `)?"":`
10
- `;return`${t}${r}${o}`}let s=t.indexOf(n);if(s<0)throw new Error("patch hunk context not found in target file");return`${t.slice(0,s)}${o}${t.slice(s+n.length)}`}function st(t){let e=In(t);if(e)throw new Error(e)}var Dn=O({name:"apply_patch",description:"Apply a structured patch with Add/Update/Delete operations and hunk-based replacements.",inputSchema:Fs,supportsParallelToolCalls:!1,isMutating:!0,execute:async t=>{try{let e=js(t.input);for(let n of e){if(n.type==="add"){let r=re(n.file);st(r),await On($n(r),{recursive:!0}),await Ht(r,n.lines.join(`
11
- `),"utf8");continue}if(n.type==="delete"){let r=re(n.file);st(r),await Ln(r);continue}let o=re(n.file);st(o);let s=await Hs(o,"utf8");for(let r of n.hunks)s=Bs(s,r);if(n.moveTo){let r=re(n.moveTo);st(r),await On($n(r),{recursive:!0}),await Ht(r,s,"utf8"),r!==o&&await Ln(o)}else await Ht(o,s,"utf8")}return p(`apply_patch succeeded (${e.length} operations)`)}catch(e){return p(`apply_patch failed: ${e.message}`,!0)}}});import{readFile as Ws}from"fs/promises";import{z as ae}from"zod";var Un=500,Hn=200,zs=ae.object({file_path:ae.string().min(1),offset:ae.number().int().positive().optional(),limit:ae.number().int().positive().optional(),mode:ae.enum(["slice","indentation"]).optional(),indentation:ae.object({anchor_line:ae.number().int().positive().optional(),max_levels:ae.number().int().nonnegative().optional(),include_siblings:ae.boolean().optional(),include_header:ae.boolean().optional(),max_lines:ae.number().int().positive().optional()}).strict().optional()}).strict();function qs(t){return t.length<=Un?t:t.slice(0,Un)}function Ks(t){let e=0;for(let n of t)if(n===" ")e+=1;else if(n===" ")e+=4;else break;return e}function Vs(t){return t.split(/\r?\n/).map((n,o)=>({line:o+1,text:qs(n),indent:Ks(n)}))}function Gs(t){return t.map(e=>`L${e.line}: ${e.text}`).join(`
12
- `)}function Xs(t,e,n){let o=e-1;if(o>=t.length)throw new Error("offset exceeds file length");return t.slice(o,o+n)}function Js(t,e){let n=e.offset??1,o=e.limit??Hn,s=e.indentation,r=s?.anchor_line??n;if(r<=0||r>t.length)throw new Error("anchor_line exceeds file length");let i=t[r-1];if(!i)throw new Error("anchor_line exceeds file length");let l=s?.max_levels??0,a=s?.include_siblings??!0,c=s?.include_header??!0,u=s?.max_lines??o,m=Math.max(1,Math.min(o,u)),d=l===0?0:Math.max(0,i.indent-l*4),h=r-1,w=r-1;for(;h-1>=0;){let f=t[h-1];if(!f)break;let I=/^\s*(#|\/\/|--)/.test(f.text),S=f.text.trim().length===0;if(f.indent<d||!a&&f.indent===d&&!I&&!S||!c&&(I||S)&&f.indent<i.indent||(h-=1,w-h+1>=m))break}for(;w+1<t.length&&w-h+1<m;){let f=t[w+1];if(!f||f.indent<d||!a&&f.indent===d)break;w+=1}return t.slice(h,w+1)}var Fn=O({name:"read_file",description:"Reads a local file with 1-indexed line numbers, supporting slice and indentation-aware block modes.",inputSchema:zs,supportsParallelToolCalls:!0,isMutating:!1,execute:async t=>{let e=t.offset??1,n=t.limit??Hn;if(e<=0)return p("offset must be a 1-indexed line number",!0);if(n<=0)return p("limit must be greater than zero",!0);let o=t.file_path.trim();if(!o.startsWith("/"))return p("file_path must be an absolute path",!0);let s=re(o);try{let r=await Ws(s,"utf8"),i=Vs(r);if(i.length===0)return p("");let a=(t.mode??"slice")==="indentation"?Js(i,t):Xs(i,e,n);return p(Gs(a))}catch(r){return p(`read_file failed: ${r.message}`,!0)}}});import{readdir as Ys,lstat as Zs}from"fs/promises";import{join as Qs}from"path";import{z as We}from"zod";var ei=1,ti=25,ni=2,oi=We.object({dir_path:We.string().min(1),offset:We.number().int().positive().optional(),limit:We.number().int().positive().optional(),depth:We.number().int().positive().optional()}).strict();function ri(t){let e=" ".repeat(t.displayDepth*2),n="";t.kind==="dir"&&(n="/"),t.kind==="symlink"&&(n="@"),t.kind==="other"&&(n="?");let o=t.path.split("/"),s=o[o.length-1]??t.path;return`${e}${s}${n}`}var jn=O({name:"list_dir",description:"Lists entries in a local directory with 1-indexed entry numbers and simple type labels.",inputSchema:oi,supportsParallelToolCalls:!0,isMutating:!1,execute:async t=>{let e=t.offset??ei,n=t.limit??ti,o=t.depth??ni;if(e<=0)return p("offset must be a 1-indexed entry number",!0);if(n<=0)return p("limit must be greater than zero",!0);if(o<=0)return p("depth must be greater than zero",!0);let s=t.dir_path.trim();if(!s.startsWith("/"))return p("dir_path must be an absolute path",!0);let r=re(s);try{let i=[{absPath:r,depth:o,displayDepth:0}],l=[];for(;i.length>0;){let m=i.shift();if(!m)continue;let d=await Ys(m.absPath);d.sort((h,w)=>h.localeCompare(w));for(let h of d){let w=Qs(m.absPath,h),f=await Zs(w),I=f.isSymbolicLink()?"symlink":f.isDirectory()?"dir":f.isFile()?"file":"other";l.push({path:w,displayDepth:m.displayDepth,kind:I}),I==="dir"&&m.depth>1&&i.push({absPath:w,depth:m.depth-1,displayDepth:m.displayDepth+1})}}if(l.length===0)return p(`Absolute path: ${r}`);let a=e-1;if(a>=l.length)return p("offset exceeds directory entry count",!0);let c=l.slice(a,a+n),u=[`Absolute path: ${r}`,...c.map(ri)];return a+n<l.length&&u.push(`More than ${n} entries found`),p(u.join(`
13
- `))}catch(i){return p(`list_dir failed: ${i.message}`,!0)}}});import{spawn as si}from"child_process";import{resolve as ii}from"path";import{z as ze}from"zod";var ai=100,li=2e3,ci=3e4,ui=ze.object({pattern:ze.string().min(1),include:ze.string().optional(),path:ze.string().optional(),limit:ze.number().int().positive().optional()}).strict();function pi(t){return new Promise((e,n)=>{let o=["--files-with-matches","--sortr=modified","--regexp",t.pattern,"--no-messages"];t.include?.trim()&&o.push("--glob",t.include.trim()),o.push("--",t.searchPath);let s=si("rg",o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),r=[],i=[];s.stdout?.setEncoding("utf8"),s.stderr?.setEncoding("utf8"),s.stdout?.on("data",a=>r.push(a)),s.stderr?.on("data",a=>i.push(a));let l=setTimeout(()=>{s.kill("SIGTERM"),n(new Error("rg timed out after 30 seconds"))},ci);s.on("error",a=>{clearTimeout(l),n(a)}),s.on("close",a=>{clearTimeout(l),e({exitCode:typeof a=="number"?a:-1,stdout:r.join(""),stderr:i.join("")})})})}var Bn=O({name:"grep_files",description:"Finds files whose contents match the pattern and lists them by modification time.",inputSchema:ui,supportsParallelToolCalls:!0,isMutating:!1,execute:async t=>{let e=t.pattern.trim();if(!e)return p("pattern must not be empty",!0);let n=Math.min(t.limit??ai,li),o=t.path?.trim()?ii(process.cwd(),t.path.trim()):process.cwd();try{let s=await pi({pattern:e,include:t.include,searchPath:o,cwd:process.cwd(),limit:n});if(s.exitCode===1)return p("No matches found.");if(s.exitCode!==0)return p(`rg failed: ${s.stderr||s.stdout}`,!0);let r=s.stdout.split(/\r?\n/).map(i=>i.trim()).filter(Boolean).slice(0,n);return r.length===0?p("No matches found."):p(r.join(`
14
- `))}catch(s){return p(`grep_files failed: ${s.message}`,!0)}}});import{z as Te}from"zod";var Wn=null;function Ft(t){Wn=t}function zn(){return Wn}var mi=Te.object({server:Te.string().optional(),cursor:Te.string().optional()}).strict(),di=Te.object({server:Te.string().optional(),cursor:Te.string().optional()}).strict(),fi=Te.object({server:Te.string().min(1),uri:Te.string().min(1)}).strict();function jt(){let t=zn();if(!t)throw new Error("MCP pool is not initialized");return t}var qn=O({name:"list_mcp_resources",description:"Lists resources provided by MCP servers. Prefer resources over web search when possible.",inputSchema:mi,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:t,cursor:e})=>{try{let n=jt();if(t?.trim()){let r=n.get(t.trim());if(!r)return p(`MCP server not found: ${t}`,!0);let i=await r.client.listResources(e?{cursor:e}:void 0);return p(JSON.stringify({server:r.name,resources:i.resources,nextCursor:i.nextCursor},null,2))}if(e)return p("cursor is only supported when server is specified",!0);let o=n.getAll().sort((r,i)=>r.name.localeCompare(i.name)),s=[];for(let r of o){let i=await r.client.listResources();for(let l of i.resources)s.push({server:r.name,...l})}return p(JSON.stringify({resources:s},null,2))}catch(n){return p(`list_mcp_resources failed: ${n.message}`,!0)}}}),Kn=O({name:"list_mcp_resource_templates",description:"Lists resource templates provided by MCP servers. Prefer resource templates over web search when possible.",inputSchema:di,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:t,cursor:e})=>{try{let n=jt();if(t?.trim()){let r=n.get(t.trim());if(!r)return p(`MCP server not found: ${t}`,!0);let i=await r.client.listResourceTemplates(e?{cursor:e}:void 0);return p(JSON.stringify({server:r.name,resourceTemplates:i.resourceTemplates,nextCursor:i.nextCursor},null,2))}if(e)return p("cursor is only supported when server is specified",!0);let o=n.getAll().sort((r,i)=>r.name.localeCompare(i.name)),s=[];for(let r of o){let i=await r.client.listResourceTemplates();for(let l of i.resourceTemplates)s.push({server:r.name,...l})}return p(JSON.stringify({resourceTemplates:s},null,2))}catch(n){return p(`list_mcp_resource_templates failed: ${n.message}`,!0)}}}),Vn=O({name:"read_mcp_resource",description:"Read a specific resource from an MCP server given the server name and resource URI.",inputSchema:fi,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:t,uri:e})=>{try{let o=jt().get(t);if(!o)return p(`MCP server not found: ${t}`,!0);let s=await o.client.readResource({uri:e});return p(JSON.stringify({server:t,uri:e,...s},null,2))}catch(n){return p(`read_mcp_resource failed: ${n.message}`,!0)}}});import{z as Le}from"zod";var gi=Le.object({step:Le.string().min(1),status:Le.enum(["pending","in_progress","completed"])}).strict(),hi=Le.object({explanation:Le.string().optional(),plan:Le.array(gi).min(1)}).strict(),Gn=[],Xn=O({name:"update_plan",description:"Updates the task plan. At most one step can be in_progress at a time.",inputSchema:hi,supportsParallelToolCalls:!1,isMutating:!1,execute:async({explanation:t,plan:e})=>e.filter(o=>o.status==="in_progress").length>1?p("At most one step can be in_progress at a time",!0):(Gn=e,p(JSON.stringify({message:"Plan updated",explanation:t,plan:Gn},null,2)))});import{readFile as yi}from"fs/promises";import{homedir as Ti}from"os";import{join as Jn}from"path";import{z as Yn}from"zod";var _i=Yn.object({memory_id:Yn.string().min(1)}).strict();function Si(){let t=process.env.MEMO_HOME?.trim()||Jn(Ti(),".memo");return Jn(t,"Agents.md")}var Zn=O({name:"get_memory",description:"Loads the stored memory payload for a memory_id.",inputSchema:_i,supportsParallelToolCalls:!0,isMutating:!1,execute:async({memory_id:t})=>{try{let e=Si(),n=await yi(e,"utf8");return p(JSON.stringify({memory_id:t,memory_summary:n},null,2))}catch{return p(`memory not found for memory_id=${t}`,!0)}}});import{z as Qn}from"zod";var vi=Qn.object({url:Qn.string().min(1)}).strict(),eo=1e4,qe=512e3,Bt=4e3,xi=new Set(["http:","https:","data:"]),Ci=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,Ei=/<\s*(br|hr)\s*\/?>/gi,Ai=/<\s*li[^>]*>/gi,wi=/<[^>]+>/g,bi=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,ki=t=>t.replace(/&nbsp;/gi," ").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&amp;/gi,"&").replace(/&quot;/gi,'"').replace(/&#39;/g,"'").replace(/&#(x?[0-9a-fA-F]+);/g,(o,s)=>{try{let r=s.startsWith("x")||s.startsWith("X")?parseInt(s.slice(1),16):parseInt(s,10);return Number.isFinite(r)?String.fromCharCode(r):""}catch{return""}}),Mi=t=>{let o=t.replace(bi," ").replace(Ai,"- ").replace(Ei,`
15
- `).replace(Ci,`
16
- `).replace(wi," "),r=ki(o).replace(/\r/g,"").split(`
17
- `).map(l=>l.trim().replace(/[ \t]{2,}/g," "));return r.filter((l,a)=>l.length>0||a>0&&(r[a-1]?.length??0)>0).join(`
18
- `).trim()},Pi=t=>t.replace(/\s+/g," ").trim(),to=O({name:"webfetch",description:"HTTP GET \u8BF7\u6C42\uFF0C\u8FD4\u56DE\u5904\u7406\u540E\u7684\u7EAF\u6587\u672C\u6B63\u6587\uFF08\u81EA\u52A8\u5265\u79BB HTML \u6807\u7B7E\uFF09",inputSchema:vi,supportsParallelToolCalls:!0,isMutating:!1,execute:async t=>{let e;try{e=new URL(t.url)}catch{return p(`\u65E0\u6548 URL: ${t.url}`,!0)}if(!xi.has(e.protocol))return p(`\u4E0D\u652F\u6301\u7684\u534F\u8BAE: ${e.protocol}`,!0);let n=new AbortController,o=setTimeout(()=>n.abort(),eo);try{let s=await globalThis.fetch(e,{signal:n.signal}),r=s.headers.get("content-length"),i=r?Number(r):void 0;if(i&&i>qe)return p(`\u8BF7\u6C42\u88AB\u62D2\u7EDD: \u54CD\u5E94\u4F53\u8FC7\u5927\uFF08${i} bytes\uFF09`,!0);let l=0,a="";if(s.body&&s.body.getReader){let I=s.body.getReader(),S=[];for(;;){let{done:N,value:M}=await I.read();if(N)break;if(M){if(l+=M.byteLength,l>qe)return n.abort(),p(`\u8BF7\u6C42\u88AB\u4E2D\u6B62: \u54CD\u5E94\u4F53\u8D85\u8FC7 ${qe} bytes`,!0);S.push(M)}}let _=new Uint8Array(l),U=0;for(let N of S)_.set(N,U),U+=N.byteLength;a=new TextDecoder().decode(_)}else if(a=await s.text(),l=new TextEncoder().encode(a).byteLength,l>qe)return p(`\u8BF7\u6C42\u88AB\u62D2\u7EDD: \u54CD\u5E94\u4F53\u8D85\u8FC7 ${qe} bytes`,!0);let c=s.headers.get("content-type")||"",u=/text\/html/i.test(c)||/^\s*<!doctype html/i.test(a)||/^\s*<html[\s>]/i.test(a),m=u?Mi(a):a.trim(),d=Pi(m),h=d.length>Bt?`${d.slice(0,Bt)}...`:d,w=d.length>Bt?" text_truncated=true":"",f=u?" source=html_stripped":"";return p(`status=${s.status} bytes=${l} text_chars=${d.length} text="${h}"${w}${f}`)}catch(s){return s.name==="AbortError"?p(`\u8BF7\u6C42\u8D85\u65F6\u6216\u88AB\u4E2D\u6B62\uFF08${eo}ms\uFF09`,!0):p(`\u8BF7\u6C42\u5931\u8D25: ${s.message}`,!0)}finally{clearTimeout(o)}}});import{spawn as Ri}from"child_process";import{existsSync as Ii}from"fs";import{resolve as Oi}from"path";import{z as Y}from"zod";var Li=3e4,$i=1e4,Ni=3e5,no=4,Di=1500,oo=2e3,ve=new Map,Ui=Y.object({message:Y.string().min(1),agent_type:Y.string().optional()}).strict(),Hi=Y.object({id:Y.string().min(1),message:Y.string().min(1),interrupt:Y.boolean().optional()}).strict(),Fi=Y.object({id:Y.string().min(1)}).strict(),ji=Y.object({ids:Y.array(Y.string().min(1)).min(1),timeout_ms:Y.number().int().positive().optional()}).strict(),Bi=Y.object({id:Y.string().min(1)}).strict();function $e(){return new Date().toISOString()}function Wt(t){return p(`agent not found: ${t}`,!0)}function Wi(){let t=process.env.MEMO_SUBAGENT_MAX_AGENTS?.trim();if(!t)return no;let e=Number(t);return!Number.isFinite(e)||e<=0?no:Math.floor(e)}function zi(){let t=0;for(let e of ve.values())e.running&&(t+=1);return t}function qi(){let t=process.env.MEMO_SUBAGENT_COMMAND?.trim();if(t)return t;let e=Oi(process.cwd(),"dist/index.js");return Ii(e)?`node ${JSON.stringify(e)} --dangerous`:"memo --dangerous"}function Ki(t){return t!=="running"}function Vi(t){return new Promise(e=>{setTimeout(e,t)})}function Gi(t){return t===void 0?Li:t<=0?null:Math.max($i,Math.min(Ni,t))}function Xi(t){return t.length<=oo?t:`${t.slice(0,oo)}
19
- ...[truncated]`}function Ji(t,e){let n=[],o=t.trim(),s=e.trim();return o&&n.push(o),s&&n.push(`stderr:
20
- ${s}`),Xi(n.join(`
21
-
22
- `))}async function ro(t){let e=t.running;if(!e)return;e.interrupted=!0;let n=e.process;n.exitCode!==null||n.killed||await new Promise(o=>{let s=!1,r=()=>{s||(s=!0,clearTimeout(i),n.off("close",r),o())},i=setTimeout(()=>{if(n.exitCode===null)try{n.kill("SIGKILL")}catch{r()}},Di);n.on("close",r);try{n.kill("SIGTERM")}catch{r()}})}function Yi(t){let e=ve.get(t);return e?e.status:"not_found"}function Zi(t){let e=ve.get(t);return e?{status:e.status,last_message:e.lastMessage,last_output:e.lastOutput,last_error:e.lastError,last_submission_id:e.lastSubmissionId,updated_at:e.updatedAt}:{status:"not_found",last_message:null,last_output:null,last_error:null,last_submission_id:null,updated_at:null}}function Qi(t){return{agent_id:t.id,status:t.status,created_at:t.createdAt,updated_at:t.updatedAt,last_message:t.lastMessage,last_submission_id:t.lastSubmissionId,has_last_output:!!t.lastOutput,has_last_error:!!t.lastError}}function ea(t){let{record:e,submissionId:n,stdout:o,stderr:s,exitCode:r,interrupted:i}=t;if(!(!e.running||e.running.id!==n)&&(e.running=null,e.updatedAt=$e(),e.lastOutput=Ji(o,s)||null,e.lastError=null,e.status!=="closed")){if(i){e.status="errored",e.lastError="interrupted",e.statusBeforeClose="errored";return}if(r===0){e.status="completed",e.statusBeforeClose="completed";return}e.status="errored",e.lastError=`submission failed with exit code ${r}`,e.statusBeforeClose="errored"}}async function so(t,e){let n=Wi();if(zi()>=n)throw new Error(`subagent concurrency limit reached (${n})`);let o=crypto.randomUUID(),s=qi(),r=Ri(s,{cwd:process.cwd(),env:{...process.env},shell:!0,stdio:["pipe","pipe","pipe"]}),i=[],l=[];r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",a=>i.push(a)),r.stderr?.on("data",a=>l.push(a)),r.on("error",a=>{l.push(`[spawn error] ${a.message}`)}),t.running={id:o,message:e,process:r,startedAt:$e(),interrupted:!1},t.status="running",t.lastMessage=e,t.lastSubmissionId=o,t.updatedAt=$e(),r.on("close",a=>{let c=typeof a=="number"?a:-1,u=!!(t.running?.id===o&&t.running.interrupted);ea({record:t,submissionId:o,stdout:i.join(""),stderr:l.join(""),exitCode:c,interrupted:u})});try{r.stdin?.write(`${e.trim()}
23
- `)}catch{}try{r.stdin?.end()}catch{}return o}var io=O({name:"spawn_agent",description:"Spawn a sub-agent for a well-scoped task and return the agent id.",inputSchema:Ui,supportsParallelToolCalls:!1,isMutating:!0,execute:async({message:t})=>{let e=t.trim();if(!e)return p("spawn_agent failed: message must not be empty",!0);let n=crypto.randomUUID(),o=$e(),s={id:n,createdAt:o,updatedAt:o,status:"running",statusBeforeClose:"completed",lastMessage:e,lastSubmissionId:null,lastOutput:null,lastError:null,running:null};ve.set(n,s);try{let r=await so(s,e);return p(JSON.stringify({...Qi(s),submission_id:r},null,2))}catch(r){return ve.delete(n),p(`spawn_agent failed: ${r.message}`,!0)}}}),ao=O({name:"send_input",description:"Send a message to an existing agent.",inputSchema:Hi,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:t,message:e,interrupt:n})=>{let o=ve.get(t);if(!o)return Wt(t);let s=e.trim();if(!s)return p("send_input failed: message must not be empty",!0);if(o.status==="closed")return p(`send_input failed: agent ${t} is closed; run resume_agent first`,!0);if(o.running){if(!n)return p(`send_input failed: agent ${t} is busy; set interrupt=true to cancel current submission`,!0);await ro(o)}try{let r=await so(o,s);return p(JSON.stringify({agent_id:o.id,status:o.status,submission_id:r},null,2))}catch(r){return p(`send_input failed: ${r.message}`,!0)}}}),lo=O({name:"resume_agent",description:"Resume a previously closed agent by id.",inputSchema:Fi,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:t})=>{let e=ve.get(t);return e?(e.status==="closed"&&(e.status=e.statusBeforeClose,e.updatedAt=$e()),p(JSON.stringify({agent_id:t,status:e.status},null,2))):Wt(t)}}),co=O({name:"wait",description:"Wait for agent statuses and return current snapshots.",inputSchema:ji,supportsParallelToolCalls:!1,isMutating:!1,execute:async({ids:t,timeout_ms:e})=>{let n=Gi(e);if(n===null)return p("wait failed: timeout_ms must be greater than zero",!0);let o=()=>{let i={},l={};for(let a of t){let c=Yi(a);Ki(c)&&(i[a]=c,l[a]=Zi(a))}return{status:i,details:l}},s=o();if(Object.keys(s.status).length>0)return p(JSON.stringify({status:s.status,details:s.details,timed_out:!1},null,2));let r=Date.now()+n;for(;Date.now()<r;)if(await Vi(100),s=o(),Object.keys(s.status).length>0)return p(JSON.stringify({status:s.status,details:s.details,timed_out:!1},null,2));return p(JSON.stringify({status:{},details:{},timed_out:!0},null,2))}}),uo=O({name:"close_agent",description:"Close an agent and return its last known status.",inputSchema:Bi,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:t})=>{let e=ve.get(t);return e?e.status==="closed"?p(JSON.stringify({agent_id:t,status:"closed"},null,2)):(e.statusBeforeClose=e.running?"completed":e.status,e.status="closed",e.updatedAt=$e(),await ro(e),p(JSON.stringify({agent_id:t,status:"closed"},null,2))):Wt(t)}});var zt={list_mcp_resources:"read",list_mcp_resource_templates:"read",read_mcp_resource:"read",update_plan:"read",get_memory:"read",webfetch:"read",read_file:"read",list_dir:"read",grep_files:"read",wait:"read",spawn_agent:"read",send_input:"read",resume_agent:"read",close_agent:"read",apply_patch:"write",shell:"execute",shell_command:"execute",exec_command:"execute",write_stdin:"execute"},po=new Set(["spawn_agent","send_input","resume_agent","wait","close_agent"]),it={read:0,write:1,execute:2},mo=["exec","run","shell","command","stdin"],fo=["write","patch","create","delete","modify","update"],go=["read","get","fetch","search","list","find"],ho=new Set(["write","execute"]);function Kt(t){let e={...zt,...t?.customLevels};return{getRiskLevel(n){if(n in e)return e[n];let o=n.toLowerCase();return qt(o,mo)?"execute":qt(o,fo)?"write":qt(o,go)?"read":"write"},compareRisk(n,o){return it[n]-it[o]},needsApproval(n,o){return o==="strict"?!0:ho.has(n)}}}function qt(t,e){return e.some(n=>t.includes(n))}import{createHash as ta}from"crypto";function at(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?"["+t.map(n=>at(n)).join(",")+"]":`{${Object.entries(t).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${at(o)}`).join(",")}}`}function Vt(t,e){let n=at(e),o=`${t}:${n}`;return ta("sha256").update(o).digest("hex").slice(0,16)}function na(t){return`Tool "${t}" requires approval.`}function Gt(t){let{mode:e="auto",dangerous:n=!1,toolRiskLevels:o}=t||{},s=e==="strict"?"strict":"auto";if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let r=Kt({customLevels:o}),i={session:new Set,once:new Set,denied:new Set};return{get isDangerousMode(){return!1},getRiskLevel(l){return r.getRiskLevel(l)},check(l,a){if(po.has(l))return{needApproval:!1,decision:"auto-execute"};let c=r.getRiskLevel(l);if(!r.needsApproval(c,s))return{needApproval:!1,decision:"auto-execute"};let u=Vt(l,a);return i.session.has(u)||i.once.has(u)?{needApproval:!1,decision:"auto-execute"}:i.denied.has(u)?{needApproval:!0,fingerprint:u,riskLevel:c,reason:"This request was previously denied.",toolName:l,params:a}:{needApproval:!0,fingerprint:u,riskLevel:c,reason:na(l),toolName:l,params:a}},recordDecision(l,a){switch(i.session.delete(l),i.once.delete(l),i.denied.delete(l),a){case"session":i.session.add(l);break;case"once":i.once.add(l);break;case"deny":i.denied.add(l);break}},isGranted(l){return i.session.has(l)||i.once.has(l)},clearOnceApprovals(){i.once.clear()},dispose(){i.session.clear(),i.once.clear(),i.denied.clear()}}}var yo=12e3;function oa(){let t=process.env.MEMO_TOOL_RESULT_MAX_CHARS?.trim();if(!t)return yo;let e=Number(t);return!Number.isFinite(e)||e<=0?yo:Math.floor(e)}function ra(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function sa(t){let e=0;for(let n of t.content??[]){if(n.type==="text"){e+=n.text.length;continue}try{e+=JSON.stringify(n).length}catch{e+=100}}return e}function ia(t,e,n){return`<system_hint type="tool_output_omitted" tool="${ra(t)}" reason="too_long" actual_chars="${e}" max_chars="${n}">\u5DE5\u5177\u8FD4\u56DE\u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u81EA\u52A8\u7701\u7565\u3002\u8BF7\u7F29\u5C0F\u8303\u56F4\u6216\u589E\u52A0\u9650\u5236\u53C2\u6570\u540E\u91CD\u8BD5\u3002</system_hint>`}function aa(t,e){let n=oa(),o=sa(e);return o<=n?e:{content:[{type:"text",text:ia(t,o,n)}],isError:!1}}function la(t){return(t.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
24
- `)}function ca(t,e){let n=e;if(typeof e=="string"){let o=e.trim();if(o)try{n=JSON.parse(o)}catch{n=o}else n={}}return typeof n!="object"||n===null?{ok:!1,error:`${t.name} invalid input: expected object`}:typeof t.validateInput=="function"?t.validateInput(n):{ok:!0,data:n}}function ua(t){let e=t instanceof Error?t.message.toLowerCase():String(t).toLowerCase();return e.includes("sandbox")||e.includes("permission denied")||e.includes("operation not permitted")||e.includes("eacces")?"sandbox_denied":"execution_failed"}var Xt=class{constructor(e){this.config=e;this.approvalManager=Gt(e.approval)}approvalManager;async executeAction(e,n){let o=Date.now(),s=e.id??`${e.name}:${o}`,r=this.approvalManager.check(e.name,e.input);if(r.needApproval){let l={toolName:r.toolName,params:r.params,fingerprint:r.fingerprint,riskLevel:r.riskLevel,reason:r.reason};await n?.onApprovalRequest?.(l);let a=n?.requestApproval?await n.requestApproval(l):"deny";if(this.approvalManager.recordDecision(r.fingerprint,a),await n?.onApprovalResponse?.({fingerprint:r.fingerprint,decision:a}),a==="deny")return{actionId:s,tool:e.name,status:"approval_denied",errorType:"approval_denied",success:!1,observation:`\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C: ${e.name}`,durationMs:Date.now()-o,rejected:!0}}let i=this.config.tools[e.name];if(!i)return{actionId:s,tool:e.name,status:"tool_not_found",errorType:"tool_not_found",success:!1,observation:`Unknown tool: ${e.name}`,durationMs:Date.now()-o};try{let l=ca(i,e.input);if(!l.ok)return{actionId:s,tool:e.name,status:"input_invalid",errorType:"input_invalid",success:!1,observation:l.error,durationMs:Date.now()-o};let a=await i.execute(l.data),c=aa(e.name,a);return{actionId:s,tool:e.name,status:"success",success:!0,observation:la(c)||"(no tool output)",durationMs:Date.now()-o}}catch(l){let a=ua(l);return{actionId:s,tool:e.name,status:a,errorType:a,success:!1,observation:`Tool execution failed: ${l.message}`,durationMs:Date.now()-o}}}async executeActions(e,n={}){let o=n.executionMode??"sequential",s=n.failurePolicy??(n.stopOnRejection===!1?"collect_all":"fail_fast"),r=[];if(o==="parallel"){let a=await Promise.all(e.map(c=>this.executeAction(c,n)));if(s==="fail_fast"){let c=a.findIndex(u=>u.rejected);r=c>=0?a.slice(0,c+1):a}else r=a}else for(let a of e){let c=await this.executeAction(a,n);if(r.push(c),c.rejected&&s==="fail_fast")break}let i=r.some(a=>a.rejected),l=r.map(a=>`[${a.tool}]: ${a.observation}`).join(`
25
-
26
- `);return{results:r,combinedObservation:l,hasRejection:i,executionMode:o,failurePolicy:s}}clearOnceApprovals(){this.approvalManager.clearOnceApprovals()}dispose(){this.approvalManager.dispose()}};function To(t){return new Xt(t)}var lt=class{tools=new Map;register(e){this.tools.set(e.name,e)}registerMany(e){for(let n of e)this.register(n)}get(e){return this.tools.get(e)}getAll(){return Array.from(this.tools.values())}toRegistry(){let e={};for(let[n,o]of this.tools)e[n]=o;return e}has(e){return this.tools.has(e)}get size(){return this.tools.size}};import{Client as pa}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as ma}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as da}from"@modelcontextprotocol/sdk/client/stdio.js";function fa(t){if(!t)return;let e={...process.env,...t},n=Object.entries(e).filter(o=>typeof o[1]=="string");return Object.fromEntries(n)}function _o(){return new pa({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function ga(t){if(!(!t||Object.keys(t).length===0))return{headers:t}}function ha(t){let e={...t.http_headers??t.headers??{}};if(t.bearer_token_env_var){let n=process.env[t.bearer_token_env_var];n&&!e.Authorization&&(e.Authorization=`Bearer ${n}`)}return e}async function ya(t){let e=new URL(t.url),n=ga(ha(t));try{let o=_o(),s=new ma(e,{requestInit:n});return await o.connect(s),{client:o,transport:s}}catch(o){let s=`Failed to connect via streamable_http (${o.message})`,r=new Error(s);throw r.cause=o,r}}async function Ta(t){if("url"in t)return ya(t);let e={command:t.command,args:t.args,env:fa(t.env),stderr:t.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},n=new da(e),o=_o();return await o.connect(n),{client:o,transport:n}}var ct=class{connections=new Map;async connect(e,n){let o=this.connections.get(e);if(o)return o;let{client:s,transport:r}=await Ta(n),i=await s.listTools(),l={name:e,client:s,transport:r,tools:(i.tools||[]).map(a=>({name:`${e}_${a.name}`,description:a.description||`Tool from ${e}: ${a.name}`,source:"mcp",serverName:e,originalName:a.name,inputSchema:a.inputSchema,execute:async()=>({content:[]})}))};return this.connections.set(e,l),l}get(e){return this.connections.get(e)}getAll(){return Array.from(this.connections.values())}getAllTools(){let e=[];for(let n of this.connections.values())for(let o of n.tools)e.push({name:o.name,description:o.description,serverName:o.serverName,originalName:o.originalName,inputSchema:o.inputSchema,client:n.client});return e}async closeAll(){let e=Array.from(this.connections.values()).map(async n=>{try{await n.client.close()}catch(o){console.error(`[MCP] Error closing client ${n.name}:`,o)}});await Promise.all(e),this.connections.clear()}get size(){return this.connections.size}};var ut=class{pool;tools=new Map;shouldLog;constructor(){this.pool=new ct,Ft(this.pool),this.shouldLog=process.env.MEMO_MCP_LOG==="1"||!(process.stdout.isTTY&&process.stdin.isTTY)}async loadServers(e){if(!e||Object.keys(e).length===0)return 0;let n=0;return await Promise.all(Object.entries(e).map(async([o,s])=>{try{let r=await this.pool.connect(o,s);for(let i of r.tools){let l={...i,execute:async a=>{let c=this.pool.get(i.serverName)?.client;if(!c)throw new Error(`MCP client for server '${i.serverName}' not found`);return c.callTool({name:i.originalName,arguments:a})}};this.tools.set(l.name,l)}n+=r.tools.length,this.shouldLog&&console.log(`[MCP] Connected to '${o}' with ${r.tools.length} tools`)}catch(r){this.shouldLog&&console.error(`[MCP] Failed to connect to server '${o}':`,r)}})),n}get(e){return this.tools.get(e)}getAll(){return Array.from(this.tools.values())}toRegistry(){let e={};for(let[n,o]of this.tools)e[n]=o;return e}has(e){return this.tools.has(e)}get size(){return this.tools.size}async dispose(){await this.pool.closeAll(),this.tools.clear(),Ft(null)}getPool(){return this.pool}};var pt=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new lt,this.mcpRegistry=new ut}registerNativeTool(e){this.nativeRegistry.register(e)}registerNativeTools(e){for(let n of e)this.registerNativeTool(n)}async loadMcpServers(e){return this.mcpRegistry.loadServers(e)}getTool(e){return this.nativeRegistry.get(e)??this.mcpRegistry.get(e)}getAllTools(){return[...this.nativeRegistry.getAll(),...this.mcpRegistry.getAll()]}toRegistry(){return{...this.nativeRegistry.toRegistry(),...this.mcpRegistry.toRegistry()}}hasTool(e){return this.nativeRegistry.has(e)||this.mcpRegistry.has(e)}getToolCount(){let e=this.nativeRegistry.size,n=this.mcpRegistry.size;return{native:e,mcp:n,total:e+n}}async execute(e,n){let o=this.getTool(e);if(!o)throw new Error(`Tool '${e}' not found`);return o.execute(n)}generateToolDefinitions(){return this.getAllTools().map(e=>({name:e.name,description:e.description,input_schema:e.inputSchema||{type:"object",properties:{}}}))}generateToolDescriptions(){let e=this.getAllTools();if(e.length===0)return"";let n=[];n.push("## Available Tools"),n.push("");let o=e.filter(r=>r.source==="native"),s=e.filter(r=>r.source==="mcp");if(o.length>0){n.push("### Built-in Tools"),n.push("");for(let r of o)n.push(this.formatToolDescription(r));n.push("")}if(s.length>0){n.push("### External MCP Tools"),n.push("");let r=this.groupByServer(s);for(let[i,l]of Object.entries(r)){n.push(`**Server: ${i}**`),n.push("");for(let a of l)n.push(this.formatToolDescription(a));n.push("")}}return n.join(`
27
- `)}formatToolDescription(e){let n=[];return n.push(`#### ${e.name}`),n.push(`- **Description**: ${e.description}`),e.inputSchema&&Object.keys(e.inputSchema).length>0&&n.push(`- **Input Schema**: ${JSON.stringify(e.inputSchema)}`),n.join(`
28
- `)}groupByServer(e){let n={};for(let o of e)if(o.source==="mcp"){let s=o.serverName;n[s]||(n[s]=[]),n[s].push(o)}return n}getToolDescriptions(){return this.getAllTools().map(e=>({name:e.name,description:e.description,source:e.source,serverName:e.source==="mcp"?e.serverName:void 0,inputSchema:e.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};function _a(t){let e=process.env[t]?.trim();return e?new Set(e.split(",").map(n=>n.trim()).filter(Boolean)):new Set}function Sa(){let t=[],e=process.env.MEMO_SHELL_TOOL_TYPE?.trim()||"unified_exec",n=_a("MEMO_EXPERIMENTAL_TOOLS"),o=n.size===0,s=process.env.MEMO_ENABLE_COLLAB_TOOLS!=="0",r=process.env.MEMO_ENABLE_MEMORY_TOOL!=="0";return e==="shell"?t.push(Sn):e==="shell_command"?t.push(vn):e==="unified_exec"?t.push(Rt,It):e!=="disabled"&&t.push(Rt,It),t.push(qn,Kn,Vn),t.push(Xn),t.push(Dn),(o||n.has("grep_files"))&&t.push(Bn),(o||n.has("read_file"))&&t.push(Fn),(o||n.has("list_dir"))&&t.push(jn),r&&t.push(Zn),t.push(to),s&&t.push(io,ao,lo,co,uo),t}function va(t){let e={};for(let n of t)e[n.name]=n;return e}var xa=va(Sa()),Ca=Object.values(xa),So=Ca;import Ha from"openai";import{encoding_for_model as Ea,get_encoding as Aa}from"@dqbd/tiktoken";var vo="cl100k_base";function wa(t){let e=t?.trim()||vo;try{let n=()=>Ea(e);return n().free(),{model:e,factory:n}}catch{let n=vo,o=()=>Aa(n);return o().free(),{model:n,factory:o}}}function ba(t){return t.role==="assistant"&&t.tool_calls?.length?`${t.content}
29
- ${JSON.stringify(t.tool_calls)}`:t.role==="tool"?`${t.content}
30
- ${t.tool_call_id}
31
- ${t.name??""}`:t.content}function xo(t){let{model:e,factory:n}=wa(t),o=n(),s=4,r=2,i=1,l=c=>c?o.encode(c).length:0;return{model:e,countText:l,countMessages:c=>{if(!c.length)return 0;let u=0;for(let m of c)u+=s,u+=l(ba(m)),m.name&&(u+=i);return u+=r,u},dispose:()=>o.free()}}import{mkdir as ka,writeFile as Ma,readFile as Pa,access as Ra}from"fs/promises";import{homedir as Co}from"os";import{dirname as Ia,join as Ve}from"path";import{randomUUID as pm}from"crypto";import{parse as Oa}from"toml";var La=Ve(Co(),".memo"),$a="sessions",Ke={current_provider:"deepseek",max_prompt_tokens:12e4,providers:[{name:"deepseek",env_api_key:"DEEPSEEK_API_KEY",model:"deepseek-chat",base_url:"https://api.deepseek.com"}],mcp_servers:{}};function Na(t){return/^[A-Za-z0-9_-]+$/.test(t)?t:JSON.stringify(t)}function Da(t){if(!t||typeof t!="object"||Array.isArray(t))return[];let e=[];for(let[n,o]of Object.entries(t)){if(!o)continue;let s=Array.isArray(o)?o:[o];for(let r of s){if(!r||typeof r!="object")continue;let i={...r};(typeof i.name!="string"||i.name.length===0)&&n&&(i.name=n),e.push(i)}}return e}function Eo(t){return t.startsWith("~")?Ve(Co(),t.slice(1)):t}function Ua(t){let e=t.providers.map(r=>{let i=typeof r?.name=="string"?r.name:"";if(!i)return"";let a=[`[[providers.${Na(i)}]]`,`name = ${JSON.stringify(i)}`,`env_api_key = ${JSON.stringify(String(r.env_api_key??""))}`,`model = ${JSON.stringify(String(r.model??""))}`];return r.base_url&&a.push(`base_url = ${JSON.stringify(String(r.base_url))}`),a.join(`
2
+ var ii=Object.create;var dr=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var li=Object.getOwnPropertyNames;var ci=Object.getPrototypeOf,ui=Object.prototype.hasOwnProperty;var pi=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var mi=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of li(t))!ui.call(e,o)&&o!==n&&dr(e,o,{get:()=>t[o],enumerable:!(r=ai(t,o))||r.enumerable});return e};var di=(e,t,n)=>(n=e!=null?ii(ci(e)):{},mi(t||!e||!e.__esModule?dr(n,"default",{value:e,enumerable:!0}):n,e));var Ur=pi((rd,Dr)=>{"use strict";function Pr(e){return Array.isArray(e)?e:[e]}var kn="",Ir=" ",Mn="\\",aa=/^\s+$/,la=/(?:[^\\]|^)\\$/,ca=/^\\!/,ua=/^\\#/,pa=/\r?\n/g,ma=/^\.*\/|^\.+$/,wn="/",Lr="node-ignore";typeof Symbol<"u"&&(Lr=Symbol.for("node-ignore"));var Rr=Lr,da=(e,t,n)=>Object.defineProperty(e,t,{value:n}),fa=/([0-z])-([0-z])/g,Nr=()=>!1,ga=e=>e.replace(fa,(t,n,r)=>n.charCodeAt(0)<=r.charCodeAt(0)?t:kn),ha=e=>{let{length:t}=e;return e.slice(0,t-t%2)},ya=[[/^\uFEFF/,()=>kn],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?Ir:kn)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+Ir}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let r=n.replace(/\\\*/g,"[^\\/]*");return t+r}],[/\\\\\\(?=[$.|*+(){^])/g,()=>Mn],[/\\\\/g,()=>Mn],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,r,o)=>t===Mn?`\\[${n}${ha(r)}${o}`:o==="]"&&r.length%2===0?`[${ga(n)}${r}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`]],Or=Object.create(null),Ta=(e,t)=>{let n=Or[e];return n||(n=ya.reduce((r,[o,s])=>r.replace(o,s.bind(e)),e),Or[e]=n),t?new RegExp(n,"i"):new RegExp(n)},Rn=e=>typeof e=="string",_a=e=>e&&Rn(e)&&!aa.test(e)&&!la.test(e)&&e.indexOf("#")!==0,Sa=e=>e.split(pa),Pn=class{constructor(t,n,r,o){this.origin=t,this.pattern=n,this.negative=r,this.regex=o}},va=(e,t)=>{let n=e,r=!1;e.indexOf("!")===0&&(r=!0,e=e.substr(1)),e=e.replace(ca,"!").replace(ua,"#");let o=Ta(e,t);return new Pn(n,e,r,o)},xa=(e,t)=>{throw new t(e)},De=(e,t,n)=>Rn(e)?e?De.isNotRelative(e)?n(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:n("path must not be empty",TypeError):n(`path must be a string, but got \`${t}\``,TypeError),$r=e=>ma.test(e);De.isNotRelative=$r;De.convert=e=>e;var In=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:r=!1}={}){da(this,Rr,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=r,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(t){if(t&&t[Rr]){this._rules=this._rules.concat(t._rules),this._added=!0;return}if(_a(t)){let n=va(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,Pr(Rn(t)?Sa(t):t).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(t){return this.add(t)}_testOne(t,n){let r=!1,o=!1;return this._rules.forEach(s=>{let{negative:i}=s;if(o===i&&r!==o||i&&!r&&!o&&!n)return;s.regex.test(t)&&(r=!i,o=i)}),{ignored:r,unignored:o}}_test(t,n,r,o){let s=t&&De.convert(t);return De(s,t,this._allowRelativePaths?Nr:xa),this._t(s,n,r,o)}_t(t,n,r,o){if(t in n)return n[t];if(o||(o=t.split(wn)),o.pop(),!o.length)return n[t]=this._testOne(t,r);let s=this._t(o.join(wn)+wn,n,r,o);return n[t]=s.ignored?s:this._testOne(t,r)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return Pr(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},Wt=e=>new In(e),Ca=e=>De(e&&De.convert(e),e,Nr);Wt.isPathValid=Ca;Wt.default=Wt;Dr.exports=Wt;if(typeof process<"u"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");De.convert=e;let t=/^[a-z]:\//i;De.isNotRelative=n=>t.test(n)||$r(n)}});import{randomUUID as ti}from"crypto";import{createInterface as cm}from"readline/promises";import{stdin as um,stdout as pm}from"process";import{render as mm}from"ink";import fi from"os";import{readFile as fr}from"fs/promises";import{join as gr,dirname as gi}from"path";import{fileURLToPath as hi}from"url";var yi=/{{\s*([\w.-]+)\s*}}/g;function Ti(e,t){return e.replace(yi,(n,r)=>t[r]??"")}function _i(){try{return fi.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}async function Si(e){let t=gr(e,"AGENTS.md");try{let n=await fr(t,"utf-8");return n.trim()?{path:t,content:n}:null}catch{return null}}function vi(e,t){return`${e}
3
+
4
+ ## Project AGENTS.md (Startup Root)
5
+ Loaded from: ${t.path}
6
+
7
+ ${t.content}`}async function hr(e={}){let t=e.cwd??process.cwd(),n=gi(hi(import.meta.url)),r=gr(n,"prompt.md"),o=await fr(r,"utf-8"),s={date:new Date().toISOString(),user:_i(),pwd:t},i=Ti(o,s),a=await Si(t);return a?vi(i,a):i}import{appendFile as xi,mkdir as Ci}from"fs/promises";import{dirname as bi}from"path";var Bt=class{constructor(t){this.filePath=t}ready=!1;async append(t){this.ready||(await Ci(bi(this.filePath),{recursive:!0}),this.ready=!0),await xi(this.filePath,`${JSON.stringify(t)}
8
+ `,"utf8")}async flush(){return Promise.resolve()}};function yr(e){return{ts:new Date().toISOString(),sessionId:e.sessionId,turn:e.turn,step:e.step,type:e.type,content:e.content,role:e.role,meta:e.meta}}import{z as Ne}from"zod";function N(e){let{inputSchema:t,execute:n,...r}=e,o=t.toJSONSchema?.(),{$schema:s,...i}=o??{};return{...r,source:"native",inputSchema:i,validateInput:a=>{let l=t.safeParse(a);if(!l.success){let c=l.error.issues[0]?.message??"invalid input";return{ok:!1,error:`${e.name} invalid input: ${c}`}}return{ok:!0,data:l.data}},execute:n}}function f(e,t=!1){return{content:[{type:"text",text:e}],isError:t}}import{spawn as qi}from"child_process";import{EventEmitter as Gi}from"events";import{resolve as Ki}from"path";import{posix as Ai}from"path";var Tr=220,_r=4096,Ei=/^\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)$/i,Mi=/(?:^|[\s(])(?:\d?>>?|>>|>\||&>)\s*\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)(?:\s|$)/i,wi=new Set(["-u","--user","-g","--group","-h","--host","-p","--prompt","-C","-T","-r","--role","-t","--type","-D","--chdir"]),ki=new Set(["fdisk","sfdisk","cfdisk","parted","sgdisk","gdisk","wipefs","blkdiscard","shred"]);function Sn(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Pi(e){let t=e.replace(/\s+/g," ").trim();return t.length>Tr?`${t.slice(0,Tr)}\u2026`:t}function Sr(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return(t.split(/[\\/]/).at(-1)??t).toLowerCase()}function Ii(e){let t=null,n=!1;for(let r=0;r<e.length;r+=1){let o=e[r];if(n){n=!1;continue}if(o==="\\"&&t!=="'"){n=!0;continue}if(t){o===t&&(t=null);continue}if(o==='"'||o==="'"){t=o;continue}if(o==="#")return e.slice(0,r)}return e}function Ri(e){let t=[],n="",r=null,o=!1,s=()=>{let i=Ii(n).trim();i&&t.push(i),n=""};for(let i=0;i<e.length;i+=1){let a=e[i];if(o){n+=a,o=!1;continue}if(a==="\\"&&r!=="'"){n+=a,o=!0;continue}if(r){n+=a,a===r&&(r=null);continue}if(a==='"'||a==="'"){r=a,n+=a;continue}if(a===";"||a===`
9
+ `){s();continue}if(a==="&"){e[i+1]==="&"&&(i+=1),s();continue}if(a==="|"){e[i+1]==="|"&&(i+=1),s();continue}n+=a}return s(),t}function Oi(e){let t=[],n="",r=null,o=!1,s=()=>{n&&t.push(n),n=""};for(let i=0;i<e.length;i+=1){let a=e[i];if(o){n+=a,o=!1;continue}if(a==="\\"&&r!=="'"){o=!0;continue}if(r){a===r?r=null:n+=a;continue}if(a==='"'||a==="'"){r=a;continue}if(/\s/.test(a)){s();continue}n+=a}return s(),t}function vr(e){return/^[A-Za-z_][A-Za-z0-9_]*=.*/.test(e)}function Li(e,t){let n=t;for(;n<e.length;){let r=Sr(e[n]??"");if(r==="sudo"){for(n+=1;n<e.length;){let o=e[n]??"";if(!o.startsWith("-"))break;n+=1,wi.has(o)&&n<e.length&&(n+=1)}continue}if(r==="env"){for(n+=1;n<e.length;){let o=e[n]??"";if(o.startsWith("-")||vr(o)){n+=1;continue}break}continue}if(r==="command"||r==="nohup"||r==="time"){n+=1;continue}break}return n}function Ni(e){let t=Oi(e);if(t.length===0)return null;let n=0;for(;n<t.length&&vr(t[n]??"");)n+=1;if(n=Li(t,n),n>=t.length)return null;let r=Sr(t[n]??"");return r?{raw:e,commandName:r,args:t.slice(n+1)}:null}function vn(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return Ei.test(t)}function $i(e){let t=e.trim().replace(/^['"]|['"]$/g,""),n=t.toLowerCase();return n==="/"||n==="/*"||n==="/.*"||n==="~"||n==="~/"||n==="~/*"||n==="$home"||n==="$home/"||n==="$home/*"||n==="${home}"||n==="${home}/"||n==="${home}/*"?!0:t.startsWith("/")&&!/[*?[\]{}$]/.test(t)?Ai.normalize(t)==="/":!1}function Di(e){return e.startsWith("-")&&e!=="-"}function Ui(e){if(e.commandName!=="rm")return null;let t=!1,n=0;for(;n<e.args.length;){let o=e.args[n]??"";if(o==="--"){n+=1;break}if(!Di(o))break;if(o==="--recursive"){t=!0,n+=1;continue}if(o.startsWith("--")){n+=1;continue}let s=o.slice(1);(s.includes("r")||s.includes("R"))&&(t=!0),n+=1}if(!t)return null;let r=e.args.slice(n);for(let o of r)if($i(o))return{ruleId:"rm_recursive_critical_target",matchedSegment:e.raw};return null}function Hi(e){return e.commandName==="mkfs"||e.commandName.startsWith("mkfs.")?{ruleId:"mkfs_filesystem_create",matchedSegment:e.raw}:null}function Fi(e){if(e.commandName!=="dd")return null;for(let t=0;t<e.args.length;t+=1){let n=e.args[t]??"",r=n.indexOf("=");if(r<=0)continue;let o=n.slice(0,r).toLowerCase(),s=n.slice(r+1);if(o==="of"&&vn(s))return{ruleId:"dd_write_block_device",matchedSegment:e.raw}}for(let t=0;t<e.args.length-1;t+=1){let n=(e.args[t]??"").toLowerCase(),r=e.args[t+1]??"";if(n==="of"&&vn(r))return{ruleId:"dd_write_block_device",matchedSegment:e.raw}}return null}function Bi(e){return!ki.has(e.commandName)||!e.args.some(t=>vn(t))?null:{ruleId:"disk_mutation_block_device",matchedSegment:e.raw}}function Wi(e){return Mi.test(e)?{ruleId:"redirect_block_device",matchedSegment:e}:null}function ji(e){for(let t of Ri(e)){let n=Ni(t);if(n){let o=Ui(n);if(o)return o;let s=Hi(n);if(s)return s;let i=Fi(n);if(i)return i;let a=Bi(n);if(a)return a}let r=Wi(t);if(r)return r}return null}function zi(e,t){let n=Pi(e.command),r=typeof e.sessionId=="number"?` session_id="${e.sessionId}"`:"";return`<system_hint type="tool_call_denied" tool="${Sn(e.toolName)}" reason="dangerous_command" policy="blacklist" rule="${Sn(t.ruleId)}"${r} command="${Sn(n)}">Blocked a high-risk shell command to prevent irreversible data loss. Use a safer and scoped alternative.</system_hint>`}function xn(e){let t=ji(e.command);return t?{blocked:!0,xml:zi(e,t),match:t}:{blocked:!1}}function xr(e){let n=e.replace(/\r\n/g,`
10
+ `).replace(/\r/g,`
11
+ `).split(`
12
+ `),r=n.pop()??"";return{completedLines:n,remainder:r}}function Cn(e){return e.length<=_r?e:e.slice(-_r)}var Vi=1e4,Xi=250,Ji=2e3,Cr=64;function Yi(e){return Math.ceil(e.length/4)}function Zi(){return Math.random().toString(16).slice(2)||String(Date.now())}function Qi(e){let t=e.login,n=e.shell?.trim();if(process.platform==="win32"){let o=n||"powershell.exe";return o.toLowerCase().includes("powershell")?{file:o,args:["-NoProfile","-Command",e.cmd]}:{file:o,args:[t?"-lc":"-c",e.cmd]}}return{file:n||process.env.SHELL||"/bin/bash",args:[t?"-lc":"-c",e.cmd]}}function ea(e,t){let r=(typeof t=="number"&&t>0?Math.floor(t):Ji)*4,o=Yi(e);return e.length<=r?{output:e,originalTokenCount:o}:{output:e.slice(0,r),originalTokenCount:o}}function ta(e){let t=[];return t.push(`Chunk ID: ${e.chunkId}`),t.push(`Wall time: ${e.wallTimeSeconds.toFixed(4)} seconds`),e.exitCode!==null?t.push(`Process exited with code ${e.exitCode}`):t.push(`Process running with session ID ${e.sessionId}`),t.push(`Original token count: ${e.originalTokenCount}`),t.push("Output:"),t.push(e.output),t.join(`
13
+ `)}function br(e,t){return typeof e!="number"||Number.isNaN(e)?t:e<0?0:Math.floor(e)}async function Ar(e,t){t<=0||e.exited||await Promise.race([new Promise(n=>{let r=setTimeout(()=>{s(),n()},t),o=()=>{clearTimeout(r),s(),n()},s=()=>{e.eventBus.off("exit",o)};e.eventBus.on("exit",o)})])}var bn=class{sessions=new Map;nextId=1;cleanupSessions(){if(this.sessions.size<=Cr)return;let t=Array.from(this.sessions.values()).filter(n=>n.exited).sort((n,r)=>n.startedAtMs-r.startedAtMs);for(let n of t){if(this.sessions.size<=Cr)break;this.sessions.delete(n.id)}}async start(t){let n=t.cmd.trim();if(!n)throw new Error("cmd must not be empty");let r=xn({toolName:t.source_tool??"exec_command",command:n});if(r.blocked)return r.xml;let o=this.nextId++,s=Date.now(),i=Qi({cmd:n,shell:t.shell,login:t.login!==!1}),a=t.workdir?.trim()?Ki(process.cwd(),t.workdir.trim()):process.cwd(),l=qi(i.file,i.args,{cwd:a,env:process.env,stdio:["pipe","pipe","pipe"],shell:!1}),c={id:o,output:"",readOffset:0,pendingStdinInput:"",startedAtMs:s,exited:!1,exitCode:null,eventBus:new Gi,proc:l},u=(y,p)=>{let h=typeof p=="string"?p:p.toString("utf8");c.output+=y?`${y}${h}`:h,c.eventBus.emit("output")};l.stdout?.on("data",y=>u("",y)),l.stderr?.on("data",y=>u("",y)),l.on("error",y=>{c.output+=`
14
+ [exec error] ${y.message}`,c.eventBus.emit("output")}),l.on("close",y=>{c.exited=!0,c.exitCode=typeof y=="number"?y:-1,c.eventBus.emit("exit")}),this.sessions.set(o,c),this.cleanupSessions();let d=br(t.yield_time_ms,Vi);return await Ar(c,d),this.buildResponseText(c,t.max_output_tokens)}async write(t){let n=this.sessions.get(t.session_id);if(!n)throw new Error(`session_id ${t.session_id} not found`);if(!n.exited&&t.chars&&t.chars.length>0){let o=Cn(`${n.pendingStdinInput}${t.chars}`),{completedLines:s,remainder:i}=xr(o);for(let a of s){if(!a.trim())continue;let l=xn({toolName:t.source_tool??"write_stdin",command:a,sessionId:n.id});if(l.blocked)return n.pendingStdinInput="",l.xml}n.pendingStdinInput=Cn(i),n.proc.stdin?.write(t.chars)}let r=br(t.yield_time_ms,Xi);return await Ar(n,r),this.buildResponseText(n,t.max_output_tokens)}buildResponseText(t,n){let r=t.output.slice(t.readOffset);t.readOffset=t.output.length;let o=ea(r,n),s={sessionId:t.id,chunkId:Zi(),wallTimeSeconds:(Date.now()-t.startedAtMs)/1e3,exitCode:t.exited?t.exitCode:null,output:o.output,originalTokenCount:o.originalTokenCount};return ta(s)}},Er=new bn;async function st(e){return Er.start(e)}async function Mr(e){return Er.write(e)}var na=Ne.object({command:Ne.array(Ne.string().min(1)).min(1,"command cannot be empty"),workdir:Ne.string().optional(),timeout_ms:Ne.number().int().positive().optional(),sandbox_permissions:Ne.enum(["use_default","require_escalated"]).optional(),justification:Ne.string().optional(),prefix_rule:Ne.array(Ne.string().min(1)).optional()}).strict();function ra(e){return e.map(t=>/^[A-Za-z0-9_./:@%+-]+$/.test(t)?t:JSON.stringify(t)).join(" ")}var wr=N({name:"shell",description:"Runs a shell command (argv form) and returns output.",inputSchema:na,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,timeout_ms:n})=>{try{let r=await st({cmd:ra(e),workdir:t,login:!1,yield_time_ms:n,source_tool:"shell"});return f(r)}catch(r){return f(`shell failed: ${r.message}`,!0)}}});import{z as $e}from"zod";var oa=$e.object({command:$e.string().min(1,"command cannot be empty"),workdir:$e.string().optional(),login:$e.boolean().optional(),timeout_ms:$e.number().int().positive().optional(),sandbox_permissions:$e.enum(["use_default","require_escalated"]).optional(),justification:$e.string().optional(),prefix_rule:$e.array($e.string().min(1)).optional()}).strict(),kr=N({name:"shell_command",description:"Runs a shell command and returns its output. Always set workdir when possible.",inputSchema:oa,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,login:n,timeout_ms:r})=>{try{let o=await st({cmd:e,workdir:t,login:n,yield_time_ms:r,source_tool:"shell_command"});return f(o)}catch(o){return f(`shell_command failed: ${o.message}`,!0)}}});import{z as _e}from"zod";var sa=_e.object({cmd:_e.string().min(1,"cmd cannot be empty"),workdir:_e.string().optional(),shell:_e.string().optional(),login:_e.boolean().optional(),tty:_e.boolean().optional(),yield_time_ms:_e.number().int().nonnegative().optional(),max_output_tokens:_e.number().int().positive().optional(),sandbox_permissions:_e.enum(["use_default","require_escalated"]).optional(),justification:_e.string().optional(),prefix_rule:_e.array(_e.string().min(1)).optional()}).strict(),An=N({name:"exec_command",description:"Runs a command in a PTY-like managed session, returning output or a session ID for ongoing interaction.",inputSchema:sa,supportsParallelToolCalls:!0,isMutating:!0,execute:async e=>{try{let t=await st({...e,source_tool:"exec_command"});return f(t)}catch(t){return f(`exec_command failed: ${t.message}`,!0)}}});import{z as Tt}from"zod";var ia=Tt.object({session_id:Tt.number().int().positive(),chars:Tt.string().optional(),yield_time_ms:Tt.number().int().nonnegative().optional(),max_output_tokens:Tt.number().int().positive().optional()}).strict(),En=N({name:"write_stdin",description:"Writes characters to an existing unified exec session and returns recent output.",inputSchema:ia,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{try{let t=await Mr({...e,source_tool:"write_stdin"});return f(t)}catch(t){return f(`write_stdin failed: ${t.message}`,!0)}}});import{access as La,readFile as Na,writeFile as $a}from"fs/promises";import{z as me}from"zod";var Pa=di(Ur(),1);import{normalize as ba,resolve as Aa,dirname as sd,join as Ea,relative as Ma,isAbsolute as wa}from"path";import{homedir as ka}from"os";import{existsSync as ld,statSync as cd}from"fs";import{readFile as pd}from"fs/promises";function Ue(e){return ba(Aa(e))}function Ia(e,t){let n=Ma(t,e);return n===""||!n.startsWith("..")&&!wa(n)}function Ra(){let e=process.env.MEMO_SANDBOX_WRITABLE_ROOTS?.trim();return e?e.split(",").map(t=>t.trim()).filter(Boolean).map(t=>Ue(t)):[]}function Hr(){let e=new Set;e.add(Ue(process.cwd()));let t=process.env.MEMO_HOME?.trim()||Ea(ka(),".memo");e.add(Ue(t));for(let n of Ra())e.add(n);return Array.from(e)}function Oa(e){return Hr().some(n=>Ia(e,n))}function Fr(e){if(Oa(e))return null;let t=Hr();return`sandbox \u62D2\u7EDD\u5199\u5165: ${e} \u4E0D\u5728\u5141\u8BB8\u76EE\u5F55\u5185 (${t.join(", ")})`}var Da=me.object({old_string:me.string().min(1,"old_string cannot be empty"),new_string:me.string(),replace_all:me.boolean().optional()}).strict(),Ua=me.object({file_path:me.string().min(1),old_string:me.string().optional(),new_string:me.string().optional(),replace_all:me.boolean().optional(),edits:me.array(Da).min(1).optional()}).superRefine((e,t)=>{let n=!!(e.edits&&e.edits.length>0),r=e.old_string!==void 0||e.new_string!==void 0||e.replace_all!==void 0;if(n&&r){t.addIssue({code:me.ZodIssueCode.custom,message:"Use either edits or old_string/new_string fields, not both."});return}if(!n){if(typeof e.old_string!="string"||typeof e.new_string!="string"){t.addIssue({code:me.ZodIssueCode.custom,message:"Provide old_string/new_string, or use edits."});return}e.old_string.trim()||t.addIssue({code:me.ZodIssueCode.custom,message:"old_string cannot be empty",path:["old_string"]});return}for(let o=0;o<(e.edits?.length??0);o+=1){let s=e.edits?.[o];s&&(s.old_string.trim()||t.addIssue({code:me.ZodIssueCode.custom,message:"old_string cannot be empty",path:["edits",o,"old_string"]}))}}).strict();function Ha(e){let t=Fr(e);if(t)throw new Error(t)}function Fa(e){return e.edits&&e.edits.length>0?e.edits:[{old_string:e.old_string??"",new_string:e.new_string??"",replace_all:e.replace_all}]}var Br=N({name:"apply_patch",description:"Edit a local file by direct string replacement. Supports single replacement fields or batch edits.",inputSchema:Ua,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{let t=Ue(e.file_path);try{Ha(t),await La(t);let n=await Na(t,"utf8"),r=Fa(e),o=n,s=0;for(let i=0;i<r.length;i+=1){let a=r[i];if(!a)continue;let l=a.old_string,c=a.replace_all??!1;if(!o.includes(l))return r.length===1?f("apply_patch failed: target text not found.",!0):f(`apply_patch failed: target text not found at edit ${i+1}.`,!0);if(c){let u=o.split(l),d=u.length-1;o=u.join(a.new_string),s+=d}else o=o.replace(l,a.new_string),s+=1}return o===n?f("No changes made."):(await $a(t,o,"utf8"),f(`Success. Updated file: ${t}
15
+ Edits: ${r.length}
16
+ Replacements: ${s}`))}catch(n){return n.code==="ENOENT"?f(`apply_patch failed: file does not exist: ${t}`,!0):f(`apply_patch failed: ${n.message}`,!0)}}});import{readFile as Ba}from"fs/promises";import{z as be}from"zod";var Wr=500,jr=200,Wa=be.object({file_path:be.string().min(1),offset:be.number().int().positive().optional(),limit:be.number().int().positive().optional(),mode:be.enum(["slice","indentation"]).optional(),indentation:be.object({anchor_line:be.number().int().positive().optional(),max_levels:be.number().int().nonnegative().optional(),include_siblings:be.boolean().optional(),include_header:be.boolean().optional(),max_lines:be.number().int().positive().optional()}).strict().optional()}).strict();function ja(e){return e.length<=Wr?e:e.slice(0,Wr)}function za(e){let t=0;for(let n of e)if(n===" ")t+=1;else if(n===" ")t+=4;else break;return t}function qa(e){return e.split(/\r?\n/).map((n,r)=>({line:r+1,text:ja(n),indent:za(n)}))}function Ga(e){return e.map(t=>`L${t.line}: ${t.text}`).join(`
17
+ `)}function Ka(e,t,n){let r=t-1;if(r>=e.length)throw new Error("offset exceeds file length");return e.slice(r,r+n)}function Va(e,t){let n=t.offset??1,r=t.limit??jr,o=t.indentation,s=o?.anchor_line??n;if(s<=0||s>e.length)throw new Error("anchor_line exceeds file length");let i=e[s-1];if(!i)throw new Error("anchor_line exceeds file length");let a=o?.max_levels??0,l=o?.include_siblings??!0,c=o?.include_header??!0,u=o?.max_lines??r,d=Math.max(1,Math.min(r,u)),y=a===0?0:Math.max(0,i.indent-a*4),p=s-1,h=s-1;for(;p-1>=0;){let m=e[p-1];if(!m)break;let k=/^\s*(#|\/\/|--)/.test(m.text),v=m.text.trim().length===0;if(m.indent<y||!l&&m.indent===y&&!k&&!v||!c&&(k||v)&&m.indent<i.indent||(p-=1,h-p+1>=d))break}for(;h+1<e.length&&h-p+1<d;){let m=e[h+1];if(!m||m.indent<y||!l&&m.indent===y)break;h+=1}return e.slice(p,h+1)}var zr=N({name:"read_file",description:"Reads a local file with 1-indexed line numbers, supporting slice and indentation-aware block modes.",inputSchema:Wa,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??1,n=e.limit??jr;if(t<=0)return f("offset must be a 1-indexed line number",!0);if(n<=0)return f("limit must be greater than zero",!0);let r=e.file_path.trim();if(!r.startsWith("/"))return f("file_path must be an absolute path",!0);let o=Ue(r);try{let s=await Ba(o,"utf8"),i=qa(s);if(i.length===0)return f("");let l=(e.mode??"slice")==="indentation"?Va(i,e):Ka(i,t,n);return f(Ga(l))}catch(s){return f(`read_file failed: ${s.message}`,!0)}}});import{readdir as Xa,lstat as Ja}from"fs/promises";import{join as Ya}from"path";import{z as _t}from"zod";var Za=1,Qa=25,el=2,tl=_t.object({dir_path:_t.string().min(1),offset:_t.number().int().positive().optional(),limit:_t.number().int().positive().optional(),depth:_t.number().int().positive().optional()}).strict();function nl(e){let t=" ".repeat(e.displayDepth*2),n="";e.kind==="dir"&&(n="/"),e.kind==="symlink"&&(n="@"),e.kind==="other"&&(n="?");let r=e.path.split("/"),o=r[r.length-1]??e.path;return`${t}${o}${n}`}var qr=N({name:"list_dir",description:"Lists entries in a local directory with 1-indexed entry numbers and simple type labels.",inputSchema:tl,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??Za,n=e.limit??Qa,r=e.depth??el;if(t<=0)return f("offset must be a 1-indexed entry number",!0);if(n<=0)return f("limit must be greater than zero",!0);if(r<=0)return f("depth must be greater than zero",!0);let o=e.dir_path.trim();if(!o.startsWith("/"))return f("dir_path must be an absolute path",!0);let s=Ue(o);try{let i=[{absPath:s,depth:r,displayDepth:0}],a=[];for(;i.length>0;){let d=i.shift();if(!d)continue;let y=await Xa(d.absPath);y.sort((p,h)=>p.localeCompare(h));for(let p of y){let h=Ya(d.absPath,p),m=await Ja(h),k=m.isSymbolicLink()?"symlink":m.isDirectory()?"dir":m.isFile()?"file":"other";a.push({path:h,displayDepth:d.displayDepth,kind:k}),k==="dir"&&d.depth>1&&i.push({absPath:h,depth:d.depth-1,displayDepth:d.displayDepth+1})}}if(a.length===0)return f(`Absolute path: ${s}`);let l=t-1;if(l>=a.length)return f("offset exceeds directory entry count",!0);let c=a.slice(l,l+n),u=[`Absolute path: ${s}`,...c.map(nl)];return l+n<a.length&&u.push(`More than ${n} entries found`),f(u.join(`
18
+ `))}catch(i){return f(`list_dir failed: ${i.message}`,!0)}}});import{spawn as rl}from"child_process";import{resolve as ol}from"path";import{z as St}from"zod";var sl=100,il=2e3,al=3e4,ll=St.object({pattern:St.string().min(1),include:St.string().optional(),path:St.string().optional(),limit:St.number().int().positive().optional()}).strict();function cl(e){return new Promise((t,n)=>{let r=["--files-with-matches","--sortr=modified","--regexp",e.pattern,"--no-messages"];e.include?.trim()&&r.push("--glob",e.include.trim()),r.push("--",e.searchPath);let o=rl("rg",r,{cwd:e.cwd,stdio:["ignore","pipe","pipe"]}),s=[],i=[];o.stdout?.setEncoding("utf8"),o.stderr?.setEncoding("utf8"),o.stdout?.on("data",l=>s.push(l)),o.stderr?.on("data",l=>i.push(l));let a=setTimeout(()=>{o.kill("SIGTERM"),n(new Error("rg timed out after 30 seconds"))},al);o.on("error",l=>{clearTimeout(a),n(l)}),o.on("close",l=>{clearTimeout(a),t({exitCode:typeof l=="number"?l:-1,stdout:s.join(""),stderr:i.join("")})})})}var Gr=N({name:"grep_files",description:"Finds files whose contents match the pattern and lists them by modification time.",inputSchema:ll,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.pattern.trim();if(!t)return f("pattern must not be empty",!0);let n=Math.min(e.limit??sl,il),r=e.path?.trim()?ol(process.cwd(),e.path.trim()):process.cwd();try{let o=await cl({pattern:t,include:e.include,searchPath:r,cwd:process.cwd(),limit:n});if(o.exitCode===1)return f("No matches found.");if(o.exitCode!==0)return f(`rg failed: ${o.stderr||o.stdout}`,!0);let s=o.stdout.split(/\r?\n/).map(i=>i.trim()).filter(Boolean).slice(0,n);return s.length===0?f("No matches found."):f(s.join(`
19
+ `))}catch(o){return f(`grep_files failed: ${o.message}`,!0)}}});import{z as He}from"zod";var Kr=null;function On(e){Kr=e}function Vr(){return Kr}var ul=He.object({server:He.string().optional(),cursor:He.string().optional()}).strict(),pl=He.object({server:He.string().optional(),cursor:He.string().optional()}).strict(),ml=He.object({server:He.string().min(1),uri:He.string().min(1)}).strict();function Ln(){let e=Vr();if(!e)throw new Error("MCP pool is not initialized");return e}var Xr=N({name:"list_mcp_resources",description:"Lists resources provided by MCP servers. Prefer resources over web search when possible.",inputSchema:ul,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=Ln();if(e?.trim()){let s=n.get(e.trim());if(!s)return f(`MCP server not found: ${e}`,!0);let i=await s.client.listResources(t?{cursor:t}:void 0);return f(JSON.stringify({server:s.name,resources:i.resources,nextCursor:i.nextCursor},null,2))}if(t)return f("cursor is only supported when server is specified",!0);let r=n.getAll().sort((s,i)=>s.name.localeCompare(i.name)),o=[];for(let s of r){let i=await s.client.listResources();for(let a of i.resources)o.push({server:s.name,...a})}return f(JSON.stringify({resources:o},null,2))}catch(n){return f(`list_mcp_resources failed: ${n.message}`,!0)}}}),Jr=N({name:"list_mcp_resource_templates",description:"Lists resource templates provided by MCP servers. Prefer resource templates over web search when possible.",inputSchema:pl,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=Ln();if(e?.trim()){let s=n.get(e.trim());if(!s)return f(`MCP server not found: ${e}`,!0);let i=await s.client.listResourceTemplates(t?{cursor:t}:void 0);return f(JSON.stringify({server:s.name,resourceTemplates:i.resourceTemplates,nextCursor:i.nextCursor},null,2))}if(t)return f("cursor is only supported when server is specified",!0);let r=n.getAll().sort((s,i)=>s.name.localeCompare(i.name)),o=[];for(let s of r){let i=await s.client.listResourceTemplates();for(let a of i.resourceTemplates)o.push({server:s.name,...a})}return f(JSON.stringify({resourceTemplates:o},null,2))}catch(n){return f(`list_mcp_resource_templates failed: ${n.message}`,!0)}}}),Yr=N({name:"read_mcp_resource",description:"Read a specific resource from an MCP server given the server name and resource URI.",inputSchema:ml,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,uri:t})=>{try{let r=Ln().get(e);if(!r)return f(`MCP server not found: ${e}`,!0);let o=await r.client.readResource({uri:t});return f(JSON.stringify({server:e,uri:t,...o},null,2))}catch(n){return f(`read_mcp_resource failed: ${n.message}`,!0)}}});import{z as it}from"zod";var dl=it.object({step:it.string().min(1),status:it.enum(["pending","in_progress","completed"])}).strict(),fl=it.object({explanation:it.string().optional(),plan:it.array(dl).min(1)}).strict(),Zr=[],Qr=N({name:"update_plan",description:"Updates the task plan. At most one step can be in_progress at a time.",inputSchema:fl,supportsParallelToolCalls:!1,isMutating:!1,execute:async({explanation:e,plan:t})=>{if(t.filter(r=>r.status==="in_progress").length>1)return f("At most one step can be in_progress at a time",!0);if(t.length<4){let r=t[0]?.step??"";return f(`<system_hint tool="update_plan" reason="simple_task">Task "${r}" is simple (${t.length} step${t.length>1?"s":""}) - execute directly without update_plan.</system_hint>`)}return Zr=t,f(JSON.stringify({message:"Plan updated",explanation:e,plan:Zr},null,2))}});import{readFile as gl}from"fs/promises";import{homedir as hl}from"os";import{join as eo}from"path";import{z as to}from"zod";var yl=to.object({memory_id:to.string().min(1)}).strict();function Tl(){let e=process.env.MEMO_HOME?.trim()||eo(hl(),".memo");return eo(e,"Agents.md")}var no=N({name:"get_memory",description:"Loads the stored memory payload for a memory_id.",inputSchema:yl,supportsParallelToolCalls:!0,isMutating:!1,execute:async({memory_id:e})=>{try{let t=Tl(),n=await gl(t,"utf8");return f(JSON.stringify({memory_id:e,memory_summary:n},null,2))}catch{return f(`memory not found for memory_id=${e}`,!0)}}});import{z as ro}from"zod";var _l=ro.object({url:ro.string().min(1)}).strict(),oo=1e4,vt=512e3,Nn=4e3,Sl=new Set(["http:","https:","data:"]),vl=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,xl=/<\s*(br|hr)\s*\/?>/gi,Cl=/<\s*li[^>]*>/gi,bl=/<[^>]+>/g,Al=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,El=e=>e.replace(/&nbsp;/gi," ").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&amp;/gi,"&").replace(/&quot;/gi,'"').replace(/&#39;/g,"'").replace(/&#(x?[0-9a-fA-F]+);/g,(r,o)=>{try{let s=o.startsWith("x")||o.startsWith("X")?parseInt(o.slice(1),16):parseInt(o,10);return Number.isFinite(s)?String.fromCharCode(s):""}catch{return""}}),Ml=e=>{let r=e.replace(Al," ").replace(Cl,"- ").replace(xl,`
20
+ `).replace(vl,`
21
+ `).replace(bl," "),s=El(r).replace(/\r/g,"").split(`
22
+ `).map(a=>a.trim().replace(/[ \t]{2,}/g," "));return s.filter((a,l)=>a.length>0||l>0&&(s[l-1]?.length??0)>0).join(`
23
+ `).trim()},wl=e=>e.replace(/\s+/g," ").trim(),so=N({name:"webfetch",description:"HTTP GET request, returns processed plain text body (automatically strips HTML tags)",inputSchema:_l,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t;try{t=new URL(e.url)}catch{return f(`Invalid URL: ${e.url}`,!0)}if(!Sl.has(t.protocol))return f(`Unsupported protocol: ${t.protocol}`,!0);let n=new AbortController,r=setTimeout(()=>n.abort(),oo);try{let o=await globalThis.fetch(t,{signal:n.signal}),s=o.headers.get("content-length"),i=s?Number(s):void 0;if(i&&i>vt)return f(`Request rejected: response body too large (${i} bytes)`,!0);let a=0,l="";if(o.body&&o.body.getReader){let k=o.body.getReader(),v=[];for(;;){let{done:ee,value:q}=await k.read();if(ee)break;if(q){if(a+=q.byteLength,a>vt)return n.abort(),f(`Request aborted: response body exceeds ${vt} bytes`,!0);v.push(q)}}let S=new Uint8Array(a),W=0;for(let ee of v)S.set(ee,W),W+=ee.byteLength;l=new TextDecoder().decode(S)}else if(l=await o.text(),a=new TextEncoder().encode(l).byteLength,a>vt)return f(`Request rejected: response body exceeds ${vt} bytes`,!0);let c=o.headers.get("content-type")||"",u=/text\/html/i.test(c)||/^\s*<!doctype html/i.test(l)||/^\s*<html[\s>]/i.test(l),d=u?Ml(l):l.trim(),y=wl(d),p=y.length>Nn?`${y.slice(0,Nn)}...`:y,h=y.length>Nn?" text_truncated=true":"",m=u?" source=html_stripped":"";return f(`status=${o.status} bytes=${a} text_chars=${y.length} text="${p}"${h}${m}`)}catch(o){return o.name==="AbortError"?f(`Request timeout or aborted (${oo}ms)`,!0):f(`Request failed: ${o.message}`,!0)}finally{clearTimeout(r)}}});import{spawn as kl}from"child_process";import{existsSync as Pl}from"fs";import{resolve as Il}from"path";import{z as le}from"zod";var Rl=3e4,Ol=1e4,Ll=3e5,io=4,Nl=1500,ao=2e3,ze=new Map,$l=le.object({message:le.string().min(1),agent_type:le.string().optional()}).strict(),Dl=le.object({id:le.string().min(1),message:le.string().min(1),interrupt:le.boolean().optional()}).strict(),Ul=le.object({id:le.string().min(1)}).strict(),Hl=le.object({ids:le.array(le.string().min(1)).min(1),timeout_ms:le.number().int().positive().optional()}).strict(),Fl=le.object({id:le.string().min(1)}).strict();function at(){return new Date().toISOString()}function $n(e){return f(`agent not found: ${e}`,!0)}function Bl(){let e=process.env.MEMO_SUBAGENT_MAX_AGENTS?.trim();if(!e)return io;let t=Number(e);return!Number.isFinite(t)||t<=0?io:Math.floor(t)}function Wl(){let e=0;for(let t of ze.values())t.running&&(e+=1);return e}function jl(){let e=process.env.MEMO_SUBAGENT_COMMAND?.trim();if(e)return e;let t=Il(process.cwd(),"dist/index.js");return Pl(t)?`node ${JSON.stringify(t)} --dangerous`:"memo --dangerous"}function zl(e){return e!=="running"}function ql(e){return new Promise(t=>{setTimeout(t,e)})}function Gl(e){return e===void 0?Rl:e<=0?null:Math.max(Ol,Math.min(Ll,e))}function Kl(e){return e.length<=ao?e:`${e.slice(0,ao)}
24
+ ...[truncated]`}function Vl(e,t){let n=[],r=e.trim(),o=t.trim();return r&&n.push(r),o&&n.push(`stderr:
25
+ ${o}`),Kl(n.join(`
26
+
27
+ `))}async function lo(e){let t=e.running;if(!t)return;t.interrupted=!0;let n=t.process;n.exitCode!==null||n.killed||await new Promise(r=>{let o=!1,s=()=>{o||(o=!0,clearTimeout(i),n.off("close",s),r())},i=setTimeout(()=>{if(n.exitCode===null)try{n.kill("SIGKILL")}catch{s()}},Nl);n.on("close",s);try{n.kill("SIGTERM")}catch{s()}})}function Xl(e){let t=ze.get(e);return t?t.status:"not_found"}function Jl(e){let t=ze.get(e);return t?{status:t.status,last_message:t.lastMessage,last_output:t.lastOutput,last_error:t.lastError,last_submission_id:t.lastSubmissionId,updated_at:t.updatedAt}:{status:"not_found",last_message:null,last_output:null,last_error:null,last_submission_id:null,updated_at:null}}function Yl(e){return{agent_id:e.id,status:e.status,created_at:e.createdAt,updated_at:e.updatedAt,last_message:e.lastMessage,last_submission_id:e.lastSubmissionId,has_last_output:!!e.lastOutput,has_last_error:!!e.lastError}}function Zl(e){let{record:t,submissionId:n,stdout:r,stderr:o,exitCode:s,interrupted:i}=e;if(!(!t.running||t.running.id!==n)&&(t.running=null,t.updatedAt=at(),t.lastOutput=Vl(r,o)||null,t.lastError=null,t.status!=="closed")){if(i){t.status="errored",t.lastError="interrupted",t.statusBeforeClose="errored";return}if(s===0){t.status="completed",t.statusBeforeClose="completed";return}t.status="errored",t.lastError=`submission failed with exit code ${s}`,t.statusBeforeClose="errored"}}async function co(e,t){let n=Bl();if(Wl()>=n)throw new Error(`subagent concurrency limit reached (${n})`);let r=crypto.randomUUID(),o=jl(),s=kl(o,{cwd:process.cwd(),env:{...process.env},shell:!0,stdio:["pipe","pipe","pipe"]}),i=[],a=[];s.stdout?.setEncoding("utf8"),s.stderr?.setEncoding("utf8"),s.stdout?.on("data",l=>i.push(l)),s.stderr?.on("data",l=>a.push(l)),s.on("error",l=>{a.push(`[spawn error] ${l.message}`)}),e.running={id:r,message:t,process:s,startedAt:at(),interrupted:!1},e.status="running",e.lastMessage=t,e.lastSubmissionId=r,e.updatedAt=at(),s.on("close",l=>{let c=typeof l=="number"?l:-1,u=!!(e.running?.id===r&&e.running.interrupted);Zl({record:e,submissionId:r,stdout:i.join(""),stderr:a.join(""),exitCode:c,interrupted:u})});try{s.stdin?.write(`${t.trim()}
28
+ `)}catch{}try{s.stdin?.end()}catch{}return r}var uo=N({name:"spawn_agent",description:"Spawn a sub-agent for a well-scoped task and return the agent id.",inputSchema:$l,supportsParallelToolCalls:!1,isMutating:!0,execute:async({message:e})=>{let t=e.trim();if(!t)return f("spawn_agent failed: message must not be empty",!0);let n=crypto.randomUUID(),r=at(),o={id:n,createdAt:r,updatedAt:r,status:"running",statusBeforeClose:"completed",lastMessage:t,lastSubmissionId:null,lastOutput:null,lastError:null,running:null};ze.set(n,o);try{let s=await co(o,t);return f(JSON.stringify({...Yl(o),submission_id:s},null,2))}catch(s){return ze.delete(n),f(`spawn_agent failed: ${s.message}`,!0)}}}),po=N({name:"send_input",description:"Send a message to an existing agent.",inputSchema:Dl,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e,message:t,interrupt:n})=>{let r=ze.get(e);if(!r)return $n(e);let o=t.trim();if(!o)return f("send_input failed: message must not be empty",!0);if(r.status==="closed")return f(`send_input failed: agent ${e} is closed; run resume_agent first`,!0);if(r.running){if(!n)return f(`send_input failed: agent ${e} is busy; set interrupt=true to cancel current submission`,!0);await lo(r)}try{let s=await co(r,o);return f(JSON.stringify({agent_id:r.id,status:r.status,submission_id:s},null,2))}catch(s){return f(`send_input failed: ${s.message}`,!0)}}}),mo=N({name:"resume_agent",description:"Resume a previously closed agent by id.",inputSchema:Ul,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=ze.get(e);return t?(t.status==="closed"&&(t.status=t.statusBeforeClose,t.updatedAt=at()),f(JSON.stringify({agent_id:e,status:t.status},null,2))):$n(e)}}),fo=N({name:"wait",description:"Wait for agent statuses and return current snapshots.",inputSchema:Hl,supportsParallelToolCalls:!1,isMutating:!1,execute:async({ids:e,timeout_ms:t})=>{let n=Gl(t);if(n===null)return f("wait failed: timeout_ms must be greater than zero",!0);let r=()=>{let i={},a={};for(let l of e){let c=Xl(l);zl(c)&&(i[l]=c,a[l]=Jl(l))}return{status:i,details:a}},o=r();if(Object.keys(o.status).length>0)return f(JSON.stringify({status:o.status,details:o.details,timed_out:!1},null,2));let s=Date.now()+n;for(;Date.now()<s;)if(await ql(100),o=r(),Object.keys(o.status).length>0)return f(JSON.stringify({status:o.status,details:o.details,timed_out:!1},null,2));return f(JSON.stringify({status:{},details:{},timed_out:!0},null,2))}}),go=N({name:"close_agent",description:"Close an agent and return its last known status.",inputSchema:Fl,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=ze.get(e);return t?t.status==="closed"?f(JSON.stringify({agent_id:e,status:"closed"},null,2)):(t.statusBeforeClose=t.running?"completed":t.status,t.status="closed",t.updatedAt=at(),await lo(t),f(JSON.stringify({agent_id:e,status:"closed"},null,2))):$n(e)}});var Dn={list_mcp_resources:"read",list_mcp_resource_templates:"read",read_mcp_resource:"read",update_plan:"read",get_memory:"read",webfetch:"read",read_file:"read",list_dir:"read",grep_files:"read",wait:"read",spawn_agent:"read",send_input:"read",resume_agent:"read",close_agent:"read",apply_patch:"write",shell:"execute",shell_command:"execute",exec_command:"execute",write_stdin:"execute"},ho=new Set(["spawn_agent","send_input","resume_agent","wait","close_agent"]),jt={read:0,write:1,execute:2},yo=["exec","run","shell","command","stdin"],To=["write","patch","create","delete","modify","update"],_o=["read","get","fetch","search","list","find"],So=new Set(["write","execute"]);function Hn(e){let t={...Dn,...e?.customLevels};return{getRiskLevel(n){if(n in t)return t[n];let r=n.toLowerCase();return Un(r,yo)?"execute":Un(r,To)?"write":Un(r,_o)?"read":"write"},compareRisk(n,r){return jt[n]-jt[r]},needsApproval(n,r){return r==="strict"?!0:So.has(n)}}}function Un(e,t){return t.some(n=>e.includes(n))}import{createHash as Ql}from"crypto";function zt(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map(n=>zt(n)).join(",")+"]":`{${Object.entries(e).sort(([n],[r])=>n.localeCompare(r)).map(([n,r])=>`${JSON.stringify(n)}:${zt(r)}`).join(",")}}`}function Fn(e,t){let n=zt(t),r=`${e}:${n}`;return Ql("sha256").update(r).digest("hex").slice(0,16)}function ec(e){return`Tool "${e}" requires approval.`}function Bn(e){let{mode:t="auto",dangerous:n=!1,toolRiskLevels:r}=e||{},o=t==="strict"?"strict":"auto";if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let s=Hn({customLevels:r}),i={sessionTools:new Set,onceTools:new Set,deniedTools:new Set,toolByFingerprint:new Map};return{get isDangerousMode(){return!1},getRiskLevel(a){return s.getRiskLevel(a)},check(a,l){if(ho.has(a))return{needApproval:!1,decision:"auto-execute"};let c=s.getRiskLevel(a);if(!s.needsApproval(c,o))return{needApproval:!1,decision:"auto-execute"};let u=Fn(a,l);return i.toolByFingerprint.set(u,a),i.sessionTools.has(a)||i.onceTools.has(a)?{needApproval:!1,decision:"auto-execute"}:i.deniedTools.has(a)?{needApproval:!0,fingerprint:u,riskLevel:c,reason:"This request was previously denied.",toolName:a,params:l}:{needApproval:!0,fingerprint:u,riskLevel:c,reason:ec(a),toolName:a,params:l}},recordDecision(a,l){let c=i.toolByFingerprint.get(a);if(c)switch(i.sessionTools.delete(c),i.onceTools.delete(c),i.deniedTools.delete(c),l){case"session":i.sessionTools.add(c);break;case"once":i.onceTools.add(c);break;case"deny":i.deniedTools.add(c);break}},isGranted(a){let l=i.toolByFingerprint.get(a);return l?i.sessionTools.has(l)||i.onceTools.has(l):!1},clearOnceApprovals(){i.onceTools.clear()},dispose(){i.sessionTools.clear(),i.onceTools.clear(),i.deniedTools.clear(),i.toolByFingerprint.clear()}}}var vo=12e3;function tc(){let e=process.env.MEMO_TOOL_RESULT_MAX_CHARS?.trim();if(!e)return vo;let t=Number(e);return!Number.isFinite(t)||t<=0?vo:Math.floor(t)}function nc(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function rc(e){let t=0;for(let n of e.content??[]){if(n.type==="text"){t+=n.text.length;continue}try{t+=JSON.stringify(n).length}catch{t+=100}}return t}function oc(e,t,n){return`<system_hint type="tool_output_omitted" tool="${nc(e)}" reason="too_long" actual_chars="${t}" max_chars="${n}">Tool output too long, automatically omitted. Please narrow the scope or add limit parameters and try again.</system_hint>`}function sc(e,t){let n=tc(),r=rc(t);return r<=n?t:{content:[{type:"text",text:oc(e,r,n)}],isError:!1}}function ic(e){return(e.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
29
+ `)}function ac(e,t){let n=t;if(typeof t=="string"){let r=t.trim();if(r)try{n=JSON.parse(r)}catch{n=r}else n={}}return typeof n!="object"||n===null?{ok:!1,error:`${e.name} invalid input: expected object`}:typeof e.validateInput=="function"?e.validateInput(n):{ok:!0,data:n}}function lc(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("sandbox")||t.includes("permission denied")||t.includes("operation not permitted")||t.includes("eacces")?"sandbox_denied":"execution_failed"}var Wn=class{constructor(t){this.config=t;this.approvalManager=Bn(t.approval)}approvalManager;async executeAction(t,n){let r=Date.now(),o=t.id??`${t.name}:${r}`,s=this.approvalManager.check(t.name,t.input);if(s.needApproval){let a={toolName:s.toolName,params:s.params,fingerprint:s.fingerprint,riskLevel:s.riskLevel,reason:s.reason};await n?.onApprovalRequest?.(a);let l=n?.requestApproval?await n.requestApproval(a):"deny";if(this.approvalManager.recordDecision(s.fingerprint,l),await n?.onApprovalResponse?.({fingerprint:s.fingerprint,decision:l}),l==="deny")return{actionId:o,tool:t.name,status:"approval_denied",errorType:"approval_denied",success:!1,observation:`User denied tool execution: ${t.name}`,durationMs:Date.now()-r,rejected:!0}}let i=this.config.tools[t.name];if(!i)return{actionId:o,tool:t.name,status:"tool_not_found",errorType:"tool_not_found",success:!1,observation:`Unknown tool: ${t.name}`,durationMs:Date.now()-r};try{let a=ac(i,t.input);if(!a.ok)return{actionId:o,tool:t.name,status:"input_invalid",errorType:"input_invalid",success:!1,observation:a.error,durationMs:Date.now()-r};let l=await i.execute(a.data),c=sc(t.name,l);return{actionId:o,tool:t.name,status:"success",success:!0,observation:ic(c)||"(no tool output)",durationMs:Date.now()-r}}catch(a){let l=lc(a);return{actionId:o,tool:t.name,status:l,errorType:l,success:!1,observation:`Tool execution failed: ${a.message}`,durationMs:Date.now()-r}}}async executeActions(t,n={}){let r=n.executionMode??"sequential",o=n.failurePolicy??(n.stopOnRejection===!1?"collect_all":"fail_fast"),s=[];if(r==="parallel"){let l=await Promise.all(t.map(c=>this.executeAction(c,n)));if(o==="fail_fast"){let c=l.findIndex(u=>u.rejected);s=c>=0?l.slice(0,c+1):l}else s=l}else for(let l of t){let c=await this.executeAction(l,n);if(s.push(c),c.rejected&&o==="fail_fast")break}let i=s.some(l=>l.rejected),a=s.map(l=>`[${l.tool}]: ${l.observation}`).join(`
30
+
31
+ `);return{results:s,combinedObservation:a,hasRejection:i,executionMode:r,failurePolicy:o}}clearOnceApprovals(){this.approvalManager.clearOnceApprovals()}dispose(){this.approvalManager.dispose()}};function xo(e){return new Wn(e)}var qt=class{tools=new Map;register(t){this.tools.set(t.name,t)}registerMany(t){for(let n of t)this.register(n)}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,r]of this.tools)t[n]=r;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}};import{Client as cc}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as uc}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as pc}from"@modelcontextprotocol/sdk/client/stdio.js";function mc(e){if(!e)return;let t={...process.env,...e},n=Object.entries(t).filter(r=>typeof r[1]=="string");return Object.fromEntries(n)}function Co(){return new cc({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function dc(e){if(!(!e||Object.keys(e).length===0))return{headers:e}}function fc(e){let t={...e.http_headers??e.headers??{}};if(e.bearer_token_env_var){let n=process.env[e.bearer_token_env_var];n&&!t.Authorization&&(t.Authorization=`Bearer ${n}`)}return t}async function gc(e){let t=new URL(e.url),n=dc(fc(e));try{let r=Co(),o=new uc(t,{requestInit:n});return await r.connect(o),{client:r,transport:o}}catch(r){let o=`Failed to connect via streamable_http (${r.message})`,s=new Error(o);throw s.cause=r,s}}async function hc(e){if("url"in e)return gc(e);let t={command:e.command,args:e.args,env:mc(e.env),stderr:e.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},n=new pc(t),r=Co();return await r.connect(n),{client:r,transport:n}}var Gt=class{connections=new Map;async connect(t,n){let r=this.connections.get(t);if(r)return r;let{client:o,transport:s}=await hc(n),i=await o.listTools(),a={name:t,client:o,transport:s,tools:(i.tools||[]).map(l=>({name:`${t}_${l.name}`,description:l.description||`Tool from ${t}: ${l.name}`,source:"mcp",serverName:t,originalName:l.name,inputSchema:l.inputSchema,execute:async()=>({content:[]})}))};return this.connections.set(t,a),a}get(t){return this.connections.get(t)}getAll(){return Array.from(this.connections.values())}getAllTools(){let t=[];for(let n of this.connections.values())for(let r of n.tools)t.push({name:r.name,description:r.description,serverName:r.serverName,originalName:r.originalName,inputSchema:r.inputSchema,client:n.client});return t}async closeAll(){let t=Array.from(this.connections.values()).map(async n=>{try{await n.client.close()}catch(r){console.error(`[MCP] Error closing client ${n.name}:`,r)}});await Promise.all(t),this.connections.clear()}get size(){return this.connections.size}};var Kt=class{pool;tools=new Map;shouldLog;constructor(){this.pool=new Gt,On(this.pool),this.shouldLog=!(process.stdout.isTTY&&process.stdin.isTTY)}async loadServers(t){if(!t||Object.keys(t).length===0)return 0;let n=0;return await Promise.all(Object.entries(t).map(async([r,o])=>{try{let s=await this.pool.connect(r,o);for(let i of s.tools){let a={...i,execute:async l=>{let c=this.pool.get(i.serverName)?.client;if(!c)throw new Error(`MCP client for server '${i.serverName}' not found`);return c.callTool({name:i.originalName,arguments:l})}};this.tools.set(a.name,a)}n+=s.tools.length,this.shouldLog&&console.log(`[MCP] Connected to '${r}' with ${s.tools.length} tools`)}catch(s){this.shouldLog&&console.error(`[MCP] Failed to connect to server '${r}':`,s)}})),n}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,r]of this.tools)t[n]=r;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}async dispose(){await this.pool.closeAll(),this.tools.clear(),On(null)}getPool(){return this.pool}};var Vt=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new qt,this.mcpRegistry=new Kt}registerNativeTool(t){this.nativeRegistry.register(t)}registerNativeTools(t){for(let n of t)this.registerNativeTool(n)}async loadMcpServers(t){return this.mcpRegistry.loadServers(t)}getTool(t){return this.nativeRegistry.get(t)??this.mcpRegistry.get(t)}getAllTools(){return[...this.nativeRegistry.getAll(),...this.mcpRegistry.getAll()]}toRegistry(){return{...this.nativeRegistry.toRegistry(),...this.mcpRegistry.toRegistry()}}hasTool(t){return this.nativeRegistry.has(t)||this.mcpRegistry.has(t)}getToolCount(){let t=this.nativeRegistry.size,n=this.mcpRegistry.size;return{native:t,mcp:n,total:t+n}}async execute(t,n){let r=this.getTool(t);if(!r)throw new Error(`Tool '${t}' not found`);return r.execute(n)}generateToolDefinitions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema||{type:"object",properties:{}}}))}generateToolDescriptions(){let t=this.getAllTools();if(t.length===0)return"";let n=[];n.push("## Available Tools"),n.push("");let r=t.filter(s=>s.source==="native"),o=t.filter(s=>s.source==="mcp");if(r.length>0){n.push("### Built-in Tools"),n.push("");for(let s of r)n.push(this.formatToolDescription(s));n.push("")}if(o.length>0){n.push("### External MCP Tools"),n.push("");let s=this.groupByServer(o);for(let[i,a]of Object.entries(s)){n.push(`**Server: ${i}**`),n.push("");for(let l of a)n.push(this.formatToolDescription(l));n.push("")}}return n.join(`
32
+ `)}formatToolDescription(t){let n=[];return n.push(`#### ${t.name}`),n.push(`- **Description**: ${t.description}`),t.inputSchema&&Object.keys(t.inputSchema).length>0&&n.push(`- **Input Schema**: ${JSON.stringify(t.inputSchema)}`),n.join(`
33
+ `)}groupByServer(t){let n={};for(let r of t)if(r.source==="mcp"){let o=r.serverName;n[o]||(n[o]=[]),n[o].push(r)}return n}getToolDescriptions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,source:t.source,serverName:t.source==="mcp"?t.serverName:void 0,inputSchema:t.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};function yc(e){let t=process.env[e]?.trim();return t?new Set(t.split(",").map(n=>n.trim()).filter(Boolean)):new Set}function Tc(){let e=[],t=process.env.MEMO_SHELL_TOOL_TYPE?.trim()||"unified_exec",n=yc("MEMO_EXPERIMENTAL_TOOLS"),r=n.size===0,o=process.env.MEMO_ENABLE_COLLAB_TOOLS!=="0",s=process.env.MEMO_ENABLE_MEMORY_TOOL!=="0";return t==="shell"?e.push(wr):t==="shell_command"?e.push(kr):t==="unified_exec"?e.push(An,En):t!=="disabled"&&e.push(An,En),e.push(Xr,Jr,Yr),e.push(Qr),e.push(Br),(r||n.has("grep_files"))&&e.push(Gr),(r||n.has("read_file"))&&e.push(zr),(r||n.has("list_dir"))&&e.push(qr),s&&e.push(no),e.push(so),o&&e.push(uo,po,mo,fo,go),e}function _c(e){let t={};for(let n of e)t[n.name]=n;return t}var Sc=_c(Tc()),vc=Object.values(Sc),bo=vc;import Dc from"openai";import{encoding_for_model as xc,get_encoding as Cc}from"@dqbd/tiktoken";var Ao="cl100k_base";function bc(e){let t=e?.trim()||Ao;try{let n=()=>xc(t);return n().free(),{model:t,factory:n}}catch{let n=Ao,r=()=>Cc(n);return r().free(),{model:n,factory:r}}}function Ac(e){if(e.role==="assistant"){let t=e.reasoning_content?`
34
+ ${e.reasoning_content}`:"";return e.tool_calls?.length?`${e.content}${t}
35
+ ${JSON.stringify(e.tool_calls)}`:`${e.content}${t}`}return e.role==="tool"?`${e.content}
36
+ ${e.tool_call_id}
37
+ ${e.name??""}`:e.content}function Eo(e){let{model:t,factory:n}=bc(e),r=n(),o=4,s=2,i=1,a=c=>c?r.encode(c).length:0;return{model:t,countText:a,countMessages:c=>{if(!c.length)return 0;let u=0;for(let d of c)u+=o,u+=a(Ac(d)),d.name&&(u+=i);return u+=s,u},dispose:()=>r.free()}}import{mkdir as Ec,writeFile as Mc,readFile as wc,access as kc}from"fs/promises";import{homedir as Mo}from"os";import{dirname as Pc,join as Ct}from"path";import{randomUUID as cg}from"crypto";import{parse as Ic}from"toml";var Rc=Ct(Mo(),".memo"),Oc="sessions",xt={current_provider:"deepseek",max_prompt_tokens:12e4,providers:[{name:"deepseek",env_api_key:"DEEPSEEK_API_KEY",model:"deepseek-chat",base_url:"https://api.deepseek.com"}],mcp_servers:{}};function Lc(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:JSON.stringify(e)}function Nc(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=[];for(let[n,r]of Object.entries(e)){if(!r)continue;let o=Array.isArray(r)?r:[r];for(let s of o){if(!s||typeof s!="object")continue;let i={...s};(typeof i.name!="string"||i.name.length===0)&&n&&(i.name=n),t.push(i)}}return t}function wo(e){return e.startsWith("~")?Ct(Mo(),e.slice(1)):e}function $c(e){let t=e.providers.map(s=>{let i=typeof s?.name=="string"?s.name:"";if(!i)return"";let l=[`[[providers.${Lc(i)}]]`,`name = ${JSON.stringify(i)}`,`env_api_key = ${JSON.stringify(String(s.env_api_key??""))}`,`model = ${JSON.stringify(String(s.model??""))}`];return s.base_url&&l.push(`base_url = ${JSON.stringify(String(s.base_url))}`),l.join(`
32
38
  `)}).filter(Boolean).join(`
33
39
 
34
- `),n="";t.mcp_servers&&Object.keys(t.mcp_servers).length>0&&(n=Object.entries(t.mcp_servers).map(([r,i])=>{if("url"in i){let h=[`[mcp_servers.${r}]`];h.push(`type = "${i.type??"streamable_http"}"`),h.push(`url = "${i.url}"`),i.bearer_token_env_var&&h.push(`bearer_token_env_var = ${JSON.stringify(i.bearer_token_env_var)}`);let w=i.http_headers??i.headers;if(w&&Object.keys(w).length>0){let f=Object.entries(w).map(([S,_])=>`${JSON.stringify(S)} = ${JSON.stringify(_)}`).join(", "),I=i.http_headers?"http_headers":"headers";h.push(`${I} = { ${f} }`)}return h.join(`
35
- `)}let l=i.args?`args = ${JSON.stringify(i.args)}`:"",a=i.type?`type = "${i.type}"
40
+ `),n="";e.mcp_servers&&Object.keys(e.mcp_servers).length>0&&(n=Object.entries(e.mcp_servers).map(([s,i])=>{if("url"in i){let p=[`[mcp_servers.${s}]`];p.push(`type = "${i.type??"streamable_http"}"`),p.push(`url = "${i.url}"`),i.bearer_token_env_var&&p.push(`bearer_token_env_var = ${JSON.stringify(i.bearer_token_env_var)}`);let h=i.http_headers??i.headers;if(h&&Object.keys(h).length>0){let m=Object.entries(h).map(([v,S])=>`${JSON.stringify(v)} = ${JSON.stringify(S)}`).join(", "),k=i.http_headers?"http_headers":"headers";p.push(`${k} = { ${m} }`)}return p.join(`
41
+ `)}let a=i.args?`args = ${JSON.stringify(i.args)}`:"",l=i.type?`type = "${i.type}"
36
42
  `:"",c=i.stderr?`stderr = "${i.stderr}"
37
- `:"",u=`[mcp_servers.${r}]
38
- ${a}command = "${i.command}"
39
- ${c}${l}`.trimEnd(),m=i.env?Object.entries(i.env):[];if(m.length===0)return u;let d=m.map(([h,w])=>`${JSON.stringify(h)} = ${JSON.stringify(w)}`).join(`
43
+ `:"",u=`[mcp_servers.${s}]
44
+ ${l}command = "${i.command}"
45
+ ${c}${a}`.trimEnd(),d=i.env?Object.entries(i.env):[];if(d.length===0)return u;let y=d.map(([p,h])=>`${JSON.stringify(p)} = ${JSON.stringify(h)}`).join(`
40
46
  `);return`${u}
41
47
 
42
- [mcp_servers.${r}.env]
43
- ${d}`}).join(`
48
+ [mcp_servers.${s}.env]
49
+ ${y}`}).join(`
50
+
51
+ `));let r=[`current_provider = "${e.current_provider}"`];return typeof e.max_prompt_tokens=="number"&&Number.isFinite(e.max_prompt_tokens)&&r.push(`max_prompt_tokens = ${Math.floor(e.max_prompt_tokens)}`),Array.isArray(e.active_mcp_servers)&&r.push(`active_mcp_servers = ${JSON.stringify(e.active_mcp_servers)}`),[r.join(`
52
+ `),t,n].filter(Boolean).join(`
53
+
54
+ `)}async function Se(e,t){await Ec(Pc(e),{recursive:!0}),await Mc(e,$c(t),"utf-8")}async function ce(){let e=process.env.MEMO_HOME?wo(process.env.MEMO_HOME):Rc,t=Ct(e,"config.toml");try{await kc(t);let n=await wc(t,"utf-8"),r=Ic(n),o=Nc(r.providers),s=typeof r.max_prompt_tokens=="number"&&Number.isFinite(r.max_prompt_tokens)&&r.max_prompt_tokens>0?Math.floor(r.max_prompt_tokens):void 0,i=Array.isArray(r.active_mcp_servers)?r.active_mcp_servers.filter(c=>typeof c=="string"&&c.trim().length>0):void 0,a={current_provider:r.current_provider??xt.current_provider,max_prompt_tokens:s??xt.max_prompt_tokens,providers:o,mcp_servers:r.mcp_servers??{},active_mcp_servers:i},l=!a.providers.length;return{config:l?xt:a,home:e,configPath:t,needsSetup:l}}catch{return{config:xt,home:e,configPath:t,needsSetup:!0}}}function Ye(e,t){let n=t||e.current_provider,r=e.providers.find(o=>o.name===n);return r||(e.providers?.[0]??xt.providers[0])}function Xt(e,t){let n=t.historyDir??Ct(e.home,Oc);return wo(n)}function ko(e,t){let n=new Date,r=String(n.getFullYear()),o=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),a=String(n.getMinutes()).padStart(2,"0"),l=String(n.getSeconds()).padStart(2,"0"),c=`rollout-${r}-${o}-${s}T${i}-${a}-${l}-${t}.jsonl`;return Ct(e,r,o,s,c)}function Uc(e,t){if(!e||!t)return e;let n=new Set(t.map(o=>o.trim()).filter(Boolean));if(n.size===0)return{};let r={};for(let[o,s]of Object.entries(e))n.has(o)&&(r[o]=s);return r}function Hc(e){try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,raw:e,error:t.message}}}function Fc(e){if(e.role==="assistant"){let t={role:"assistant",content:e.content,tool_calls:e.tool_calls?.map(n=>({id:n.id,type:n.type,function:{name:n.function.name,arguments:n.function.arguments}}))};return e.reasoning_content&&(t.reasoning_content=e.reasoning_content),t}return e.role==="tool"?{role:"tool",content:e.content,tool_call_id:e.tool_call_id}:{role:e.role,content:e.content}}function Bc(e){let t=e?.reasoning_content;if(typeof t!="string")return;let n=t.trim();return n.length>0?n:void 0}async function Po(e,t,n){let r=await ce(),o=r.config,s=new Vt;if(s.registerNativeTools(bo),await s.loadMcpServers(Uc(o.mcp_servers,t.activeMcpServers)),e.tools)for(let[y,p]of Object.entries(e.tools))s.registerNativeTool({name:y,description:p.description,source:"native",inputSchema:{type:"object"},execute:p.execute});let i=s.toRegistry(),a=async()=>{let y=await(e.loadPrompt??hr)(),p=s.generateToolDescriptions();return p&&(y+=`
44
55
 
45
- `));let o=[`current_provider = "${t.current_provider}"`];return typeof t.max_prompt_tokens=="number"&&Number.isFinite(t.max_prompt_tokens)&&o.push(`max_prompt_tokens = ${Math.floor(t.max_prompt_tokens)}`),[o.join(`
46
- `),e,n].filter(Boolean).join(`
56
+ ${p}`),y},l=s.generateToolDefinitions(),c=Xt(r,t),u=ko(c,n),d=new Bt(u);return{tools:i,dispose:async()=>{e.dispose&&await e.dispose(),await s.dispose()},callLLM:e.callLLM??(async(y,p,h)=>{let m=Ye(o,t.providerName),k=process.env[m.env_api_key]??process.env.OPENAI_API_KEY??process.env.DEEPSEEK_API_KEY;if(!k)throw new Error(`Missing env var ${m.env_api_key} (or OPENAI_API_KEY/DEEPSEEK_API_KEY)`);let v=new Dc({apiKey:k,baseURL:m.base_url}),S=y.map(Fc),W=h?.tools??l,ee=W.length>0?W.map(F=>({type:"function",function:{name:F.name,description:F.description,parameters:F.input_schema}})):void 0,q=await v.chat.completions.create({model:m.model,messages:S,tools:ee,tool_choice:ee?"auto":void 0},{signal:h?.signal}),V=q.choices?.[0]?.message,he=Bc(V);if(V?.tool_calls&&V.tool_calls.length>0){let F=[];V.content&&F.push({type:"text",text:V.content});for(let P of V.tool_calls)if(P.type==="function"){let ue=Hc(P.function.arguments);ue.ok?F.push({type:"tool_use",id:P.id,name:P.function.name,input:ue.data}):F.push({type:"text",text:`[tool_use parse error] ${ue.error}; raw: ${ue.raw}`})}let E=F.some(P=>P.type==="tool_use");return{content:F,reasoning_content:he,stop_reason:E?"tool_use":"end_turn",usage:{prompt:q.usage?.prompt_tokens??void 0,completion:q.usage?.completion_tokens??void 0,total:q.usage?.total_tokens??void 0}}}let A=V?.content;if(typeof A!="string")throw new Error("OpenAI-compatible API returned empty content");return{content:[{type:"text",text:A}],reasoning_content:he,stop_reason:"end_turn",usage:{prompt:q.usage?.prompt_tokens??void 0,completion:q.usage?.completion_tokens??void 0,total:q.usage?.total_tokens??void 0}}}),loadPrompt:a,historySinks:e.historySinks??[d],tokenCounter:e.tokenCounter??Eo(t.tokenizerModel),historyFilePath:u}}function Wc(e){let t=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,r=e.replace(n,(o,s,i)=>{let a=(i??"").trim();return a&&t.push(a),a});return{thinkingParts:t,cleaned:r.trim()}}function Io(e){if(e.length===0)return;let t=e.join(`
57
+ `),{thinkingParts:n,cleaned:r}=Wc(t);return n.length>0?n.join(`
47
58
 
48
- `)}async function le(t,e){await ka(Ia(t),{recursive:!0}),await Ma(t,Ua(e),"utf-8")}async function Q(){let t=process.env.MEMO_HOME?Eo(process.env.MEMO_HOME):La,e=Ve(t,"config.toml");try{await Ra(e);let n=await Pa(e,"utf-8"),o=Oa(n),s=Da(o.providers),r=typeof o.max_prompt_tokens=="number"&&Number.isFinite(o.max_prompt_tokens)&&o.max_prompt_tokens>0?Math.floor(o.max_prompt_tokens):void 0,i={current_provider:o.current_provider??Ke.current_provider,max_prompt_tokens:r??Ke.max_prompt_tokens,providers:s,mcp_servers:o.mcp_servers??{}},l=!i.providers.length;return{config:l?Ke:i,home:t,configPath:e,needsSetup:l}}catch{return{config:Ke,home:t,configPath:e,needsSetup:!0}}}function be(t,e){let n=e||t.current_provider,o=t.providers.find(s=>s.name===n);return o||(t.providers?.[0]??Ke.providers[0])}function mt(t,e){let n=e.historyDir??Ve(t.home,$a);return Eo(n)}function Ao(t,e){let n=new Date,o=String(n.getFullYear()),s=String(n.getMonth()+1).padStart(2,"0"),r=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),l=String(n.getMinutes()).padStart(2,"0"),a=String(n.getSeconds()).padStart(2,"0"),c=`rollout-${o}-${s}-${r}T${i}-${l}-${a}-${e}.jsonl`;return Ve(t,o,s,r,c)}function Fa(t){try{return{ok:!0,data:JSON.parse(t)}}catch(e){return{ok:!1,raw:t,error:e.message}}}function ja(t){return t.role==="assistant"?{role:"assistant",content:t.content,tool_calls:t.tool_calls?.map(e=>({id:e.id,type:e.type,function:{name:e.function.name,arguments:e.function.arguments}}))}:t.role==="tool"?{role:"tool",content:t.content,tool_call_id:t.tool_call_id}:{role:t.role,content:t.content}}async function wo(t,e,n){let o=await Q(),s=o.config,r=new pt;if(r.registerNativeTools(So),await r.loadMcpServers(s.mcp_servers),t.tools)for(let[d,h]of Object.entries(t.tools))r.registerNativeTool({name:d,description:h.description,source:"native",inputSchema:{type:"object"},execute:h.execute});let i=r.toRegistry(),l=async()=>{let d=await(t.loadPrompt??dn)(),h=r.generateToolDescriptions();return h&&(d+=`
59
+ `):r||void 0}import{randomUUID as Kc}from"crypto";var Jt="interactive";var jn="success",ct="Tool usage is disabled in the current permission mode. Switch to /tools once or /tools full to enable tools.",Ro=`Generate a concise session title based on the user's first prompt.
60
+ Requirements:
61
+ - 3 to 8 words when possible
62
+ - Keep it specific and descriptive
63
+ - Return title only, no quotes, no punctuation-only output
64
+ `;var jc="Skipped tool execution after previous rejection.",Oo="Tool execution skipped: tools are disabled in current permission mode.";function Lo(e){if(e.toolPermissionMode==="none")return{mode:"none",toolsDisabled:!0,dangerous:!1,approvalMode:"auto"};if(e.toolPermissionMode==="once")return{mode:"once",toolsDisabled:!1,dangerous:!1,approvalMode:"auto"};if(e.toolPermissionMode==="full")return{mode:"full",toolsDisabled:!1,dangerous:!0,approvalMode:"auto"};let t=e.dangerous??!1;return{mode:t?"full":"auto",toolsDisabled:!1,dangerous:t,approvalMode:"auto"}}function zn(){return{prompt:0,completion:0,total:0}}function qn(e,t){if(!t)return;let n=t.prompt??0,r=t.completion??0,o=t.total??n+r;e.prompt+=n,e.completion+=r,e.total+=o}function No(e){let t=e.content.filter(r=>r.type==="text"),n=e.content.filter(r=>r.type==="tool_use");return{textContent:t.map(r=>r.text).join(`
65
+ `),toolUseBlocks:n.map(r=>({id:r.id,name:r.name,input:r.input})),reasoningContent:typeof e.reasoning_content=="string"&&e.reasoning_content.trim().length>0?e.reasoning_content:void 0,stopReason:e.stop_reason,usage:e.usage}}async function $o(e,t){for(let n of t)try{await n.append(e)}catch(r){console.error(`Failed to write history event: ${r.message}`)}}function Gn(e){return e instanceof Error&&e.name==="AbortError"}function lt(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(n=>lt(n)).join(",")}]`:`{${Object.entries(e).sort(([n],[r])=>n.localeCompare(r)).map(([n,r])=>`${JSON.stringify(n)}:${lt(r)}`).join(",")}}`}function Do(e){return e.map(t=>({id:t.id,type:"function",function:{name:t.name,arguments:lt(t.input)}}))}function Uo(e,t){let n=e.trim();if(!n)return null;let r=[n],o=n.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);o?.[1]&&r.push(o[1].trim());for(let s of r)if(!(!s.startsWith("{")||!s.endsWith("}")))try{let i=JSON.parse(s);if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i,l=typeof a.tool=="string"?a.tool.trim():"";if(!l||!Object.prototype.hasOwnProperty.call(t,l))continue;return{tool:l,input:a.input??{}}}catch{}return null}function Ho(e){return e.length<=60?e:`${e.slice(0,57).trimEnd()}...`}function Fo(e){let t=e.replace(/\r?\n+/g," ").replace(/\s+/g," ").trim();if(!t)return"";let n=t.replace(/^["'`“”‘’]+|["'`“”‘’]+$/g,"").trim();return n?Ho(n):""}function Bo(e){let t=e.replace(/\s+/g," ").trim();if(!t)return"New Session";if(!t.includes(" "))return t.length<=20?t:`${t.slice(0,20).trimEnd()}...`;let r=t.split(" ").filter(Boolean).slice(0,8).join(" ");return Ho(r||t)}function Kn(e){return{role:"tool",content:e.observation,tool_call_id:e.actionId,name:e.tool}}function Wo(e,t,n){let r=new Map(t.map(o=>[o.actionId,o]));return e.map(o=>{let s=r.get(o.id);return s||{actionId:o.id,tool:o.name,status:n?"approval_denied":"execution_failed",errorType:n?"approval_denied":"execution_failed",success:!1,observation:n?`${jc} ${o.name}`:`Tool result missing for ${o.name}; execution aborted before producing output.`,durationMs:0,rejected:n?!0:void 0}})}import{randomUUID as Gc}from"crypto";function zc(){return{onTurnStart:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[],onTitleGenerated:[]}}function jo(e,t){t&&(t.onTurnStart&&e.onTurnStart.push(t.onTurnStart),t.onAction&&e.onAction.push(t.onAction),t.onObservation&&e.onObservation.push(t.onObservation),t.onFinal&&e.onFinal.push(t.onFinal),t.onApprovalRequest&&e.onApprovalRequest.push(t.onApprovalRequest),t.onApprovalResponse&&e.onApprovalResponse.push(t.onApprovalResponse),t.onTitleGenerated&&e.onTitleGenerated.push(t.onTitleGenerated))}function zo(e){let t=zc();if(jo(t,e.hooks),Array.isArray(e.middlewares))for(let n of e.middlewares)jo(t,n);return t}async function Q(e,t,n){let r=e[t];if(r.length)for(let o of r)try{await o(n)}catch(s){console.warn(`Hook ${t} failed: ${s.message}`)}}function ut(e){return e.map(t=>t.role==="assistant"&&t.tool_calls?.length?{...t,tool_calls:t.tool_calls.map(n=>({...n,function:{...n.function}}))}:{...t})}var Yt=class{constructor(t,n,r,o,s){this.deps=t;this.options=n;this.id=n.sessionId||Gc(),this.mode=n.mode||Jt,this.history=[{role:"system",content:r}],this.tokenCounter=o,this.sinks=t.historySinks??[],this.hooks=zo(t),this.historyFilePath=s;let i=Lo(n);this.toolsDisabled=i.toolsDisabled,this.toolPermissionMode=i.mode,this.toolOrchestrator=xo({tools:t.tools,approval:{dangerous:i.dangerous,mode:i.approvalMode}})}title;id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=zn();startedAt=Date.now();hooks;closed=!1;sessionStartEmitted=!1;currentAbortController=null;cancelling=!1;lastActionSignature=null;repeatedActionCount=0;toolOrchestrator;toolsDisabled=!1;toolPermissionMode="auto";async init(){}resetActionRepetition(){this.lastActionSignature=null,this.repeatedActionCount=0}maybeWarnRepeatedAction(t,n){let r=`${t}:${lt(n)}`;if(this.lastActionSignature===r?this.repeatedActionCount+=1:(this.lastActionSignature=r,this.repeatedActionCount=1),this.repeatedActionCount===3){let o=lt(n).slice(0,200),s=`\u7CFB\u7EDF\u63D0\u9192\uFF1A\u4F60\u5DF2\u8FDE\u7EED3\u6B21\u8C03\u7528\u540C\u4E00\u5DE5\u5177\u300C${t}\u300D\u4E14\u53C2\u6570\u76F8\u540C\uFF08${o}${o.length>=200?"\u2026":""}\uFF09\u3002\u8BF7\u786E\u8BA4\u662F\u5426\u9677\u5165\u5FAA\u73AF\uFF0C\u5FC5\u8981\u65F6\u76F4\u63A5\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\u6216\u8C03\u6574\u53C2\u6570\u3002`;this.history.push({role:"system",content:s})}}buildToolApprovalHooks(t,n){return{onApprovalRequest:async r=>{await Q(this.hooks,"onApprovalRequest",{sessionId:this.id,turn:t,step:n,request:r})},requestApproval:async r=>this.deps.requestApproval?this.deps.requestApproval(r):"deny",onApprovalResponse:async({fingerprint:r,decision:o})=>{await Q(this.hooks,"onApprovalResponse",{sessionId:this.id,turn:t,step:n,fingerprint:r,decision:o})}}}async executeToolAction(t,n,r,o,s){return this.toolOrchestrator.executeAction({id:t,name:n,input:r},this.buildToolApprovalHooks(o,s))}async maybeGenerateSessionTitle(t,n,r){if(t!==1||this.title)return;let o=Bo(n),s="fallback";try{let i=await this.deps.callLLM([{role:"system",content:Ro},{role:"user",content:n}],void 0,{signal:r,tools:[]}),a=Fo(i.content.filter(l=>l.type==="text").map(l=>l.text).join(" "));a&&(o=a,s="llm")}catch(i){if(Gn(i))return}this.title=o,await this.emitEvent("session_title",{turn:t,content:o,meta:{source:s,original_prompt:n}}),await Q(this.hooks,"onTitleGenerated",{sessionId:this.id,turn:t,title:o,originalPrompt:n})}async runTurn(t){let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let r=this.turnIndex,o=[],s=zn(),i=Date.now(),a=this.options.maxPromptTokens??12e4;if(!this.sessionStartEmitted){let l=this.history[0]?.role==="system"?this.history[0].content:void 0;await this.emitEvent("session_start",{content:l,role:l?"system":void 0,meta:{mode:this.mode,cwd:process.cwd(),tokenizer:this.tokenCounter.model,warnPromptTokens:this.options.warnPromptTokens,maxPromptTokens:a,toolPermissionMode:this.toolPermissionMode}}),this.sessionStartEmitted=!0}this.history.push({role:"user",content:t});try{let l=this.tokenCounter.countMessages(this.history);await this.emitEvent("turn_start",{turn:r,content:t,meta:{tokens:{prompt:l}}}),await Q(this.hooks,"onTurnStart",{sessionId:this.id,turn:r,input:t,promptTokens:l,history:ut(this.history)}),this.options.generateSessionTitle&&await this.maybeGenerateSessionTitle(r,t,n.signal);let c="",u="ok",d,y=0,p=null,h=-1;for(let m=0;;m++){let k=this.tokenCounter.countMessages(this.history);if(k>a){let M=`Context tokens (${k}) exceed the limit. Please shorten the input or restart the session.`;this.history.push({role:"assistant",content:M}),u="prompt_limit",c=M,d=M,await this.emitEvent("final",{turn:r,step:m,content:M,role:"assistant",meta:{tokens:{prompt:k}}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:M,status:u,errorMessage:d,turnUsage:{...s},steps:o});break}this.options.warnPromptTokens&&k>this.options.warnPromptTokens&&console.warn(`Prompt tokens are near the limit: ${k}`);let v="",S=[],W,ee,q,V=!1;try{let M=await this.deps.callLLM(this.history,ne=>{ne&&(V=!0),this.deps.onAssistantStep?.(ne,m)},{signal:n.signal}),R=No(M);v=R.textContent,S=R.toolUseBlocks,ee=R.stopReason,W=R.usage,q=R.reasoningContent,v.trim().length>0&&(p=v,h=m)}catch(M){if(this.cancelling&&Gn(M)){u="cancelled",c="",d="Turn cancelled",await this.emitEvent("final",{turn:r,step:m,content:"",role:"assistant",meta:{cancelled:!0}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,errorMessage:d,turnUsage:{...s},steps:o});break}let R=`LLM call failed: ${M.message}`;this.history.push({role:"assistant",content:R}),u="error",c=R,d=R,await this.emitEvent("final",{turn:r,content:R,role:"assistant"}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,errorMessage:d,turnUsage:{...s},steps:o});break}!V&&v&&this.deps.onAssistantStep?.(v,m);let he=S.length===0&&v?Uo(v,this.deps.tools):null,A,F=null;if(S.length>0){let M=S[0];if(M){let R=v?Io([v]):void 0;A={action:{tool:M.name,input:M.input},thinking:R},F={role:"assistant",content:v,reasoning_content:q,tool_calls:Do(S)}}else A={}}else v?(A={final:v},F={role:"assistant",content:v,reasoning_content:q}):A={};let E=this.tokenCounter.countText(v),P=W?.prompt??k,ue=W?.completion??E,Me=W?.total??P+ue,te={prompt:P,completion:ue,total:Me};if(qn(s,te),qn(this.sessionUsage,te),o.push({index:m,assistantText:v,parsed:A,tokenUsage:te}),await this.emitEvent("assistant",{turn:r,step:m,content:v,role:"assistant",meta:{tokens:te,protocol_violation:!!he,protocol_violation_count:he?y+1:y||void 0}}),he){y+=1;let M=`Model protocol error: returned plain-text tool JSON for "${he.tool}" ${y} times. Structured tool calls are required.`;u="error",c=M,d=M,this.history.push({role:"assistant",content:M}),await this.emitEvent("final",{turn:r,step:m,content:M,role:"assistant",meta:{error_type:"model_protocol_error",tool:he.tool,protocol_violation:!0,protocol_violation_count:y,tokens:te}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,errorMessage:d,tokenUsage:te,turnUsage:{...s},steps:o});break}if(F&&this.history.push(F),S.length>0&&this.toolsDisabled){for(let M of S)this.history.push({role:"tool",content:Oo,tool_call_id:M.id,name:M.name});u="error",c=ct,d=ct,this.history.push({role:"assistant",content:ct}),await this.emitEvent("final",{turn:r,step:m,content:ct,role:"assistant",meta:{error_type:"tool_disabled",tool_count:S.length,tools:S.map(M=>M.name).join(","),tokens:te}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:ct,status:u,errorMessage:d,tokenUsage:te,turnUsage:{...s},steps:o});break}if(S.length>1){for(let w of S)this.maybeWarnRepeatedAction(w.name,w.input);await this.emitEvent("action",{turn:r,step:m,meta:{tools:S.map(w=>w.name),action_ids:S.map(w=>w.id),action_id:S[0]?.id,parallel:!0,phase:"dispatch",thinking:A.thinking,toolBlocks:S.map(w=>({id:w.id,name:w.name,input:w.input}))}});let M=S[0];M&&await Q(this.hooks,"onAction",{sessionId:this.id,turn:r,step:m,action:{tool:M.name,input:M.input},parallelActions:S.map(w=>({tool:w.name,input:w.input})),thinking:A.thinking,history:ut(this.history)});let R=S.every(w=>!!this.deps.tools[w.name]?.supportsParallelToolCalls),ne=S.some(w=>!!this.deps.tools[w.name]?.isMutating),se=R&&!ne?"parallel":"sequential",Be=await this.toolOrchestrator.executeActions(S.map(w=>({id:w.id,name:w.name,input:w.input})),{...this.buildToolApprovalHooks(r,m),executionMode:se,failurePolicy:"fail_fast"}),we=Wo(S,Be.results,Be.hasRejection);for(let[w,Y]of we.entries())this.history.push(Kn(Y)),await this.emitEvent("observation",{turn:r,step:m,content:Y.observation,meta:{tool:Y.tool,index:w,action_id:Y.actionId,phase:"result",status:Y.status,error_type:Y.errorType,duration_ms:Y.durationMs,execution_mode:se}});let pe=we.map(w=>`[${w.tool}]: ${w.observation}`).join(`
49
66
 
50
- ${h}`),d},a=r.generateToolDefinitions(),c=mt(o,e),u=Ao(c,n),m=new ot(u);return{tools:i,dispose:async()=>{t.dispose&&await t.dispose(),await r.dispose()},callLLM:t.callLLM??(async(d,h,w)=>{let f=be(s,e.providerName),I=process.env[f.env_api_key]??process.env.OPENAI_API_KEY??process.env.DEEPSEEK_API_KEY;if(!I)throw new Error(`Missing env var ${f.env_api_key} (or OPENAI_API_KEY/DEEPSEEK_API_KEY)`);let S=new Ha({apiKey:I,baseURL:f.base_url}),_=d.map(ja),U=a.length>0?a.map(E=>({type:"function",function:{name:E.name,description:E.description,parameters:E.input_schema}})):void 0,N=await S.chat.completions.create({model:f.model,messages:_,tools:U,tool_choice:U?"auto":void 0},{signal:w?.signal}),M=N.choices?.[0]?.message;if(M?.tool_calls&&M.tool_calls.length>0){let E=[];M.content&&E.push({type:"text",text:M.content});for(let D of M.tool_calls)if(D.type==="function"){let ne=Fa(D.function.arguments);ne.ok?E.push({type:"tool_use",id:D.id,name:D.function.name,input:ne.data}):E.push({type:"text",text:`[tool_use parse error] ${ne.error}; raw: ${ne.raw}`})}let ie=E.some(D=>D.type==="tool_use");return{content:E,stop_reason:ie?"tool_use":"end_turn",usage:{prompt:N.usage?.prompt_tokens??void 0,completion:N.usage?.completion_tokens??void 0,total:N.usage?.total_tokens??void 0}}}let y=M?.content;if(typeof y!="string")throw new Error("OpenAI-compatible API returned empty content");return{content:[{type:"text",text:y}],stop_reason:"end_turn",usage:{prompt:N.usage?.prompt_tokens??void 0,completion:N.usage?.completion_tokens??void 0,total:N.usage?.total_tokens??void 0}}}),loadPrompt:l,historySinks:t.historySinks??[m],tokenCounter:t.tokenCounter??xo(e.tokenizerModel),historyFilePath:u}}function Ba(t){let e=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,o=t.replace(n,(s,r,i)=>{let l=(i??"").trim();return l&&e.push(l),l});return{thinkingParts:e,cleaned:o.trim()}}function bo(t){if(t.length===0)return;let e=t.join(`
51
- `),{thinkingParts:n,cleaned:o}=Ba(e);return n.length>0?n.join(`
67
+ `),ke=we.map(w=>w.status),Xe=ke.find(w=>w!==jn)??jn,Le=o[o.length-1];if(Le&&(Le.observation=pe),await Q(this.hooks,"onObservation",{sessionId:this.id,turn:r,step:m,tool:S.map(w=>w.name).join(", "),observation:pe,resultStatus:Xe,parallelResultStatuses:ke,history:ut(this.history)}),Be.hasRejection){let w=we.find(Y=>Y.rejected);u="cancelled",c="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:r,step:m,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:w?.actionId,error_type:w?.errorType??"approval_denied",duration_ms:w?.durationMs}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,tokenUsage:te,turnUsage:{...s},steps:o});break}continue}else if(A.action){this.maybeWarnRepeatedAction(A.action.tool,A.action.input);let M=S[0]?.id??`${r}:${m}:single:${A.action.tool}`;await this.emitEvent("action",{turn:r,step:m,meta:{tool:A.action.tool,input:A.action.input,action_id:M,phase:"dispatch",thinking:A.thinking}}),await Q(this.hooks,"onAction",{sessionId:this.id,turn:r,step:m,action:A.action,thinking:A.thinking,history:ut(this.history)});let R=await this.executeToolAction(M,A.action.tool,A.action.input,r,m);if(R.rejected){this.history.push(Kn({...R,observation:R.observation||`User denied tool execution: ${A.action.tool}`})),u="cancelled",c="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:r,step:m,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:R.actionId,error_type:R.errorType??"approval_denied",duration_ms:R.durationMs}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,tokenUsage:te,turnUsage:{...s},steps:o});break}let ne=R.observation;this.history.push({role:"tool",content:ne,tool_call_id:R.actionId,name:A.action.tool});let se=o[o.length-1];se&&(se.observation=ne),await this.emitEvent("observation",{turn:r,step:m,content:ne,meta:{tool:A.action.tool,action_id:R.actionId,phase:"result",status:R.status,error_type:R.errorType,duration_ms:R.durationMs}}),await Q(this.hooks,"onObservation",{sessionId:this.id,turn:r,step:m,tool:A.action.tool,observation:ne,resultStatus:R.status,history:ut(this.history)});continue}if(ee==="end_turn"||A.final){this.resetActionRepetition();let M=ee==="end_turn"&&!A.final&&v.trim().length===0&&!!p&&h===m-1;c=M?p??"":A.final||v,A.final&&(A.final=c),await this.emitEvent("final",{turn:r,step:m,content:c,role:"assistant",meta:{tokens:te,fallback_from_previous_text:M||void 0}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:m,finalText:c,status:u,tokenUsage:te,turnUsage:{...s},steps:o});break}this.resetActionRepetition();break}return!c&&u!=="cancelled"&&(u==="ok"&&(u="error"),c="Unable to produce a final answer. Please retry or adjust the request.",d=c,this.history.push({role:"assistant",content:c}),await this.emitEvent("final",{turn:r,content:c,role:"assistant"}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:r,finalText:c,status:u,errorMessage:d,turnUsage:{...s},steps:o})),await this.emitEvent("turn_end",{turn:r,meta:{status:u,stepCount:o.length,durationMs:Date.now()-i,tokens:s,protocol_violation_count:y||void 0}}),{finalText:c,steps:o,status:u,errorMessage:d,tokenUsage:s}}finally{this.currentAbortController=null,this.cancelling=!1,this.toolOrchestrator.clearOnceApprovals()}}cancelCurrentTurn(){this.currentAbortController&&(this.cancelling=!0,this.currentAbortController.abort())}async close(){if(this.closed)return;if(this.closed=!0,this.sessionStartEmitted||this.turnIndex>=0){await this.emitEvent("session_end",{meta:{durationMs:Date.now()-this.startedAt,tokens:this.sessionUsage}});for(let n of this.sinks)if(n.flush)try{await n.flush()}catch(r){console.error(`History flush failed: ${r.message}`)}}this.tokenCounter.dispose(),this.toolOrchestrator.dispose(),this.deps.dispose&&await this.deps.dispose()}async emitEvent(t,n){if(!this.sinks.length)return;let r=yr({sessionId:this.id,type:t,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await $o(r,this.sinks)}};async function Zt(e,t={}){let n=t.sessionId||Kc(),r=await Po(e,{...t,sessionId:n},n),o=await r.loadPrompt(),s=new Yt({...e,...r},{...t,sessionId:n,mode:t.mode??Jt},o,r.tokenCounter,r.historyFilePath);return await s.init(),s}import{randomUUID as tt}from"crypto";import{readFile as Yp}from"fs/promises";import{useCallback as J,useEffect as $t,useMemo as Dt,useReducer as Zp,useRef as hn,useState as re}from"react";import{Box as Ys,Text as Qp,useApp as em}from"ink";import{memo as uu,useMemo as Qt}from"react";import{Box as rs,Static as pu,Text as en}from"ink";import{Box as qe,Text as oe}from"ink";var Fe={PENDING:"pending",EXECUTING:"executing",SUCCESS:"success",ERROR:"error"};import pt from"path";var Vc="success",bt=".";function Vn(e){return e?e===Vc?Fe.SUCCESS:Fe.ERROR:Fe.SUCCESS}function qo(e){if(e?.length)return e.map(t=>Vn(t))}function Go(e,t){return!t||t<=0||!e||e<=0?0:Math.min(100,e/t*100)}function Ko(e){return e?`tokens: ${e.total} (prompt ${e.prompt} / completion ${e.completion})`:""}function At(e,t=80){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function Vo(e){if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Xn(e,t){let n=e.trim();if(!n)return e;if(n===bt)return bt;if(pt.isAbsolute(n)){let r=pt.relative(pt.resolve(t),n);return r?pt.normalize(r):bt}if(n.startsWith("./")||n.startsWith("../")){let r=pt.normalize(n);return!r||r==="."||r==="./"?bt:r}return n}function Xo(e){return e?e===bt||pt.isAbsolute(e)?!0:e.startsWith("./")||e.startsWith("../"):!1}import{Box as Ae,Text as fe}from"ink";import{marked as Xc}from"marked";var Jc=/(`[^`\n]+`|\[[^\]]+\]\((?:\\.|[^)])+\)|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/g;function Et(e){return e.map(t=>{let n=t;return typeof n.text=="string"?n.text:typeof n.raw=="string"?n.raw:Array.isArray(n.tokens)?Et(n.tokens):Array.isArray(n.items)?n.items.map(r=>typeof r.text=="string"?r.text:Array.isArray(r.tokens)?Et(r.tokens):"").filter(Boolean).join(`
68
+ `):""}).join("")}function Yc(e){let t=[],n=e.replace(/<think>([\s\S]*?)<\/think>/gi,(r,o)=>{let s=o.trim();return s&&t.push(s),""});return{think:t,cleaned:n}}function Zc(e){if(e.startsWith("`")&&e.endsWith("`"))return{type:"inlineCode",content:e.slice(1,-1)};if(e.startsWith("**")&&e.endsWith("**")||e.startsWith("__")&&e.endsWith("__"))return{type:"bold",content:e.slice(2,-2)};if(e.startsWith("*")&&e.endsWith("*")||e.startsWith("_")&&e.endsWith("_"))return{type:"italic",content:e.slice(1,-1)};let t=e.match(/^\[([^\]]+)\]\((.+)\)$/);return t?{type:"link",label:t[1]??"",href:t[2]??""}:{type:"text",content:e}}function Yo(e){if(!e)return[];let t=[],n=0;for(let r of e.matchAll(Jc)){let o=r[0];if(!o)continue;let s=r.index??0;s>n&&t.push({type:"text",content:e.slice(n,s)}),t.push(Zc(o)),n=s+o.length}return n<e.length&&t.push({type:"text",content:e.slice(n)}),t.filter(r=>r.type==="link"?r.label.length>0||r.href.length>0:r.content.length>0)}function Qc(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.tokens)?Et(e.tokens):""}function eu(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.tokens)?Et(e.tokens):typeof e.raw=="string"?e.raw.split(`
69
+ `).map(t=>t.replace(/^>\s?/,"")).join(`
70
+ `).trim():""}function Jo(e){return typeof e.text=="string"?e.text:Array.isArray(e.tokens)?Et(e.tokens):typeof e.raw=="string"?e.raw:""}function Zo(e){let{think:t,cleaned:n}=Yc(e),r=[];t.length>0&&r.push({type:"think",content:t.join(`
52
71
 
53
- `):o||void 0}import{randomUUID as Oo}from"crypto";function Wa(){return{onTurnStart:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[]}}function ko(t,e){e&&(e.onTurnStart&&t.onTurnStart.push(e.onTurnStart),e.onAction&&t.onAction.push(e.onAction),e.onObservation&&t.onObservation.push(e.onObservation),e.onFinal&&t.onFinal.push(e.onFinal),e.onApprovalRequest&&t.onApprovalRequest.push(e.onApprovalRequest),e.onApprovalResponse&&t.onApprovalResponse.push(e.onApprovalResponse))}function Mo(t){let e=Wa();if(ko(e,t.hooks),Array.isArray(t.middlewares))for(let n of t.middlewares)ko(e,n);return e}async function J(t,e,n){let o=t[e];if(o.length)for(let s of o)try{await s(n)}catch(r){console.warn(`Hook ${e} failed: ${r.message}`)}}function Ne(t){return t.map(e=>e.role==="assistant"&&e.tool_calls?.length?{...e,tool_calls:e.tool_calls.map(n=>({...n,function:{...n.function}}))}:{...e})}var Lo="interactive",za=12e4,Po="success";function Ro(){return{prompt:0,completion:0,total:0}}function Io(t,e){if(!e)return;let n=e.prompt??0,o=e.completion??0,s=e.total??n+o;t.prompt+=n,t.completion+=o,t.total+=s}function qa(t){let e=t.content.filter(o=>o.type==="text"),n=t.content.filter(o=>o.type==="tool_use");return{textContent:e.map(o=>o.text).join(`
54
- `),toolUseBlocks:n.map(o=>({id:o.id,name:o.name,input:o.input})),stopReason:t.stop_reason,usage:t.usage}}async function Ka(t,e){for(let n of e)try{await n.append(t)}catch(o){console.error(`Failed to write history event: ${o.message}`)}}function Va(t){return t instanceof Error&&t.name==="AbortError"}function Ge(t){return t===null||typeof t!="object"?JSON.stringify(t)??"null":Array.isArray(t)?`[${t.map(n=>Ge(n)).join(",")}]`:`{${Object.entries(t).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${Ge(o)}`).join(",")}}`}function Ga(t){return t.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:Ge(e.input)}}))}function Xa(t,e){let n=t.trim();if(!n)return null;let o=[n],s=n.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);s?.[1]&&o.push(s[1].trim());for(let r of o)if(!(!r.startsWith("{")||!r.endsWith("}")))try{let i=JSON.parse(r);if(!i||typeof i!="object"||Array.isArray(i))continue;let l=i,a=typeof l.tool=="string"?l.tool.trim():"";if(!a||!Object.prototype.hasOwnProperty.call(e,a))continue;return{tool:a,input:l.input??{}}}catch{}return null}var Jt=class{constructor(e,n,o,s,r){this.deps=e;this.options=n;this.id=n.sessionId||Oo(),this.mode=n.mode||Lo,this.history=[{role:"system",content:o}],this.tokenCounter=s,this.sinks=e.historySinks??[],this.hooks=Mo(e),this.historyFilePath=r,this.toolOrchestrator=To({tools:e.tools,approval:{dangerous:n.dangerous??!1,mode:"auto"}})}id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=Ro();startedAt=Date.now();hooks;closed=!1;sessionStartEmitted=!1;currentAbortController=null;cancelling=!1;lastActionSignature=null;repeatedActionCount=0;toolOrchestrator;async init(){}resetActionRepetition(){this.lastActionSignature=null,this.repeatedActionCount=0}maybeWarnRepeatedAction(e,n){let o=`${e}:${Ge(n)}`;if(this.lastActionSignature===o?this.repeatedActionCount+=1:(this.lastActionSignature=o,this.repeatedActionCount=1),this.repeatedActionCount===3){let s=Ge(n).slice(0,200),r=`\u7CFB\u7EDF\u63D0\u9192\uFF1A\u4F60\u5DF2\u8FDE\u7EED3\u6B21\u8C03\u7528\u540C\u4E00\u5DE5\u5177\u300C${e}\u300D\u4E14\u53C2\u6570\u76F8\u540C\uFF08${s}${s.length>=200?"\u2026":""}\uFF09\u3002\u8BF7\u786E\u8BA4\u662F\u5426\u9677\u5165\u5FAA\u73AF\uFF0C\u5FC5\u8981\u65F6\u76F4\u63A5\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\u6216\u8C03\u6574\u53C2\u6570\u3002`;this.history.push({role:"system",content:r})}}buildToolApprovalHooks(e,n){return{onApprovalRequest:async o=>{await J(this.hooks,"onApprovalRequest",{sessionId:this.id,turn:e,step:n,request:o})},requestApproval:async o=>this.deps.requestApproval?this.deps.requestApproval(o):"deny",onApprovalResponse:async({fingerprint:o,decision:s})=>{await J(this.hooks,"onApprovalResponse",{sessionId:this.id,turn:e,step:n,fingerprint:o,decision:s})}}}async executeToolAction(e,n,o,s,r){return this.toolOrchestrator.executeAction({id:e,name:n,input:o},this.buildToolApprovalHooks(s,r))}async runTurn(e){let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let o=this.turnIndex,s=[],r=Ro(),i=Date.now(),l=this.options.maxPromptTokens??za;if(!this.sessionStartEmitted){let a=this.history[0]?.role==="system"?this.history[0].content:void 0;await this.emitEvent("session_start",{content:a,role:a?"system":void 0,meta:{mode:this.mode,cwd:process.cwd(),tokenizer:this.tokenCounter.model,warnPromptTokens:this.options.warnPromptTokens,maxPromptTokens:l}}),this.sessionStartEmitted=!0}this.history.push({role:"user",content:e});try{let a=this.tokenCounter.countMessages(this.history);await this.emitEvent("turn_start",{turn:o,content:e,meta:{tokens:{prompt:a}}}),await J(this.hooks,"onTurnStart",{sessionId:this.id,turn:o,input:e,promptTokens:a,history:Ne(this.history)});let c="",u="ok",m,d=0,h=null,w=-1;for(let f=0;;f++){let I=this.tokenCounter.countMessages(this.history);if(I>l){let b=`Context tokens (${I}) exceed the limit. Please shorten the input or restart the session.`;this.history.push({role:"assistant",content:b}),u="prompt_limit",c=b,m=b,await this.emitEvent("final",{turn:o,step:f,content:b,role:"assistant",meta:{tokens:{prompt:I}}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:b,status:u,errorMessage:m,turnUsage:{...r},steps:s});break}this.options.warnPromptTokens&&I>this.options.warnPromptTokens&&console.warn(`Prompt tokens are near the limit: ${I}`);let S="",_=[],U,N;try{let b=await this.deps.callLLM(this.history,V=>this.deps.onAssistantStep?.(V,f),{signal:n.signal}),R=qa(b);S=R.textContent,_=R.toolUseBlocks,N=R.stopReason,U=R.usage,S.trim().length>0&&(h=S,w=f)}catch(b){if(this.cancelling&&Va(b)){u="cancelled",c="",m="Turn cancelled",await this.emitEvent("final",{turn:o,step:f,content:"",role:"assistant",meta:{cancelled:!0}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,errorMessage:m,turnUsage:{...r},steps:s});break}let R=`LLM call failed: ${b.message}`;this.history.push({role:"assistant",content:R}),u="error",c=R,m=R,await this.emitEvent("final",{turn:o,content:R,role:"assistant"}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,errorMessage:m,turnUsage:{...r},steps:s});break}this.deps.onAssistantStep?.(S,f);let M=_.length===0&&S?Xa(S,this.deps.tools):null,y,E=null;if(_.length>0){let b=_[0];if(b){let R=S?bo([S]):void 0;y={action:{tool:b.name,input:b.input},thinking:R},E={role:"assistant",content:S,tool_calls:Ga(_)}}else y={}}else S?(y={final:S},E={role:"assistant",content:S}):y={};let ie=this.tokenCounter.countText(S),D=U?.prompt??I,ne=U?.completion??ie,q=U?.total??D+ne,B={prompt:D,completion:ne,total:q};if(Io(r,B),Io(this.sessionUsage,B),s.push({index:f,assistantText:S,parsed:y,tokenUsage:B}),await this.emitEvent("assistant",{turn:o,step:f,content:S,role:"assistant",meta:{tokens:B,protocol_violation:!!M,protocol_violation_count:M?d+1:d||void 0}}),M){d+=1;let b=`Model protocol error: returned plain-text tool JSON for "${M.tool}" ${d} times. Structured tool calls are required.`;u="error",c=b,m=b,this.history.push({role:"assistant",content:b}),await this.emitEvent("final",{turn:o,step:f,content:b,role:"assistant",meta:{error_type:"model_protocol_error",tool:M.tool,protocol_violation:!0,protocol_violation_count:d,tokens:B}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,errorMessage:m,tokenUsage:B,turnUsage:{...r},steps:s});break}if(E&&this.history.push(E),_.length>1){for(let A of _)this.maybeWarnRepeatedAction(A.name,A.input);await this.emitEvent("action",{turn:o,step:f,meta:{tools:_.map(A=>A.name),action_ids:_.map(A=>A.id),action_id:_[0]?.id,parallel:!0,phase:"dispatch",thinking:y.thinking,toolBlocks:_.map(A=>({id:A.id,name:A.name,input:A.input}))}});let b=_[0];b&&await J(this.hooks,"onAction",{sessionId:this.id,turn:o,step:f,action:{tool:b.name,input:b.input},parallelActions:_.map(A=>({tool:A.name,input:A.input})),thinking:y.thinking,history:Ne(this.history)});let R=_.every(A=>!!this.deps.tools[A.name]?.supportsParallelToolCalls),V=_.some(A=>!!this.deps.tools[A.name]?.isMutating),X=R&&!V?"parallel":"sequential",K=await this.toolOrchestrator.executeActions(_.map(A=>({id:A.id,name:A.name,input:A.input})),{...this.buildToolApprovalHooks(o,f),executionMode:X,failurePolicy:"fail_fast"});for(let[A,H]of K.results.entries())this.history.push({role:"tool",content:H.observation,tool_call_id:H.actionId,name:H.tool}),await this.emitEvent("observation",{turn:o,step:f,content:H.observation,meta:{tool:H.tool,index:A,action_id:H.actionId,phase:"result",status:H.status,error_type:H.errorType,duration_ms:H.durationMs,execution_mode:X}});let Re=K.combinedObservation,de=K.results.map(A=>A.status),Ie=de.find(A=>A!==Po)??Po,W=s[s.length-1];if(W&&(W.observation=Re),await J(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:f,tool:_.map(A=>A.name).join(", "),observation:Re,resultStatus:Ie,parallelResultStatuses:de,history:Ne(this.history)}),K.hasRejection){let A=K.results.find(H=>H.rejected);u="cancelled",c="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:o,step:f,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:A?.actionId,error_type:A?.errorType??"approval_denied",duration_ms:A?.durationMs}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,tokenUsage:B,turnUsage:{...r},steps:s});break}continue}else if(y.action){this.maybeWarnRepeatedAction(y.action.tool,y.action.input);let b=_[0]?.id??`${o}:${f}:single:${y.action.tool}`;await this.emitEvent("action",{turn:o,step:f,meta:{tool:y.action.tool,input:y.action.input,action_id:b,phase:"dispatch",thinking:y.thinking}}),await J(this.hooks,"onAction",{sessionId:this.id,turn:o,step:f,action:y.action,thinking:y.thinking,history:Ne(this.history)});let R=await this.executeToolAction(b,y.action.tool,y.action.input,o,f);if(R.rejected){u="cancelled",c="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:o,step:f,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:R.actionId,error_type:R.errorType??"approval_denied",duration_ms:R.durationMs}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,tokenUsage:B,turnUsage:{...r},steps:s});break}let V=R.observation;this.history.push({role:"tool",content:V,tool_call_id:R.actionId,name:y.action.tool});let X=s[s.length-1];X&&(X.observation=V),await this.emitEvent("observation",{turn:o,step:f,content:V,meta:{tool:y.action.tool,action_id:R.actionId,phase:"result",status:R.status,error_type:R.errorType,duration_ms:R.durationMs}}),await J(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:f,tool:y.action.tool,observation:V,resultStatus:R.status,history:Ne(this.history)});continue}if(N==="end_turn"||y.final){this.resetActionRepetition();let b=N==="end_turn"&&!y.final&&S.trim().length===0&&!!h&&w===f-1;c=b?h??"":y.final||S,y.final&&(y.final=c),await this.emitEvent("final",{turn:o,step:f,content:c,role:"assistant",meta:{tokens:B,fallback_from_previous_text:b||void 0}}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:f,finalText:c,status:u,tokenUsage:B,turnUsage:{...r},steps:s});break}this.resetActionRepetition();break}return!c&&u!=="cancelled"&&(u==="ok"&&(u="error"),c="Unable to produce a final answer. Please retry or adjust the request.",m=c,this.history.push({role:"assistant",content:c}),await this.emitEvent("final",{turn:o,content:c,role:"assistant"}),await J(this.hooks,"onFinal",{sessionId:this.id,turn:o,finalText:c,status:u,errorMessage:m,turnUsage:{...r},steps:s})),await this.emitEvent("turn_end",{turn:o,meta:{status:u,stepCount:s.length,durationMs:Date.now()-i,tokens:r,protocol_violation_count:d||void 0}}),{finalText:c,steps:s,status:u,errorMessage:m,tokenUsage:r}}finally{this.currentAbortController=null,this.cancelling=!1,this.toolOrchestrator.clearOnceApprovals()}}cancelCurrentTurn(){this.currentAbortController&&(this.cancelling=!0,this.currentAbortController.abort())}async close(){if(this.closed)return;if(this.closed=!0,this.sessionStartEmitted||this.turnIndex>=0){await this.emitEvent("session_end",{meta:{durationMs:Date.now()-this.startedAt,tokens:this.sessionUsage}});for(let n of this.sinks)if(n.flush)try{await n.flush()}catch(o){console.error(`History flush failed: ${o.message}`)}}this.tokenCounter.dispose(),this.toolOrchestrator.dispose(),this.deps.dispose&&await this.deps.dispose()}async emitEvent(e,n){if(!this.sinks.length)return;let o=fn({sessionId:this.id,type:e,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await Ka(o,this.sinks)}};async function dt(t,e={}){let n=e.sessionId||Oo(),o=await wo(t,{...e,sessionId:n},n),s=await o.loadPrompt(),r=new Jt({...t,...o},{...e,sessionId:n,mode:e.mode??Lo},s,o.tokenCounter,o.historyFilePath);return await r.init(),r}import{randomUUID as nt}from"crypto";import{readFile as sc}from"fs/promises";import{useCallback as Z,useEffect as kt,useMemo as fr,useReducer as ic,useRef as Mt,useState as te}from"react";import{Box as gr,Text as ac,useApp as lc}from"ink";import{memo as Za,useMemo as Qa}from"react";import{Box as jo,Static as el,Text as gt}from"ink";import{Box as xe,Text as G}from"ink";var _e={PENDING:"pending",EXECUTING:"executing",SUCCESS:"success",ERROR:"error"};var Ja="success";function Yt(t){return t?t===Ja?_e.SUCCESS:_e.ERROR:_e.SUCCESS}function $o(t){if(t?.length)return t.map(e=>Yt(e))}function No(t,e){return!e||e<=0||!t||t<=0?0:Math.min(100,t/e*100)}function Do(t){return t?`tokens: ${t.total} (prompt ${t.prompt} / completion ${t.completion})`:""}function Xe(t,e=80){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3))}...`}function Uo(t){if(typeof t=="string")return t;try{return JSON.stringify(t)??String(t)}catch{return String(t)}}import{jsx as ee,jsxs as se}from"react/jsx-runtime";function Ho(t){return t===_e.ERROR?"red":t===_e.EXECUTING?"yellow":"green"}function ft(t){if(t==null)return null;if(typeof t=="string")return Xe(t,70);if(typeof t!="object"||Array.isArray(t))return Xe(String(t),70);let e=t,n=["cmd","path","file_path","dir_path","query","pattern","url","content"];for(let o of n){let s=e[o];if(!(s==null||s===""))return Xe(String(s),70)}return Xe(Uo(e),70)}function Fo({message:t}){let e=t.tone==="error"?"red":t.tone==="warning"?"yellow":"cyan";return se(xe,{flexDirection:"column",children:[se(G,{color:e,children:["\u25CF ",t.title]}),ee(G,{color:"gray",children:t.content})]})}function Ya({step:t}){let e=!!(t.parallelActions&&t.parallelActions.length>1);return se(xe,{flexDirection:"column",children:[t.thinking?se(xe,{children:[ee(G,{color:"gray",children:"\u25CF "}),ee(G,{color:"gray",children:t.thinking})]}):null,e?t.parallelActions?.map((n,o)=>se(xe,{children:[se(G,{color:Ho(t.parallelToolStatuses?.[o]??t.toolStatus),children:["\u25CF"," "]}),ee(G,{color:"gray",children:"Used "}),ee(G,{color:"cyan",children:n.tool}),ft(n.input)?se(G,{color:"gray",children:[" (",ft(n.input),")"]}):null]},`${n.tool}-${o}`)):null,!e&&t.action?se(xe,{children:[ee(G,{color:Ho(t.toolStatus),children:"\u25CF "}),ee(G,{color:"gray",children:"Used "}),ee(G,{color:"cyan",children:t.action.tool}),ft(t.action.input)?se(G,{color:"gray",children:[" (",ft(t.action.input),")"]}):null]}):null]})}function Zt({turn:t}){return se(xe,{flexDirection:"column",children:[se(xe,{children:[ee(G,{color:"gray",children:"\u203A "}),ee(G,{children:t.userInput})]}),t.steps.map(e=>ee(Ya,{step:e},`${t.index}-${e.index}`)),t.finalText?ee(xe,{marginTop:0,children:ee(G,{children:t.finalText})}):null,t.status&&t.status!=="ok"?se(G,{color:"red",children:["Status: ",t.status]}):null,t.errorMessage?ee(G,{color:"red",children:t.errorMessage}):null]})}import{jsx as Je,jsxs as Ye}from"react/jsx-runtime";var Bo=Za(function({header:e,systemMessages:n,turns:o,historicalTurns:s}){let r=Qa(()=>[...s,...o],[s,o]),i=r.length>0?r[r.length-1]:void 0,l=i&&!!(i.finalText||i.status&&i.status!=="ok"),a=l?r:r.slice(0,-1),c=l?void 0:i,u=[{type:"header",data:e}],m=[...n.map(d=>({type:"system",sequence:d.sequence,data:d})),...a.map(d=>({type:"turn",sequence:d.sequence??0,data:d}))].sort((d,h)=>d.sequence-h.sequence);for(let d of m)u.push(d);return Ye(jo,{flexDirection:"column",children:[Je(el,{items:u,children:d=>d.type==="header"?Ye(jo,{borderStyle:"round",borderColor:"blue",paddingX:1,flexDirection:"column",children:[Je(gt,{bold:!0,children:"Memo CLI"}),Ye(gt,{color:"gray",children:[d.data.providerName," / ",d.data.model," \u2022 v",d.data.version]}),Ye(gt,{color:"gray",children:["cwd: ",d.data.cwd]}),Ye(gt,{color:"gray",children:["mcp: ",d.data.mcpNames.join(", ")||"none"]})]},"header"):d.type==="system"?Je(Fo,{message:d.data},d.data.id):Je(Zt,{turn:d.data},`turn-${d.data.index}`)}),c?Je(Zt,{turn:c}):null]})});import{useCallback as Yo,useEffect as Qt,useMemo as Zo,useRef as en,useState as Ce}from"react";import{Box as xt,Text as Ue,useInput as Ml}from"ink";var De=[8e4,12e4,15e4,2e5],Wo=De[1],$={HELP:"help",EXIT:"exit",NEW:"new",RESUME:"resume",MODELS:"models",CONTEXT:"context",MCP:"mcp",INIT:"init"};function ce(t){return`/${t}`}var zo="exit";var ht=[{name:$.HELP,description:"Show command and shortcut help"},{name:$.EXIT,description:"Exit current session"},{name:$.NEW,description:"Start a fresh session"},{name:$.RESUME,description:"List and load session history"},{name:$.MODELS,description:"List or switch configured models"},{name:$.CONTEXT,description:"Set context window (80k/120k/150k/200k)"},{name:$.MCP,description:"Show configured MCP servers"},{name:$.INIT,description:"Generate AGENTS.md with agent instructions"}];function tl(){let t=ht.reduce((n,o)=>Math.max(n,o.name.length),0);return["Available commands:",...ht.map(n=>` ${ce(n.name).padEnd(t+3)} ${n.description}`)," exit Exit session (without slash)","","Shortcuts:"," Enter Send message"," Shift+Enter New line"," Up/Down Browse local input history"," Tab Accept active suggestion"," Ctrl+L Clear screen and start new session"," Esc Esc Interrupt running turn / clear input"].join(`
55
- `)}function nl(t){if(!t)return null;let n=t.toLowerCase().replace(/,/g,"").match(/^(\d+)(k)?$/);if(!n)return null;let o=Number(n[1]);return Number.isFinite(o)?o*(n[2]?1e3:1):null}function qo(t,e){let[n,...o]=t.trim().slice(1).split(/\s+/);switch((n??"").toLowerCase()){case $.HELP:return{kind:"message",title:"Help",content:tl()};case $.EXIT:return{kind:"exit"};case $.NEW:return{kind:"new"};case $.RESUME:return{kind:"message",title:"Resume",content:'Type "resume" followed by keywords to load local session history.'};case $.MODELS:{if(!e.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${e.configPath}`};let r=o.join(" ").trim(),i=e.providers.find(c=>c.name===r)??e.providers.find(c=>c.model===r);if(i)return{kind:"switch_model",provider:i};let l=e.providers.map(c=>{let u=c.name===e.providerName&&c.model===e.model?" (current)":"",m=c.base_url?` @ ${c.base_url}`:"";return`- ${c.name}: ${c.model}${m}${u}`});return{kind:"message",title:"Models",content:`${r?`Not found: ${r}
72
+ `)});let o=Xc.lexer(n);for(let s of o)switch(s.type){case"html":{r.push({type:"html",content:s.text??s.raw??""});break}case"hr":{r.push({type:"hr"});break}case"heading":{r.push({type:"heading",level:typeof s.depth=="number"?s.depth:1,content:s.text??Jo(s)});break}case"paragraph":case"text":{let i=Jo(s);i.trim().length>0&&r.push({type:"paragraph",content:i});break}case"code":{r.push({type:"code",language:s.lang,content:s.text??""});break}case"blockquote":{let i=eu(s);i.trim().length>0&&r.push({type:"blockquote",content:i});break}case"list":{let i=Array.isArray(s.items)?s.items.map(a=>Qc(a)).filter(a=>a.trim().length>0):[];i.length>0&&r.push({type:"list",items:i,ordered:!!s.ordered});break}default:break}return r}import{Fragment as lu,jsx as B,jsxs as mt}from"react/jsx-runtime";var tu="\u2014\u2014\u2014";function nu(e,t){return e.repeat(Math.max(0,t))}function ru(e){let t=e.split(`
73
+ `);if(t.length===0)return["Think:"];let n=t.findIndex(r=>r.trim().length>0);return n<0&&(n=0),t.map((r,o)=>o===n?`Think: ${r}`:r)}function ou(e){return e.split(`
74
+ `)}function su({content:e}){let t=ou(e);return B(Ae,{flexDirection:"column",marginY:1,children:t.map((n,r)=>B(fe,{children:n},r))})}function iu({node:e}){switch(e.type){case"bold":return B(fe,{bold:!0,children:e.content});case"italic":return B(fe,{italic:!0,children:e.content});case"inlineCode":return B(fe,{color:"cyan",children:e.content});case"link":return mt(lu,{children:[B(fe,{color:"blue",underline:!0,children:e.label}),mt(fe,{color:"gray",children:[" (",e.href,")"]})]});case"text":return B(fe,{children:e.content});default:return null}}function Jn({content:e}){let t=Yo(e);return B(Ae,{flexWrap:"wrap",children:t.map((n,r)=>B(iu,{node:n},r))})}function au(e,t){switch(e.type){case"html":return B(Ae,{children:B(fe,{color:"gray",dimColor:!0,children:e.content})},t);case"hr":return B(Ae,{marginY:1,children:B(fe,{color:"gray",dimColor:!0,children:tu})},t);case"think":return B(Ae,{flexDirection:"column",marginY:1,children:ru(e.content).map((n,r)=>B(fe,{color:"gray",dimColor:!0,children:n},r))},t);case"heading":return B(Ae,{children:mt(fe,{bold:!0,color:"cyan",children:[nu("#",e.level)," ",e.content]})},t);case"paragraph":return B(Jn,{content:e.content},t);case"code":return B(su,{content:e.content},t);case"blockquote":return B(Ae,{flexDirection:"column",children:e.content.split(`
75
+ `).map((n,r)=>mt(Ae,{children:[B(fe,{color:"gray",dimColor:!0,children:"> "}),B(Jn,{content:n})]},r))},t);case"list":return B(Ae,{flexDirection:"column",children:e.items.map((n,r)=>mt(Ae,{children:[mt(fe,{color:"gray",children:[e.ordered?`${r+1}.`:"\u2022"," "]}),B(Jn,{content:n})]},r))},t);default:return null}}function Qo({content:e}){let t=Zo(e);return B(Ae,{flexDirection:"column",children:t.map((n,r)=>au(n,`${n.type}-${r}`))})}import{jsx as de,jsxs as ve}from"react/jsx-runtime";function es(e){return e===Fe.ERROR?"red":e===Fe.EXECUTING?"yellow":"green"}function ts(e,t){if(e==null)return null;if(typeof e=="string"){let s=Xo(e)?Xn(e,t):e;return At(s,70)}if(typeof e!="object"||Array.isArray(e))return At(String(e),70);let n=e,r=["cmd","path","file_path","dir_path","query","pattern","url","content"],o=new Set(["path","file_path","dir_path"]);for(let s of r){let i=n[s];if(i==null||i==="")continue;let a=String(i),l=o.has(s)?Xn(a,t):a;return At(l,70)}return At(Vo(n),70)}function ns({message:e}){let t=e.tone==="error"?"red":e.tone==="warning"?"yellow":"cyan";return ve(qe,{flexDirection:"column",children:[ve(oe,{color:t,children:["\u25CF ",e.title]}),de(oe,{color:"gray",children:e.content})]})}function cu({step:e,cwd:t}){let n=!!(e.parallelActions&&e.parallelActions.length>1),r=!n&&e.action?ts(e.action.input,t):null;return ve(qe,{flexDirection:"column",children:[e.thinking?ve(qe,{children:[de(oe,{color:"gray",children:"\u25CF "}),de(oe,{color:"gray",children:e.thinking})]}):null,n?e.parallelActions?.map((o,s)=>{let i=ts(o.input,t);return ve(qe,{children:[ve(oe,{color:es(e.parallelToolStatuses?.[s]??e.toolStatus),children:["\u25CF"," "]}),de(oe,{color:"gray",children:"Used "}),de(oe,{color:"cyan",children:o.tool}),i?ve(oe,{color:"gray",children:[" (",i,")"]}):null]},`${o.tool}-${s}`)}):null,!n&&e.action?ve(qe,{children:[de(oe,{color:es(e.toolStatus),children:"\u25CF "}),de(oe,{color:"gray",children:"Used "}),de(oe,{color:"cyan",children:e.action.tool}),r?ve(oe,{color:"gray",children:[" (",r,")"]}):null]}):null]})}function Yn({turn:e,cwd:t}){return ve(qe,{flexDirection:"column",children:[ve(qe,{marginY:.5,children:[de(oe,{color:"gray",children:"\u203A "}),de(oe,{children:e.userInput})]}),e.steps.map(n=>de(cu,{step:n,cwd:t},`${e.index}-${n.index}`)),e.finalText?de(qe,{marginTop:0,children:de(Qo,{content:e.finalText})}):null,e.status&&e.status!=="ok"?ve(oe,{color:"red",children:["Status: ",e.status]}):null,e.errorMessage?de(oe,{color:"red",children:e.errorMessage}):null]})}import{jsx as Mt,jsxs as wt}from"react/jsx-runtime";function os(e){return e.sequence??0}function mu(e){return e.type==="header"}function du(e){return e.id!==void 0}var ss=uu(function({header:t,systemMessages:n,turns:r,historicalTurns:o}){let s=Qt(()=>[...o,...r],[o,r]),i=s.length>0?s[s.length-1]:void 0,a=i&&!!(i.finalText||i.status&&i.status!=="ok"),l=a?s:s.slice(0,-1),c=a?void 0:i,u=Qt(()=>({type:"header",data:t}),[t]),d=Qt(()=>{let p=[...n,...l];return p.sort((h,m)=>os(h)-os(m)),p},[l,n]),y=Qt(()=>[u,...d],[u,d]);return wt(rs,{flexDirection:"column",children:[Mt(pu,{items:y,children:p=>mu(p)?wt(rs,{borderStyle:"round",borderColor:"blue",paddingX:1,flexDirection:"column",children:[Mt(en,{bold:!0,children:"Memo CLI"}),wt(en,{color:"gray",children:[p.data.providerName," / ",p.data.model," \u2022 v",p.data.version]}),wt(en,{color:"gray",children:["cwd: ",p.data.cwd]}),wt(en,{color:"gray",children:["mcp: ",p.data.mcpNames.join(", ")||"none"]})]},`header-${p.data.sessionId}`):du(p)?Mt(ns,{message:p},p.id):Mt(Yn,{turn:p,cwd:t.cwd},`turn-${p.sequence??p.index}`)}),c?Mt(Yn,{turn:c,cwd:t.cwd}):null]})});import{useCallback as et,useEffect as un,useMemo as Ps,useRef as It,useState as Ge}from"react";import{Box as er,Text as pn,useInput as ep,useStdout as tp}from"ink";var dt=[8e4,12e4,15e4,2e5],is=dt[1],$={HELP:"help",EXIT:"exit",NEW:"new",RESUME:"resume",MODELS:"models",CONTEXT:"context",TOOLS:"tools",MCP:"mcp",INIT:"init"},H={NONE:"none",ONCE:"once",FULL:"full"};function ge(e){return`/${e}`}var as="exit";var tn=[{name:$.HELP,description:"Show command and shortcut help"},{name:$.EXIT,description:"Exit current session"},{name:$.NEW,description:"Start a fresh session"},{name:$.RESUME,description:"List and load session history"},{name:$.MODELS,description:"List or switch configured models"},{name:$.CONTEXT,description:"Set context window (80k/120k/150k/200k)"},{name:$.TOOLS,description:"Set tool permission mode (none/once/full)"},{name:$.MCP,description:"Show configured MCP servers"},{name:$.INIT,description:"Generate AGENTS.md with agent instructions"}],fu={none:H.NONE,off:H.NONE,disabled:H.NONE,"no-tools":H.NONE,once:H.ONCE,ask:H.ONCE,single:H.ONCE,strict:H.ONCE,full:H.FULL,all:H.FULL,dangerous:H.FULL,"full-access":H.FULL};function gu(e){if(!e)return null;let t=e.trim().toLowerCase();return t?fu[t]??null:null}function ls(e){return e===H.NONE?"none (no tools)":e===H.ONCE?"once (approval required)":"full (no approval)"}function hu(){let e=tn.reduce((n,r)=>Math.max(n,r.name.length),0);return["Available commands:",...tn.map(n=>` ${ge(n.name).padEnd(e+3)} ${n.description}`)," exit Exit session (without slash)","","Shortcuts:"," Enter Send message"," Shift+Enter New line"," Up/Down Browse local input history"," Tab Accept active suggestion"," Ctrl+L Clear screen and start new session"," Esc Esc Interrupt running turn / clear input"].join(`
76
+ `)}function yu(e){if(!e)return null;let n=e.toLowerCase().replace(/,/g,"").match(/^(\d+)(k)?$/);if(!n)return null;let r=Number(n[1]);return Number.isFinite(r)?r*(n[2]?1e3:1):null}function cs(e,t){let[n,...r]=e.trim().slice(1).split(/\s+/);switch((n??"").toLowerCase()){case $.HELP:return{kind:"message",title:"Help",content:hu()};case $.EXIT:return{kind:"exit"};case $.NEW:return{kind:"new"};case $.RESUME:return{kind:"message",title:"Resume",content:'Type "resume" followed by keywords to load local session history.'};case $.MODELS:{if(!t.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${t.configPath}`};let s=r.join(" ").trim(),i=t.providers.find(c=>c.name===s)??t.providers.find(c=>c.model===s);if(i)return{kind:"switch_model",provider:i};let a=t.providers.map(c=>{let u=c.name===t.providerName&&c.model===t.model?" (current)":"",d=c.base_url?` @ ${c.base_url}`:"";return`- ${c.name}: ${c.model}${d}${u}`});return{kind:"message",title:"Models",content:`${s?`Not found: ${s}
56
77
 
57
- `:""}${l.join(`
58
- `)}`}}case $.CONTEXT:{let r=nl(o[0]),i=De.map(l=>`${Math.floor(l/1e3)}k`).join(", ");return r===null?{kind:"message",title:"Context",content:`Current: ${(e.contextLimit/1e3).toFixed(0)}k
59
- Usage: ${ce($.CONTEXT)} <length>
60
- Choices: ${i}`}:De.includes(r)?{kind:"set_context_limit",limit:r}:{kind:"message",title:"Context",content:`Unsupported value: ${r}. Choose one of ${i}`}}case $.MCP:{let r=Object.keys(e.mcpServers);if(!r.length)return{kind:"message",title:"MCP Servers",content:"No MCP servers configured in current config."};let i=[];i.push(`Total: ${r.length}`),i.push("");for(let[l,a]of Object.entries(e.mcpServers))i.push(`- ${l}`),"url"in a?(i.push(` type: ${a.type??"streamable_http"}`),i.push(` url: ${a.url}`),a.bearer_token_env_var&&i.push(` bearer: ${a.bearer_token_env_var}`)):(i.push(` type: ${a.type??"stdio"}`),i.push(` command: ${a.command}`),a.args?.length&&i.push(` args: ${a.args.join(" ")}`)),i.push("");return{kind:"message",title:"MCP Servers",content:i.join(`
61
- `)}}case $.INIT:return{kind:"init_agents_md"};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${t}
62
- Type ${ce($.HELP)} for available commands.`}}}import{readdir as ol}from"fs/promises";import{join as rl,relative as sl,sep as il}from"path";var al=6,ll=2500,Ko=25,cl=new Set([".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs"]),yt=new Map;function ul(t){return t.split(il).join("/")}function pl(t){return{maxDepth:typeof t.maxDepth=="number"?Math.max(1,t.maxDepth):al,maxEntries:typeof t.maxEntries=="number"?Math.max(100,t.maxEntries):ll,limit:typeof t.limit=="number"?Math.max(1,t.limit):Ko,ignoreGlobs:t.ignoreGlobs?.length?t.ignoreGlobs:[]}}function ml(t,e){let n=t.split("/").filter(Boolean),o=n[n.length-1]??"";return n.some(s=>cl.has(s))||o.endsWith(".log")?!0:e.ignoreGlobs.length?e.ignoreGlobs.some(s=>{let r=s.replace(/\\/g,"/").trim();if(!r)return!1;if(r.endsWith("/**")){let i=r.slice(0,-3);return t.startsWith(i)}if(r.startsWith("*")){let i=r.slice(1);return t.endsWith(i)}return t.includes(r)}):!1}function dl(t){return JSON.stringify({maxDepth:t.maxDepth,maxEntries:t.maxEntries,ignoreGlobs:t.ignoreGlobs})}async function fl(t,e){let n=[],o=async(s,r)=>{if(n.length>=e.maxEntries)return;let i;try{i=await ol(s,{withFileTypes:!0})}catch{return}for(let l of i){if(n.length>=e.maxEntries)break;if(l.isSymbolicLink())continue;let a=rl(s,l.name),c=sl(t,a);if(!c)continue;let u=ul(c);if(ml(u,e))continue;let m=u.split("/").filter(Boolean),d=l.isDirectory();n.push({path:u,pathLower:u.toLowerCase(),segments:m,segmentsLower:m.map(h=>h.toLowerCase()),depth:r,isDir:d}),d&&r<e.maxDepth&&await o(a,r+1)}};return await o(t,0),n.sort((s,r)=>s.path.localeCompare(r.path)),n}async function gl(t,e){let n=pl(e),o=dl(n),s=yt.get(t);if(s&&s.signature===o)return s.pending?s.pending:s.entries;let r=fl(t,n).then(i=>(yt.set(t,{entries:i,signature:o}),i)).catch(i=>{throw yt.delete(t),i});return yt.set(t,{entries:[],signature:o,pending:r}),r}function hl(t,e){if(!e.length)return t.depth+(t.isDir?-.2:.2);let n=t.depth,o=0;for(let s of e){let r=-1;for(let i=o;i<t.segmentsLower.length;i++){let l=t.segmentsLower[i];if(l.startsWith(s)){r=i,n+=(i-o)*1.2,n+=l.length-s.length;break}let a=l.indexOf(s);if(a!==-1){r=i,n+=(i-o)*2+a+2;break}}if(r===-1)return null;o=r+1}return t.isDir&&(n-=.5),n}function yl(t,e,n){let s=e.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(i=>i.toLowerCase()),r=[];for(let i of t){let l=hl(i,s);l!==null&&r.push({entry:i,score:l})}return r.sort((i,l)=>{let a=i.score-l.score;return a!==0?a:i.entry.path.localeCompare(l.entry.path)}),r.slice(0,n).map(({entry:i})=>({id:i.path,path:i.path,name:i.segments[i.segments.length-1]??i.path,parent:i.segments.length>1?i.segments.slice(0,-1).join("/"):void 0,isDir:i.isDir}))}async function Vo(t){let e=await gl(t.cwd,t),n=typeof t.limit=="number"?Math.max(1,t.limit):Ko;return yl(e,t.query,n)}import{readdir as Tl,readFile as _l,stat as Sl}from"fs/promises";import{basename as vl,join as Tt,resolve as Ze}from"path";function Go(t){let e=Ze(t);return process.platform==="win32"?e.toLowerCase():e}function xl(t,e){return e?Go(t)===Go(e):!1}function Cl(t){return vl(t).replace(/\.jsonl$/i,"")}function El(t){let e=null,n=null;for(let o of t.split(`
63
- `)){let s=o.trim();if(!s)continue;let r;try{r=JSON.parse(s)}catch{continue}if(!(!r||typeof r!="object")){if(r.type==="session_start"&&!n){let i=r.meta?.cwd;typeof i=="string"&&i.trim()&&(n=i);continue}if(r.type==="turn_start"&&!e){let i=typeof r.content=="string"?r.content.trim():"";i&&(e=i)}}}return{firstPrompt:e,sessionCwd:n}}async function Al(t,e,n){try{let o=await _l(t,"utf8"),{firstPrompt:s,sessionCwd:r}=El(o);return xl(e,r)?{id:t,cwd:e,input:s?.trim()||Cl(t),ts:n,sessionFile:t}:null}catch{return null}}async function wl(t){let e=async r=>{try{return await Tl(r,{withFileTypes:!0})}catch{return[]}},n=(await e(t)).filter(r=>r.isDirectory()&&/^\d{4}$/.test(r.name)),o=[];for(let r of n){let i=Tt(t,r.name),l=(await e(i)).filter(a=>a.isDirectory()&&/^\d{2}$/.test(a.name));for(let a of l){let c=Tt(i,a.name),u=(await e(c)).filter(m=>m.isDirectory()&&/^\d{2}$/.test(m.name));for(let m of u){let d=Tt(c,m.name),h=(await e(d)).filter(w=>w.isFile()&&w.name.endsWith(".jsonl"));for(let w of h)o.push(Tt(d,w.name))}}}return(await Promise.all(o.map(async r=>{try{let i=await Sl(r);return{path:r,mtimeMs:i.mtimeMs}}catch{return null}}))).filter(r=>!!r)}async function Xo(t){let e=t.activeSessionFile?Ze(t.activeSessionFile):null,o=(await wl(t.sessionsDir)).filter(l=>!e||Ze(l.path)!==e).filter((l,a,c)=>c.findIndex(u=>Ze(u.path)===Ze(l.path))===a).sort((l,a)=>a.mtimeMs-l.mtimeMs),s=t.keyword?.trim().toLowerCase(),r=t.limit??10,i=[];for(let l of o){if(i.length>=r)break;let a=await Al(l.path,t.cwd,l.mtimeMs);a&&(s&&!a.input.toLowerCase().includes(s)||i.push(a))}return i}import{Box as _t,Text as St}from"ink";import{jsx as ke,jsxs as kl}from"react/jsx-runtime";var bl="#3a3a3a",vt="#262626";function Jo({items:t,activeIndex:e,loading:n}){return n?ke(_t,{paddingX:1,backgroundColor:vt,children:ke(St,{color:"gray",children:"Loading..."})}):t.length?ke(_t,{flexDirection:"column",backgroundColor:vt,children:t.map((o,s)=>{let r=s===e;return kl(_t,{paddingX:1,gap:2,backgroundColor:r?bl:vt,children:[ke(St,{color:r?"cyan":"white",bold:r,children:o.title}),o.subtitle?ke(St,{color:"gray",children:o.subtitle}):null]},o.id)})}):ke(_t,{paddingX:1,backgroundColor:vt,children:ke(St,{color:"gray",children:"No matches"})})}import{jsx as Me,jsxs as Ct}from"react/jsx-runtime";var Pl=400,tn=ce($.MODELS),nn=ce($.CONTEXT),Rl=ce($.INIT);function Il(t){let e=t.lastIndexOf("@");if(e===-1)return null;if(e>0){let o=t[e-1];if(o&&!/\s/.test(o))return null}let n=t.slice(e+1);return/\s/.test(n)?null:{type:"file",query:n,tokenStart:e+1}}function Ol(t){let e=t.trimStart(),n=t.length-e.length;if(!e.length)return null;let o=e;if(o.startsWith("/")&&(o=o.slice(1)),!o.toLowerCase().startsWith($.RESUME)||t.slice(0,n).trim().length>0)return null;let r=o.slice($.RESUME.length);return r&&!r.startsWith(" ")?null:{type:"history",keyword:r.trim()}}function Ll(t){let e=t.trimStart();if(!e.startsWith("/"))return null;let n=e.slice(1);return n.includes(" ")?null:n.length?/^[a-zA-Z-]+$/.test(n)?{type:"slash",keyword:n.toLowerCase()}:null:{type:"slash",keyword:""}}function $l(t){let e=t.trimStart();if(!e.startsWith(tn))return null;let n=e.slice(tn.length);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim().toLowerCase()}}function Nl(t){let e=t.trimStart();if(!e.startsWith(nn))return null;let n=e.slice(nn.length);return n&&!n.startsWith(" ")?null:{type:"context"}}function Dl(t){return Nl(t)??$l(t)??Ll(t)??Il(t)??Ol(t)}function Ul(t){let e=new Date(t);if(Number.isNaN(e.getTime()))return"";let n=String(e.getFullYear()),o=String(e.getMonth()+1).padStart(2,"0"),s=String(e.getDate()).padStart(2,"0"),r=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0");return`${n}-${o}-${s} ${r}:${i}`}function Qo({disabled:t,busy:e,history:n,cwd:o,sessionsDir:s,currentSessionFile:r,providers:i,configPath:l,providerName:a,model:c,contextLimit:u,mcpServers:m,onSubmit:d,onExit:h,onClear:w,onNewSession:f,onCancelRun:I,onHistorySelect:S,onModelSelect:_,onSetContextLimit:U,onSystemMessage:N}){let[M,y]=Ce(""),E=en(""),[ie,D]=Ce(null),[ne,q]=Ce(""),[B,b]=Ce("none"),[R,V]=Ce([]),[X,K]=Ce(0),[Re,de]=Ce(!1),[Ie,W]=Ce(!1),A=en(0),H=en(0);Qt(()=>{E.current=M,W(!1)},[M]);let Ae=Zo(()=>({configPath:l,providerName:a,model:c,mcpServers:m,providers:i,contextLimit:u}),[l,a,c,m,i,u]),j=Zo(()=>t||Ie?null:Dl(M),[t,Ie,M]),z=Yo((P=!0)=>{P&&W(!0),b("none"),V([]),K(0),de(!1)},[]);Qt(()=>{t&&z(!1)},[t,z]),Qt(()=>{if(!j){z(!1);return}let P=!1,k=++A.current;return de(!0),(async()=>{try{if(j.type==="file"){let C=await Vo({cwd:o,query:j.query,limit:8});if(P||k!==A.current)return;let v=C.map(x=>({id:x.id,title:x.isDir?`${x.path}/`:x.path,kind:"file",value:x.isDir?`${x.path}/`:x.path,meta:{type:"file",isDir:x.isDir}}));b("file"),V(v),K(x=>v.length?Math.min(x,v.length-1):0);return}if(j.type==="history"){let C=await Xo({sessionsDir:s,cwd:o,keyword:j.keyword,activeSessionFile:r});if(P||k!==A.current)return;let v=C.map(x=>({id:x.id,title:x.input,subtitle:Ul(x.ts),kind:"history",value:x.input,meta:{type:"history",entry:x}}));b("history"),V(v),K(x=>v.length?Math.min(x,v.length-1):0);return}if(j.type==="models"){let C=i.filter(v=>{if(!j.keyword)return!0;let x=v.name.toLowerCase(),F=v.model.toLowerCase();return x.includes(j.keyword)||F.includes(j.keyword)}).map(v=>({id:v.name,title:`${v.name}: ${v.model}`,subtitle:v.base_url,kind:"model",value:`${tn} ${v.name}`,meta:{type:"model",provider:v}}));b("model"),V(C),K(v=>C.length?Math.min(v,C.length-1):0);return}if(j.type==="context"){let C=De.map(v=>({id:`${v}`,title:`${Math.floor(v/1e3)}k tokens`,subtitle:v===u?"Current":void 0,kind:"context",value:`${nn} ${Math.floor(v/1e3)}k`,meta:{type:"context",value:v}}));b("context"),V(C),K(v=>C.length?Math.min(v,C.length-1):0);return}if(j.type==="slash"){let C=ht.filter(v=>v.name.startsWith(j.keyword)).map(v=>({id:v.name,title:`/${v.name}`,subtitle:v.description,kind:"slash",value:`/${v.name}`,meta:{type:"slash"}}));b("slash"),V(C),K(v=>C.length?Math.min(v,C.length-1):0)}}finally{!P&&k===A.current&&de(!1)}})(),()=>{P=!0}},[j,o,s,r,i,u,z]);let Fe=Yo(P=>{if(P){if(B==="file"&&j?.type==="file"){let k=M.slice(0,j.tokenStart),C=M.slice(j.tokenStart+j.query.length),v=`${k}${P.value}${C}`;E.current=v,y(v),D(null),q(""),P.meta?.type==="file"&&P.meta.isDir||z();return}if(P.meta?.type==="history"){S(P.meta.entry),E.current=P.value,y(P.value),D(null),q(""),z();return}if(P.meta?.type==="model"){_(P.meta.provider),E.current="",y(""),D(null),q(""),z();return}if(P.meta?.type==="context"){U(P.meta.value),N("Context",`Context limit set to ${Math.floor(P.meta.value/1e3)}k`),E.current="",y(""),D(null),q(""),z();return}if(P.meta?.type==="slash"){E.current=`${P.value} `,y(`${P.value} `),D(null),q(""),z(!1);return}E.current=P.value,y(P.value),D(null),q(""),z()}},[B,j,M,z,S,_,U,N]);Ml((P,k)=>{if(k.ctrl&&P==="c"){h();return}if(k.ctrl&&P==="l"){E.current="",y(""),D(null),q(""),z(),w(),f();return}let C=B!=="none",v=C&&R.length>0;if(k.escape){let x=Date.now();if(x-H.current<=Pl){H.current=0,e?I():(E.current="",y(""),D(null),q(""),z());return}H.current=x,C&&z();return}if(!t){if(k.upArrow){if(v){K(fe=>fe<=0?R.length-1:fe-1);return}if(!n.length)return;if(ie===null){q(E.current);let fe=n.length-1;D(fe);let je=n[fe]??"";E.current=je,y(je);return}let x=Math.max(0,ie-1);D(x);let F=n[x]??"";E.current=F,y(F);return}if(k.downArrow){if(v){K(fe=>(fe+1)%R.length);return}if(ie===null)return;let x=ie+1;if(x>=n.length){D(null),E.current=ne,y(ne),q("");return}D(x);let F=n[x]??"";E.current=F,y(F);return}if(k.tab&&v){Fe(R[X]);return}if(k.return){if(v){Fe(R[X]);return}if(k.shift){let F=`${E.current}
64
- `;E.current=F,y(F);return}let x=E.current.trim();if(!x)return;if(x.startsWith("/")){let F=qo(x,Ae);F.kind==="message"?N(F.title,F.content):F.kind==="new"?f():F.kind==="exit"?h():F.kind==="switch_model"?_(F.provider):F.kind==="set_context_limit"?U(F.limit):F.kind==="init_agents_md"&&d(Rl),E.current="",y(""),D(null),q(""),z(!1);return}d(x),E.current="",y(""),D(null),q(""),z(!1);return}if(k.backspace||k.delete){let x=E.current.slice(0,Math.max(0,E.current.length-1));E.current=x,y(x);return}if(P){let x=`${E.current}${P}`;E.current=x,y(x)}}});let Se=M.split(`
65
- `);return Ct(xt,{flexDirection:"column",gap:1,children:[Ct(xt,{flexDirection:"column",paddingY:1,children:[Ct(xt,{children:[Me(Ue,{color:"gray",children:"\u203A "}),Me(Ue,{children:Se[0]??""}),!t&&Se.length===1?Me(Ue,{color:"cyan",children:"\u258A"}):null]}),Se.slice(1).map((P,k)=>Ct(xt,{children:[Me(Ue,{color:"gray",children:" "}),Me(Ue,{children:P}),k===Se.length-2&&!t?Me(Ue,{color:"cyan",children:"\u258A"}):null]},`line-${k}`))]}),B!=="none"?Me(Jo,{items:R.map(({value:P,meta:k,...C})=>C),activeIndex:X,loading:Re}):null]})}import{Box as Hl,Text as er}from"ink";import{jsx as Fl,jsxs as tr}from"react/jsx-runtime";function nr({busy:t,contextPercent:e,tokenLine:n}){let o=`${e.toFixed(1)}%`;return tr(Hl,{justifyContent:"space-between",children:[Fl(er,{color:"gray",children:t?"Working... Esc Esc to interrupt":"Enter send \u2022 Shift+Enter newline \u2022 /help"}),tr(er,{color:"gray",children:[n?`${n} \u2022 `:"","context: ",o]})]})}import{useState as jl}from"react";import{Box as or,Text as Et,useInput as Bl}from"ink";import{jsx as on,jsxs as rn}from"react/jsx-runtime";var At=[{label:"Allow once",decision:"once"},{label:"Allow for this session",decision:"session"},{label:"Deny",decision:"deny"}];function Wl(t){if(!t)return"";if(typeof t!="object")return String(t);let e=Object.entries(t);if(!e.length)return"";let[n,o]=e[0]??[];if(!n)return"";let s=typeof o=="string"?o:JSON.stringify(o);return`${n}=${s?.slice(0,60)??""}${s&&s.length>60?"...":""}`}function rr({request:t,onDecision:e}){let[n,o]=jl(0);Bl((r,i)=>{if(i.upArrow){o(l=>l<=0?At.length-1:l-1);return}if(i.downArrow){o(l=>(l+1)%At.length);return}if(i.return){let l=At[n];l&&e(l.decision);return}(i.escape||i.ctrl&&r==="c")&&e("deny")});let s=Wl(t.params);return rn(or,{flexDirection:"column",borderStyle:"single",borderColor:"yellow",paddingX:1,children:[on(Et,{bold:!0,color:"yellow",children:"Tool Approval Required"}),rn(Et,{children:[t.toolName,s?` (${s})`:""]}),on(Et,{color:"gray",children:t.reason}),on(or,{marginTop:1,flexDirection:"column",children:At.map((r,i)=>rn(Et,{color:n===i?"green":"gray",children:[n===i?"> ":" ",r.label]},r.decision))})]})}import{Box as Qe,Text as ue,useInput as zl}from"ink";import{useCallback as sr,useMemo as ql,useState as et}from"react";import{jsx as me,jsxs as He}from"react/jsx-runtime";var Ee=[{key:"name",label:"Provider name",hint:"Used for /models switching",defaultValue:"deepseek"},{key:"envKey",label:"API key env var",hint:"Read at runtime from environment variables",defaultValue:"DEEPSEEK_API_KEY"},{key:"model",label:"Model name",defaultValue:"deepseek-chat"},{key:"baseUrl",label:"Base URL",defaultValue:"https://api.deepseek.com"}];function ir({configPath:t,onComplete:e,onExit:n}){let[o,s]=et(0),[r,i]=et(""),[l,a]=et({}),[c,u]=et(!1),[m,d]=et(null),h=Ee[o]??Ee[0],w=sr(async S=>{u(!0),d(null);try{let _={current_provider:S.name,providers:[{name:S.name,env_api_key:S.envKey,model:S.model,base_url:S.baseUrl||void 0}]};await le(t,_),e()}catch(_){d(_.message),u(!1)}},[t,e]),f=sr(async()=>{if(!h)return;let S=r.trim()||h.defaultValue,_={...l,[h.key]:S};if(a(_),i(""),o<Ee.length-1){s(o+1);return}let U={name:_.name||Ee[0].defaultValue,envKey:_.envKey||Ee[1].defaultValue,model:_.model||Ee[2].defaultValue,baseUrl:_.baseUrl||Ee[3].defaultValue};await w(U)},[r,w,h,o,l]);zl((S,_)=>{if(!c){if(_.ctrl&&S==="c"){n();return}if(_.return){f();return}if(_.backspace||_.delete){i(U=>U.slice(0,-1));return}S&&i(U=>U+S)}});let I=ql(()=>`Step ${o+1}/${Ee.length}`,[o]);return h?He(Qe,{flexDirection:"column",children:[me(ue,{bold:!0,children:"Memo setup"}),me(ue,{color:"gray",children:"No provider config found. Complete setup to continue."}),He(ue,{color:"gray",children:["Config path: ",t]}),He(Qe,{marginTop:1,flexDirection:"column",children:[me(ue,{color:"cyan",children:I}),me(ue,{children:h.label}),He(ue,{color:"gray",children:["Default: ",h.defaultValue]}),h.hint?me(ue,{color:"gray",children:h.hint}):null]}),He(Qe,{marginTop:1,children:[me(ue,{children:"> "}),me(ue,{children:r})]}),me(Qe,{marginTop:1,children:me(ue,{color:"gray",children:"Enter to continue, Ctrl+C to exit."})}),m?me(Qe,{marginTop:1,children:He(ue,{color:"red",children:["Failed to save config: ",m]})}):null]}):null}function ar(t){let e=[],n=[],o=[],s=t.split(`
66
- `).map(a=>a.trim()).filter(Boolean),r=null,i=0,l=0;for(let a of s){let c;try{c=JSON.parse(a)}catch{continue}if(!(!c||typeof c!="object")){if(c.type==="turn_start"){let u=typeof c.content=="string"?c.content:"";r={index:-(i+1),userInput:u,steps:[],status:"ok",sequence:l+=1},n.push(r),u&&(e.push({role:"user",content:u}),o.push(`User: ${u}`)),i+=1;continue}if(c.type==="assistant"){let u=typeof c.content=="string"?c.content:"";if(u&&(e.push({role:"assistant",content:u}),o.push(`Assistant: ${u}`),r)){let m={index:r.steps.length,assistantText:u};r.steps=[...r.steps,m],r.finalText=u}continue}if(c.type==="action"&&r){let u=c.meta;if(u&&typeof u=="object"){let m=typeof u.tool=="string"?u.tool:"",d=u.input,h=typeof u.thinking=="string"?u.thinking:"",f=(Array.isArray(u.toolBlocks)?u.toolBlocks:[]).map(S=>{let _=typeof S?.name=="string"?S.name:"";return _?{tool:_,input:S?.input}:null}).filter(Boolean),I=r.steps[r.steps.length-1];I&&(f.length>1?(I.action=f[0],I.parallelActions=f):m&&(I.action={tool:m,input:d}),h&&(I.thinking=h))}continue}if(c.type==="observation"&&r){let u=typeof c.content=="string"?c.content:"",m=r.steps[r.steps.length-1];m&&(m.observation=u);continue}}}return{summary:o.join(`
67
- `),messages:e,turns:n,maxSequence:l}}function an(){return{turns:[],historicalTurns:[],systemMessages:[],sequence:0}}function Kl(t,e){return{index:t,userInput:"",steps:[],sequence:e}}function sn(t,e){let n=t.slice();for(;n.length<=e;)n.push({index:n.length,assistantText:""});return n}function tt(t,e,n){let o=t.turns.slice(),s=o.findIndex(i=>i.index===e);if(s===-1){let i=t.sequence+1;return o.push(n(Kl(e,i))),{turns:o,sequence:i}}let r=o[s];return r?(o[s]=n(r),{turns:o,sequence:t.sequence}):{turns:o,sequence:t.sequence}}function Vl(t){return{id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,title:t.title,content:t.content,tone:t.tone??"info",sequence:t.sequence}}function lr(t,e){switch(e.type){case"append_system_message":{let n=t.sequence+1;return{...t,sequence:n,systemMessages:[...t.systemMessages,Vl({title:e.title,content:e.content,tone:e.tone,sequence:n})]}}case"turn_start":{let n=tt(t,e.turn,o=>({...o,index:e.turn,userInput:e.input,steps:[],finalText:void 0,status:void 0,errorMessage:void 0,tokenUsage:void 0,startedAt:Date.now(),durationMs:void 0,contextPromptTokens:e.promptTokens??o.contextPromptTokens}));return{...t,turns:n.turns,sequence:n.sequence}}case"assistant_chunk":{let n=tt(t,e.turn,o=>{let s=sn(o.steps,e.step),r=s[e.step];return r?(s[e.step]={...r,assistantText:`${r.assistantText}${e.chunk}`},{...o,steps:s}):o});return{...t,turns:n.turns,sequence:n.sequence}}case"tool_action":{let n=tt(t,e.turn,o=>{let s=sn(o.steps,e.step),r=s[e.step];return r?(s[e.step]={...r,action:e.action,thinking:e.thinking,parallelActions:e.parallelActions&&e.parallelActions.length>1?e.parallelActions:void 0,toolStatus:_e.EXECUTING},{...o,steps:s}):o});return{...t,turns:n.turns,sequence:n.sequence}}case"tool_observation":{let n=tt(t,e.turn,o=>{let s=sn(o.steps,e.step),r=s[e.step];return r?(s[e.step]={...r,observation:e.observation,toolStatus:e.toolStatus,parallelToolStatuses:e.parallelToolStatuses},{...o,steps:s}):o});return{...t,turns:n.turns,sequence:n.sequence}}case"turn_final":{let n=tt(t,e.turn,o=>{let s=o.startedAt??Date.now(),r=Math.max(0,Date.now()-s),i=e.tokenUsage?.prompt??o.contextPromptTokens;return{...o,finalText:e.finalText,status:e.status,errorMessage:e.errorMessage,tokenUsage:e.turnUsage,contextPromptTokens:i,startedAt:s,durationMs:r}});return{...t,turns:n.turns,sequence:n.sequence}}case"replace_history":return{...t,historicalTurns:e.turns,sequence:Math.max(t.sequence,e.maxSequence)};case"clear_current_timeline":return{...t,turns:[],systemMessages:[]};case"reset_all":return an();default:return t}}import{dirname as wt,join as ur,resolve as Gl}from"path";import{statSync as Xl,existsSync as pr,readFileSync as Jl}from"fs";import{readFile as Yl}from"fs/promises";import{get as Zl}from"https";import{fileURLToPath as Ql}from"url";function cr(t){let e=t.trim().replace(/^v/i,""),[n="",o]=e.split("-",2),s=n.split(".").map(r=>Number(r));return s.length<3||s.some(r=>!Number.isFinite(r))?null:{major:s[0]??0,minor:s[1]??0,patch:s[2]??0,prerelease:o??null}}function ec(t,e){let n=cr(t),o=cr(e);return!n||!o?!1:n.major!==o.major?n.major>o.major:n.minor!==o.minor?n.minor>o.minor:n.patch!==o.patch?n.patch>o.patch:n.prerelease&&!o.prerelease?!1:!n.prerelease&&o.prerelease?!0:n.prerelease&&o.prerelease?n.prerelease>o.prerelease:!1}function mr(){try{let e=Ql(import.meta.url);return wt(e)}catch{}let t=Gl(process.argv[1]??process.cwd());try{return Xl(t).isFile()?wt(t):t}catch{return process.cwd()}}async function tc(t){let e=ur(t,"package.json");if(!pr(e))return null;let n=await Yl(e,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}function nc(t){let e=ur(t,"package.json");if(!pr(e))return null;try{let n=Jl(e,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}catch{return null}}async function oc(){let t=mr();for(;;){let e=await tc(t);if(e&&e.name==="@memo-code/memo")return e;let n=wt(t);if(n===t)break;t=n}return null}function bt(){let t=mr();for(;;){let e=nc(t);if(e&&e.name==="@memo-code/memo")return e;let n=wt(t);if(n===t)break;t=n}return null}async function rc(t,e=1500){let o=`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`;return new Promise(s=>{let r=Zl(o,{timeout:e},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),s(null);return}let l=[];i.on("data",a=>l.push(a)),i.on("end",()=>{try{let a=JSON.parse(Buffer.concat(l).toString("utf8"));s(a.version??null)}catch{s(null)}})});r.on("timeout",()=>{r.destroy(),s(null)}),r.on("error",()=>s(null))})}async function dr(){let t=await oc();if(!t)return null;let e=await rc(t.name);return!e||!ec(e,t.version)?null:{current:t.version,latest:e}}import{jsx as Pe,jsxs as cc}from"react/jsx-runtime";function hr({sessionOptions:t,providerName:e,model:n,configPath:o,mcpServers:s,cwd:r,sessionsDir:i,providers:l,dangerous:a=!1,needsSetup:c=!1}){let{exit:u}=lc(),[m,d]=ic(lr,void 0,an),[h,w]=te(e),[f,I]=te(n),[S,_]=te(l),[U,N]=te({...t,providerName:e}),[M,y]=te(!1),[E,ie]=te([]),[D,ne]=te(null),[q,B]=te(null),[b,R]=te(t.maxPromptTokens??Wo),[V,X]=te(0),[K,Re]=te(c),[de,Ie]=te(null),[W,A]=te(null),H=Mt(null),Ae=Mt(null),j=Mt(null),[z,Fe]=te(null),Se=Mt(null),P=fr(()=>bt(),[]),k=Z(g=>{d(g)},[]),C=Z((g,T,L="info")=>{k({type:"append_system_message",title:g,content:T,tone:L})},[k]),v=fr(()=>({onAssistantStep:(g,T)=>{let L=Ae.current;L&&k({type:"assistant_chunk",turn:L,step:T,chunk:g})},requestApproval:a?void 0:g=>new Promise(T=>{Fe(g),Se.current=T}),hooks:{onTurnStart:({turn:g,input:T,promptTokens:L})=>{Ae.current=g;let pe=j.current;pe&&(j.current=null);let we=pe??T;L&&L>0&&X(L),k({type:"turn_start",turn:g,input:we,promptTokens:L})},onAction:({turn:g,step:T,action:L,thinking:pe,parallelActions:we})=>{k({type:"tool_action",turn:g,step:T,action:L,thinking:pe,parallelActions:we})},onObservation:({turn:g,step:T,observation:L,resultStatus:pe,parallelResultStatuses:we})=>{k({type:"tool_observation",turn:g,step:T,observation:L,toolStatus:Yt(pe),parallelToolStatuses:$o(we)})},onFinal:({turn:g,finalText:T,status:L,errorMessage:pe,turnUsage:we,tokenUsage:Pr})=>{k({type:"turn_final",turn:g,finalText:T,status:L,errorMessage:pe,turnUsage:we,tokenUsage:Pr}),y(!1)}}}),[k,a]);kt(()=>{let g=!1;return(async()=>{if(K)return;let T=H.current;T&&await T.close();let L=await dt(v,U);if(g){await L.close();return}H.current=L,A(L),ne(L.historyFilePath??null)})(),()=>{g=!0}},[v,U,K]),kt(()=>{let g=!1;return(async()=>{let T=await dr();g||!T||C("Update",`Update available: v${T.latest}. Run: npm install -g @memo-code/memo@latest`)})(),()=>{g=!0}},[C]),kt(()=>()=>{H.current&&H.current.close()},[]);let x=Z(async()=>{H.current&&await H.current.close(),Ie("Bye!"),setTimeout(()=>u(),250)},[u]),F=Z(()=>{k({type:"clear_current_timeline"}),B(null),X(0)},[k]),fe=Z(()=>{k({type:"reset_all"}),B(null),X(0),Ae.current=null,N(g=>({...g,sessionId:nt()})),C("New Session","Started a fresh session.")},[C,k]),je=Z(async g=>{try{let T=await Q();await le(T.configPath,{...T.config,current_provider:g})}catch(T){C("Config",`Failed to persist provider: ${T.message}`,"warning")}},[C]),vr=Z(async g=>{if(M){C("Model switch","Cancel current run before switching models.","warning");return}if(g.name===h&&g.model===f){C("Model switch",`Already using ${g.name} (${g.model}).`);return}k({type:"reset_all"}),X(0),Ae.current=null,w(g.name),I(g.model),N(T=>({...T,sessionId:nt(),providerName:g.name})),await je(g.name),C("Model switch",`Switched to ${g.name} (${g.model}).`)},[C,M,f,h,k,je]),un=Z(async g=>{try{let T=await Q();await le(T.configPath,{...T.config,max_prompt_tokens:g})}catch(T){C("Context",`Failed to persist context limit: ${T.message}`,"warning")}},[C]),xr=Z(g=>{R(g),X(0),N(T=>({...T,maxPromptTokens:g,sessionId:nt()})),C("Context",`Context window set to ${Math.floor(g/1e3)}k.`),un(g)},[C,un]),Cr=Z(async g=>{try{let T=await sc(g.sessionFile,"utf8"),L=ar(T);k({type:"clear_current_timeline"}),k({type:"replace_history",turns:L.turns,maxSequence:L.maxSequence}),B(L.messages),y(!1),A(null),ne(null),X(0),Ae.current=null,N(pe=>({...pe,sessionId:nt()})),C("History",L.summary||g.input)}catch(T){C("History",`Failed to load ${g.sessionFile}: ${T.message}`,"error")}},[C,k]),Er=Z(()=>{M&&W?.cancelCurrentTurn?.()},[M,W]),pn=Z(async()=>{if(!W||M)return;let g=`Please analyze the current project and create an AGENTS.md file at the project root.
78
+ `:""}${a.join(`
79
+ `)}`}}case $.CONTEXT:{let s=yu(r[0]),i=dt.map(a=>`${Math.floor(a/1e3)}k`).join(", ");return s===null?{kind:"message",title:"Context",content:`Current: ${(t.contextLimit/1e3).toFixed(0)}k
80
+ Usage: ${ge($.CONTEXT)} <length>
81
+ Choices: ${i}`}:dt.includes(s)?{kind:"set_context_limit",limit:s}:{kind:"message",title:"Context",content:`Unsupported value: ${s}. Choose one of ${i}`}}case $.TOOLS:{let s=r.join(" ").trim(),i=gu(s),a=["none","once","full"].join(", ");return s?i?i===t.toolPermissionMode?{kind:"message",title:"Tools",content:`Already using ${ls(i)}.`}:{kind:"set_tool_permission",mode:i}:{kind:"message",title:"Tools",content:`Unsupported mode: ${s}
82
+ Choose one of: ${a}`}:{kind:"message",title:"Tools",content:`Current: ${ls(t.toolPermissionMode)}
83
+ Usage: ${ge($.TOOLS)} <mode>
84
+ Modes: ${a}`}}case $.MCP:{let s=Object.keys(t.mcpServers);if(!s.length)return{kind:"message",title:"MCP Servers",content:"No MCP servers configured in current config."};let i=[];i.push(`Total: ${s.length}`),i.push("");for(let[a,l]of Object.entries(t.mcpServers))i.push(`- ${a}`),"url"in l?(i.push(` type: ${l.type??"streamable_http"}`),i.push(` url: ${l.url}`),l.bearer_token_env_var&&i.push(` bearer: ${l.bearer_token_env_var}`)):(i.push(` type: ${l.type??"stdio"}`),i.push(` command: ${l.command}`),l.args?.length&&i.push(` args: ${l.args.join(" ")}`)),i.push("");return{kind:"message",title:"MCP Servers",content:i.join(`
85
+ `)}}case $.INIT:return{kind:"init_agents_md"};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${e}
86
+ Type ${ge($.HELP)} for available commands.`}}}import{readdir as Tu}from"fs/promises";import{join as _u,relative as Su,sep as vu}from"path";var xu=6,Cu=2500,us=25,bu=new Set([".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs"]),nn=new Map;function Au(e){return e.split(vu).join("/")}function Eu(e){return{maxDepth:typeof e.maxDepth=="number"?Math.max(1,e.maxDepth):xu,maxEntries:typeof e.maxEntries=="number"?Math.max(100,e.maxEntries):Cu,limit:typeof e.limit=="number"?Math.max(1,e.limit):us,ignoreGlobs:e.ignoreGlobs?.length?e.ignoreGlobs:[]}}function Mu(e,t){let n=e.split("/").filter(Boolean),r=n[n.length-1]??"";return n.some(o=>bu.has(o))||r.endsWith(".log")?!0:t.ignoreGlobs.length?t.ignoreGlobs.some(o=>{let s=o.replace(/\\/g,"/").trim();if(!s)return!1;if(s.endsWith("/**")){let i=s.slice(0,-3);return e.startsWith(i)}if(s.startsWith("*")){let i=s.slice(1);return e.endsWith(i)}return e.includes(s)}):!1}function wu(e){return JSON.stringify({maxDepth:e.maxDepth,maxEntries:e.maxEntries,ignoreGlobs:e.ignoreGlobs})}async function ku(e,t){let n=[],r=async(o,s)=>{if(n.length>=t.maxEntries)return;let i;try{i=await Tu(o,{withFileTypes:!0})}catch{return}for(let a of i){if(n.length>=t.maxEntries)break;if(a.isSymbolicLink())continue;let l=_u(o,a.name),c=Su(e,l);if(!c)continue;let u=Au(c);if(Mu(u,t))continue;let d=u.split("/").filter(Boolean),y=a.isDirectory();n.push({path:u,pathLower:u.toLowerCase(),segments:d,segmentsLower:d.map(p=>p.toLowerCase()),depth:s,isDir:y}),y&&s<t.maxDepth&&await r(l,s+1)}};return await r(e,0),n.sort((o,s)=>o.path.localeCompare(s.path)),n}async function Pu(e,t){let n=Eu(t),r=wu(n),o=nn.get(e);if(o&&o.signature===r)return o.pending?o.pending:o.entries;let s=ku(e,n).then(i=>(nn.set(e,{entries:i,signature:r}),i)).catch(i=>{throw nn.delete(e),i});return nn.set(e,{entries:[],signature:r,pending:s}),s}function Iu(e,t){if(!t.length)return e.depth+(e.isDir?-.2:.2);let n=e.depth,r=0;for(let o of t){let s=-1;for(let i=r;i<e.segmentsLower.length;i++){let a=e.segmentsLower[i];if(a.startsWith(o)){s=i,n+=(i-r)*1.2,n+=a.length-o.length;break}let l=a.indexOf(o);if(l!==-1){s=i,n+=(i-r)*2+l+2;break}}if(s===-1)return null;r=s+1}return e.isDir&&(n-=.5),n}function Ru(e,t,n){let o=t.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(i=>i.toLowerCase()),s=[];for(let i of e){let a=Iu(i,o);a!==null&&s.push({entry:i,score:a})}return s.sort((i,a)=>{let l=i.score-a.score;return l!==0?l:i.entry.path.localeCompare(a.entry.path)}),s.slice(0,n).map(({entry:i})=>({id:i.path,path:i.path,name:i.segments[i.segments.length-1]??i.path,parent:i.segments.length>1?i.segments.slice(0,-1).join("/"):void 0,isDir:i.isDir}))}async function ps(e){let t=await Pu(e.cwd,e),n=typeof e.limit=="number"?Math.max(1,e.limit):us;return Ru(t,e.query,n)}import{readdir as Ou,readFile as Lu,stat as Nu}from"fs/promises";import{basename as $u,join as rn,resolve as kt}from"path";function ms(e){let t=kt(e);return process.platform==="win32"?t.toLowerCase():t}function Du(e,t){return t?ms(e)===ms(t):!1}function Uu(e){return $u(e).replace(/\.jsonl$/i,"")}function Hu(e){let t=null,n=null,r=null;for(let o of e.split(`
87
+ `)){let s=o.trim();if(!s)continue;let i;try{i=JSON.parse(s)}catch{continue}if(!(!i||typeof i!="object")){if(i.type==="session_start"&&!r){let a=i.meta?.cwd;typeof a=="string"&&a.trim()&&(r=a);continue}if(i.type==="turn_start"&&!t){let a=typeof i.content=="string"?i.content.trim():"";a&&(t=a)}if(i.type==="session_title"&&!n){let a=typeof i.content=="string"?i.content.trim():"";a&&(n=a)}}}return{firstPrompt:t,sessionTitle:n,sessionCwd:r}}async function Fu(e,t,n){try{let r=await Lu(e,"utf8"),{firstPrompt:o,sessionTitle:s,sessionCwd:i}=Hu(r);if(!Du(t,i))return null;let a=s?.trim()||o?.trim()||Uu(e);return{id:e,cwd:t,input:a,ts:n,sessionFile:e}}catch{return null}}async function Bu(e){let t=async s=>{try{return await Ou(s,{withFileTypes:!0})}catch{return[]}},n=(await t(e)).filter(s=>s.isDirectory()&&/^\d{4}$/.test(s.name)),r=[];for(let s of n){let i=rn(e,s.name),a=(await t(i)).filter(l=>l.isDirectory()&&/^\d{2}$/.test(l.name));for(let l of a){let c=rn(i,l.name),u=(await t(c)).filter(d=>d.isDirectory()&&/^\d{2}$/.test(d.name));for(let d of u){let y=rn(c,d.name),p=(await t(y)).filter(h=>h.isFile()&&h.name.endsWith(".jsonl"));for(let h of p)r.push(rn(y,h.name))}}}return(await Promise.all(r.map(async s=>{try{let i=await Nu(s);return{path:s,mtimeMs:i.mtimeMs}}catch{return null}}))).filter(s=>!!s)}async function ds(e){let t=e.activeSessionFile?kt(e.activeSessionFile):null,r=(await Bu(e.sessionsDir)).filter(a=>!t||kt(a.path)!==t).filter((a,l,c)=>c.findIndex(u=>kt(u.path)===kt(a.path))===l).sort((a,l)=>l.mtimeMs-a.mtimeMs),o=e.keyword?.trim().toLowerCase(),s=e.limit??10,i=[];for(let a of r){if(i.length>=s)break;let l=await Fu(a.path,e.cwd,a.mtimeMs);l&&(o&&!l.input.toLowerCase().includes(o)||i.push(l))}return i}import{Box as on,Text as sn}from"ink";import{jsx as Ze,jsxs as ju}from"react/jsx-runtime";var Wu="#3a3a3a",an="#262626";function fs({items:e,activeIndex:t,loading:n}){return n?Ze(on,{paddingX:1,backgroundColor:an,children:Ze(sn,{color:"gray",children:"Loading..."})}):e.length?Ze(on,{flexDirection:"column",backgroundColor:an,children:e.map((r,o)=>{let s=o===t;return ju(on,{paddingX:1,gap:2,backgroundColor:s?Wu:an,children:[Ze(sn,{color:s?"cyan":"white",bold:s,children:r.title}),r.subtitle?Ze(sn,{color:"gray",children:r.subtitle}):null]},r.id)})}):Ze(on,{paddingX:1,backgroundColor:an,children:Ze(sn,{color:"gray",children:"No matches"})})}import zu from"string-width";var qu=55296,Gu=56319,Ku=56320,Vu=57343;function gs(e){return e>=qu&&e<=Gu}function hs(e){return e>=Ku&&e<=Vu}function xe(e,t){if(!Number.isFinite(t)||t<=0)return 0;if(t>=e.length)return e.length;if(e.length===0)return 0;let n=Math.floor(t);if(n<=0)return 0;if(n>=e.length)return e.length;let r=e.charCodeAt(n),o=e.charCodeAt(n-1);return hs(r)&&gs(o)?n-1:n}function ys(e,t){let n=xe(e,t);if(n>=e.length)return e.length;let r=e.codePointAt(n);return r===void 0?Math.min(e.length,n+1):Math.min(e.length,n+(r>65535?2:1))}function Qe(e,t){let n=xe(e,t);if(n<=0)return 0;let r=n-1;if(r<=0)return r;let o=e.charCodeAt(r),s=e.charCodeAt(r-1);return hs(o)&&gs(s)?r-1:r}function ln(e,t){let n=xe(e,t),r=e.lastIndexOf(`
88
+ `,Math.max(0,n-1));return r===-1?0:r+1}function cn(e,t){let n=xe(e,t),r=e.indexOf(`
89
+ `,n);return r===-1?e.length:r}function Xu(e){return/[\p{L}\p{N}_]/u.test(e)}function Ts(e,t,n){let r=xe(e,t);return n?{value:`${e.slice(0,r)}${n}${e.slice(r)}`,cursor:r+n.length}:{value:e,cursor:r}}function _s(e,t){let n=xe(e,t);if(n<=0)return{value:e,cursor:n};let r=Qe(e,n);return{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function Zn(e,t){let n=xe(e,t);if(n>=e.length)return{value:e,cursor:n};let r=ys(e,n);return{value:`${e.slice(0,n)}${e.slice(r)}`,cursor:n}}function Ss(e,t){let n=xe(e,t);if(n<=0)return{value:e,cursor:n};let r=n;for(;r>0;){let s=Qe(e,r);if(e.slice(s,r).trim().length>0)break;r=s}for(;r>0;){let s=Qe(e,r),i=e.slice(s,r);if(!Xu(i))break;r=s}return r===n&&(r=Qe(e,n)),{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function vs(e,t){let n=xe(e,t),r=ln(e,n);return r>=n?{value:e,cursor:n}:{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function xs(e,t){let n=xe(e,t),r=cn(e,n);return r<=n?{value:e,cursor:n}:{value:`${e.slice(0,n)}${e.slice(r)}`,cursor:n}}function Cs(e,t){return Qe(e,t)}function bs(e,t){return ys(e,t)}function As(e,t){return ln(e,t)}function Es(e,t){return cn(e,t)}function Qn(e,t,n,r){let o=xe(e,t),s=ln(e,o),i=cn(e,o),a=o-s,l=r??a;if(n==="up"){if(s===0)return{cursor:o,preferredColumn:l,changed:!1};let y=s-1,p=ln(e,y),h=Math.min(p+l,y);return{cursor:h,preferredColumn:l,changed:h!==o}}if(i>=e.length)return{cursor:o,preferredColumn:l,changed:!1};let c=i+1,u=cn(e,c),d=Math.min(c+l,u);return{cursor:d,preferredColumn:l,changed:d!==o}}function Ms(e,t,n){let r=xe(e,t),o=Number.isFinite(n)?Math.max(1,Math.floor(n)):1,s=[],i=0,a=0,l="",c=0,u=()=>{s.push({text:l,start:i,end:a})},d=0;for(let h of e){let m=d;if(d+=h.length,h===`
90
+ `){a=m,u(),i=d,a=d,l="",c=0;continue}let k=Math.max(0,zu(h));l.length>0&&c+k>o&&(u(),i=m,a=m,l="",c=0),l+=h,a=d,c+=k}if(u(),s.length===0)return{lines:[{text:"",start:0,end:0}],row:0,cursorInRow:0};let y=Math.max(0,s.length-1),p=(s[y]?.text??"").length;for(let h=0;h<s.length;h+=1){let m=s[h];if(m&&!(r<m.start)&&r<=m.end){y=h,p=r-m.start;break}}return{lines:s,row:y,cursorInRow:p}}function ws(e,t){let n=e==="\b"||e==="\x7F",r=!!t.ctrl&&e.toLowerCase()==="h";return t.backspace||n||r||t.delete&&!(t.ctrl||t.meta)?"backspace":t.delete?"delete":"none"}var Ju=3,ks=8,Yu=120,Zu=process.platform==="win32"?60:8,Pt=class{lastPlainCharAtMs=null;consecutivePlainChars=0;burstWindowUntilMs=null;buffer="";active=!1;pendingFirstChar=null;minChars;charIntervalMs;enterSuppressWindowMs;activeIdleTimeoutMs;constructor(t={}){this.minChars=t.minChars??Ju,this.charIntervalMs=t.charIntervalMs??ks,this.enterSuppressWindowMs=t.enterSuppressWindowMs??Yu,this.activeIdleTimeoutMs=t.activeIdleTimeoutMs??Zu}static recommendedFlushDelayMs(){return ks+1}recommendedActiveFlushDelayMs(){return this.activeIdleTimeoutMs+1}onPlainChar(t,n){let r=Array.from(t)[0]??"";return this.notePlainChar(n),this.active?(this.extendWindow(n),{type:"buffer_append"}):this.pendingFirstChar&&n-this.pendingFirstChar.atMs<=this.charIntervalMs?(this.active=!0,this.buffer+=this.pendingFirstChar.ch,this.pendingFirstChar=null,this.extendWindow(n),{type:"begin_buffer_from_pending"}):this.consecutivePlainChars>=this.minChars?{type:"begin_buffer",retroChars:Math.max(0,this.consecutivePlainChars-1)}:r?(this.pendingFirstChar={ch:r,atMs:n},{type:"retain_first_char"}):{type:"retain_first_char"}}onPlainCharNoHold(t){return this.notePlainChar(t),this.active?(this.extendWindow(t),{type:"buffer_append"}):this.consecutivePlainChars>=this.minChars?{type:"begin_buffer",retroChars:Math.max(0,this.consecutivePlainChars-1)}:null}flushIfDue(t){let n=this.isActiveInternal()?this.activeIdleTimeoutMs:this.charIntervalMs;if(!(this.lastPlainCharAtMs!==null&&t-this.lastPlainCharAtMs>n))return{type:"none"};if(this.isActiveInternal()){this.active=!1;let o=this.buffer;return this.buffer="",{type:"paste",text:o}}if(this.pendingFirstChar){let o=this.pendingFirstChar.ch;return this.pendingFirstChar=null,{type:"typed",text:o}}return{type:"none"}}appendNewlineIfActive(t){return this.isActiveInternal()?(this.buffer+=`
91
+ `,this.extendWindow(t),!0):!1}newlineShouldInsertInsteadOfSubmit(t){let n=this.burstWindowUntilMs!==null&&t<=this.burstWindowUntilMs;return this.isActiveInternal()||n}extendWindow(t){this.burstWindowUntilMs=t+this.enterSuppressWindowMs}beginWithRetroGrabbed(t,n){t&&(this.buffer+=t),this.active=!0,this.extendWindow(n)}appendCharToBuffer(t,n){t&&(this.buffer+=t,this.extendWindow(n))}decideBeginBuffer(t,n,r){let o=Qu(n,r),s=n.slice(o);return/\s/u.test(s)||Array.from(s).length>=16?(this.beginWithRetroGrabbed(s,t),{start:o,grabbed:s}):null}flushBeforeModifiedInput(){if(!this.isActive())return null;this.active=!1;let t=this.buffer;return this.buffer="",this.pendingFirstChar&&(t+=this.pendingFirstChar.ch,this.pendingFirstChar=null),t}clearWindowAfterNonChar(){this.consecutivePlainChars=0,this.lastPlainCharAtMs=null,this.burstWindowUntilMs=null,this.active=!1,this.pendingFirstChar=null}isActive(){return this.isActiveInternal()||this.pendingFirstChar!==null}isBuffering(){return this.isActiveInternal()}hasPendingFirstChar(){return this.pendingFirstChar!==null}clearAfterExplicitPaste(){this.lastPlainCharAtMs=null,this.consecutivePlainChars=0,this.burstWindowUntilMs=null,this.active=!1,this.buffer="",this.pendingFirstChar=null}notePlainChar(t){this.lastPlainCharAtMs!==null&&t-this.lastPlainCharAtMs<=this.charIntervalMs?this.consecutivePlainChars+=1:this.consecutivePlainChars=1,this.lastPlainCharAtMs=t}isActiveInternal(){return this.active||this.buffer.length>0}};function Qu(e,t){if(t<=0)return e.length;let n=e.length,r=t;for(;r>0&&n>0;)n=Qe(e,n),r-=1;return n}import{jsx as ft,jsxs as Is}from"react/jsx-runtime";var np=400,tr=ge($.MODELS),nr=ge($.CONTEXT),rr=ge($.TOOLS),rp=ge($.INIT),op=[{mode:H.NONE,description:"Disable all tool calls"},{mode:H.ONCE,description:"Require approval when needed"},{mode:H.FULL,description:"Run tools without approval"}];function sp(e){let t=e.lastIndexOf("@");if(t===-1)return null;if(t>0){let r=e[t-1];if(r&&!/\s/.test(r))return null}let n=e.slice(t+1);return/\s/.test(n)?null:{type:"file",query:n,tokenStart:t+1}}function ip(e){let t=e.trimStart(),n=e.length-t.length;if(!t.length)return null;let r=t;if(r.startsWith("/")&&(r=r.slice(1)),!r.toLowerCase().startsWith($.RESUME)||e.slice(0,n).trim().length>0)return null;let s=r.slice($.RESUME.length);return s&&!s.startsWith(" ")?null:{type:"history",keyword:s.trim()}}function ap(e){let t=e.trimStart();if(!t.startsWith("/"))return null;let n=t.slice(1);return n.includes(" ")?null:n.length?/^[a-zA-Z-]+$/.test(n)?{type:"slash",keyword:n.toLowerCase()}:null:{type:"slash",keyword:""}}function lp(e){let t=e.trimStart();if(!t.startsWith(tr))return null;let n=t.slice(tr.length);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim().toLowerCase()}}function cp(e){let t=e.trimStart();if(!t.startsWith(nr))return null;let n=t.slice(nr.length);return n&&!n.startsWith(" ")?null:{type:"context"}}function up(e){let t=e.trimStart();if(!t.startsWith(rr))return null;let n=t.slice(rr.length);return n&&!n.startsWith(" ")?null:{type:"tools"}}function pp(e){return up(e)??cp(e)??lp(e)??ap(e)??sp(e)??ip(e)}function mp(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let n=String(t.getFullYear()),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${n}-${r}-${o} ${s}:${i}`}function dp(e,t){return{mode:"model",items:e.filter(r=>{if(!t)return!0;let o=r.name.toLowerCase(),s=r.model.toLowerCase();return o.includes(t)||s.includes(t)}).map(r=>({id:r.name,title:`${r.name}: ${r.model}`,subtitle:r.base_url,kind:"model",value:`${tr} ${r.name}`,meta:{type:"model",provider:r}}))}}function fp(e){return{mode:"context",items:dt.map(n=>({id:`${n}`,title:`${Math.floor(n/1e3)}k tokens`,subtitle:n===e?"Current":void 0,kind:"context",value:`${nr} ${Math.floor(n/1e3)}k`,meta:{type:"context",value:n}}))}}function gp(e){return{mode:"tools",items:op.map(n=>({id:n.mode,title:n.mode,subtitle:n.mode===e?`Current \xB7 ${n.description}`:n.description,kind:"tools",value:`${rr} ${n.mode}`,meta:{type:"tools",mode:n.mode}}))}}function hp(e){return{mode:"slash",items:tn.filter(n=>n.name.startsWith(e)).map(n=>({id:n.name,title:`/${n.name}`,subtitle:n.description,kind:"slash",value:`/${n.name}`,meta:{type:"slash"}}))}}async function yp({trigger:e,cwd:t,sessionsDir:n,currentSessionFile:r,providers:o,contextLimit:s,toolPermissionMode:i}){switch(e.type){case"file":return{mode:"file",items:(await ps({cwd:t,query:e.query,limit:8})).map(c=>({id:c.id,title:c.isDir?`${c.path}/`:c.path,kind:"file",value:c.isDir?`${c.path}/`:c.path,meta:{type:"file",isDir:c.isDir}}))};case"history":return{mode:"history",items:(await ds({sessionsDir:n,cwd:t,keyword:e.keyword,activeSessionFile:r})).map(c=>({id:c.id,title:c.input,subtitle:mp(c.ts),kind:"history",value:c.input,meta:{type:"history",entry:c}}))};case"models":return dp(o,e.keyword);case"context":return fp(s);case"tools":return gp(i);case"slash":return hp(e.keyword)}}function Rs({disabled:e,busy:t,history:n,cwd:r,sessionsDir:o,currentSessionFile:s,providers:i,configPath:a,providerName:l,model:c,contextLimit:u,toolPermissionMode:d,mcpServers:y,onSubmit:p,onExit:h,onClear:m,onNewSession:k,onCancelRun:v,onHistorySelect:S,onModelSelect:W,onSetContextLimit:ee,onSetToolPermission:q,onSystemMessage:V}){let{stdout:he}=tp(),[A,F]=Ge({value:"",cursor:0}),E=It(A),P=It(null),[ue,Me]=Ge(null),[te,M]=Ge(""),[R,ne]=Ge("none"),[se,Be]=Ge([]),[we,pe]=Ge(0),[ke,Xe]=Ge(!1),[Le,w]=Ge(!1),Y=It(0),nt=It(0),G=It(new Pt);un(()=>{E.current=A,w(!1)},[A]);let yn=Ps(()=>({configPath:a,providerName:l,model:c,mcpServers:y,providers:i,contextLimit:u,toolPermissionMode:d}),[a,l,c,y,i,u,d]),j=Ps(()=>e||Le?null:pp(A.value),[e,A.value,Le]),z=et((T=!0)=>{T&&w(!0),ne("none"),Be([]),pe(0),Xe(!1)},[]),O=et((T,x=!1)=>{E.current=T,F(T),x&&(Me(null),M(""))},[]),Pe=et(()=>{O({value:"",cursor:0},!0)},[O]),ie=et((T,x=!0)=>{if(!T)return;let U=E.current;P.current=null;let Z=Ts(U.value,U.cursor,T);O(Z,x),T.includes(`
92
+ `)&&z(!1)},[O,z]),K=et(T=>T.type==="none"?!1:T.type==="paste"?(T.text&&ie(T.text,!0),!0):(ie(T.text,!0),!0),[ie]),Ce=et((T=!0)=>{let x=G.current.flushBeforeModifiedInput();return x&&ie(x,!0),T&&G.current.clearWindowAfterNonChar(),!!x},[ie]);un(()=>{let T=setInterval(()=>{let x=G.current.flushIfDue(Date.now());K(x)},Pt.recommendedFlushDelayMs());return()=>{clearInterval(T)}},[K]),un(()=>{e&&z(!1)},[e,z]),un(()=>{if(!j){z(!1);return}let T=!1,x=++Y.current;return Xe(!0),(async()=>{try{let{mode:U,items:Z}=await yp({trigger:j,cwd:r,sessionsDir:o,currentSessionFile:s,providers:i,contextLimit:u,toolPermissionMode:d});if(T||x!==Y.current)return;ne(U),Be(Z),pe(ye=>Z.length?Math.min(ye,Z.length-1):0)}finally{!T&&x===Y.current&&Xe(!1)}})(),()=>{T=!0}},[j,r,o,s,i,u,d,z]);let We=et(T=>{if(T){if(R==="file"&&j?.type==="file"){let x=E.current.value,U=x.slice(0,j.tokenStart),Z=x.slice(j.tokenStart+j.query.length),ye=`${U}${T.value}${Z}`,Ie=U.length+T.value.length;O({value:ye,cursor:Ie},!0),T.meta?.type==="file"&&T.meta.isDir||z();return}switch(T.meta?.type){case"history":S(T.meta.entry),O({value:T.value,cursor:T.value.length},!1),z();return;case"model":W(T.meta.provider),Pe(),z();return;case"context":ee(T.meta.value),Pe(),z();return;case"tools":q(T.meta.mode),Pe(),z();return;case"slash":O({value:`${T.value} `,cursor:`${T.value} `.length},!0),z(!1);return;default:O({value:T.value,cursor:T.value.length},!0),z()}}},[O,R,j,z,Pe,S,W,ee,q]);ep((T,x)=>{if(x.ctrl&&T==="c"){h();return}if(e)return;let U=Date.now();K(G.current.flushIfDue(U));let Z=R!=="none",ye=Z&&se.length>0,Ie=ws(T,x),Tn=!!(x.ctrl||x.meta),rt=!!T&&!Tn&&!x.return&&!x.tab&&Ie==="none"&&!x.escape&&!x.upArrow&&!x.downArrow&&!x.leftArrow&&!x.rightArrow;if(!rt&&!x.return&&Ce(!0),x.ctrl&&T==="a"){let C=E.current,L=As(C.value,C.cursor);P.current=null,O({value:C.value,cursor:L},!1);return}if(x.ctrl&&T==="e"){let C=E.current,L=Es(C.value,C.cursor);P.current=null,O({value:C.value,cursor:L},!1);return}if(x.ctrl&&T==="u"){let C=E.current,L=vs(C.value,C.cursor);P.current=null,O(L,!0);return}if(x.ctrl&&T==="k"){let C=E.current,L=xs(C.value,C.cursor);P.current=null,O(L,!0);return}if(x.ctrl&&T==="w"){let C=E.current,L=Ss(C.value,C.cursor);P.current=null,O(L,!0);return}if(x.ctrl&&T==="d"){let C=E.current;if(!C.value){h();return}let L=Zn(C.value,C.cursor);P.current=null,O(L,!0);return}if(x.ctrl&&T==="l"){O({value:"",cursor:0},!0),z(),m(),k();return}if(x.escape){if(U-nt.current<=np){nt.current=0,t?v():(P.current=null,O({value:"",cursor:0},!0),z());return}nt.current=U,Z&&z();return}if(x.upArrow){if(ye){pe(D=>D<=0?se.length-1:D-1);return}let C=E.current;if(C.value.includes(`
93
+ `)){let D=Qn(C.value,C.cursor,"up",P.current??void 0);if(D.changed){P.current=D.preferredColumn,O({value:C.value,cursor:D.cursor},!1);return}}if(!n.length)return;if(ue===null){M(C.value);let D=n.length-1;Me(D);let Re=n[D]??"";P.current=null,O({value:Re,cursor:Re.length},!1);return}let L=Math.max(0,ue-1);Me(L);let ae=n[L]??"";P.current=null,O({value:ae,cursor:ae.length},!1);return}if(x.downArrow){if(ye){pe(D=>(D+1)%se.length);return}let C=E.current;if(C.value.includes(`
94
+ `)){let D=Qn(C.value,C.cursor,"down",P.current??void 0);if(D.changed){P.current=D.preferredColumn,O({value:C.value,cursor:D.cursor},!1);return}}if(ue===null)return;let L=ue+1;if(L>=n.length){Me(null),P.current=null,O({value:te,cursor:te.length},!1),M("");return}Me(L);let ae=n[L]??"";P.current=null,O({value:ae,cursor:ae.length},!1);return}if(x.leftArrow){let C=E.current,L=Cs(C.value,C.cursor);P.current=null,O({value:C.value,cursor:L},!1);return}if(x.rightArrow){let C=E.current,L=bs(C.value,C.cursor);P.current=null,O({value:C.value,cursor:L},!1);return}if(x.tab&&ye){We(se[we]);return}if(x.return){if(ye){We(se[we]);return}G.current.hasPendingFirstChar()&&!G.current.isBuffering()&&Ce(!1);let C=E.current.value.trimStart().startsWith("/");if(!x.shift&&!C){if(G.current.appendNewlineIfActive(U))return;if(G.current.newlineShouldInsertInsteadOfSubmit(U)){Ce(!1),ie(`
95
+ `,!0),G.current.extendWindow(U);return}}if(Ce(!0),x.shift){ie(`
96
+ `,!0);return}let ae=E.current.value.trim();if(!ae)return;if(ae.startsWith("/")){let D=cs(ae,yn);D.kind==="message"?V(D.title,D.content):D.kind==="new"?k():D.kind==="exit"?h():D.kind==="switch_model"?W(D.provider):D.kind==="set_context_limit"?ee(D.limit):D.kind==="set_tool_permission"?q(D.mode):D.kind==="init_agents_md"&&p(rp),P.current=null,O({value:"",cursor:0},!0),z(!1);return}p(ae),P.current=null,O({value:"",cursor:0},!0),z(!1);return}if(Ie!=="none"){let C=E.current,L=Ie==="backspace"?_s(C.value,C.cursor):Zn(C.value,C.cursor);P.current=null,O(L,!0);return}if(T&&rt){let C=Array.from(T);if(C.length!==1){Ce(!1),ie(T,!0),G.current.clearAfterExplicitPaste();return}let L=C[0]??"";if(!L)return;let ae=je=>{let ot=E.current,Ft=ot.value.slice(0,ot.cursor),_n=ot.value.slice(ot.cursor),yt=G.current.decideBeginBuffer(U,Ft,je);return yt?(P.current=null,O({value:`${Ft.slice(0,yt.start)}${_n}`,cursor:yt.start},!0),G.current.appendCharToBuffer(L,U),!0):!1};if(!((L.codePointAt(0)??0)<=127)){let je=G.current.onPlainCharNoHold(U);if(je?.type==="buffer_append"){G.current.appendCharToBuffer(L,U);return}if(je?.type==="begin_buffer"&&ae(je.retroChars))return;Ce(!1),ie(L,!0);return}let Re=G.current.onPlainChar(L,U);if(Re.type==="retain_first_char")return;if(Re.type==="buffer_append"||Re.type==="begin_buffer_from_pending"){G.current.appendCharToBuffer(L,U);return}if(Re.type==="begin_buffer"&&ae(Re.retroChars))return;Ce(!1),ie(L,!0);return}T&&(ie(T,!0),G.current.clearWindowAfterNonChar())});let Ut=he?.columns??process.stdout?.columns??80,X=Math.max(1,Ut-3),b=Ms(A.value,A.cursor,X),Ht=b.lines;return Is(er,{flexDirection:"column",gap:1,children:[ft(er,{flexDirection:"column",paddingY:1,children:Ht.map((T,x)=>{let U=T.text,Z=!e&&x===b.row,ye=Z?U.slice(0,b.cursorInRow):U,Ie=Z?U.slice(b.cursorInRow):"";return Is(er,{children:[ft(pn,{color:"gray",children:x===0?"\u203A ":" "}),ft(pn,{children:ye}),Z?ft(pn,{color:"cyan",children:"\u258A"}):null,Z?ft(pn,{children:Ie}):null]},`line-${x}`)})}),R!=="none"?ft(fs,{items:se.map(({value:T,meta:x,...U})=>U),activeIndex:we,loading:ke}):null]})}import{Box as Tp,Text as Os}from"ink";import{jsx as _p,jsxs as Ls}from"react/jsx-runtime";function Ns({busy:e,pendingApproval:t=!1,contextPercent:n,tokenLine:r}){let o=`${n.toFixed(1)}%`;return Ls(Tp,{justifyContent:"space-between",children:[_p(Os,{color:"gray",children:t?"Approval pending \u2022 \u2191/\u2193 select \u2022 Enter confirm \u2022 Esc deny":e?"Working... Esc Esc to interrupt":"Enter send \u2022 Shift+Enter newline \u2022 /help"}),Ls(Os,{color:"gray",children:[r?`${r} \u2022 `:"","context: ",o]})]})}import{useState as Sp}from"react";import{Box as $s,Text as mn,useInput as vp}from"ink";import{jsx as or,jsxs as sr}from"react/jsx-runtime";var xp=[{label:"Allow once",decision:"once"},{label:"Allow for this session",decision:"session"},{label:"Deny",decision:"deny"}];function Cp(e){if(!e)return"";if(typeof e!="object")return String(e);let t=Object.entries(e);if(!t.length)return"";let[n,r]=t[0]??[];if(!n)return"";let o=typeof r=="string"?r:JSON.stringify(r);return`${n}=${o?.slice(0,60)??""}${o&&o.length>60?"...":""}`}function Ds({request:e,onDecision:t}){let[n,r]=Sp(0),o=xp;vp((i,a)=>{if(a.upArrow){r(l=>l<=0?o.length-1:l-1);return}if(a.downArrow){r(l=>(l+1)%o.length);return}if(a.return){let l=o[n];l&&t(l.decision);return}(a.escape||a.ctrl&&i==="c")&&t("deny")});let s=Cp(e.params);return sr($s,{flexDirection:"column",borderStyle:"single",borderColor:"yellow",paddingX:1,children:[or(mn,{bold:!0,color:"yellow",children:"Tool Approval Required"}),sr(mn,{children:[e.toolName,s?` (${s})`:""]}),or(mn,{color:"gray",children:e.reason}),or($s,{marginTop:1,flexDirection:"column",children:o.map((i,a)=>sr(mn,{color:n===a?"green":"gray",children:[n===a?"> ":" ",i.label]},i.decision))})]})}import{useMemo as Us,useState as ir}from"react";import{Box as ar,Text as gt,useInput as bp}from"ink";import{jsx as dn,jsxs as Rt}from"react/jsx-runtime";function Ap(e,t){let n=new Set(e);return t.filter(r=>n.has(r))}function Hs({serverNames:e,defaultSelected:t,onConfirm:n,onExit:r}){let o=Us(()=>{let p=Ap(e,t);return t.length===0?[]:p.length>0?p:[...e]},[t,e]),[s,i]=ir(o),[a,l]=ir(0),[c,u]=ir(!0),d=Us(()=>new Set(s),[s]),y=s.length===e.length;return bp((p,h)=>{if(h.ctrl&&p==="c"){r();return}if(h.upArrow){l(m=>m<=0?e.length-1:m-1);return}if(h.downArrow){l(m=>(m+1)%e.length);return}if(h.return){n(s,c);return}if(p===" "){let m=e[a];if(!m)return;i(k=>{let v=new Set(k);return v.has(m)?v.delete(m):v.add(m),e.filter(S=>v.has(S))});return}if(p.toLowerCase()==="a"){i([...e]);return}if(p.toLowerCase()==="n"){i([]);return}if(p.toLowerCase()==="p"){u(m=>!m);return}h.escape&&n(s,c)}),Rt(ar,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[dn(gt,{bold:!0,color:"cyan",children:"Activate MCP Servers"}),dn(gt,{color:"gray",children:"Select servers to load for this run."}),dn(ar,{marginTop:1,flexDirection:"column",children:e.map((p,h)=>{let m=d.has(p);return Rt(gt,{color:h===a?"green":"gray",children:[h===a?"> ":" ","[",m?"x":" ","] ",p]},p)})}),Rt(ar,{marginTop:1,flexDirection:"column",children:[Rt(gt,{color:"gray",children:["Selected: ",s.length,"/",e.length,y?" (all)":""]}),Rt(gt,{color:"gray",children:["Persist as default: ",c?"yes":"no"]}),dn(gt,{color:"gray",children:"Controls: \u2191/\u2193 move, Space toggle, A all, N none, P persist, Enter confirm"})]})]})}import{spawn as Ep}from"child_process";var lr="\x07",Mp="Memo: Approval required",wp="Memo CLI",kp=2e3;function Pp(e){return e.replace(/\s+/g," ").trim()}function Ip(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function Rp(e){let t=Pp(e.reason),n=`Tool ${e.toolName} is waiting for your approval.`;return t?Ip(`${n} ${t}`,220):n}function Fs(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Op(e,t=process.platform){let n=Mp,r=Rp(e);return t==="darwin"?{command:"osascript",args:["-e",`display notification "${Fs(r)}" with title "${Fs(n)}"`]}:t==="linux"?{command:"notify-send",args:["--app-name",wp,n,r]}:null}async function Lp(e,t){await new Promise((n,r)=>{let o=Ep(e,t,{stdio:"ignore"}),s=!1,i=l=>{if(!s){if(s=!0,l){r(l);return}n()}},a=setTimeout(()=>{try{o.kill()}catch{}i()},kp);o.once("error",l=>{clearTimeout(a),i(l)}),o.once("exit",l=>{if(clearTimeout(a),l===0||l===null){i();return}i(new Error(`${e} exited with code ${l}`))})})}function Np(e){if(e){e(lr);return}try{if(process.stdout?.isTTY){process.stdout.write(lr);return}process.stderr?.isTTY&&process.stderr.write(lr)}catch{}}async function Bs(e,t={}){Np(t.writeBell);let n=Op(e,t.platform??process.platform);if(!n)return;let r=t.runCommand??Lp;try{await r(n.command,n.args)}catch{}}import{Box as Ot,Text as Ee,useInput as $p}from"ink";import{useCallback as Ws,useMemo as Dp,useState as Lt}from"react";import{jsx as Oe,jsxs as ht}from"react/jsx-runtime";var Ke=[{key:"name",label:"Provider name",hint:"Used for /models switching",defaultValue:"deepseek"},{key:"envKey",label:"API key env var",hint:"Read at runtime from environment variables",defaultValue:"DEEPSEEK_API_KEY"},{key:"model",label:"Model name",defaultValue:"deepseek-chat"},{key:"baseUrl",label:"Base URL",defaultValue:"https://api.deepseek.com"}];function js({configPath:e,onComplete:t,onExit:n}){let[r,o]=Lt(0),[s,i]=Lt(""),[a,l]=Lt({}),[c,u]=Lt(!1),[d,y]=Lt(null),p=Ke[r]??Ke[0],h=Ws(async v=>{u(!0),y(null);try{let S={current_provider:v.name,providers:[{name:v.name,env_api_key:v.envKey,model:v.model,base_url:v.baseUrl||void 0}]};await Se(e,S),t()}catch(S){y(S.message),u(!1)}},[e,t]),m=Ws(async()=>{if(!p)return;let v=s.trim()||p.defaultValue,S={...a,[p.key]:v};if(l(S),i(""),r<Ke.length-1){o(r+1);return}let W={name:S.name||Ke[0].defaultValue,envKey:S.envKey||Ke[1].defaultValue,model:S.model||Ke[2].defaultValue,baseUrl:S.baseUrl||Ke[3].defaultValue};await h(W)},[s,h,p,r,a]);$p((v,S)=>{if(!c){if(S.ctrl&&v==="c"){n();return}if(S.return){m();return}if(S.backspace||S.delete){i(W=>W.slice(0,-1));return}v&&i(W=>W+v)}});let k=Dp(()=>`Step ${r+1}/${Ke.length}`,[r]);return p?ht(Ot,{flexDirection:"column",children:[Oe(Ee,{bold:!0,children:"Memo setup"}),Oe(Ee,{color:"gray",children:"No provider config found. Complete setup to continue."}),ht(Ee,{color:"gray",children:["Config path: ",e]}),ht(Ot,{marginTop:1,flexDirection:"column",children:[Oe(Ee,{color:"cyan",children:k}),Oe(Ee,{children:p.label}),ht(Ee,{color:"gray",children:["Default: ",p.defaultValue]}),p.hint?Oe(Ee,{color:"gray",children:p.hint}):null]}),ht(Ot,{marginTop:1,children:[Oe(Ee,{children:"> "}),Oe(Ee,{children:s})]}),Oe(Ot,{marginTop:1,children:Oe(Ee,{color:"gray",children:"Enter to continue, Ctrl+C to exit."})}),d?Oe(Ot,{marginTop:1,children:ht(Ee,{color:"red",children:["Failed to save config: ",d]})}):null]}):null}function zs(e){let t=[],n=[],r=[],o=e.split(`
97
+ `).map(l=>l.trim()).filter(Boolean),s=null,i=0,a=0;for(let l of o){let c;try{c=JSON.parse(l)}catch{continue}if(!(!c||typeof c!="object")){if(c.type==="turn_start"){let u=typeof c.content=="string"?c.content:"";s={index:-(i+1),userInput:u,steps:[],status:"ok",sequence:a+=1},n.push(s),u&&(t.push({role:"user",content:u}),r.push(`User: ${u}`)),i+=1;continue}if(c.type==="assistant"){let u=typeof c.content=="string"?c.content:"";if(u&&(t.push({role:"assistant",content:u}),r.push(`Assistant: ${u}`),s)){let d={index:s.steps.length,assistantText:u};s.steps=[...s.steps,d],s.finalText=u}continue}if(c.type==="action"&&s){let u=c.meta;if(u&&typeof u=="object"){let d=typeof u.tool=="string"?u.tool:"",y=u.input,p=typeof u.thinking=="string"?u.thinking:"",m=(Array.isArray(u.toolBlocks)?u.toolBlocks:[]).map(v=>{let S=typeof v?.name=="string"?v.name:"";return S?{tool:S,input:v?.input}:null}).filter(Boolean),k=s.steps[s.steps.length-1];k&&(m.length>1?(k.action=m[0],k.parallelActions=m):d&&(k.action={tool:d,input:y}),p&&(k.thinking=p))}continue}if(c.type==="observation"&&s){let u=typeof c.content=="string"?c.content:"",d=s.steps[s.steps.length-1];d&&(d.observation=u);continue}}}return{summary:r.join(`
98
+ `),messages:t,turns:n,maxSequence:a}}function ur(){return{turns:[],historicalTurns:[],systemMessages:[],sequence:0}}function Up(e,t){return{index:e,userInput:"",steps:[],sequence:t}}function cr(e,t){let n=e.slice();for(;n.length<=t;)n.push({index:n.length,assistantText:""});return n}function Nt(e,t,n){let r=e.turns.slice(),o=r.findIndex(i=>i.index===t);if(o===-1){let i=e.sequence+1;return r.push(n(Up(t,i))),{turns:r,sequence:i}}let s=r[o];return s?(r[o]=n(s),{turns:r,sequence:e.sequence}):{turns:r,sequence:e.sequence}}function Hp(e){return{id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,title:e.title,content:e.content,tone:e.tone??"info",sequence:e.sequence}}function qs(e,t){switch(t.type){case"append_system_message":{let n=e.sequence+1;return{...e,sequence:n,systemMessages:[...e.systemMessages,Hp({title:t.title,content:t.content,tone:t.tone,sequence:n})]}}case"turn_start":{let n=Nt(e,t.turn,r=>({...r,index:t.turn,userInput:t.input,steps:[],finalText:void 0,status:void 0,errorMessage:void 0,tokenUsage:void 0,startedAt:Date.now(),durationMs:void 0,contextPromptTokens:t.promptTokens??r.contextPromptTokens}));return{...e,turns:n.turns,sequence:n.sequence}}case"assistant_chunk":{let n=Nt(e,t.turn,r=>{let o=cr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,assistantText:`${s.assistantText}${t.chunk}`},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_action":{let n=Nt(e,t.turn,r=>{let o=cr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,action:t.action,thinking:t.thinking,parallelActions:t.parallelActions&&t.parallelActions.length>1?t.parallelActions:void 0,toolStatus:Fe.EXECUTING},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_observation":{let n=Nt(e,t.turn,r=>{let o=cr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,observation:t.observation,toolStatus:t.toolStatus,parallelToolStatuses:t.parallelToolStatuses},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"turn_final":{let n=Nt(e,t.turn,r=>{let o=r.startedAt??Date.now(),s=Math.max(0,Date.now()-o),i=t.tokenUsage?.prompt??r.contextPromptTokens;return{...r,finalText:t.finalText,status:t.status,errorMessage:t.errorMessage,tokenUsage:t.turnUsage,contextPromptTokens:i,startedAt:o,durationMs:s}});return{...e,turns:n.turns,sequence:n.sequence}}case"replace_history":return{...e,historicalTurns:t.turns,sequence:Math.max(e.sequence,t.maxSequence)};case"clear_current_timeline":return{...e,turns:[],systemMessages:[]};case"reset_all":return ur();default:return e}}import{dirname as fn,join as Ks,resolve as Fp}from"path";import{statSync as Bp,existsSync as Vs,readFileSync as Wp}from"fs";import{readFile as jp}from"fs/promises";import{get as zp}from"https";import{fileURLToPath as qp}from"url";function Gs(e){let t=e.trim().replace(/^v/i,""),[n="",r]=t.split("-",2),o=n.split(".").map(s=>Number(s));return o.length<3||o.some(s=>!Number.isFinite(s))?null:{major:o[0]??0,minor:o[1]??0,patch:o[2]??0,prerelease:r??null}}function Gp(e,t){let n=Gs(e),r=Gs(t);return!n||!r?!1:n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch!==r.patch?n.patch>r.patch:n.prerelease&&!r.prerelease?!1:!n.prerelease&&r.prerelease?!0:n.prerelease&&r.prerelease?n.prerelease>r.prerelease:!1}function Xs(){try{let t=qp(import.meta.url);return fn(t)}catch{}let e=Fp(process.argv[1]??process.cwd());try{return Bp(e).isFile()?fn(e):e}catch{return process.cwd()}}async function Kp(e){let t=Ks(e,"package.json");if(!Vs(t))return null;let n=await jp(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}function Vp(e){let t=Ks(e,"package.json");if(!Vs(t))return null;try{let n=Wp(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}catch{return null}}async function Xp(){let e=Xs();for(;;){let t=await Kp(e);if(t&&t.name==="@memo-code/memo")return t;let n=fn(e);if(n===e)break;e=n}return null}function gn(){let e=Xs();for(;;){let t=Vp(e);if(t&&t.name==="@memo-code/memo")return t;let n=fn(e);if(n===e)break;e=n}return null}async function Jp(e,t=1500){let r=`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`;return new Promise(o=>{let s=zp(r,{timeout:t},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),o(null);return}let a=[];i.on("data",l=>a.push(l)),i.on("end",()=>{try{let l=JSON.parse(Buffer.concat(a).toString("utf8"));o(l.version??null)}catch{o(null)}})});s.on("timeout",()=>{s.destroy(),o(null)}),s.on("error",()=>o(null))})}async function Js(){let e=await Xp();if(!e)return null;let t=await Jp(e.name);return!t||!Gp(t,e.version)?null:{current:e.version,latest:t}}import{jsx as Ve,jsxs as om}from"react/jsx-runtime";function tm(e,t){if(e.length===0)return[];if(t===void 0)return[...e];if(t.length===0)return[];let n=new Set(e),r=t.filter(o=>n.has(o));return r.length>0?r:[...e]}function nm(e,t){if(e.length===0)return[];if(t.length===0)return[];let n=new Set(e);return t.filter(r=>n.has(r))}function rm(){try{process.stdout?.isTTY&&process.stdout.write("\x1Bc")}catch{}}function Zs({sessionOptions:e,providerName:t,model:n,configPath:r,mcpServers:o,cwd:s,sessionsDir:i,providers:a,dangerous:l=!1,needsSetup:c=!1}){let{exit:u}=em(),d=Dt(()=>Object.keys(o??{}).sort(),[o]),y=Dt(()=>tm(d,e.activeMcpServers),[d,e.activeMcpServers]),p=e.toolPermissionMode??(l?H.FULL:H.ONCE),[h,m]=Zp(qs,void 0,ur),[k,v]=re(t),[S,W]=re(n),[ee,q]=re(a),[V,he]=re(p),[A,F]=re({...e,providerName:t,dangerous:p===H.FULL,toolPermissionMode:p}),[E,P]=re(!1),[ue,Me]=re([]),[te,M]=re(null),[R,ne]=re(null),[se,Be]=re(e.maxPromptTokens??is),[we,pe]=re(0),[ke,Xe]=re(c),[Le,w]=re(!c&&d.length>0),[Y,nt]=re(y),[G,yn]=re(null),[j,z]=re(null),O=hn(null),Pe=hn(null),ie=hn(null),[K,Ce]=re(null),We=hn(null),Ut=Dt(()=>gn(),[]),X=J(g=>{m(g)},[]);$t(()=>{ke||(nt(y),w(d.length>0))},[ke,y,d.length]);let b=J((g,_,I="info")=>{X({type:"append_system_message",title:g,content:_,tone:I})},[X]),Ht=Dt(()=>({onAssistantStep:(g,_)=>{let I=Pe.current;I&&X({type:"assistant_chunk",turn:I,step:_,chunk:g})},requestApproval:V===H.FULL||V===H.NONE?void 0:g=>new Promise(_=>{Bs(g),Ce(g),We.current=_}),hooks:{onTurnStart:({turn:g,input:_,promptTokens:I})=>{Pe.current=g;let Te=ie.current;Te&&(ie.current=null);let Je=Te??_;I&&I>0&&pe(I),X({type:"turn_start",turn:g,input:Je,promptTokens:I})},onAction:({turn:g,step:_,action:I,thinking:Te,parallelActions:Je})=>{X({type:"tool_action",turn:g,step:_,action:I,thinking:Te,parallelActions:Je})},onObservation:({turn:g,step:_,observation:I,resultStatus:Te,parallelResultStatuses:Je})=>{X({type:"tool_observation",turn:g,step:_,observation:I,toolStatus:Vn(Te),parallelToolStatuses:qo(Je)})},onFinal:({turn:g,finalText:_,status:I,errorMessage:Te,turnUsage:Je,tokenUsage:si})=>{X({type:"turn_final",turn:g,finalText:_,status:I,errorMessage:Te,turnUsage:Je,tokenUsage:si}),P(!1)}}}),[X,V]);$t(()=>{let g=!1;return(async()=>{if(!(ke||Le))try{let _=O.current;_&&await _.close();let I=await Zt(Ht,A);if(g){await I.close();return}O.current=I,z(I),M(I.historyFilePath??null)}catch(_){if(g)return;O.current=null,z(null),M(null),P(!1),b("Session",`Failed to create session: ${_.message}`,"error")}})(),()=>{g=!0}},[b,Ht,Le,A,ke]),$t(()=>{let g=!1;return(async()=>{let _=await Js();g||!_||b("Update",`Update available: v${_.latest}. Run: npm install -g @memo-code/memo@latest`)})(),()=>{g=!0}},[b]),$t(()=>()=>{O.current&&O.current.close()},[]);let T=J(async()=>{let g=We.current;g&&(g("deny"),We.current=null),K&&Ce(null),O.current&&await O.current.close(),yn("Bye!"),setTimeout(()=>u(),250)},[u,K]),x=J(()=>{if(E){b("Clear","Cancel current run before clearing timeline.","warning");return}if(K){b("Clear","Resolve current approval request before clearing timeline.","warning");return}X({type:"clear_current_timeline"}),ne(null),pe(0),rm()},[b,E,X,K]),U=J(()=>{if(E){b("New Session","Cancel current run before starting a new session.","warning");return}if(K){b("New Session","Resolve current approval request before starting a new session.","warning");return}X({type:"reset_all"}),ne(null),pe(0),Pe.current=null,F(g=>({...g,sessionId:tt()})),b("New Session","Started a fresh session.")},[b,E,X,K]),Z=J(async g=>{try{let _=await ce();await Se(_.configPath,{..._.config,current_provider:g})}catch(_){b("Config",`Failed to persist provider: ${_.message}`,"warning")}},[b]),ye=J(async g=>{if(E){b("Model switch","Cancel current run before switching models.","warning");return}if(g.name===k&&g.model===S){b("Model switch",`Already using ${g.name} (${g.model}).`);return}X({type:"reset_all"}),pe(0),Pe.current=null,v(g.name),W(g.model),F(_=>({..._,sessionId:tt(),providerName:g.name})),await Z(g.name),b("Model switch",`Switched to ${g.name} (${g.model}).`)},[b,E,S,k,X,Z]),Ie=J(async g=>{try{let _=await ce();await Se(_.configPath,{..._.config,max_prompt_tokens:g})}catch(_){b("Context",`Failed to persist context limit: ${_.message}`,"warning")}},[b]),Tn=J(g=>{if(E){b("Context","Cancel current run before changing context window.","warning");return}if(K){b("Context","Resolve current approval request before changing context window.","warning");return}Be(g),pe(0),F(_=>({..._,maxPromptTokens:g,sessionId:tt()})),b("Context",`Context window set to ${Math.floor(g/1e3)}k.`),Ie(g)},[b,E,K,Ie]),rt=J(g=>g===H.NONE?"none (no tools)":g===H.ONCE?"once (approval required)":"full (no approval)",[]),C=J(g=>{if(E){b("Tools","Cancel current run before changing tool permission mode.","warning");return}if(K){b("Tools","Resolve current approval request before changing tool permission mode.","warning");return}if(g===V){b("Tools",`Already using ${rt(g)}.`);return}he(g),F(_=>({..._,sessionId:tt(),dangerous:g===H.FULL,toolPermissionMode:g})),b("Tools",`Tool permission set to ${rt(g)}.`)},[b,E,K,rt,V]),L=J(async g=>{try{let _=await ce();await Se(_.configPath,{..._.config,active_mcp_servers:g})}catch(_){b("MCP",`Failed to persist active MCP servers: ${_.message}`,"warning")}},[b]),ae=J((g,_)=>{let I=nm(d,g);nt(I),w(!1),F(Te=>({...Te,sessionId:tt(),activeMcpServers:I})),_&&L(I)},[d,L]),D=J(async g=>{if(E){b("History","Cancel current run before loading session history.","warning");return}if(K){b("History","Resolve current approval request before loading session history.","warning");return}try{let _=await Yp(g.sessionFile,"utf8"),I=zs(_);X({type:"clear_current_timeline"}),X({type:"replace_history",turns:I.turns,maxSequence:I.maxSequence}),ne(I.messages),P(!1),z(null),M(null),pe(0),Pe.current=null,F(Te=>({...Te,sessionId:tt()})),b("History",I.summary||g.input)}catch(_){b("History",`Failed to load ${g.sessionFile}: ${_.message}`,"error")}},[b,E,X,K]),Re=J(()=>{E&&j?.cancelCurrentTurn?.()},[E,j]),je=J(async()=>{if(!j||E)return;let g=`Please analyze the current project and create an AGENTS.md file at the project root.
68
99
 
69
100
  The AGENTS.md should include:
70
101
  1. Project name and brief description
@@ -80,7 +111,7 @@ Steps:
80
111
  3. Understand stack and conventions
81
112
  4. Create AGENTS.md using apply_patch
82
113
 
83
- Keep the result concise and actionable.`,T=ce($.INIT);ie(L=>[...L,T]),y(!0);try{j.current=T,await W.runTurn(g)}catch{y(!1)}},[M,W]),Ar=Z(async g=>{let T=g.trim();if(T){if(T.toLowerCase()===zo){await x();return}if(T===ce($.INIT)){await pn();return}if(!(!W||M)){ie(L=>[...L,T]),y(!0);try{await W.runTurn(T)}catch{y(!1)}}}},[M,x,pn,W]),wr=Z(async()=>{try{let g=await Q(),T=be(g.config);_(g.config.providers),w(T.name),I(T.model),N(L=>({...L,sessionId:nt(),providerName:T.name})),Re(!1),C("Setup",`Config saved to ${g.configPath}`)}catch(g){C("Setup",`Failed to reload config: ${g.message}`,"error")}},[C]);kt(()=>{if(!W||!q?.length)return;let g=W.history[0];g&&(W.history.splice(0,W.history.length,g,...q),B(null))},[q,W]);let br=Z(g=>{let T=Se.current;T&&(T(g),Se.current=null),Fe(null)},[]),kr=Do(m.turns[m.turns.length-1]?.tokenUsage),Mr=No(V,b);return de?Pe(gr,{children:Pe(ac,{color:"green",children:de})}):K?Pe(ir,{configPath:o,onComplete:wr,onExit:x}):cc(gr,{flexDirection:"column",children:[Pe(Bo,{header:{providerName:h,model:f,cwd:r,sessionId:U.sessionId??"unknown",mcpNames:Object.keys(s??{}).sort(),version:P?.version??"unknown"},systemMessages:m.systemMessages,turns:m.turns,historicalTurns:m.historicalTurns}),Pe(Qo,{disabled:!W||!!z,busy:M,history:E,cwd:r,sessionsDir:i,currentSessionFile:D??void 0,providers:S,configPath:o,providerName:h,model:f,contextLimit:b,mcpServers:s,onSubmit:g=>{Ar(g)},onExit:()=>{x()},onClear:F,onNewSession:fe,onCancelRun:Er,onHistorySelect:g=>{Cr(g)},onModelSelect:g=>{vr(g)},onSetContextLimit:xr,onSystemMessage:C}),z?Pe(rr,{request:z,onDecision:br}):null,Pe(nr,{busy:M,contextPercent:Mr,tokenLine:kr})]})}var uc=`
114
+ Keep the result concise and actionable.`,_=ge($.INIT);Me(I=>[...I,_]),P(!0);try{ie.current=_,await j.runTurn(g)}catch(I){P(!1),b("Init",`Failed to run init task: ${I.message}`,"error")}},[b,E,j]),ot=J(async g=>{let _=g.trim();if(_){if(_.toLowerCase()===as){await T();return}if(_===ge($.INIT)){await je();return}if(!(!j||E)){Me(I=>[...I,_]),P(!0);try{await j.runTurn(_)}catch(I){P(!1),b("Run",`Turn failed: ${I.message}`,"error")}}}},[b,E,T,je,j]),Ft=J(async()=>{try{let g=await ce(),_=Ye(g.config);q(g.config.providers),v(_.name),W(_.model),F(I=>({...I,sessionId:tt(),providerName:_.name})),Xe(!1),b("Setup",`Config saved to ${g.configPath}`)}catch(g){b("Setup",`Failed to reload config: ${g.message}`,"error")}},[b]);$t(()=>{if(!j||!R?.length)return;let g=j.history[0];g&&(j.history.splice(0,j.history.length,g,...R),ne(null))},[R,j]);let _n=J(g=>{let _=We.current;_&&(_(g),We.current=null),Ce(null)},[]),yt=Ko(h.turns[h.turns.length-1]?.tokenUsage),ri=Go(we,se),oi=Dt(()=>({providerName:k,model:S,cwd:s,sessionId:A.sessionId??"unknown",mcpNames:Y,version:Ut?.version??"unknown"}),[Y,S,k,s,Ut?.version,A.sessionId]);return G?Ve(Ys,{children:Ve(Qp,{color:"green",children:G})}):ke?Ve(js,{configPath:r,onComplete:Ft,onExit:T}):Le?Ve(Hs,{serverNames:d,defaultSelected:y,onConfirm:ae,onExit:()=>{T()}}):om(Ys,{flexDirection:"column",children:[Ve(ss,{header:oi,systemMessages:h.systemMessages,turns:h.turns,historicalTurns:h.historicalTurns}),Ve(Rs,{disabled:!j||!!K,busy:E,history:ue,cwd:s,sessionsDir:i,currentSessionFile:te??void 0,providers:ee,configPath:r,providerName:k,model:S,contextLimit:se,toolPermissionMode:V,mcpServers:o,onSubmit:g=>{ot(g)},onExit:()=>{T()},onClear:x,onNewSession:U,onCancelRun:Re,onHistorySelect:g=>{D(g)},onModelSelect:g=>{ye(g)},onSetContextLimit:Tn,onSetToolPermission:C,onSystemMessage:b}),K?Ve(Ds,{request:K,onDecision:_n}):null,Ve(Ns,{busy:E,pendingApproval:!!K,contextPercent:ri,tokenLine:yt})]})}var sm=`
84
115
  Usage:
85
116
  memo mcp list [--json]
86
117
  memo mcp get <name> [--json]
@@ -89,14 +120,14 @@ Usage:
89
120
  memo mcp remove <name>
90
121
  memo mcp login <name> [--scopes scope1,scope2]
91
122
  memo mcp logout <name>
92
- `;function ln(){console.log(uc.trim())}function pc(t){let e=t.indexOf("=");if(e<=0)return null;let n=t.slice(0,e).trim(),o=t.slice(e+1);return n?{key:n,value:o}:null}function yr(t,e){let n=[];if(n.push(`${t}`),"url"in e){n.push(` type: ${e.type??"streamable_http"}`),n.push(` url: ${e.url}`),e.bearer_token_env_var&&n.push(` bearer_token_env_var: ${e.bearer_token_env_var}`);let o=e.http_headers??e.headers;o&&Object.keys(o).length>0&&n.push(` headers: ${Object.entries(o).map(([s,r])=>`${s}=${r}`).join(", ")}`)}else n.push(` type: ${e.type??"stdio"}`),n.push(` command: ${e.command}`),e.args&&e.args.length>0&&n.push(` args: ${e.args.join(" ")}`),e.env&&Object.keys(e.env).length>0&&n.push(` env: ${Object.entries(e.env).map(([o,s])=>`${o}=${s}`).join(", ")}`);return n.join(`
93
- `)}function mc(t){let e=t.shift();if(!e)return{error:"Missing server name."};let n,o,s={},r=[];for(let i=0;i<t.length;i+=1){let l=t[i];if(l){if(l==="--"){r=t.slice(i+1);break}if(l==="--url"){let a=t[i+1];if(!a)return{error:"Missing value for --url."};n=a,i+=1;continue}if(l==="--bearer-token-env-var"){let a=t[i+1];if(!a)return{error:"Missing value for --bearer-token-env-var."};o=a,i+=1;continue}if(l==="--env"){let a=t[i+1];if(!a)return{error:"Missing value for --env (KEY=VALUE)."};let c=pc(a);if(!c)return{error:"Invalid --env format. Use KEY=VALUE."};s[c.key]=c.value,i+=1;continue}return l==="--help"||l==="-h"?{error:""}:{error:`Unknown option: ${l}`}}}return n?r.length>0?{error:"Use either --url or a stdio command, not both."}:Object.keys(s).length>0?{error:"--env is only supported with stdio servers."}:{options:{name:e,url:n,bearerTokenEnvVar:o}}:o?{error:"--bearer-token-env-var is only supported with HTTP servers."}:r.length===0?{error:"Missing stdio command. Use `-- <command...>`."}:{options:{name:e,command:r[0],args:r.slice(1),env:Object.keys(s).length>0?s:void 0}}}function dc(t){let[e,...n]=t;return!e||e==="--help"||e==="-h"||e==="help"?{command:"help",rest:[]}:{command:e,rest:n}}function cn(t,e=[]){let n=new Set(e);for(let o=0;o<t.length;o+=1){let s=t[o];if(s){if(s.startsWith("--")){n.has(s)&&(o+=1);continue}return s}}return null}async function Tr(t){let{command:e,rest:n}=dc(t);if(e==="help"){ln();return}if(e==="list"){let o=n.includes("--json"),r=(await Q()).config.mcp_servers??{};if(o){console.log(JSON.stringify(r,null,2));return}let i=Object.keys(r);if(i.length===0){console.log('No MCP servers configured. Add one with "memo mcp add".');return}console.log(`MCP servers (${i.length}):`);for(let l of i){let a=r[l];a&&console.log(yr(l,a))}return}if(e==="get"){let o=n.includes("--json"),s=cn(n);if(!s){console.error("Missing server name."),process.exitCode=1;return}let i=(await Q()).config.mcp_servers?.[s];if(!i){console.error(`Unknown MCP server "${s}".`),process.exitCode=1;return}if(o){console.log(JSON.stringify(i,null,2));return}console.log(yr(s,i));return}if(e==="add"){let o=mc(n);if(o.error!==void 0){o.error&&(console.error(o.error),process.exitCode=1),ln();return}let s=o.options;if(!s)return;if(s.url)try{new URL(s.url)}catch{console.error("Invalid URL."),process.exitCode=1;return}let r=await Q(),i={...r.config.mcp_servers??{}};if(i[s.name]){console.error(`MCP server "${s.name}" already exists.`),process.exitCode=1;return}let l;s.url?l={type:"streamable_http",url:s.url,...s.bearerTokenEnvVar?{bearer_token_env_var:s.bearerTokenEnvVar}:{}}:l={command:s.command,args:s.args&&s.args.length>0?s.args:void 0,env:s.env},i[s.name]=l,await le(r.configPath,{...r.config,mcp_servers:i}),console.log(`Added MCP server "${s.name}".`);return}if(e==="remove"){let o=cn(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let s=await Q(),r={...s.config.mcp_servers??{}};if(!r[o]){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}delete r[o],await le(s.configPath,{...s.config,mcp_servers:r}),console.log(`Removed MCP server "${o}".`);return}if(e==="login"||e==="logout"){let o=cn(n,["--scopes"]);if(!o){console.error("Missing server name."),process.exitCode=1;return}let r=(await Q()).config.mcp_servers?.[o];if(!r){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}if(!("url"in r)){console.error("OAuth login/logout only applies to streamable HTTP servers."),process.exitCode=1;return}console.error("OAuth login/logout is not supported in memo yet. Configure a bearer token env var instead."),process.exitCode=1;return}console.error(`Unknown subcommand: ${e}`),ln(),process.exitCode=1}import{jsx as Cc}from"react/jsx-runtime";function Tc(t){let e={dangerous:!1,showVersion:!1,removedOnceFlag:!1},n=[];for(let o=0;o<t.length;o++){let s=t[o];if(s!==void 0){if(s==="--version"||s==="-v"){e.showVersion=!0;continue}if(s==="--once"){e.removedOnceFlag=!0;continue}if(s==="--dangerous"||s==="-d"){e.dangerous=!0;continue}n.push(s)}}return{question:n.join(" "),options:e}}async function Sr(t){let e=await Q();if(!e.needsSetup)return e;let n=e.config.providers[0],s=[n?.env_api_key,"OPENAI_API_KEY","DEEPSEEK_API_KEY"].filter(Boolean).some(l=>!!process.env[l]);if(n&&s)return await le(e.configPath,e.config),console.log(`Detected API key in env. Wrote default provider (${n.name}) to ${e.configPath}`),{...e,needsSetup:!1};if(t==="tui")return e;let r=fc({input:gc,output:hc}),i=async(l,a)=>(await r.question(l)).trim()||a;try{console.log("No provider config found. Please answer the prompts:");let l=await i("Provider name [deepseek]: ","deepseek"),a=await i("API key env var [DEEPSEEK_API_KEY]: ","DEEPSEEK_API_KEY"),c=await i("Model name [deepseek-chat]: ","deepseek-chat"),u=await i("Base URL [https://api.deepseek.com]: ","https://api.deepseek.com"),m={current_provider:l,providers:[{name:l,env_api_key:a,model:c,base_url:u||void 0}]};return await le(e.configPath,m),console.log(`Config written to ${e.configPath}
94
- `),{...e,config:m,needsSetup:!1}}finally{r.close()}}async function _c(t){let e=await Sr("plain"),n=be(e.config),s={sessionId:_r(),mode:"interactive",maxPromptTokens:e.config.max_prompt_tokens,dangerous:t.options.dangerous};t.options.dangerous&&console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!");let r={requestApproval:t.options.dangerous?void 0:a=>(console.log(`
95
- [approval required] ${a.toolName}: ${a.reason}`),console.log("[approval] Run with --dangerous to bypass approval"),Promise.resolve("deny")),hooks:{onAction:({action:a})=>{console.log(`
96
- [tool] ${a.tool}`),a.input!==void 0&&console.log(`[input] ${JSON.stringify(a.input)}`)},onObservation:()=>{}}},i=await dt(r,s),l=t.question;if(!l&&!process.stdin.isTTY&&(l=await xc()),!l){console.error("No input provided. Pass a question or use stdin."),await i.close();return}try{console.log(`User: ${l}
97
- `);let a=await i.runTurn(l);console.log(`
98
- ${a.finalText}`),console.log(`
99
- [tokens] prompt=${a.tokenUsage.prompt} completion=${a.tokenUsage.completion} total=${a.tokenUsage.total}`),console.log(`
100
- provider=${n.name} model=${n.model}`)}catch(a){console.error(`Run failed: ${a.message}`)}finally{await i.close()}}async function Sc(t){let e=await Sr("tui"),n=be(e.config),s={sessionId:_r(),mode:"interactive",maxPromptTokens:e.config.max_prompt_tokens,dangerous:t.options.dangerous},r=mt(e,s);t.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
101
- `)),await yc(Cc(hr,{sessionOptions:s,providerName:n.name,model:n.model,configPath:e.configPath,mcpServers:e.config.mcp_servers??{},cwd:process.cwd(),sessionsDir:r,providers:e.config.providers,dangerous:t.options.dangerous,needsSetup:e.needsSetup}),{exitOnCtrlC:!1,patchConsole:!1}).waitUntilExit()}async function vc(){let t=process.argv.slice(2);if(t[0]==="mcp"||t[0]==="--"&&t[1]==="mcp"){let o=t[0]==="--"?2:1;await Tr(t.slice(o));return}let e=Tc(t);if(e.options.removedOnceFlag){console.error("`--once` has been removed. Use `memo` (interactive) or pipe input to `memo`."),process.exitCode=1;return}if(e.options.showVersion){let s=bt()?.version??"unknown";console.log(s);return}if(!(process.stdin.isTTY&&process.stdout.isTTY)){await _c(e);return}await Sc(e)}vc();async function xc(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n}),process.stdin.on("end",()=>{t(e.trim())}),process.stdin.resume()})}
123
+ `;function pr(){console.log(sm.trim())}function im(e){let t=e.indexOf("=");if(t<=0)return null;let n=e.slice(0,t).trim(),r=e.slice(t+1);return n?{key:n,value:r}:null}function Qs(e,t){let n=[];if(n.push(`${e}`),"url"in t){n.push(` type: ${t.type??"streamable_http"}`),n.push(` url: ${t.url}`),t.bearer_token_env_var&&n.push(` bearer_token_env_var: ${t.bearer_token_env_var}`);let r=t.http_headers??t.headers;r&&Object.keys(r).length>0&&n.push(` headers: ${Object.entries(r).map(([o,s])=>`${o}=${s}`).join(", ")}`)}else n.push(` type: ${t.type??"stdio"}`),n.push(` command: ${t.command}`),t.args&&t.args.length>0&&n.push(` args: ${t.args.join(" ")}`),t.env&&Object.keys(t.env).length>0&&n.push(` env: ${Object.entries(t.env).map(([r,o])=>`${r}=${o}`).join(", ")}`);return n.join(`
124
+ `)}function am(e){let t=e.shift();if(!t)return{error:"Missing server name."};let n,r,o={},s=[];for(let i=0;i<e.length;i+=1){let a=e[i];if(a){if(a==="--"){s=e.slice(i+1);break}if(a==="--url"){let l=e[i+1];if(!l)return{error:"Missing value for --url."};n=l,i+=1;continue}if(a==="--bearer-token-env-var"){let l=e[i+1];if(!l)return{error:"Missing value for --bearer-token-env-var."};r=l,i+=1;continue}if(a==="--env"){let l=e[i+1];if(!l)return{error:"Missing value for --env (KEY=VALUE)."};let c=im(l);if(!c)return{error:"Invalid --env format. Use KEY=VALUE."};o[c.key]=c.value,i+=1;continue}return a==="--help"||a==="-h"?{error:""}:{error:`Unknown option: ${a}`}}}return n?s.length>0?{error:"Use either --url or a stdio command, not both."}:Object.keys(o).length>0?{error:"--env is only supported with stdio servers."}:{options:{name:t,url:n,bearerTokenEnvVar:r}}:r?{error:"--bearer-token-env-var is only supported with HTTP servers."}:s.length===0?{error:"Missing stdio command. Use `-- <command...>`."}:{options:{name:t,command:s[0],args:s.slice(1),env:Object.keys(o).length>0?o:void 0}}}function lm(e){let[t,...n]=e;return!t||t==="--help"||t==="-h"||t==="help"?{command:"help",rest:[]}:{command:t,rest:n}}function mr(e,t=[]){let n=new Set(t);for(let r=0;r<e.length;r+=1){let o=e[r];if(o){if(o.startsWith("--")){n.has(o)&&(r+=1);continue}return o}}return null}async function ei(e){let{command:t,rest:n}=lm(e);if(t==="help"){pr();return}if(t==="list"){let r=n.includes("--json"),s=(await ce()).config.mcp_servers??{};if(r){console.log(JSON.stringify(s,null,2));return}let i=Object.keys(s);if(i.length===0){console.log('No MCP servers configured. Add one with "memo mcp add".');return}console.log(`MCP servers (${i.length}):`);for(let a of i){let l=s[a];l&&console.log(Qs(a,l))}return}if(t==="get"){let r=n.includes("--json"),o=mr(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let i=(await ce()).config.mcp_servers?.[o];if(!i){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}if(r){console.log(JSON.stringify(i,null,2));return}console.log(Qs(o,i));return}if(t==="add"){let r=am(n);if(r.error!==void 0){r.error&&(console.error(r.error),process.exitCode=1),pr();return}let o=r.options;if(!o)return;if(o.url)try{new URL(o.url)}catch{console.error("Invalid URL."),process.exitCode=1;return}let s=await ce(),i={...s.config.mcp_servers??{}};if(i[o.name]){console.error(`MCP server "${o.name}" already exists.`),process.exitCode=1;return}let a;o.url?a={type:"streamable_http",url:o.url,...o.bearerTokenEnvVar?{bearer_token_env_var:o.bearerTokenEnvVar}:{}}:a={command:o.command,args:o.args&&o.args.length>0?o.args:void 0,env:o.env},i[o.name]=a,await Se(s.configPath,{...s.config,mcp_servers:i}),console.log(`Added MCP server "${o.name}".`);return}if(t==="remove"){let r=mr(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let o=await ce(),s={...o.config.mcp_servers??{}};if(!s[r]){console.error(`Unknown MCP server "${r}".`),process.exitCode=1;return}delete s[r],await Se(o.configPath,{...o.config,mcp_servers:s}),console.log(`Removed MCP server "${r}".`);return}if(t==="login"||t==="logout"){let r=mr(n,["--scopes"]);if(!r){console.error("Missing server name."),process.exitCode=1;return}let s=(await ce()).config.mcp_servers?.[r];if(!s){console.error(`Unknown MCP server "${r}".`),process.exitCode=1;return}if(!("url"in s)){console.error("OAuth login/logout only applies to streamable HTTP servers."),process.exitCode=1;return}console.error("OAuth login/logout is not supported in memo yet. Configure a bearer token env var instead."),process.exitCode=1;return}console.error(`Unknown subcommand: ${t}`),pr(),process.exitCode=1}import{jsx as Tm}from"react/jsx-runtime";function dm(e){let t={dangerous:!1,showVersion:!1,removedOnceFlag:!1},n=[];for(let r=0;r<e.length;r++){let o=e[r];if(o!==void 0){if(o==="--version"||o==="-v"){t.showVersion=!0;continue}if(o==="--once"){t.removedOnceFlag=!0;continue}if(o==="--dangerous"||o==="-d"){t.dangerous=!0;continue}n.push(o)}}return{question:n.join(" "),options:t}}async function ni(e){let t=await ce();if(!t.needsSetup)return t;let n=t.config.providers[0],o=[n?.env_api_key,"OPENAI_API_KEY","DEEPSEEK_API_KEY"].filter(Boolean).some(a=>!!process.env[a]);if(n&&o)return await Se(t.configPath,t.config),console.log(`Detected API key in env. Wrote default provider (${n.name}) to ${t.configPath}`),{...t,needsSetup:!1};if(e==="tui")return t;let s=cm({input:um,output:pm}),i=async(a,l)=>(await s.question(a)).trim()||l;try{console.log("No provider config found. Please answer the prompts:");let a=await i("Provider name [deepseek]: ","deepseek"),l=await i("API key env var [DEEPSEEK_API_KEY]: ","DEEPSEEK_API_KEY"),c=await i("Model name [deepseek-chat]: ","deepseek-chat"),u=await i("Base URL [https://api.deepseek.com]: ","https://api.deepseek.com"),d={current_provider:a,providers:[{name:a,env_api_key:l,model:c,base_url:u||void 0}]};return await Se(t.configPath,d),console.log(`Config written to ${t.configPath}
125
+ `),{...t,config:d,needsSetup:!1}}finally{s.close()}}async function fm(e){let t=await ni("plain"),n=Ye(t.config),o={sessionId:ti(),mode:"interactive",maxPromptTokens:t.config.max_prompt_tokens,activeMcpServers:t.config.active_mcp_servers,generateSessionTitle:!0,dangerous:e.options.dangerous};e.options.dangerous&&console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!");let s={requestApproval:e.options.dangerous?void 0:l=>(console.log(`
126
+ [approval required] ${l.toolName}: ${l.reason}`),console.log("[approval] Run with --dangerous to bypass approval"),Promise.resolve("deny")),hooks:{onAction:({action:l})=>{console.log(`
127
+ [tool] ${l.tool}`),l.input!==void 0&&console.log(`[input] ${JSON.stringify(l.input)}`)},onObservation:()=>{}}},i=await Zt(s,o),a=e.question;if(!a&&!process.stdin.isTTY&&(a=await ym()),!a){console.error("No input provided. Pass a question or use stdin."),await i.close();return}try{console.log(`User: ${a}
128
+ `);let l=await i.runTurn(a);console.log(`
129
+ ${l.finalText}`),console.log(`
130
+ [tokens] prompt=${l.tokenUsage.prompt} completion=${l.tokenUsage.completion} total=${l.tokenUsage.total}`),console.log(`
131
+ provider=${n.name} model=${n.model}`)}catch(l){console.error(`Run failed: ${l.message}`)}finally{await i.close()}}async function gm(e){let t=await ni("tui"),n=Ye(t.config),o={sessionId:ti(),mode:"interactive",maxPromptTokens:t.config.max_prompt_tokens,activeMcpServers:t.config.active_mcp_servers,generateSessionTitle:!0,dangerous:e.options.dangerous},s=Xt(t,o);e.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
132
+ `)),await mm(Tm(Zs,{sessionOptions:o,providerName:n.name,model:n.model,configPath:t.configPath,mcpServers:t.config.mcp_servers??{},cwd:process.cwd(),sessionsDir:s,providers:t.config.providers,dangerous:e.options.dangerous,needsSetup:t.needsSetup}),{exitOnCtrlC:!1,patchConsole:!1}).waitUntilExit()}async function hm(){let e=process.argv.slice(2);if(e[0]==="mcp"||e[0]==="--"&&e[1]==="mcp"){let r=e[0]==="--"?2:1;await ei(e.slice(r));return}let t=dm(e);if(t.options.removedOnceFlag){console.error("`--once` has been removed. Use `memo` (interactive) or pipe input to `memo`."),process.exitCode=1;return}if(t.options.showVersion){let o=gn()?.version??"unknown";console.log(o);return}if(!(process.stdin.isTTY&&process.stdout.isTTY)){await fm(t);return}await gm(t)}hm();async function ym(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t.trim())}),process.stdin.resume()})}
102
133
  //# sourceMappingURL=index.js.map
package/dist/prompt.md CHANGED
@@ -336,7 +336,7 @@ Common tools include:
336
336
 
337
337
  - **exec_command / write_stdin**: Run and continue interactive shell sessions
338
338
  - **shell / shell_command**: Shell execution compatibility variants
339
- - **apply_patch**: Structured file edits via patch grammar
339
+ - **apply_patch**: Direct string-replacement edits on a target file
340
340
  - **read_file / list_dir / grep_files**: Local file reading, directory listing, and content-based file search
341
341
  - **list_mcp_resources / list_mcp_resource_templates / read_mcp_resource**: MCP resource context access
342
342
  - **update_plan**: Structured progress plan updates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memo-code/memo",
3
- "version": "0.6.32",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "A lightweight coding agent that runs in your terminal",
@@ -44,11 +44,11 @@
44
44
  "start": "tsx packages/tui/src/cli.tsx",
45
45
  "build": "tsup",
46
46
  "dev": "tsup --watch",
47
- "web:dev": "pnpm --filter @memo-code/web dev",
48
- "web:build": "pnpm --filter @memo-code/web build",
49
- "web:start": "pnpm --filter @memo-code/web start",
50
- "format": "prettier --write \"{packages,web}/**/*.{ts,tsx,js,jsx,mjs,cjs,json,css,mdx}\" \"{package.json,pnpm-workspace.yaml,tsconfig.json,tsup.config.ts,vitest.config.ts,vitest.setup.ts,.prettierrc}\"",
51
- "format:check": "prettier --check \"{packages,web}/**/*.{ts,tsx,js,jsx,mjs,cjs,json,css,mdx}\" \"{package.json,pnpm-workspace.yaml,tsconfig.json,tsup.config.ts,vitest.config.ts,vitest.setup.ts,.prettierrc}\"",
47
+ "site:dev": "pnpm --filter @memo-code/site dev",
48
+ "site:build": "pnpm --filter @memo-code/site build",
49
+ "site:start": "pnpm --filter @memo-code/site start",
50
+ "format": "prettier --write \"{packages,site}/**/*.{ts,tsx,js,jsx,mjs,cjs,json,css,mdx}\" \"{package.json,pnpm-workspace.yaml,tsconfig.json,tsup.config.ts,vitest.config.ts,vitest.setup.ts,.prettierrc}\"",
51
+ "format:check": "prettier --check \"{packages,site}/**/*.{ts,tsx,js,jsx,mjs,cjs,json,css,mdx}\" \"{package.json,pnpm-workspace.yaml,tsconfig.json,tsup.config.ts,vitest.config.ts,vitest.setup.ts,.prettierrc}\"",
52
52
  "test": "vitest run",
53
53
  "test:core": "vitest run packages/core",
54
54
  "test:tools": "vitest run packages/tools",