@memo-code/memo 0.6.32 → 0.6.55

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):
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 风格):
package/dist/index.js CHANGED
@@ -1,70 +1,115 @@
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 ws=Object.create;var jn=Object.defineProperty;var Ms=Object.getOwnPropertyDescriptor;var ks=Object.getOwnPropertyNames;var As=Object.getPrototypeOf,Ps=Object.prototype.hasOwnProperty;var Rs=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Is=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ks(t))!Ps.call(e,r)&&r!==n&&jn(e,r,{get:()=>t[r],enumerable:!(o=Ms(t,r))||o.enumerable});return e};var Os=(e,t,n)=>(n=e!=null?ws(As(e)):{},Is(t||!e||!e.__esModule?jn(n,"default",{value:e,enumerable:!0}):n,e));var mo=Rs((td,po)=>{"use strict";function ro(e){return Array.isArray(e)?e:[e]}var on="",so=" ",tn="\\",Mi=/^\s+$/,ki=/(?:[^\\]|^)\\$/,Ai=/^\\!/,Pi=/^\\#/,Ri=/\r?\n/g,Ii=/^\.*\/|^\.+$/,nn="/",lo="node-ignore";typeof Symbol<"u"&&(lo=Symbol.for("node-ignore"));var io=lo,Oi=(e,t,n)=>Object.defineProperty(e,t,{value:n}),Li=/([0-z])-([0-z])/g,co=()=>!1,$i=e=>e.replace(Li,(t,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?t:on),Ni=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Di=[[/^\uFEFF/,()=>on],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?so:on)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+so}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let o=n.replace(/\\\*/g,"[^\\/]*");return t+o}],[/\\\\\\(?=[$.|*+(){^])/g,()=>tn],[/\\\\/g,()=>tn],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,o,r)=>t===tn?`\\[${n}${Ni(o)}${r}`:r==="]"&&o.length%2===0?`[${$i(n)}${o}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`]],ao=Object.create(null),Ui=(e,t)=>{let n=ao[e];return n||(n=Di.reduce((o,[r,s])=>o.replace(r,s.bind(e)),e),ao[e]=n),t?new RegExp(n,"i"):new RegExp(n)},an=e=>typeof e=="string",Hi=e=>e&&an(e)&&!Mi.test(e)&&!ki.test(e)&&e.indexOf("#")!==0,Fi=e=>e.split(Ri),rn=class{constructor(t,n,o,r){this.origin=t,this.pattern=n,this.negative=o,this.regex=r}},ji=(e,t)=>{let n=e,o=!1;e.indexOf("!")===0&&(o=!0,e=e.substr(1)),e=e.replace(Ai,"!").replace(Pi,"#");let r=Ui(e,t);return new rn(n,e,o,r)},Bi=(e,t)=>{throw new t(e)},Ee=(e,t,n)=>an(e)?e?Ee.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),uo=e=>Ii.test(e);Ee.isNotRelative=uo;Ee.convert=e=>e;var sn=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:o=!1}={}){Oi(this,io,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=o,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(t){if(t&&t[io]){this._rules=this._rules.concat(t._rules),this._added=!0;return}if(Hi(t)){let n=ji(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,ro(an(t)?Fi(t):t).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(t){return this.add(t)}_testOne(t,n){let o=!1,r=!1;return this._rules.forEach(s=>{let{negative:i}=s;if(r===i&&o!==r||i&&!o&&!r&&!n)return;s.regex.test(t)&&(o=!i,r=i)}),{ignored:o,unignored:r}}_test(t,n,o,r){let s=t&&Ee.convert(t);return Ee(s,t,this._allowRelativePaths?co:Bi),this._t(s,n,o,r)}_t(t,n,o,r){if(t in n)return n[t];if(r||(r=t.split(nn)),r.pop(),!r.length)return n[t]=this._testOne(t,o);let s=this._t(r.join(nn)+nn,n,o,r);return n[t]=s.ignored?s:this._testOne(t,o)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return ro(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},_t=e=>new sn(e),Wi=e=>Ee(e&&Ee.convert(e),e,co);_t.isPathValid=Wi;_t.default=_t;po.exports=_t;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,"/");Ee.convert=e;let t=/^[a-z]:\//i;Ee.isNotRelative=n=>t.test(n)||uo(n)}});import{randomUUID as us}from"crypto";import{createInterface as ap}from"readline/promises";import{stdin as lp,stdout as cp}from"process";import{render as up}from"ink";import Ls from"os";import{readFile as Bn}from"fs/promises";import{join as Wn,dirname as $s}from"path";import{fileURLToPath as Ns}from"url";var Ds=/{{\s*([\w.-]+)\s*}}/g;function Us(e,t){return e.replace(Ds,(n,o)=>t[o]??"")}function Hs(){try{return Ls.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}async function Fs(e){let t=Wn(e,"AGENTS.md");try{let n=await Bn(t,"utf-8");return n.trim()?{path:t,content:n}:null}catch{return null}}function js(e,t){return`${e}
3
+
4
+ ## Project AGENTS.md (Startup Root)
5
+ Loaded from: ${t.path}
6
+
7
+ ${t.content}`}async function zn(e={}){let t=e.cwd??process.cwd(),n=$s(Ns(import.meta.url)),o=Wn(n,"prompt.md"),r=await Bn(o,"utf-8"),s={date:new Date().toISOString(),user:Hs(),pwd:t},i=Us(r,s),a=await Fs(t);return a?js(i,a):i}import{appendFile as Bs,mkdir as Ws}from"fs/promises";import{dirname as zs}from"path";var St=class{constructor(t){this.filePath=t}ready=!1;async append(t){this.ready||(await Ws(zs(this.filePath),{recursive:!0}),this.ready=!0),await Bs(this.filePath,`${JSON.stringify(t)}
8
+ `,"utf8")}async flush(){return Promise.resolve()}};function qn(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 be}from"zod";function A(e){let{inputSchema:t,execute:n,...o}=e,r=t.toJSONSchema?.(),{$schema:s,...i}=r??{};return{...o,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 m(e,t=!1){return{content:[{type:"text",text:e}],isError:t}}import{spawn as pi}from"child_process";import{EventEmitter as di}from"events";import{resolve as mi}from"path";import{posix as qs}from"path";var Gn=220,Kn=4096,Gs=/^\/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,Ks=/(?:^|[\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,Vs=new Set(["-u","--user","-g","--group","-h","--host","-p","--prompt","-C","-T","-r","--role","-t","--type","-D","--chdir"]),Xs=new Set(["fdisk","sfdisk","cfdisk","parted","sgdisk","gdisk","wipefs","blkdiscard","shred"]);function Vt(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Js(e){let t=e.replace(/\s+/g," ").trim();return t.length>Gn?`${t.slice(0,Gn)}\u2026`:t}function Vn(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return(t.split(/[\\/]/).at(-1)??t).toLowerCase()}function Ys(e){let t=null,n=!1;for(let o=0;o<e.length;o+=1){let r=e[o];if(n){n=!1;continue}if(r==="\\"&&t!=="'"){n=!0;continue}if(t){r===t&&(t=null);continue}if(r==='"'||r==="'"){t=r;continue}if(r==="#")return e.slice(0,o)}return e}function Zs(e){let t=[],n="",o=null,r=!1,s=()=>{let i=Ys(n).trim();i&&t.push(i),n=""};for(let i=0;i<e.length;i+=1){let a=e[i];if(r){n+=a,r=!1;continue}if(a==="\\"&&o!=="'"){n+=a,r=!0;continue}if(o){n+=a,a===o&&(o=null);continue}if(a==='"'||a==="'"){o=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 Qs(e){let t=[],n="",o=null,r=!1,s=()=>{n&&t.push(n),n=""};for(let i=0;i<e.length;i+=1){let a=e[i];if(r){n+=a,r=!1;continue}if(a==="\\"&&o!=="'"){r=!0;continue}if(o){a===o?o=null:n+=a;continue}if(a==='"'||a==="'"){o=a;continue}if(/\s/.test(a)){s();continue}n+=a}return s(),t}function Xn(e){return/^[A-Za-z_][A-Za-z0-9_]*=.*/.test(e)}function ei(e,t){let n=t;for(;n<e.length;){let o=Vn(e[n]??"");if(o==="sudo"){for(n+=1;n<e.length;){let r=e[n]??"";if(!r.startsWith("-"))break;n+=1,Vs.has(r)&&n<e.length&&(n+=1)}continue}if(o==="env"){for(n+=1;n<e.length;){let r=e[n]??"";if(r.startsWith("-")||Xn(r)){n+=1;continue}break}continue}if(o==="command"||o==="nohup"||o==="time"){n+=1;continue}break}return n}function ti(e){let t=Qs(e);if(t.length===0)return null;let n=0;for(;n<t.length&&Xn(t[n]??"");)n+=1;if(n=ei(t,n),n>=t.length)return null;let o=Vn(t[n]??"");return o?{raw:e,commandName:o,args:t.slice(n+1)}:null}function Xt(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return Gs.test(t)}function ni(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)?qs.normalize(t)==="/":!1}function oi(e){return e.startsWith("-")&&e!=="-"}function ri(e){if(e.commandName!=="rm")return null;let t=!1,n=0;for(;n<e.args.length;){let r=e.args[n]??"";if(r==="--"){n+=1;break}if(!oi(r))break;if(r==="--recursive"){t=!0,n+=1;continue}if(r.startsWith("--")){n+=1;continue}let s=r.slice(1);(s.includes("r")||s.includes("R"))&&(t=!0),n+=1}if(!t)return null;let o=e.args.slice(n);for(let r of o)if(ni(r))return{ruleId:"rm_recursive_critical_target",matchedSegment:e.raw};return null}function si(e){return e.commandName==="mkfs"||e.commandName.startsWith("mkfs.")?{ruleId:"mkfs_filesystem_create",matchedSegment:e.raw}:null}function ii(e){if(e.commandName!=="dd")return null;for(let t=0;t<e.args.length;t+=1){let n=e.args[t]??"",o=n.indexOf("=");if(o<=0)continue;let r=n.slice(0,o).toLowerCase(),s=n.slice(o+1);if(r==="of"&&Xt(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(),o=e.args[t+1]??"";if(n==="of"&&Xt(o))return{ruleId:"dd_write_block_device",matchedSegment:e.raw}}return null}function ai(e){return!Xs.has(e.commandName)||!e.args.some(t=>Xt(t))?null:{ruleId:"disk_mutation_block_device",matchedSegment:e.raw}}function li(e){return Ks.test(e)?{ruleId:"redirect_block_device",matchedSegment:e}:null}function ci(e){for(let t of Zs(e)){let n=ti(t);if(n){let r=ri(n);if(r)return r;let s=si(n);if(s)return s;let i=ii(n);if(i)return i;let a=ai(n);if(a)return a}let o=li(t);if(o)return o}return null}function ui(e,t){let n=Js(e.command),o=typeof e.sessionId=="number"?` session_id="${e.sessionId}"`:"";return`<system_hint type="tool_call_denied" tool="${Vt(e.toolName)}" reason="dangerous_command" policy="blacklist" rule="${Vt(t.ruleId)}"${o} command="${Vt(n)}">Blocked a high-risk shell command to prevent irreversible data loss. Use a safer and scoped alternative.</system_hint>`}function Jt(e){let t=ci(e.command);return t?{blocked:!0,xml:ui(e,t),match:t}:{blocked:!1}}function Jn(e){let n=e.replace(/\r\n/g,`
10
+ `).replace(/\r/g,`
11
+ `).split(`
12
+ `),o=n.pop()??"";return{completedLines:n,remainder:o}}function Yt(e){return e.length<=Kn?e:e.slice(-Kn)}var fi=1e4,gi=250,hi=2e3,Yn=64;function yi(e){return Math.ceil(e.length/4)}function Ti(){return Math.random().toString(16).slice(2)||String(Date.now())}function Si(e){let t=e.login,n=e.shell?.trim();if(process.platform==="win32"){let r=n||"powershell.exe";return r.toLowerCase().includes("powershell")?{file:r,args:["-NoProfile","-Command",e.cmd]}:{file:r,args:[t?"-lc":"-c",e.cmd]}}return{file:n||process.env.SHELL||"/bin/bash",args:[t?"-lc":"-c",e.cmd]}}function _i(e,t){let o=(typeof t=="number"&&t>0?Math.floor(t):hi)*4,r=yi(e);return e.length<=o?{output:e,originalTokenCount:r}:{output:e.slice(0,o),originalTokenCount:r}}function vi(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 Zn(e,t){return typeof e!="number"||Number.isNaN(e)?t:e<0?0:Math.floor(e)}async function Qn(e,t){t<=0||e.exited||await Promise.race([new Promise(n=>{let o=setTimeout(()=>{s(),n()},t),r=()=>{clearTimeout(o),s(),n()},s=()=>{e.eventBus.off("exit",r)};e.eventBus.on("exit",r)})])}var Zt=class{sessions=new Map;nextId=1;cleanupSessions(){if(this.sessions.size<=Yn)return;let t=Array.from(this.sessions.values()).filter(n=>n.exited).sort((n,o)=>n.startedAtMs-o.startedAtMs);for(let n of t){if(this.sessions.size<=Yn)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 o=Jt({toolName:t.source_tool??"exec_command",command:n});if(o.blocked)return o.xml;let r=this.nextId++,s=Date.now(),i=Si({cmd:n,shell:t.shell,login:t.login!==!1}),a=t.workdir?.trim()?mi(process.cwd(),t.workdir.trim()):process.cwd(),l=pi(i.file,i.args,{cwd:a,env:process.env,stdio:["pipe","pipe","pipe"],shell:!1}),c={id:r,output:"",readOffset:0,pendingStdinInput:"",startedAtMs:s,exited:!1,exitCode:null,eventBus:new di,proc:l},u=(d,h)=>{let S=typeof h=="string"?h:h.toString("utf8");c.output+=d?`${d}${S}`:S,c.eventBus.emit("output")};l.stdout?.on("data",d=>u("",d)),l.stderr?.on("data",d=>u("",d)),l.on("error",d=>{c.output+=`
14
+ [exec error] ${d.message}`,c.eventBus.emit("output")}),l.on("close",d=>{c.exited=!0,c.exitCode=typeof d=="number"?d:-1,c.eventBus.emit("exit")}),this.sessions.set(r,c),this.cleanupSessions();let p=Zn(t.yield_time_ms,fi);return await Qn(c,p),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 r=Yt(`${n.pendingStdinInput}${t.chars}`),{completedLines:s,remainder:i}=Jn(r);for(let a of s){if(!a.trim())continue;let l=Jt({toolName:t.source_tool??"write_stdin",command:a,sessionId:n.id});if(l.blocked)return n.pendingStdinInput="",l.xml}n.pendingStdinInput=Yt(i),n.proc.stdin?.write(t.chars)}let o=Zn(t.yield_time_ms,gi);return await Qn(n,o),this.buildResponseText(n,t.max_output_tokens)}buildResponseText(t,n){let o=t.output.slice(t.readOffset);t.readOffset=t.output.length;let r=_i(o,n),s={sessionId:t.id,chunkId:Ti(),wallTimeSeconds:(Date.now()-t.startedAtMs)/1e3,exitCode:t.exited?t.exitCode:null,output:r.output,originalTokenCount:r.originalTokenCount};return vi(s)}},eo=new Zt;async function Be(e){return eo.start(e)}async function to(e){return eo.write(e)}var xi=be.object({command:be.array(be.string().min(1)).min(1,"command cannot be empty"),workdir:be.string().optional(),timeout_ms:be.number().int().positive().optional(),sandbox_permissions:be.enum(["use_default","require_escalated"]).optional(),justification:be.string().optional(),prefix_rule:be.array(be.string().min(1)).optional()}).strict();function bi(e){return e.map(t=>/^[A-Za-z0-9_./:@%+-]+$/.test(t)?t:JSON.stringify(t)).join(" ")}var no=A({name:"shell",description:"Runs a shell command (argv form) and returns output.",inputSchema:xi,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,timeout_ms:n})=>{try{let o=await Be({cmd:bi(e),workdir:t,login:!1,yield_time_ms:n,source_tool:"shell"});return m(o)}catch(o){return m(`shell failed: ${o.message}`,!0)}}});import{z as Ce}from"zod";var Ci=Ce.object({command:Ce.string().min(1,"command cannot be empty"),workdir:Ce.string().optional(),login:Ce.boolean().optional(),timeout_ms:Ce.number().int().positive().optional(),sandbox_permissions:Ce.enum(["use_default","require_escalated"]).optional(),justification:Ce.string().optional(),prefix_rule:Ce.array(Ce.string().min(1)).optional()}).strict(),oo=A({name:"shell_command",description:"Runs a shell command and returns its output. Always set workdir when possible.",inputSchema:Ci,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,login:n,timeout_ms:o})=>{try{let r=await Be({cmd:e,workdir:t,login:n,yield_time_ms:o,source_tool:"shell_command"});return m(r)}catch(r){return m(`shell_command failed: ${r.message}`,!0)}}});import{z as ce}from"zod";var Ei=ce.object({cmd:ce.string().min(1,"cmd cannot be empty"),workdir:ce.string().optional(),shell:ce.string().optional(),login:ce.boolean().optional(),tty:ce.boolean().optional(),yield_time_ms:ce.number().int().nonnegative().optional(),max_output_tokens:ce.number().int().positive().optional(),sandbox_permissions:ce.enum(["use_default","require_escalated"]).optional(),justification:ce.string().optional(),prefix_rule:ce.array(ce.string().min(1)).optional()}).strict(),Qt=A({name:"exec_command",description:"Runs a command in a PTY-like managed session, returning output or a session ID for ongoing interaction.",inputSchema:Ei,supportsParallelToolCalls:!0,isMutating:!0,execute:async e=>{try{let t=await Be({...e,source_tool:"exec_command"});return m(t)}catch(t){return m(`exec_command failed: ${t.message}`,!0)}}});import{z as tt}from"zod";var wi=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=A({name:"write_stdin",description:"Writes characters to an existing unified exec session and returns recent output.",inputSchema:wi,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{try{let t=await to({...e,source_tool:"write_stdin"});return m(t)}catch(t){return m(`write_stdin failed: ${t.message}`,!0)}}});import{mkdir as ho,readFile as ea,rm as yo,writeFile as ln}from"fs/promises";import{dirname as To}from"path";import{z as So}from"zod";var Ji=Os(mo(),1);import{normalize as zi,resolve as qi,dirname as od,join as Gi,relative as Ki,isAbsolute as Vi}from"path";import{homedir as Xi}from"os";import{existsSync as id,statSync as ad}from"fs";import{readFile as cd}from"fs/promises";function ue(e){return zi(qi(e))}function Yi(e,t){let n=Ki(t,e);return n===""||!n.startsWith("..")&&!Vi(n)}function Zi(){let e=process.env.MEMO_SANDBOX_WRITABLE_ROOTS?.trim();return e?e.split(",").map(t=>t.trim()).filter(Boolean).map(t=>ue(t)):[]}function fo(){let e=new Set;e.add(ue(process.cwd()));let t=process.env.MEMO_HOME?.trim()||Gi(Xi(),".memo");e.add(ue(t));for(let n of Zi())e.add(n);return Array.from(e)}function Qi(e){return fo().some(n=>Yi(e,n))}function go(e){if(Qi(e))return null;let t=fo();return`sandbox \u62D2\u7EDD\u5199\u5165: ${e} \u4E0D\u5728\u5141\u8BB8\u76EE\u5F55\u5185 (${t.join(", ")})`}var ta='Expected markers: "*** Add File:", "*** Update File:", "*** Delete File:", "*** End Patch".',na='Format hint: start with "*** Begin Patch", include one or more operations, and end with "*** End Patch". Update hunks use "@@" headers and body lines prefixed by " ", "+", or "-".',oa=2,ra=So.object({input:So.string().min(1,"patch input cannot be empty")}).strict();function ie(e){return`${e} ${na}`}function sa(e,t){if(/^@@\s*$/.test(e))return{header:e};let n=e.match(/^@@\s*-(\d+)(?:,\d+)?\s+\+\d+(?:,\d+)?\s*@@(?:\s.*)?$/);if(!n)throw new Error(ie(`Invalid hunk header at line ${t}: "${e}". Use "@@" or "@@ -start,count +start,count @@".`));return{header:e,sourceStart:Number(n[1])}}function ia(e){let t=e.replace(/\r/g,"").split(`
15
+ `);if(t[0]!=="*** Begin Patch")throw new Error(ie('patch must start with "*** Begin Patch".'));let n=[],o=1,r=!1;for(;o<t.length;){let s=t[o]??"";if(s==="*** End Patch"){r=!0;break}if(!s){o+=1;continue}if(s.startsWith("*** Add File: ")){let i=s.slice(14).trim();if(!i)throw new Error(ie(`Add File requires a path at line ${o+1}.`));o+=1;let a=[];for(;o<t.length;){let l=t[o];if(l===void 0||l.startsWith("*** "))break;if(!l.startsWith("+"))throw new Error(ie(`Invalid Add File content at line ${o+1}: each content line must start with "+".`));a.push(l.slice(1)),o+=1}n.push({type:"add",file:i,lines:a});continue}if(s.startsWith("*** Delete File: ")){let i=s.slice(17).trim();if(!i)throw new Error(ie(`Delete File requires a path at line ${o+1}.`));n.push({type:"delete",file:i}),o+=1;continue}if(s.startsWith("*** Update File: ")){let i=s.slice(17).trim();if(!i)throw new Error(ie(`Update File requires a path at line ${o+1}.`));o+=1;let a,l=t[o];l&&l.startsWith("*** Move to: ")&&(a=l.slice(13).trim(),o+=1);let c=[],u=null;for(;o<t.length;){let p=t[o];if(p===void 0||p.startsWith("*** "))break;if(p.startsWith("@@")){if(u){if(u.lines.length===0)throw new Error(ie(`Update File ${i} has an empty hunk at line ${o}.`));c.push(u)}u={...sa(p,o+1),lines:[]},o+=1;continue}if(p==="*** End of File"){o+=1;continue}if(p.startsWith("+")||p.startsWith("-")||p.startsWith(" ")){u||(u={header:"@@",lines:[]}),u.lines.push(p),o+=1;continue}throw new Error(ie(`Unexpected patch line at line ${o+1}: "${p}". Hunk lines must start with " ", "+", "-", or "@@".`))}if(u){if(u.lines.length===0)throw new Error(ie(`Update File ${i} has an empty hunk near line ${o}.`));c.push(u)}if(c.length===0)throw new Error(ie(`Update File ${i} has no hunks.`));n.push({type:"update",file:i,moveTo:a,hunks:c});continue}throw new Error(ie(`Unexpected patch marker at line ${o+1}: "${s}". ${ta}`))}if(!r)throw new Error(ie('patch is missing "*** End Patch".'));if(n.length===0)throw new Error(ie("patch contains no operations."));return n}function aa(e){let t=e.endsWith(`
16
+ `),n=t?e.slice(0,-1):e;return{lines:n.length>0?n.split(`
17
+ `):[],trailingNewline:t}}function _o(e,t){let n=e.join(`
18
+ `);return t&&n.length>0?`${n}
19
+ `:n}function la(e,t){if(t.length===0)return[];let n=e.length-t.length;if(n<0)return[];let o=[];for(let r=0;r<=n;r+=1){let s=!0;for(let i=0;i<t.length;i+=1)if(e[r+i]!==t[i]){s=!1;break}s&&o.push(r)}return o}function ca(e,t,n,o){if(e.length===0)throw new Error(`patch hunk context not found in ${n} (header: "${o}").`);if(t!==void 0){let r=Math.max(0,t-1),s=e.filter(i=>Math.abs(i-r)<=oa);if(s.length===1)return s[0];if(s.length>1)throw new Error(`patch hunk is ambiguous in ${n}: matched ${s.length} anchored locations near line ${t}. Add more context lines in this hunk.`)}if(e.length===1)return e[0];throw new Error(`patch hunk is ambiguous in ${n}: matched ${e.length} locations. Add more context lines or a more accurate @@ header.`)}function ua(e,t,n){let o=t.lines.filter(c=>c.startsWith(" ")||c.startsWith("-")).map(c=>c.slice(1)),r=t.lines.filter(c=>c.startsWith(" ")||c.startsWith("+")).map(c=>c.slice(1)),s=aa(e);if(o.length===0){if(r.length===0)return e;let c=t.sourceStart!==void 0?Math.max(0,t.sourceStart-1):s.lines.length,u=Math.min(c,s.lines.length),p=[...s.lines.slice(0,u),...r,...s.lines.slice(u)];return _o(p,s.trailingNewline)}let i=la(s.lines,o),a=ca(i,t.sourceStart,n,t.header),l=[...s.lines.slice(0,a),...r,...s.lines.slice(a+o.length)];return _o(l,s.trailingNewline)}function vt(e){let t=go(e);if(t)throw new Error(t)}var vo=A({name:"apply_patch",description:`Apply a structured patch.
20
+
21
+ Required envelope:
22
+ *** Begin Patch
23
+ ...operations...
24
+ *** End Patch
25
+
26
+ Supported operations:
27
+ 1) Add file
28
+ *** Add File: path/to/file.ts
29
+ +line 1
30
+ +line 2
31
+
32
+ 2) Update file (with optional move)
33
+ *** Update File: path/to/file.ts
34
+ *** Move to: path/to/new-file.ts
35
+ @@ -3,2 +3,2 @@
36
+ -old line
37
+ +new line
38
+
39
+ 3) Delete file
40
+ *** Delete File: path/to/file.ts
41
+
42
+ Update hunks may use "@@" or "@@ -start,count +start,count @@" headers.
43
+ Hunk body lines must start with " ", "+", or "-".`,inputSchema:ra,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{try{let t=ia(e.input);for(let n of t){if(n.type==="add"){let s=ue(n.file);vt(s),await ho(To(s),{recursive:!0}),await ln(s,n.lines.join(`
44
+ `),"utf8");continue}if(n.type==="delete"){let s=ue(n.file);vt(s),await yo(s);continue}let o=ue(n.file);vt(o);let r=await ea(o,"utf8");for(let s of n.hunks)r=ua(r,s,o);if(n.moveTo){let s=ue(n.moveTo);vt(s),await ho(To(s),{recursive:!0}),await ln(s,r,"utf8"),s!==o&&await yo(o)}else await ln(o,r,"utf8")}return m(`apply_patch succeeded (${t.length} operations)`)}catch(t){return m(`apply_patch failed: ${t.message}`,!0)}}});import{readFile as pa}from"fs/promises";import{z as ye}from"zod";var xo=500,bo=200,da=ye.object({file_path:ye.string().min(1),offset:ye.number().int().positive().optional(),limit:ye.number().int().positive().optional(),mode:ye.enum(["slice","indentation"]).optional(),indentation:ye.object({anchor_line:ye.number().int().positive().optional(),max_levels:ye.number().int().nonnegative().optional(),include_siblings:ye.boolean().optional(),include_header:ye.boolean().optional(),max_lines:ye.number().int().positive().optional()}).strict().optional()}).strict();function ma(e){return e.length<=xo?e:e.slice(0,xo)}function fa(e){let t=0;for(let n of e)if(n===" ")t+=1;else if(n===" ")t+=4;else break;return t}function ga(e){return e.split(/\r?\n/).map((n,o)=>({line:o+1,text:ma(n),indent:fa(n)}))}function ha(e){return e.map(t=>`L${t.line}: ${t.text}`).join(`
45
+ `)}function ya(e,t,n){let o=t-1;if(o>=e.length)throw new Error("offset exceeds file length");return e.slice(o,o+n)}function Ta(e,t){let n=t.offset??1,o=t.limit??bo,r=t.indentation,s=r?.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=r?.max_levels??0,l=r?.include_siblings??!0,c=r?.include_header??!0,u=r?.max_lines??o,p=Math.max(1,Math.min(o,u)),d=a===0?0:Math.max(0,i.indent-a*4),h=s-1,S=s-1;for(;h-1>=0;){let g=e[h-1];if(!g)break;let E=/^\s*(#|\/\/|--)/.test(g.text),_=g.text.trim().length===0;if(g.indent<d||!l&&g.indent===d&&!E&&!_||!c&&(E||_)&&g.indent<i.indent||(h-=1,S-h+1>=p))break}for(;S+1<e.length&&S-h+1<p;){let g=e[S+1];if(!g||g.indent<d||!l&&g.indent===d)break;S+=1}return e.slice(h,S+1)}var Co=A({name:"read_file",description:"Reads a local file with 1-indexed line numbers, supporting slice and indentation-aware block modes.",inputSchema:da,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??1,n=e.limit??bo;if(t<=0)return m("offset must be a 1-indexed line number",!0);if(n<=0)return m("limit must be greater than zero",!0);let o=e.file_path.trim();if(!o.startsWith("/"))return m("file_path must be an absolute path",!0);let r=ue(o);try{let s=await pa(r,"utf8"),i=ga(s);if(i.length===0)return m("");let l=(e.mode??"slice")==="indentation"?Ta(i,e):ya(i,t,n);return m(ha(l))}catch(s){return m(`read_file failed: ${s.message}`,!0)}}});import{readdir as Sa,lstat as _a}from"fs/promises";import{join as va}from"path";import{z as nt}from"zod";var xa=1,ba=25,Ca=2,Ea=nt.object({dir_path:nt.string().min(1),offset:nt.number().int().positive().optional(),limit:nt.number().int().positive().optional(),depth:nt.number().int().positive().optional()}).strict();function wa(e){let t=" ".repeat(e.displayDepth*2),n="";e.kind==="dir"&&(n="/"),e.kind==="symlink"&&(n="@"),e.kind==="other"&&(n="?");let o=e.path.split("/"),r=o[o.length-1]??e.path;return`${t}${r}${n}`}var Eo=A({name:"list_dir",description:"Lists entries in a local directory with 1-indexed entry numbers and simple type labels.",inputSchema:Ea,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??xa,n=e.limit??ba,o=e.depth??Ca;if(t<=0)return m("offset must be a 1-indexed entry number",!0);if(n<=0)return m("limit must be greater than zero",!0);if(o<=0)return m("depth must be greater than zero",!0);let r=e.dir_path.trim();if(!r.startsWith("/"))return m("dir_path must be an absolute path",!0);let s=ue(r);try{let i=[{absPath:s,depth:o,displayDepth:0}],a=[];for(;i.length>0;){let p=i.shift();if(!p)continue;let d=await Sa(p.absPath);d.sort((h,S)=>h.localeCompare(S));for(let h of d){let S=va(p.absPath,h),g=await _a(S),E=g.isSymbolicLink()?"symlink":g.isDirectory()?"dir":g.isFile()?"file":"other";a.push({path:S,displayDepth:p.displayDepth,kind:E}),E==="dir"&&p.depth>1&&i.push({absPath:S,depth:p.depth-1,displayDepth:p.displayDepth+1})}}if(a.length===0)return m(`Absolute path: ${s}`);let l=t-1;if(l>=a.length)return m("offset exceeds directory entry count",!0);let c=a.slice(l,l+n),u=[`Absolute path: ${s}`,...c.map(wa)];return l+n<a.length&&u.push(`More than ${n} entries found`),m(u.join(`
46
+ `))}catch(i){return m(`list_dir failed: ${i.message}`,!0)}}});import{spawn as Ma}from"child_process";import{resolve as ka}from"path";import{z as ot}from"zod";var Aa=100,Pa=2e3,Ra=3e4,Ia=ot.object({pattern:ot.string().min(1),include:ot.string().optional(),path:ot.string().optional(),limit:ot.number().int().positive().optional()}).strict();function Oa(e){return new Promise((t,n)=>{let o=["--files-with-matches","--sortr=modified","--regexp",e.pattern,"--no-messages"];e.include?.trim()&&o.push("--glob",e.include.trim()),o.push("--",e.searchPath);let r=Ma("rg",o,{cwd:e.cwd,stdio:["ignore","pipe","pipe"]}),s=[],i=[];r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",l=>s.push(l)),r.stderr?.on("data",l=>i.push(l));let a=setTimeout(()=>{r.kill("SIGTERM"),n(new Error("rg timed out after 30 seconds"))},Ra);r.on("error",l=>{clearTimeout(a),n(l)}),r.on("close",l=>{clearTimeout(a),t({exitCode:typeof l=="number"?l:-1,stdout:s.join(""),stderr:i.join("")})})})}var wo=A({name:"grep_files",description:"Finds files whose contents match the pattern and lists them by modification time.",inputSchema:Ia,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.pattern.trim();if(!t)return m("pattern must not be empty",!0);let n=Math.min(e.limit??Aa,Pa),o=e.path?.trim()?ka(process.cwd(),e.path.trim()):process.cwd();try{let r=await Oa({pattern:t,include:e.include,searchPath:o,cwd:process.cwd(),limit:n});if(r.exitCode===1)return m("No matches found.");if(r.exitCode!==0)return m(`rg failed: ${r.stderr||r.stdout}`,!0);let s=r.stdout.split(/\r?\n/).map(i=>i.trim()).filter(Boolean).slice(0,n);return s.length===0?m("No matches found."):m(s.join(`
47
+ `))}catch(r){return m(`grep_files failed: ${r.message}`,!0)}}});import{z as we}from"zod";var Mo=null;function cn(e){Mo=e}function ko(){return Mo}var La=we.object({server:we.string().optional(),cursor:we.string().optional()}).strict(),$a=we.object({server:we.string().optional(),cursor:we.string().optional()}).strict(),Na=we.object({server:we.string().min(1),uri:we.string().min(1)}).strict();function un(){let e=ko();if(!e)throw new Error("MCP pool is not initialized");return e}var Ao=A({name:"list_mcp_resources",description:"Lists resources provided by MCP servers. Prefer resources over web search when possible.",inputSchema:La,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=un();if(e?.trim()){let s=n.get(e.trim());if(!s)return m(`MCP server not found: ${e}`,!0);let i=await s.client.listResources(t?{cursor:t}:void 0);return m(JSON.stringify({server:s.name,resources:i.resources,nextCursor:i.nextCursor},null,2))}if(t)return m("cursor is only supported when server is specified",!0);let o=n.getAll().sort((s,i)=>s.name.localeCompare(i.name)),r=[];for(let s of o){let i=await s.client.listResources();for(let a of i.resources)r.push({server:s.name,...a})}return m(JSON.stringify({resources:r},null,2))}catch(n){return m(`list_mcp_resources failed: ${n.message}`,!0)}}}),Po=A({name:"list_mcp_resource_templates",description:"Lists resource templates provided by MCP servers. Prefer resource templates over web search when possible.",inputSchema:$a,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=un();if(e?.trim()){let s=n.get(e.trim());if(!s)return m(`MCP server not found: ${e}`,!0);let i=await s.client.listResourceTemplates(t?{cursor:t}:void 0);return m(JSON.stringify({server:s.name,resourceTemplates:i.resourceTemplates,nextCursor:i.nextCursor},null,2))}if(t)return m("cursor is only supported when server is specified",!0);let o=n.getAll().sort((s,i)=>s.name.localeCompare(i.name)),r=[];for(let s of o){let i=await s.client.listResourceTemplates();for(let a of i.resourceTemplates)r.push({server:s.name,...a})}return m(JSON.stringify({resourceTemplates:r},null,2))}catch(n){return m(`list_mcp_resource_templates failed: ${n.message}`,!0)}}}),Ro=A({name:"read_mcp_resource",description:"Read a specific resource from an MCP server given the server name and resource URI.",inputSchema:Na,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,uri:t})=>{try{let o=un().get(e);if(!o)return m(`MCP server not found: ${e}`,!0);let r=await o.client.readResource({uri:t});return m(JSON.stringify({server:e,uri:t,...r},null,2))}catch(n){return m(`read_mcp_resource failed: ${n.message}`,!0)}}});import{z as We}from"zod";var Da=We.object({step:We.string().min(1),status:We.enum(["pending","in_progress","completed"])}).strict(),Ua=We.object({explanation:We.string().optional(),plan:We.array(Da).min(1)}).strict(),Io=[],Oo=A({name:"update_plan",description:"Updates the task plan. At most one step can be in_progress at a time.",inputSchema:Ua,supportsParallelToolCalls:!1,isMutating:!1,execute:async({explanation:e,plan:t})=>t.filter(o=>o.status==="in_progress").length>1?m("At most one step can be in_progress at a time",!0):(Io=t,m(JSON.stringify({message:"Plan updated",explanation:e,plan:Io},null,2)))});import{readFile as Ha}from"fs/promises";import{homedir as Fa}from"os";import{join as Lo}from"path";import{z as $o}from"zod";var ja=$o.object({memory_id:$o.string().min(1)}).strict();function Ba(){let e=process.env.MEMO_HOME?.trim()||Lo(Fa(),".memo");return Lo(e,"Agents.md")}var No=A({name:"get_memory",description:"Loads the stored memory payload for a memory_id.",inputSchema:ja,supportsParallelToolCalls:!0,isMutating:!1,execute:async({memory_id:e})=>{try{let t=Ba(),n=await Ha(t,"utf8");return m(JSON.stringify({memory_id:e,memory_summary:n},null,2))}catch{return m(`memory not found for memory_id=${e}`,!0)}}});import{z as Do}from"zod";var Wa=Do.object({url:Do.string().min(1)}).strict(),Uo=1e4,rt=512e3,pn=4e3,za=new Set(["http:","https:","data:"]),qa=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,Ga=/<\s*(br|hr)\s*\/?>/gi,Ka=/<\s*li[^>]*>/gi,Va=/<[^>]+>/g,Xa=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,Ja=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,(o,r)=>{try{let s=r.startsWith("x")||r.startsWith("X")?parseInt(r.slice(1),16):parseInt(r,10);return Number.isFinite(s)?String.fromCharCode(s):""}catch{return""}}),Ya=e=>{let o=e.replace(Xa," ").replace(Ka,"- ").replace(Ga,`
48
+ `).replace(qa,`
49
+ `).replace(Va," "),s=Ja(o).replace(/\r/g,"").split(`
50
+ `).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(`
51
+ `).trim()},Za=e=>e.replace(/\s+/g," ").trim(),Ho=A({name:"webfetch",description:"HTTP GET request, returns processed plain text body (automatically strips HTML tags)",inputSchema:Wa,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t;try{t=new URL(e.url)}catch{return m(`Invalid URL: ${e.url}`,!0)}if(!za.has(t.protocol))return m(`Unsupported protocol: ${t.protocol}`,!0);let n=new AbortController,o=setTimeout(()=>n.abort(),Uo);try{let r=await globalThis.fetch(t,{signal:n.signal}),s=r.headers.get("content-length"),i=s?Number(s):void 0;if(i&&i>rt)return m(`Request rejected: response body too large (${i} bytes)`,!0);let a=0,l="";if(r.body&&r.body.getReader){let E=r.body.getReader(),_=[];for(;;){let{done:J,value:W}=await E.read();if(J)break;if(W){if(a+=W.byteLength,a>rt)return n.abort(),m(`Request aborted: response body exceeds ${rt} bytes`,!0);_.push(W)}}let T=new Uint8Array(a),D=0;for(let J of _)T.set(J,D),D+=J.byteLength;l=new TextDecoder().decode(T)}else if(l=await r.text(),a=new TextEncoder().encode(l).byteLength,a>rt)return m(`Request rejected: response body exceeds ${rt} bytes`,!0);let c=r.headers.get("content-type")||"",u=/text\/html/i.test(c)||/^\s*<!doctype html/i.test(l)||/^\s*<html[\s>]/i.test(l),p=u?Ya(l):l.trim(),d=Za(p),h=d.length>pn?`${d.slice(0,pn)}...`:d,S=d.length>pn?" text_truncated=true":"",g=u?" source=html_stripped":"";return m(`status=${r.status} bytes=${a} text_chars=${d.length} text="${h}"${S}${g}`)}catch(r){return r.name==="AbortError"?m(`Request timeout or aborted (${Uo}ms)`,!0):m(`Request failed: ${r.message}`,!0)}finally{clearTimeout(o)}}});import{spawn as Qa}from"child_process";import{existsSync as el}from"fs";import{resolve as tl}from"path";import{z as Q}from"zod";var nl=3e4,ol=1e4,rl=3e5,Fo=4,sl=1500,jo=2e3,Ae=new Map,il=Q.object({message:Q.string().min(1),agent_type:Q.string().optional()}).strict(),al=Q.object({id:Q.string().min(1),message:Q.string().min(1),interrupt:Q.boolean().optional()}).strict(),ll=Q.object({id:Q.string().min(1)}).strict(),cl=Q.object({ids:Q.array(Q.string().min(1)).min(1),timeout_ms:Q.number().int().positive().optional()}).strict(),ul=Q.object({id:Q.string().min(1)}).strict();function ze(){return new Date().toISOString()}function dn(e){return m(`agent not found: ${e}`,!0)}function pl(){let e=process.env.MEMO_SUBAGENT_MAX_AGENTS?.trim();if(!e)return Fo;let t=Number(e);return!Number.isFinite(t)||t<=0?Fo:Math.floor(t)}function dl(){let e=0;for(let t of Ae.values())t.running&&(e+=1);return e}function ml(){let e=process.env.MEMO_SUBAGENT_COMMAND?.trim();if(e)return e;let t=tl(process.cwd(),"dist/index.js");return el(t)?`node ${JSON.stringify(t)} --dangerous`:"memo --dangerous"}function fl(e){return e!=="running"}function gl(e){return new Promise(t=>{setTimeout(t,e)})}function hl(e){return e===void 0?nl:e<=0?null:Math.max(ol,Math.min(rl,e))}function yl(e){return e.length<=jo?e:`${e.slice(0,jo)}
52
+ ...[truncated]`}function Tl(e,t){let n=[],o=e.trim(),r=t.trim();return o&&n.push(o),r&&n.push(`stderr:
53
+ ${r}`),yl(n.join(`
54
+
55
+ `))}async function Bo(e){let t=e.running;if(!t)return;t.interrupted=!0;let n=t.process;n.exitCode!==null||n.killed||await new Promise(o=>{let r=!1,s=()=>{r||(r=!0,clearTimeout(i),n.off("close",s),o())},i=setTimeout(()=>{if(n.exitCode===null)try{n.kill("SIGKILL")}catch{s()}},sl);n.on("close",s);try{n.kill("SIGTERM")}catch{s()}})}function Sl(e){let t=Ae.get(e);return t?t.status:"not_found"}function _l(e){let t=Ae.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 vl(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 xl(e){let{record:t,submissionId:n,stdout:o,stderr:r,exitCode:s,interrupted:i}=e;if(!(!t.running||t.running.id!==n)&&(t.running=null,t.updatedAt=ze(),t.lastOutput=Tl(o,r)||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 Wo(e,t){let n=pl();if(dl()>=n)throw new Error(`subagent concurrency limit reached (${n})`);let o=crypto.randomUUID(),r=ml(),s=Qa(r,{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:o,message:t,process:s,startedAt:ze(),interrupted:!1},e.status="running",e.lastMessage=t,e.lastSubmissionId=o,e.updatedAt=ze(),s.on("close",l=>{let c=typeof l=="number"?l:-1,u=!!(e.running?.id===o&&e.running.interrupted);xl({record:e,submissionId:o,stdout:i.join(""),stderr:a.join(""),exitCode:c,interrupted:u})});try{s.stdin?.write(`${t.trim()}
56
+ `)}catch{}try{s.stdin?.end()}catch{}return o}var zo=A({name:"spawn_agent",description:"Spawn a sub-agent for a well-scoped task and return the agent id.",inputSchema:il,supportsParallelToolCalls:!1,isMutating:!0,execute:async({message:e})=>{let t=e.trim();if(!t)return m("spawn_agent failed: message must not be empty",!0);let n=crypto.randomUUID(),o=ze(),r={id:n,createdAt:o,updatedAt:o,status:"running",statusBeforeClose:"completed",lastMessage:t,lastSubmissionId:null,lastOutput:null,lastError:null,running:null};Ae.set(n,r);try{let s=await Wo(r,t);return m(JSON.stringify({...vl(r),submission_id:s},null,2))}catch(s){return Ae.delete(n),m(`spawn_agent failed: ${s.message}`,!0)}}}),qo=A({name:"send_input",description:"Send a message to an existing agent.",inputSchema:al,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e,message:t,interrupt:n})=>{let o=Ae.get(e);if(!o)return dn(e);let r=t.trim();if(!r)return m("send_input failed: message must not be empty",!0);if(o.status==="closed")return m(`send_input failed: agent ${e} is closed; run resume_agent first`,!0);if(o.running){if(!n)return m(`send_input failed: agent ${e} is busy; set interrupt=true to cancel current submission`,!0);await Bo(o)}try{let s=await Wo(o,r);return m(JSON.stringify({agent_id:o.id,status:o.status,submission_id:s},null,2))}catch(s){return m(`send_input failed: ${s.message}`,!0)}}}),Go=A({name:"resume_agent",description:"Resume a previously closed agent by id.",inputSchema:ll,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=Ae.get(e);return t?(t.status==="closed"&&(t.status=t.statusBeforeClose,t.updatedAt=ze()),m(JSON.stringify({agent_id:e,status:t.status},null,2))):dn(e)}}),Ko=A({name:"wait",description:"Wait for agent statuses and return current snapshots.",inputSchema:cl,supportsParallelToolCalls:!1,isMutating:!1,execute:async({ids:e,timeout_ms:t})=>{let n=hl(t);if(n===null)return m("wait failed: timeout_ms must be greater than zero",!0);let o=()=>{let i={},a={};for(let l of e){let c=Sl(l);fl(c)&&(i[l]=c,a[l]=_l(l))}return{status:i,details:a}},r=o();if(Object.keys(r.status).length>0)return m(JSON.stringify({status:r.status,details:r.details,timed_out:!1},null,2));let s=Date.now()+n;for(;Date.now()<s;)if(await gl(100),r=o(),Object.keys(r.status).length>0)return m(JSON.stringify({status:r.status,details:r.details,timed_out:!1},null,2));return m(JSON.stringify({status:{},details:{},timed_out:!0},null,2))}}),Vo=A({name:"close_agent",description:"Close an agent and return its last known status.",inputSchema:ul,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=Ae.get(e);return t?t.status==="closed"?m(JSON.stringify({agent_id:e,status:"closed"},null,2)):(t.statusBeforeClose=t.running?"completed":t.status,t.status="closed",t.updatedAt=ze(),await Bo(t),m(JSON.stringify({agent_id:e,status:"closed"},null,2))):dn(e)}});var mn={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"},Xo=new Set(["spawn_agent","send_input","resume_agent","wait","close_agent"]),xt={read:0,write:1,execute:2},Jo=["exec","run","shell","command","stdin"],Yo=["write","patch","create","delete","modify","update"],Zo=["read","get","fetch","search","list","find"],Qo=new Set(["write","execute"]);function gn(e){let t={...mn,...e?.customLevels};return{getRiskLevel(n){if(n in t)return t[n];let o=n.toLowerCase();return fn(o,Jo)?"execute":fn(o,Yo)?"write":fn(o,Zo)?"read":"write"},compareRisk(n,o){return xt[n]-xt[o]},needsApproval(n,o){return o==="strict"?!0:Qo.has(n)}}}function fn(e,t){return t.some(n=>e.includes(n))}import{createHash as bl}from"crypto";function bt(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map(n=>bt(n)).join(",")+"]":`{${Object.entries(e).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${bt(o)}`).join(",")}}`}function hn(e,t){let n=bt(t),o=`${e}:${n}`;return bl("sha256").update(o).digest("hex").slice(0,16)}function Cl(e){return`Tool "${e}" requires approval.`}function yn(e){let{mode:t="auto",dangerous:n=!1,toolRiskLevels:o}=e||{},r=t==="strict"?"strict":"auto";if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let s=gn({customLevels:o}),i={session:new Set,once:new Set,denied:new Set};return{get isDangerousMode(){return!1},getRiskLevel(a){return s.getRiskLevel(a)},check(a,l){if(Xo.has(a))return{needApproval:!1,decision:"auto-execute"};let c=s.getRiskLevel(a);if(!s.needsApproval(c,r))return{needApproval:!1,decision:"auto-execute"};let u=hn(a,l);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:a,params:l}:{needApproval:!0,fingerprint:u,riskLevel:c,reason:Cl(a),toolName:a,params:l}},recordDecision(a,l){switch(i.session.delete(a),i.once.delete(a),i.denied.delete(a),l){case"session":i.session.add(a);break;case"once":i.once.add(a);break;case"deny":i.denied.add(a);break}},isGranted(a){return i.session.has(a)||i.once.has(a)},clearOnceApprovals(){i.once.clear()},dispose(){i.session.clear(),i.once.clear(),i.denied.clear()}}}var er=12e3;function El(){let e=process.env.MEMO_TOOL_RESULT_MAX_CHARS?.trim();if(!e)return er;let t=Number(e);return!Number.isFinite(t)||t<=0?er:Math.floor(t)}function wl(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ml(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 kl(e,t,n){return`<system_hint type="tool_output_omitted" tool="${wl(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 Al(e,t){let n=El(),o=Ml(t);return o<=n?t:{content:[{type:"text",text:kl(e,o,n)}],isError:!1}}function Pl(e){return(e.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
57
+ `)}function Rl(e,t){let n=t;if(typeof t=="string"){let o=t.trim();if(o)try{n=JSON.parse(o)}catch{n=o}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 Il(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 Tn=class{constructor(t){this.config=t;this.approvalManager=yn(t.approval)}approvalManager;async executeAction(t,n){let o=Date.now(),r=t.id??`${t.name}:${o}`,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:r,tool:t.name,status:"approval_denied",errorType:"approval_denied",success:!1,observation:`User denied tool execution: ${t.name}`,durationMs:Date.now()-o,rejected:!0}}let i=this.config.tools[t.name];if(!i)return{actionId:r,tool:t.name,status:"tool_not_found",errorType:"tool_not_found",success:!1,observation:`Unknown tool: ${t.name}`,durationMs:Date.now()-o};try{let a=Rl(i,t.input);if(!a.ok)return{actionId:r,tool:t.name,status:"input_invalid",errorType:"input_invalid",success:!1,observation:a.error,durationMs:Date.now()-o};let l=await i.execute(a.data),c=Al(t.name,l);return{actionId:r,tool:t.name,status:"success",success:!0,observation:Pl(c)||"(no tool output)",durationMs:Date.now()-o}}catch(a){let l=Il(a);return{actionId:r,tool:t.name,status:l,errorType:l,success:!1,observation:`Tool execution failed: ${a.message}`,durationMs:Date.now()-o}}}async executeActions(t,n={}){let o=n.executionMode??"sequential",r=n.failurePolicy??(n.stopOnRejection===!1?"collect_all":"fail_fast"),s=[];if(o==="parallel"){let l=await Promise.all(t.map(c=>this.executeAction(c,n)));if(r==="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&&r==="fail_fast")break}let i=s.some(l=>l.rejected),a=s.map(l=>`[${l.tool}]: ${l.observation}`).join(`
58
+
59
+ `);return{results:s,combinedObservation:a,hasRejection:i,executionMode:o,failurePolicy:r}}clearOnceApprovals(){this.approvalManager.clearOnceApprovals()}dispose(){this.approvalManager.dispose()}};function tr(e){return new Tn(e)}var Ct=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,o]of this.tools)t[n]=o;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}};import{Client as Ol}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as Ll}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as $l}from"@modelcontextprotocol/sdk/client/stdio.js";function Nl(e){if(!e)return;let t={...process.env,...e},n=Object.entries(t).filter(o=>typeof o[1]=="string");return Object.fromEntries(n)}function nr(){return new Ol({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function Dl(e){if(!(!e||Object.keys(e).length===0))return{headers:e}}function Ul(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 Hl(e){let t=new URL(e.url),n=Dl(Ul(e));try{let o=nr(),r=new Ll(t,{requestInit:n});return await o.connect(r),{client:o,transport:r}}catch(o){let r=`Failed to connect via streamable_http (${o.message})`,s=new Error(r);throw s.cause=o,s}}async function Fl(e){if("url"in e)return Hl(e);let t={command:e.command,args:e.args,env:Nl(e.env),stderr:e.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},n=new $l(t),o=nr();return await o.connect(n),{client:o,transport:n}}var Et=class{connections=new Map;async connect(t,n){let o=this.connections.get(t);if(o)return o;let{client:r,transport:s}=await Fl(n),i=await r.listTools(),a={name:t,client:r,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 o of n.tools)t.push({name:o.name,description:o.description,serverName:o.serverName,originalName:o.originalName,inputSchema:o.inputSchema,client:n.client});return t}async closeAll(){let t=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(t),this.connections.clear()}get size(){return this.connections.size}};var wt=class{pool;tools=new Map;shouldLog;constructor(){this.pool=new Et,cn(this.pool),this.shouldLog=process.env.MEMO_MCP_LOG==="1"||!(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([o,r])=>{try{let s=await this.pool.connect(o,r);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 '${o}' with ${s.tools.length} tools`)}catch(s){this.shouldLog&&console.error(`[MCP] Failed to connect to server '${o}':`,s)}})),n}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,o]of this.tools)t[n]=o;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}async dispose(){await this.pool.closeAll(),this.tools.clear(),cn(null)}getPool(){return this.pool}};var Mt=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new Ct,this.mcpRegistry=new wt}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 o=this.getTool(t);if(!o)throw new Error(`Tool '${t}' not found`);return o.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 o=t.filter(s=>s.source==="native"),r=t.filter(s=>s.source==="mcp");if(o.length>0){n.push("### Built-in Tools"),n.push("");for(let s of o)n.push(this.formatToolDescription(s));n.push("")}if(r.length>0){n.push("### External MCP Tools"),n.push("");let s=this.groupByServer(r);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(`
60
+ `)}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(`
61
+ `)}groupByServer(t){let n={};for(let o of t)if(o.source==="mcp"){let r=o.serverName;n[r]||(n[r]=[]),n[r].push(o)}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 jl(e){let t=process.env[e]?.trim();return t?new Set(t.split(",").map(n=>n.trim()).filter(Boolean)):new Set}function Bl(){let e=[],t=process.env.MEMO_SHELL_TOOL_TYPE?.trim()||"unified_exec",n=jl("MEMO_EXPERIMENTAL_TOOLS"),o=n.size===0,r=process.env.MEMO_ENABLE_COLLAB_TOOLS!=="0",s=process.env.MEMO_ENABLE_MEMORY_TOOL!=="0";return t==="shell"?e.push(no):t==="shell_command"?e.push(oo):t==="unified_exec"?e.push(Qt,en):t!=="disabled"&&e.push(Qt,en),e.push(Ao,Po,Ro),e.push(Oo),e.push(vo),(o||n.has("grep_files"))&&e.push(wo),(o||n.has("read_file"))&&e.push(Co),(o||n.has("list_dir"))&&e.push(Eo),s&&e.push(No),e.push(Ho),r&&e.push(zo,qo,Go,Ko,Vo),e}function Wl(e){let t={};for(let n of e)t[n.name]=n;return t}var zl=Wl(Bl()),ql=Object.values(zl),or=ql;import ac from"openai";import{encoding_for_model as Gl,get_encoding as Kl}from"@dqbd/tiktoken";var rr="cl100k_base";function Vl(e){let t=e?.trim()||rr;try{let n=()=>Gl(t);return n().free(),{model:t,factory:n}}catch{let n=rr,o=()=>Kl(n);return o().free(),{model:n,factory:o}}}function Xl(e){if(e.role==="assistant"){let t=e.reasoning_content?`
62
+ ${e.reasoning_content}`:"";return e.tool_calls?.length?`${e.content}${t}
63
+ ${JSON.stringify(e.tool_calls)}`:`${e.content}${t}`}return e.role==="tool"?`${e.content}
64
+ ${e.tool_call_id}
65
+ ${e.name??""}`:e.content}function sr(e){let{model:t,factory:n}=Vl(e),o=n(),r=4,s=2,i=1,a=c=>c?o.encode(c).length:0;return{model:t,countText:a,countMessages:c=>{if(!c.length)return 0;let u=0;for(let p of c)u+=r,u+=a(Xl(p)),p.name&&(u+=i);return u+=s,u},dispose:()=>o.free()}}import{mkdir as Jl,writeFile as Yl,readFile as Zl,access as Ql}from"fs/promises";import{homedir as ir}from"os";import{dirname as ec,join as it}from"path";import{randomUUID as lf}from"crypto";import{parse as tc}from"toml";var nc=it(ir(),".memo"),oc="sessions",st={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 rc(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:JSON.stringify(e)}function sc(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=[];for(let[n,o]of Object.entries(e)){if(!o)continue;let r=Array.isArray(o)?o:[o];for(let s of r){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 ar(e){return e.startsWith("~")?it(ir(),e.slice(1)):e}function ic(e){let t=e.providers.map(s=>{let i=typeof s?.name=="string"?s.name:"";if(!i)return"";let l=[`[[providers.${rc(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
66
  `)}).filter(Boolean).join(`
33
67
 
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}"
68
+ `),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 h=[`[mcp_servers.${s}]`];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 S=i.http_headers??i.headers;if(S&&Object.keys(S).length>0){let g=Object.entries(S).map(([_,T])=>`${JSON.stringify(_)} = ${JSON.stringify(T)}`).join(", "),E=i.http_headers?"http_headers":"headers";h.push(`${E} = { ${g} }`)}return h.join(`
69
+ `)}let a=i.args?`args = ${JSON.stringify(i.args)}`:"",l=i.type?`type = "${i.type}"
36
70
  `:"",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(`
71
+ `:"",u=`[mcp_servers.${s}]
72
+ ${l}command = "${i.command}"
73
+ ${c}${a}`.trimEnd(),p=i.env?Object.entries(i.env):[];if(p.length===0)return u;let d=p.map(([h,S])=>`${JSON.stringify(h)} = ${JSON.stringify(S)}`).join(`
40
74
  `);return`${u}
41
75
 
42
- [mcp_servers.${r}.env]
76
+ [mcp_servers.${s}.env]
43
77
  ${d}`}).join(`
44
78
 
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(`
79
+ `));let o=[`current_provider = "${e.current_provider}"`];return typeof e.max_prompt_tokens=="number"&&Number.isFinite(e.max_prompt_tokens)&&o.push(`max_prompt_tokens = ${Math.floor(e.max_prompt_tokens)}`),Array.isArray(e.active_mcp_servers)&&o.push(`active_mcp_servers = ${JSON.stringify(e.active_mcp_servers)}`),[o.join(`
80
+ `),t,n].filter(Boolean).join(`
81
+
82
+ `)}async function pe(e,t){await Jl(ec(e),{recursive:!0}),await Yl(e,ic(t),"utf-8")}async function ee(){let e=process.env.MEMO_HOME?ar(process.env.MEMO_HOME):nc,t=it(e,"config.toml");try{await Ql(t);let n=await Zl(t,"utf-8"),o=tc(n),r=sc(o.providers),s=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=Array.isArray(o.active_mcp_servers)?o.active_mcp_servers.filter(c=>typeof c=="string"&&c.trim().length>0):void 0,a={current_provider:o.current_provider??st.current_provider,max_prompt_tokens:s??st.max_prompt_tokens,providers:r,mcp_servers:o.mcp_servers??{},active_mcp_servers:i},l=!a.providers.length;return{config:l?st:a,home:e,configPath:t,needsSetup:l}}catch{return{config:st,home:e,configPath:t,needsSetup:!0}}}function De(e,t){let n=t||e.current_provider,o=e.providers.find(r=>r.name===n);return o||(e.providers?.[0]??st.providers[0])}function kt(e,t){let n=t.historyDir??it(e.home,oc);return ar(n)}function lr(e,t){let n=new Date,o=String(n.getFullYear()),r=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-${o}-${r}-${s}T${i}-${a}-${l}-${t}.jsonl`;return it(e,o,r,s,c)}function lc(e,t){if(!e||!t)return e;let n=new Set(t.map(r=>r.trim()).filter(Boolean));if(n.size===0)return{};let o={};for(let[r,s]of Object.entries(e))n.has(r)&&(o[r]=s);return o}function cc(e){try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,raw:e,error:t.message}}}function uc(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 pc(e){let t=e?.reasoning_content;if(typeof t!="string")return;let n=t.trim();return n.length>0?n:void 0}async function cr(e,t,n){let o=await ee(),r=o.config,s=new Mt;if(s.registerNativeTools(or),await s.loadMcpServers(lc(r.mcp_servers,t.activeMcpServers)),e.tools)for(let[d,h]of Object.entries(e.tools))s.registerNativeTool({name:d,description:h.description,source:"native",inputSchema:{type:"object"},execute:h.execute});let i=s.toRegistry(),a=async()=>{let d=await(e.loadPrompt??zn)(),h=s.generateToolDescriptions();return h&&(d+=`
47
83
 
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+=`
84
+ ${h}`),d},l=s.generateToolDefinitions(),c=kt(o,t),u=lr(c,n),p=new St(u);return{tools:i,dispose:async()=>{e.dispose&&await e.dispose(),await s.dispose()},callLLM:e.callLLM??(async(d,h,S)=>{let g=De(r,t.providerName),E=process.env[g.env_api_key]??process.env.OPENAI_API_KEY??process.env.DEEPSEEK_API_KEY;if(!E)throw new Error(`Missing env var ${g.env_api_key} (or OPENAI_API_KEY/DEEPSEEK_API_KEY)`);let _=new ac({apiKey:E,baseURL:g.base_url}),T=d.map(uc),D=S?.tools??l,J=D.length>0?D.map(C=>({type:"function",function:{name:C.name,description:C.description,parameters:C.input_schema}})):void 0,W=await _.chat.completions.create({model:g.model,messages:T,tools:J,tool_choice:J?"auto":void 0},{signal:S?.signal}),j=W.choices?.[0]?.message,x=pc(j);if(j?.tool_calls&&j.tool_calls.length>0){let C=[];j.content&&C.push({type:"text",text:j.content});for(let O of j.tool_calls)if(O.type==="function"){let me=cc(O.function.arguments);me.ok?C.push({type:"tool_use",id:O.id,name:O.function.name,input:me.data}):C.push({type:"text",text:`[tool_use parse error] ${me.error}; raw: ${me.raw}`})}let B=C.some(O=>O.type==="tool_use");return{content:C,reasoning_content:x,stop_reason:B?"tool_use":"end_turn",usage:{prompt:W.usage?.prompt_tokens??void 0,completion:W.usage?.completion_tokens??void 0,total:W.usage?.total_tokens??void 0}}}let N=j?.content;if(typeof N!="string")throw new Error("OpenAI-compatible API returned empty content");return{content:[{type:"text",text:N}],reasoning_content:x,stop_reason:"end_turn",usage:{prompt:W.usage?.prompt_tokens??void 0,completion:W.usage?.completion_tokens??void 0,total:W.usage?.total_tokens??void 0}}}),loadPrompt:a,historySinks:e.historySinks??[p],tokenCounter:e.tokenCounter??sr(t.tokenizerModel),historyFilePath:u}}function dc(e){let t=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,o=e.replace(n,(r,s,i)=>{let a=(i??"").trim();return a&&t.push(a),a});return{thinkingParts:t,cleaned:o.trim()}}function ur(e){if(e.length===0)return;let t=e.join(`
85
+ `),{thinkingParts:n,cleaned:o}=dc(t);return n.length>0?n.join(`
49
86
 
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(`
87
+ `):o||void 0}import{randomUUID as Sr}from"crypto";function mc(){return{onTurnStart:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[],onTitleGenerated:[]}}function pr(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 dr(e){let t=mc();if(pr(t,e.hooks),Array.isArray(e.middlewares))for(let n of e.middlewares)pr(t,n);return t}async function X(e,t,n){let o=e[t];if(o.length)for(let r of o)try{await r(n)}catch(s){console.warn(`Hook ${t} failed: ${s.message}`)}}function qe(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 _r="interactive",fc=12e4,mr="success",at="Tool usage is disabled in the current permission mode. Switch to /tools once or /tools full to enable tools.",gc=`Generate a concise session title based on the user's first prompt.
88
+ Requirements:
89
+ - 3 to 8 words when possible
90
+ - Keep it specific and descriptive
91
+ - Return title only, no quotes, no punctuation-only output
92
+ `,fr=60,hc="Skipped tool execution after previous rejection.",yc="Tool execution skipped: tools are disabled in current permission mode.";function Tc(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 gr(){return{prompt:0,completion:0,total:0}}function hr(e,t){if(!t)return;let n=t.prompt??0,o=t.completion??0,r=t.total??n+o;e.prompt+=n,e.completion+=o,e.total+=r}function Sc(e){let t=e.content.filter(o=>o.type==="text"),n=e.content.filter(o=>o.type==="tool_use");return{textContent:t.map(o=>o.text).join(`
93
+ `),toolUseBlocks:n.map(o=>({id:o.id,name:o.name,input:o.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 _c(e,t){for(let n of t)try{await n.append(e)}catch(o){console.error(`Failed to write history event: ${o.message}`)}}function yr(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],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${lt(o)}`).join(",")}}`}function vc(e){return e.map(t=>({id:t.id,type:"function",function:{name:t.name,arguments:lt(t.input)}}))}function xc(e,t){let n=e.trim();if(!n)return null;let o=[n],r=n.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);r?.[1]&&o.push(r[1].trim());for(let s of o)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 vr(e){return e.length<=fr?e:`${e.slice(0,fr-3).trimEnd()}...`}function bc(e){let t=e.replace(/\r?\n+/g," ").replace(/\s+/g," ").trim();if(!t)return"";let n=t.replace(/^["'`“”‘’]+|["'`“”‘’]+$/g,"").trim();return n?vr(n):""}function Cc(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 o=t.split(" ").filter(Boolean).slice(0,8).join(" ");return vr(o||t)}function Tr(e){return{role:"tool",content:e.observation,tool_call_id:e.actionId,name:e.tool}}function Ec(e,t,n){let o=new Map(t.map(r=>[r.actionId,r]));return e.map(r=>{let s=o.get(r.id);return s||{actionId:r.id,tool:r.name,status:n?"approval_denied":"execution_failed",errorType:n?"approval_denied":"execution_failed",success:!1,observation:n?`${hc} ${r.name}`:`Tool result missing for ${r.name}; execution aborted before producing output.`,durationMs:0,rejected:n?!0:void 0}})}var Sn=class{constructor(t,n,o,r,s){this.deps=t;this.options=n;this.id=n.sessionId||Sr(),this.mode=n.mode||_r,this.history=[{role:"system",content:o}],this.tokenCounter=r,this.sinks=t.historySinks??[],this.hooks=dr(t),this.historyFilePath=s;let i=Tc(n);this.toolsDisabled=i.toolsDisabled,this.toolPermissionMode=i.mode,this.toolOrchestrator=tr({tools:t.tools,approval:{dangerous:i.dangerous,mode:i.approvalMode}})}title;id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=gr();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 o=`${t}:${lt(n)}`;if(this.lastActionSignature===o?this.repeatedActionCount+=1:(this.lastActionSignature=o,this.repeatedActionCount=1),this.repeatedActionCount===3){let r=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${r}${r.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 o=>{await X(this.hooks,"onApprovalRequest",{sessionId:this.id,turn:t,step:n,request:o})},requestApproval:async o=>this.deps.requestApproval?this.deps.requestApproval(o):"deny",onApprovalResponse:async({fingerprint:o,decision:r})=>{await X(this.hooks,"onApprovalResponse",{sessionId:this.id,turn:t,step:n,fingerprint:o,decision:r})}}}async executeToolAction(t,n,o,r,s){return this.toolOrchestrator.executeAction({id:t,name:n,input:o},this.buildToolApprovalHooks(r,s))}async maybeGenerateSessionTitle(t,n,o){if(t!==1||this.title)return;let r=Cc(n),s="fallback";try{let i=await this.deps.callLLM([{role:"system",content:gc},{role:"user",content:n}],void 0,{signal:o,tools:[]}),a=bc(i.content.filter(l=>l.type==="text").map(l=>l.text).join(" "));a&&(r=a,s="llm")}catch(i){if(yr(i))return}this.title=r,await this.emitEvent("session_title",{turn:t,content:r,meta:{source:s,original_prompt:n}}),await X(this.hooks,"onTitleGenerated",{sessionId:this.id,turn:t,title:r,originalPrompt:n})}async runTurn(t){let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let o=this.turnIndex,r=[],s=gr(),i=Date.now(),a=this.options.maxPromptTokens??fc;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:o,content:t,meta:{tokens:{prompt:l}}}),await X(this.hooks,"onTurnStart",{sessionId:this.id,turn:o,input:t,promptTokens:l,history:qe(this.history)}),this.options.generateSessionTitle&&await this.maybeGenerateSessionTitle(o,t,n.signal);let c="",u="ok",p,d=0,h=null,S=-1;for(let g=0;;g++){let E=this.tokenCounter.countMessages(this.history);if(E>a){let b=`Context tokens (${E}) exceed the limit. Please shorten the input or restart the session.`;this.history.push({role:"assistant",content:b}),u="prompt_limit",c=b,p=b,await this.emitEvent("final",{turn:o,step:g,content:b,role:"assistant",meta:{tokens:{prompt:E}}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:b,status:u,errorMessage:p,turnUsage:{...s},steps:r});break}this.options.warnPromptTokens&&E>this.options.warnPromptTokens&&console.warn(`Prompt tokens are near the limit: ${E}`);let _="",T=[],D,J,W;try{let b=await this.deps.callLLM(this.history,q=>this.deps.onAssistantStep?.(q,g),{signal:n.signal}),k=Sc(b);_=k.textContent,T=k.toolUseBlocks,J=k.stopReason,D=k.usage,W=k.reasoningContent,_.trim().length>0&&(h=_,S=g)}catch(b){if(this.cancelling&&yr(b)){u="cancelled",c="",p="Turn cancelled",await this.emitEvent("final",{turn:o,step:g,content:"",role:"assistant",meta:{cancelled:!0}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,errorMessage:p,turnUsage:{...s},steps:r});break}let k=`LLM call failed: ${b.message}`;this.history.push({role:"assistant",content:k}),u="error",c=k,p=k,await this.emitEvent("final",{turn:o,content:k,role:"assistant"}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,errorMessage:p,turnUsage:{...s},steps:r});break}this.deps.onAssistantStep?.(_,g);let j=T.length===0&&_?xc(_,this.deps.tools):null,x,N=null;if(T.length>0){let b=T[0];if(b){let k=_?ur([_]):void 0;x={action:{tool:b.name,input:b.input},thinking:k},N={role:"assistant",content:_,reasoning_content:W,tool_calls:vc(T)}}else x={}}else _?(x={final:_},N={role:"assistant",content:_,reasoning_content:W}):x={};let C=this.tokenCounter.countText(_),B=D?.prompt??E,O=D?.completion??C,me=D?.total??B+O,U={prompt:B,completion:O,total:me};if(hr(s,U),hr(this.sessionUsage,U),r.push({index:g,assistantText:_,parsed:x,tokenUsage:U}),await this.emitEvent("assistant",{turn:o,step:g,content:_,role:"assistant",meta:{tokens:U,protocol_violation:!!j,protocol_violation_count:j?d+1:d||void 0}}),j){d+=1;let b=`Model protocol error: returned plain-text tool JSON for "${j.tool}" ${d} times. Structured tool calls are required.`;u="error",c=b,p=b,this.history.push({role:"assistant",content:b}),await this.emitEvent("final",{turn:o,step:g,content:b,role:"assistant",meta:{error_type:"model_protocol_error",tool:j.tool,protocol_violation:!0,protocol_violation_count:d,tokens:U}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,errorMessage:p,tokenUsage:U,turnUsage:{...s},steps:r});break}if(N&&this.history.push(N),T.length>0&&this.toolsDisabled){for(let b of T)this.history.push({role:"tool",content:yc,tool_call_id:b.id,name:b.name});u="error",c=at,p=at,this.history.push({role:"assistant",content:at}),await this.emitEvent("final",{turn:o,step:g,content:at,role:"assistant",meta:{error_type:"tool_disabled",tool_count:T.length,tools:T.map(b=>b.name).join(","),tokens:U}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:at,status:u,errorMessage:p,tokenUsage:U,turnUsage:{...s},steps:r});break}if(T.length>1){for(let v of T)this.maybeWarnRepeatedAction(v.name,v.input);await this.emitEvent("action",{turn:o,step:g,meta:{tools:T.map(v=>v.name),action_ids:T.map(v=>v.id),action_id:T[0]?.id,parallel:!0,phase:"dispatch",thinking:x.thinking,toolBlocks:T.map(v=>({id:v.id,name:v.name,input:v.input}))}});let b=T[0];b&&await X(this.hooks,"onAction",{sessionId:this.id,turn:o,step:g,action:{tool:b.name,input:b.input},parallelActions:T.map(v=>({tool:v.name,input:v.input})),thinking:x.thinking,history:qe(this.history)});let k=T.every(v=>!!this.deps.tools[v.name]?.supportsParallelToolCalls),q=T.some(v=>!!this.deps.tools[v.name]?.isMutating),oe=k&&!q?"parallel":"sequential",Se=await this.toolOrchestrator.executeActions(T.map(v=>({id:v.id,name:v.name,input:v.input})),{...this.buildToolApprovalHooks(o,g),executionMode:oe,failurePolicy:"fail_fast"}),fe=Ec(T,Se.results,Se.hasRejection);for(let[v,V]of fe.entries())this.history.push(Tr(V)),await this.emitEvent("observation",{turn:o,step:g,content:V.observation,meta:{tool:V.tool,index:v,action_id:V.actionId,phase:"result",status:V.status,error_type:V.errorType,duration_ms:V.durationMs,execution_mode:oe}});let je=fe.map(v=>`[${v.tool}]: ${v.observation}`).join(`
52
94
 
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}
95
+ `),re=fe.map(v=>v.status),_e=re.find(v=>v!==mr)??mr,$e=r[r.length-1];if($e&&($e.observation=je),await X(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:g,tool:T.map(v=>v.name).join(", "),observation:je,resultStatus:_e,parallelResultStatuses:re,history:qe(this.history)}),Se.hasRejection){let v=fe.find(V=>V.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:g,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:v?.actionId,error_type:v?.errorType??"approval_denied",duration_ms:v?.durationMs}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,tokenUsage:U,turnUsage:{...s},steps:r});break}continue}else if(x.action){this.maybeWarnRepeatedAction(x.action.tool,x.action.input);let b=T[0]?.id??`${o}:${g}:single:${x.action.tool}`;await this.emitEvent("action",{turn:o,step:g,meta:{tool:x.action.tool,input:x.action.input,action_id:b,phase:"dispatch",thinking:x.thinking}}),await X(this.hooks,"onAction",{sessionId:this.id,turn:o,step:g,action:x.action,thinking:x.thinking,history:qe(this.history)});let k=await this.executeToolAction(b,x.action.tool,x.action.input,o,g);if(k.rejected){this.history.push(Tr({...k,observation:k.observation||`User denied tool execution: ${x.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:o,step:g,content:c,role:"assistant",meta:{rejected:!0,phase:"result",action_id:k.actionId,error_type:k.errorType??"approval_denied",duration_ms:k.durationMs}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,tokenUsage:U,turnUsage:{...s},steps:r});break}let q=k.observation;this.history.push({role:"tool",content:q,tool_call_id:k.actionId,name:x.action.tool});let oe=r[r.length-1];oe&&(oe.observation=q),await this.emitEvent("observation",{turn:o,step:g,content:q,meta:{tool:x.action.tool,action_id:k.actionId,phase:"result",status:k.status,error_type:k.errorType,duration_ms:k.durationMs}}),await X(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:g,tool:x.action.tool,observation:q,resultStatus:k.status,history:qe(this.history)});continue}if(J==="end_turn"||x.final){this.resetActionRepetition();let b=J==="end_turn"&&!x.final&&_.trim().length===0&&!!h&&S===g-1;c=b?h??"":x.final||_,x.final&&(x.final=c),await this.emitEvent("final",{turn:o,step:g,content:c,role:"assistant",meta:{tokens:U,fallback_from_previous_text:b||void 0}}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:g,finalText:c,status:u,tokenUsage:U,turnUsage:{...s},steps:r});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.",p=c,this.history.push({role:"assistant",content:c}),await this.emitEvent("final",{turn:o,content:c,role:"assistant"}),await X(this.hooks,"onFinal",{sessionId:this.id,turn:o,finalText:c,status:u,errorMessage:p,turnUsage:{...s},steps:r})),await this.emitEvent("turn_end",{turn:o,meta:{status:u,stepCount:r.length,durationMs:Date.now()-i,tokens:s,protocol_violation_count:d||void 0}}),{finalText:c,steps:r,status:u,errorMessage:p,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(o){console.error(`History flush failed: ${o.message}`)}}this.tokenCounter.dispose(),this.toolOrchestrator.dispose(),this.deps.dispose&&await this.deps.dispose()}async emitEvent(t,n){if(!this.sinks.length)return;let o=qn({sessionId:this.id,type:t,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await _c(o,this.sinks)}};async function At(e,t={}){let n=t.sessionId||Sr(),o=await cr(e,{...t,sessionId:n},n),r=await o.loadPrompt(),s=new Sn({...e,...o},{...t,sessionId:n,mode:t.mode??_r},r,o.tokenCounter,o.historyFilePath);return await s.init(),s}import{randomUUID as Fe}from"crypto";import{readFile as Ju}from"fs/promises";import{useCallback as K,useEffect as Tt,useMemo as zt,useReducer as Yu,useRef as qt,useState as Y}from"react";import{Box as is,Text as Zu,useApp as Qu}from"ink";import{memo as Rc,useMemo as Ic}from"react";import{Box as Rr,Static as Oc,Text as Pt}from"ink";import{Box as Re,Text as Z}from"ink";var Me={PENDING:"pending",EXECUTING:"executing",SUCCESS:"success",ERROR:"error"};import Ge from"path";var wc="success",ct=".";function _n(e){return e?e===wc?Me.SUCCESS:Me.ERROR:Me.SUCCESS}function xr(e){if(e?.length)return e.map(t=>_n(t))}function br(e,t){return!t||t<=0||!e||e<=0?0:Math.min(100,e/t*100)}function Cr(e){return e?`tokens: ${e.total} (prompt ${e.prompt} / completion ${e.completion})`:""}function ut(e,t=80){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function Er(e){if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function vn(e,t){let n=e.trim();if(!n)return e;if(n===ct)return ct;if(Ge.isAbsolute(n)){let o=Ge.relative(Ge.resolve(t),n);return o?Ge.normalize(o):ct}if(n.startsWith("./")||n.startsWith("../")){let o=Ge.normalize(n);return!o||o==="."||o==="./"?ct:o}return n}function wr(e){return e?e===ct||Ge.isAbsolute(e)?!0:e.startsWith("./")||e.startsWith("../"):!1}import{Box as Ve,Text as Pe}from"ink";import{marked as Mc}from"marked";import{jsx as ke,jsxs as Ke}from"react/jsx-runtime";function kc(e){let t=[],n=Mc.lexer(e);for(let o of n)switch(o.type){case"heading":{let r=o;t.push({type:"heading",level:r.depth,content:r.text});break}case"paragraph":{let s=o.text;s.startsWith("> ")?t.push({type:"blockquote",content:s.slice(2)}):t.push({type:"paragraph",content:s});break}case"code":{let r=o;t.push({type:"code",language:r.lang,content:r.text});break}case"list":{let r=o,s=r.items.map(i=>i.text);t.push({type:"list",items:s,ordered:r.ordered});break}case"text":{let r=o;t.push({type:"text",content:r.text});break}}return t}function Mr({content:e}){if(!e)return null;let t=kc(e);return ke(Ve,{flexDirection:"column",children:t.map((n,o)=>ke(Ac,{node:n},o))})}function Ac({node:e}){switch(e.type){case"heading":{let t="#".repeat(e.level);return ke(Ve,{children:Ke(Pe,{bold:!0,color:"cyan",children:[t," ",e.content]})})}case"paragraph":case"text":return ke(Pe,{children:e.content});case"code":{let t=e.language?`[${e.language}] `:"";return Ke(Ve,{flexDirection:"column",marginY:1,children:[Ke(Pe,{color:"yellow",dimColor:!0,children:[t,"```"]}),ke(Pe,{color:"gray",children:e.content}),ke(Pe,{color:"yellow",dimColor:!0,children:"```"})]})}case"blockquote":return ke(Ve,{children:Ke(Pe,{color:"gray",dimColor:!0,children:["\u2502 ",e.content]})});case"list":return ke(Ve,{flexDirection:"column",children:e.items.map((t,n)=>Ke(Ve,{children:[ke(Pe,{color:"gray",children:e.ordered?`${n+1}.`:"\u2022"}),Ke(Pe,{children:[" ",t]})]},n))})}}import{jsx as ne,jsxs as de}from"react/jsx-runtime";function kr(e){return e===Me.ERROR?"red":e===Me.EXECUTING?"yellow":"green"}function Ar(e,t){if(e==null)return null;if(typeof e=="string"){let s=wr(e)?vn(e,t):e;return ut(s,70)}if(typeof e!="object"||Array.isArray(e))return ut(String(e),70);let n=e,o=["cmd","path","file_path","dir_path","query","pattern","url","content"],r=new Set(["path","file_path","dir_path"]);for(let s of o){let i=n[s];if(i==null||i==="")continue;let a=String(i),l=r.has(s)?vn(a,t):a;return ut(l,70)}return ut(Er(n),70)}function Pr({message:e}){let t=e.tone==="error"?"red":e.tone==="warning"?"yellow":"cyan";return de(Re,{flexDirection:"column",children:[de(Z,{color:t,children:["\u25CF ",e.title]}),ne(Z,{color:"gray",children:e.content})]})}function Pc({step:e,cwd:t}){let n=!!(e.parallelActions&&e.parallelActions.length>1),o=!n&&e.action?Ar(e.action.input,t):null;return de(Re,{flexDirection:"column",children:[e.thinking?de(Re,{children:[ne(Z,{color:"gray",children:"\u25CF "}),ne(Z,{color:"gray",children:e.thinking})]}):null,n?e.parallelActions?.map((r,s)=>{let i=Ar(r.input,t);return de(Re,{children:[de(Z,{color:kr(e.parallelToolStatuses?.[s]??e.toolStatus),children:["\u25CF"," "]}),ne(Z,{color:"gray",children:"Used "}),ne(Z,{color:"cyan",children:r.tool}),i?de(Z,{color:"gray",children:[" (",i,")"]}):null]},`${r.tool}-${s}`)}):null,!n&&e.action?de(Re,{children:[ne(Z,{color:kr(e.toolStatus),children:"\u25CF "}),ne(Z,{color:"gray",children:"Used "}),ne(Z,{color:"cyan",children:e.action.tool}),o?de(Z,{color:"gray",children:[" (",o,")"]}):null]}):null]})}function xn({turn:e,cwd:t}){return de(Re,{flexDirection:"column",children:[de(Re,{children:[ne(Z,{color:"gray",children:"\u203A "}),ne(Z,{children:e.userInput})]}),e.steps.map(n=>ne(Pc,{step:n,cwd:t},`${e.index}-${n.index}`)),e.finalText?ne(Re,{marginTop:0,children:ne(Mr,{content:e.finalText})}):null,e.status&&e.status!=="ok"?de(Z,{color:"red",children:["Status: ",e.status]}):null,e.errorMessage?ne(Z,{color:"red",children:e.errorMessage}):null]})}import{jsx as pt,jsxs as dt}from"react/jsx-runtime";var Ir=Rc(function({header:t,systemMessages:n,turns:o,historicalTurns:r}){let s=Ic(()=>[...r,...o],[r,o]),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=[{type:"header",data:t}],p=[...n.map(d=>({type:"system",sequence:d.sequence,data:d})),...l.map(d=>({type:"turn",sequence:d.sequence??0,data:d}))].sort((d,h)=>d.sequence-h.sequence);for(let d of p)u.push(d);return dt(Rr,{flexDirection:"column",children:[pt(Oc,{items:u,children:d=>d.type==="header"?dt(Rr,{borderStyle:"round",borderColor:"blue",paddingX:1,flexDirection:"column",children:[pt(Pt,{bold:!0,children:"Memo CLI"}),dt(Pt,{color:"gray",children:[d.data.providerName," / ",d.data.model," \u2022 v",d.data.version]}),dt(Pt,{color:"gray",children:["cwd: ",d.data.cwd]}),dt(Pt,{color:"gray",children:["mcp: ",d.data.mcpNames.join(", ")||"none"]})]},"header"):d.type==="system"?pt(Pr,{message:d.data},d.data.id):pt(xn,{turn:d.data,cwd:t.cwd},`turn-${d.data.index}`)}),c?pt(xn,{turn:c,cwd:t.cwd}):null]})});import{useCallback as Dt,useEffect as bn,useMemo as Br,useRef as Cn,useState as Ie}from"react";import{Box as Ut,Text as Je,useInput as uu}from"ink";var Xe=[8e4,12e4,15e4,2e5],Or=Xe[1],P={HELP:"help",EXIT:"exit",NEW:"new",RESUME:"resume",MODELS:"models",CONTEXT:"context",TOOLS:"tools",MCP:"mcp",INIT:"init"},I={NONE:"none",ONCE:"once",FULL:"full"};function ae(e){return`/${e}`}var Lr="exit";var Rt=[{name:P.HELP,description:"Show command and shortcut help"},{name:P.EXIT,description:"Exit current session"},{name:P.NEW,description:"Start a fresh session"},{name:P.RESUME,description:"List and load session history"},{name:P.MODELS,description:"List or switch configured models"},{name:P.CONTEXT,description:"Set context window (80k/120k/150k/200k)"},{name:P.TOOLS,description:"Set tool permission mode (none/once/full)"},{name:P.MCP,description:"Show configured MCP servers"},{name:P.INIT,description:"Generate AGENTS.md with agent instructions"}],Lc={none:I.NONE,off:I.NONE,disabled:I.NONE,"no-tools":I.NONE,once:I.ONCE,ask:I.ONCE,single:I.ONCE,strict:I.ONCE,full:I.FULL,all:I.FULL,dangerous:I.FULL,"full-access":I.FULL};function $c(e){if(!e)return null;let t=e.trim().toLowerCase();return t?Lc[t]??null:null}function $r(e){return e===I.NONE?"none (no tools)":e===I.ONCE?"once (approval required)":"full (no approval)"}function Nc(){let e=Rt.reduce((n,o)=>Math.max(n,o.name.length),0);return["Available commands:",...Rt.map(n=>` ${ae(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(`
96
+ `)}function Dc(e){if(!e)return null;let n=e.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 Nr(e,t){let[n,...o]=e.trim().slice(1).split(/\s+/);switch((n??"").toLowerCase()){case P.HELP:return{kind:"message",title:"Help",content:Nc()};case P.EXIT:return{kind:"exit"};case P.NEW:return{kind:"new"};case P.RESUME:return{kind:"message",title:"Resume",content:'Type "resume" followed by keywords to load local session history.'};case P.MODELS:{if(!t.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${t.configPath}`};let s=o.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)":"",p=c.base_url?` @ ${c.base_url}`:"";return`- ${c.name}: ${c.model}${p}${u}`});return{kind:"message",title:"Models",content:`${s?`Not found: ${s}
56
97
 
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.
98
+ `:""}${a.join(`
99
+ `)}`}}case P.CONTEXT:{let s=Dc(o[0]),i=Xe.map(a=>`${Math.floor(a/1e3)}k`).join(", ");return s===null?{kind:"message",title:"Context",content:`Current: ${(t.contextLimit/1e3).toFixed(0)}k
100
+ Usage: ${ae(P.CONTEXT)} <length>
101
+ Choices: ${i}`}:Xe.includes(s)?{kind:"set_context_limit",limit:s}:{kind:"message",title:"Context",content:`Unsupported value: ${s}. Choose one of ${i}`}}case P.TOOLS:{let s=o.join(" ").trim(),i=$c(s),a=["none","once","full"].join(", ");return s?i?i===t.toolPermissionMode?{kind:"message",title:"Tools",content:`Already using ${$r(i)}.`}:{kind:"set_tool_permission",mode:i}:{kind:"message",title:"Tools",content:`Unsupported mode: ${s}
102
+ Choose one of: ${a}`}:{kind:"message",title:"Tools",content:`Current: ${$r(t.toolPermissionMode)}
103
+ Usage: ${ae(P.TOOLS)} <mode>
104
+ Modes: ${a}`}}case P.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(`
105
+ `)}}case P.INIT:return{kind:"init_agents_md"};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${e}
106
+ Type ${ae(P.HELP)} for available commands.`}}}import{readdir as Uc}from"fs/promises";import{join as Hc,relative as Fc,sep as jc}from"path";var Bc=6,Wc=2500,Dr=25,zc=new Set([".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs"]),It=new Map;function qc(e){return e.split(jc).join("/")}function Gc(e){return{maxDepth:typeof e.maxDepth=="number"?Math.max(1,e.maxDepth):Bc,maxEntries:typeof e.maxEntries=="number"?Math.max(100,e.maxEntries):Wc,limit:typeof e.limit=="number"?Math.max(1,e.limit):Dr,ignoreGlobs:e.ignoreGlobs?.length?e.ignoreGlobs:[]}}function Kc(e,t){let n=e.split("/").filter(Boolean),o=n[n.length-1]??"";return n.some(r=>zc.has(r))||o.endsWith(".log")?!0:t.ignoreGlobs.length?t.ignoreGlobs.some(r=>{let s=r.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 Vc(e){return JSON.stringify({maxDepth:e.maxDepth,maxEntries:e.maxEntries,ignoreGlobs:e.ignoreGlobs})}async function Xc(e,t){let n=[],o=async(r,s)=>{if(n.length>=t.maxEntries)return;let i;try{i=await Uc(r,{withFileTypes:!0})}catch{return}for(let a of i){if(n.length>=t.maxEntries)break;if(a.isSymbolicLink())continue;let l=Hc(r,a.name),c=Fc(e,l);if(!c)continue;let u=qc(c);if(Kc(u,t))continue;let p=u.split("/").filter(Boolean),d=a.isDirectory();n.push({path:u,pathLower:u.toLowerCase(),segments:p,segmentsLower:p.map(h=>h.toLowerCase()),depth:s,isDir:d}),d&&s<t.maxDepth&&await o(l,s+1)}};return await o(e,0),n.sort((r,s)=>r.path.localeCompare(s.path)),n}async function Jc(e,t){let n=Gc(t),o=Vc(n),r=It.get(e);if(r&&r.signature===o)return r.pending?r.pending:r.entries;let s=Xc(e,n).then(i=>(It.set(e,{entries:i,signature:o}),i)).catch(i=>{throw It.delete(e),i});return It.set(e,{entries:[],signature:o,pending:s}),s}function Yc(e,t){if(!t.length)return e.depth+(e.isDir?-.2:.2);let n=e.depth,o=0;for(let r of t){let s=-1;for(let i=o;i<e.segmentsLower.length;i++){let a=e.segmentsLower[i];if(a.startsWith(r)){s=i,n+=(i-o)*1.2,n+=a.length-r.length;break}let l=a.indexOf(r);if(l!==-1){s=i,n+=(i-o)*2+l+2;break}}if(s===-1)return null;o=s+1}return e.isDir&&(n-=.5),n}function Zc(e,t,n){let r=t.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(i=>i.toLowerCase()),s=[];for(let i of e){let a=Yc(i,r);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 Ur(e){let t=await Jc(e.cwd,e),n=typeof e.limit=="number"?Math.max(1,e.limit):Dr;return Zc(t,e.query,n)}import{readdir as Qc,readFile as eu,stat as tu}from"fs/promises";import{basename as nu,join as Ot,resolve as mt}from"path";function Hr(e){let t=mt(e);return process.platform==="win32"?t.toLowerCase():t}function ou(e,t){return t?Hr(e)===Hr(t):!1}function ru(e){return nu(e).replace(/\.jsonl$/i,"")}function su(e){let t=null,n=null,o=null;for(let r of e.split(`
107
+ `)){let s=r.trim();if(!s)continue;let i;try{i=JSON.parse(s)}catch{continue}if(!(!i||typeof i!="object")){if(i.type==="session_start"&&!o){let a=i.meta?.cwd;typeof a=="string"&&a.trim()&&(o=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:o}}async function iu(e,t,n){try{let o=await eu(e,"utf8"),{firstPrompt:r,sessionTitle:s,sessionCwd:i}=su(o);if(!ou(t,i))return null;let a=s?.trim()||r?.trim()||ru(e);return{id:e,cwd:t,input:a,ts:n,sessionFile:e}}catch{return null}}async function au(e){let t=async s=>{try{return await Qc(s,{withFileTypes:!0})}catch{return[]}},n=(await t(e)).filter(s=>s.isDirectory()&&/^\d{4}$/.test(s.name)),o=[];for(let s of n){let i=Ot(e,s.name),a=(await t(i)).filter(l=>l.isDirectory()&&/^\d{2}$/.test(l.name));for(let l of a){let c=Ot(i,l.name),u=(await t(c)).filter(p=>p.isDirectory()&&/^\d{2}$/.test(p.name));for(let p of u){let d=Ot(c,p.name),h=(await t(d)).filter(S=>S.isFile()&&S.name.endsWith(".jsonl"));for(let S of h)o.push(Ot(d,S.name))}}}return(await Promise.all(o.map(async s=>{try{let i=await tu(s);return{path:s,mtimeMs:i.mtimeMs}}catch{return null}}))).filter(s=>!!s)}async function Fr(e){let t=e.activeSessionFile?mt(e.activeSessionFile):null,o=(await au(e.sessionsDir)).filter(a=>!t||mt(a.path)!==t).filter((a,l,c)=>c.findIndex(u=>mt(u.path)===mt(a.path))===l).sort((a,l)=>l.mtimeMs-a.mtimeMs),r=e.keyword?.trim().toLowerCase(),s=e.limit??10,i=[];for(let a of o){if(i.length>=s)break;let l=await iu(a.path,e.cwd,a.mtimeMs);l&&(r&&!l.input.toLowerCase().includes(r)||i.push(l))}return i}import{Box as Lt,Text as $t}from"ink";import{jsx as Ue,jsxs as cu}from"react/jsx-runtime";var lu="#3a3a3a",Nt="#262626";function jr({items:e,activeIndex:t,loading:n}){return n?Ue(Lt,{paddingX:1,backgroundColor:Nt,children:Ue($t,{color:"gray",children:"Loading..."})}):e.length?Ue(Lt,{flexDirection:"column",backgroundColor:Nt,children:e.map((o,r)=>{let s=r===t;return cu(Lt,{paddingX:1,gap:2,backgroundColor:s?lu:Nt,children:[Ue($t,{color:s?"cyan":"white",bold:s,children:o.title}),o.subtitle?Ue($t,{color:"gray",children:o.subtitle}):null]},o.id)})}):Ue(Lt,{paddingX:1,backgroundColor:Nt,children:Ue($t,{color:"gray",children:"No matches"})})}import{jsx as He,jsxs as Ht}from"react/jsx-runtime";var pu=400,En=ae(P.MODELS),wn=ae(P.CONTEXT),Mn=ae(P.TOOLS),du=ae(P.INIT),mu=[{mode:I.NONE,description:"Disable all tool calls"},{mode:I.ONCE,description:"Require approval when needed"},{mode:I.FULL,description:"Run tools without approval"}];function fu(e){let t=e.lastIndexOf("@");if(t===-1)return null;if(t>0){let o=e[t-1];if(o&&!/\s/.test(o))return null}let n=e.slice(t+1);return/\s/.test(n)?null:{type:"file",query:n,tokenStart:t+1}}function gu(e){let t=e.trimStart(),n=e.length-t.length;if(!t.length)return null;let o=t;if(o.startsWith("/")&&(o=o.slice(1)),!o.toLowerCase().startsWith(P.RESUME)||e.slice(0,n).trim().length>0)return null;let s=o.slice(P.RESUME.length);return s&&!s.startsWith(" ")?null:{type:"history",keyword:s.trim()}}function hu(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 yu(e){let t=e.trimStart();if(!t.startsWith(En))return null;let n=t.slice(En.length);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim().toLowerCase()}}function Tu(e){let t=e.trimStart();if(!t.startsWith(wn))return null;let n=t.slice(wn.length);return n&&!n.startsWith(" ")?null:{type:"context"}}function Su(e){let t=e.trimStart();if(!t.startsWith(Mn))return null;let n=t.slice(Mn.length);return n&&!n.startsWith(" ")?null:{type:"tools"}}function _u(e){return Su(e)??Tu(e)??yu(e)??hu(e)??fu(e)??gu(e)}function vu(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let n=String(t.getFullYear()),o=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${n}-${o}-${r} ${s}:${i}`}function xu(e,t){return{mode:"model",items:e.filter(o=>{if(!t)return!0;let r=o.name.toLowerCase(),s=o.model.toLowerCase();return r.includes(t)||s.includes(t)}).map(o=>({id:o.name,title:`${o.name}: ${o.model}`,subtitle:o.base_url,kind:"model",value:`${En} ${o.name}`,meta:{type:"model",provider:o}}))}}function bu(e){return{mode:"context",items:Xe.map(n=>({id:`${n}`,title:`${Math.floor(n/1e3)}k tokens`,subtitle:n===e?"Current":void 0,kind:"context",value:`${wn} ${Math.floor(n/1e3)}k`,meta:{type:"context",value:n}}))}}function Cu(e){return{mode:"tools",items:mu.map(n=>({id:n.mode,title:n.mode,subtitle:n.mode===e?`Current \xB7 ${n.description}`:n.description,kind:"tools",value:`${Mn} ${n.mode}`,meta:{type:"tools",mode:n.mode}}))}}function Eu(e){return{mode:"slash",items:Rt.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 wu({trigger:e,cwd:t,sessionsDir:n,currentSessionFile:o,providers:r,contextLimit:s,toolPermissionMode:i}){switch(e.type){case"file":return{mode:"file",items:(await Ur({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 Fr({sessionsDir:n,cwd:t,keyword:e.keyword,activeSessionFile:o})).map(c=>({id:c.id,title:c.input,subtitle:vu(c.ts),kind:"history",value:c.input,meta:{type:"history",entry:c}}))};case"models":return xu(r,e.keyword);case"context":return bu(s);case"tools":return Cu(i);case"slash":return Eu(e.keyword)}}function Wr({disabled:e,busy:t,history:n,cwd:o,sessionsDir:r,currentSessionFile:s,providers:i,configPath:a,providerName:l,model:c,contextLimit:u,toolPermissionMode:p,mcpServers:d,onSubmit:h,onExit:S,onClear:g,onNewSession:E,onCancelRun:_,onHistorySelect:T,onModelSelect:D,onSetContextLimit:J,onSetToolPermission:W,onSystemMessage:j}){let[x,N]=Ie(""),C=Cn(""),[B,O]=Ie(null),[me,U]=Ie(""),[b,k]=Ie("none"),[q,oe]=Ie([]),[Se,fe]=Ie(0),[je,re]=Ie(!1),[_e,$e]=Ie(!1),v=Cn(0),V=Cn(0);bn(()=>{C.current=x,$e(!1)},[x]);let Gt=Br(()=>({configPath:a,providerName:l,model:c,mcpServers:d,providers:i,contextLimit:u,toolPermissionMode:p}),[a,l,c,d,i,u,p]),ge=Br(()=>e||_e?null:_u(x),[e,_e,x]),z=Dt((w=!0)=>{w&&$e(!0),k("none"),oe([]),fe(0),re(!1)},[]),xe=Dt(w=>{C.current=w,N(w),O(null),U("")},[]),G=Dt(()=>{xe("")},[xe]);bn(()=>{e&&z(!1)},[e,z]),bn(()=>{if(!ge){z(!1);return}let w=!1,H=++v.current;return re(!0),(async()=>{try{let{mode:te,items:se}=await wu({trigger:ge,cwd:o,sessionsDir:r,currentSessionFile:s,providers:i,contextLimit:u,toolPermissionMode:p});if(w||H!==v.current)return;k(te),oe(se),fe(L=>se.length?Math.min(L,se.length-1):0)}finally{!w&&H===v.current&&re(!1)}})(),()=>{w=!0}},[ge,o,r,s,i,u,p,z]);let Qe=Dt(w=>{if(w){if(b==="file"&&ge?.type==="file"){let H=x.slice(0,ge.tokenStart),te=x.slice(ge.tokenStart+ge.query.length),se=`${H}${w.value}${te}`;xe(se),w.meta?.type==="file"&&w.meta.isDir||z();return}switch(w.meta?.type){case"history":T(w.meta.entry),xe(w.value),z();return;case"model":D(w.meta.provider),G(),z();return;case"context":J(w.meta.value),G(),z();return;case"tools":W(w.meta.mode),G(),z();return;case"slash":xe(`${w.value} `),z(!1);return;default:xe(w.value),z()}}},[b,ge,x,z,xe,G,T,D,J,W]);uu((w,H)=>{if(H.ctrl&&w==="c"){S();return}if(H.ctrl&&w==="l"){C.current="",N(""),O(null),U(""),z(),g(),E();return}let te=b!=="none",se=te&&q.length>0;if(H.escape){let L=Date.now();if(L-V.current<=pu){V.current=0,t?_():(C.current="",N(""),O(null),U(""),z());return}V.current=L,te&&z();return}if(!e){if(H.upArrow){if(se){fe($=>$<=0?q.length-1:$-1);return}if(!n.length)return;if(B===null){U(C.current);let $=n.length-1;O($);let R=n[$]??"";C.current=R,N(R);return}let L=Math.max(0,B-1);O(L);let F=n[L]??"";C.current=F,N(F);return}if(H.downArrow){if(se){fe($=>($+1)%q.length);return}if(B===null)return;let L=B+1;if(L>=n.length){O(null),C.current=me,N(me),U("");return}O(L);let F=n[L]??"";C.current=F,N(F);return}if(H.tab&&se){Qe(q[Se]);return}if(H.return){if(se){Qe(q[Se]);return}if(H.shift){let F=`${C.current}
108
+ `;C.current=F,N(F);return}let L=C.current.trim();if(!L)return;if(L.startsWith("/")){let F=Nr(L,Gt);F.kind==="message"?j(F.title,F.content):F.kind==="new"?E():F.kind==="exit"?S():F.kind==="switch_model"?D(F.provider):F.kind==="set_context_limit"?J(F.limit):F.kind==="set_tool_permission"?W(F.mode):F.kind==="init_agents_md"&&h(du),C.current="",N(""),O(null),U(""),z(!1);return}h(L),C.current="",N(""),O(null),U(""),z(!1);return}if(H.backspace||H.delete){let L=C.current.slice(0,Math.max(0,C.current.length-1));C.current=L,N(L);return}if(w){let L=`${C.current}${w}`;C.current=L,N(L),w.includes(`
109
+ `)&&z(!1)}}});let he=x.split(`
110
+ `);return Ht(Ut,{flexDirection:"column",gap:1,children:[Ht(Ut,{flexDirection:"column",paddingY:1,children:[Ht(Ut,{children:[He(Je,{color:"gray",children:"\u203A "}),He(Je,{children:he[0]??""}),!e&&he.length===1?He(Je,{color:"cyan",children:"\u258A"}):null]}),he.slice(1).map((w,H)=>Ht(Ut,{children:[He(Je,{color:"gray",children:" "}),He(Je,{children:w}),H===he.length-2&&!e&&w===""?He(Je,{color:"cyan",children:"\u258A"}):null]},`line-${H}`))]}),b!=="none"?He(jr,{items:q.map(({value:w,meta:H,...te})=>te),activeIndex:Se,loading:je}):null]})}import{Box as Mu,Text as zr}from"ink";import{jsx as ku,jsxs as qr}from"react/jsx-runtime";function Gr({busy:e,contextPercent:t,tokenLine:n}){let o=`${t.toFixed(1)}%`;return qr(Mu,{justifyContent:"space-between",children:[ku(zr,{color:"gray",children:e?"Working... Esc Esc to interrupt":"Enter send \u2022 Shift+Enter newline \u2022 /help"}),qr(zr,{color:"gray",children:[n?`${n} \u2022 `:"","context: ",o]})]})}import{useState as Au}from"react";import{Box as Kr,Text as Ft,useInput as Pu}from"ink";import{jsx as kn,jsxs as An}from"react/jsx-runtime";var Ru=[{label:"Allow once",decision:"once"},{label:"Allow for this session",decision:"session"},{label:"Deny",decision:"deny"}];function Iu(e){if(!e)return"";if(typeof e!="object")return String(e);let t=Object.entries(e);if(!t.length)return"";let[n,o]=t[0]??[];if(!n)return"";let r=typeof o=="string"?o:JSON.stringify(o);return`${n}=${r?.slice(0,60)??""}${r&&r.length>60?"...":""}`}function Vr({request:e,onDecision:t}){let[n,o]=Au(0),r=Ru;Pu((i,a)=>{if(a.upArrow){o(l=>l<=0?r.length-1:l-1);return}if(a.downArrow){o(l=>(l+1)%r.length);return}if(a.return){let l=r[n];l&&t(l.decision);return}(a.escape||a.ctrl&&i==="c")&&t("deny")});let s=Iu(e.params);return An(Kr,{flexDirection:"column",borderStyle:"single",borderColor:"yellow",paddingX:1,children:[kn(Ft,{bold:!0,color:"yellow",children:"Tool Approval Required"}),An(Ft,{children:[e.toolName,s?` (${s})`:""]}),kn(Ft,{color:"gray",children:e.reason}),kn(Kr,{marginTop:1,flexDirection:"column",children:r.map((i,a)=>An(Ft,{color:n===a?"green":"gray",children:[n===a?"> ":" ",i.label]},i.decision))})]})}import{useMemo as Xr,useState as Pn}from"react";import{Box as Rn,Text as Ye,useInput as Ou}from"ink";import{jsx as jt,jsxs as ft}from"react/jsx-runtime";function Lu(e,t){let n=new Set(e);return t.filter(o=>n.has(o))}function Jr({serverNames:e,defaultSelected:t,onConfirm:n,onExit:o}){let r=Xr(()=>{let h=Lu(e,t);return t.length===0?[]:h.length>0?h:[...e]},[t,e]),[s,i]=Pn(r),[a,l]=Pn(0),[c,u]=Pn(!0),p=Xr(()=>new Set(s),[s]),d=s.length===e.length;return Ou((h,S)=>{if(S.ctrl&&h==="c"){o();return}if(S.upArrow){l(g=>g<=0?e.length-1:g-1);return}if(S.downArrow){l(g=>(g+1)%e.length);return}if(S.return){n(s,c);return}if(h===" "){let g=e[a];if(!g)return;i(E=>{let _=new Set(E);return _.has(g)?_.delete(g):_.add(g),e.filter(T=>_.has(T))});return}if(h.toLowerCase()==="a"){i([...e]);return}if(h.toLowerCase()==="n"){i([]);return}if(h.toLowerCase()==="p"){u(g=>!g);return}S.escape&&n(s,c)}),ft(Rn,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[jt(Ye,{bold:!0,color:"cyan",children:"Activate MCP Servers"}),jt(Ye,{color:"gray",children:"Select servers to load for this run."}),jt(Rn,{marginTop:1,flexDirection:"column",children:e.map((h,S)=>{let g=p.has(h);return ft(Ye,{color:S===a?"green":"gray",children:[S===a?"> ":" ","[",g?"x":" ","] ",h]},h)})}),ft(Rn,{marginTop:1,flexDirection:"column",children:[ft(Ye,{color:"gray",children:["Selected: ",s.length,"/",e.length,d?" (all)":""]}),ft(Ye,{color:"gray",children:["Persist as default: ",c?"yes":"no"]}),jt(Ye,{color:"gray",children:"Controls: \u2191/\u2193 move, Space toggle, A all, N none, P persist, Enter confirm"})]})]})}import{Box as gt,Text as Te,useInput as $u}from"ink";import{useCallback as Yr,useMemo as Nu,useState as ht}from"react";import{jsx as ve,jsxs as Ze}from"react/jsx-runtime";var Oe=[{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 Zr({configPath:e,onComplete:t,onExit:n}){let[o,r]=ht(0),[s,i]=ht(""),[a,l]=ht({}),[c,u]=ht(!1),[p,d]=ht(null),h=Oe[o]??Oe[0],S=Yr(async _=>{u(!0),d(null);try{let T={current_provider:_.name,providers:[{name:_.name,env_api_key:_.envKey,model:_.model,base_url:_.baseUrl||void 0}]};await pe(e,T),t()}catch(T){d(T.message),u(!1)}},[e,t]),g=Yr(async()=>{if(!h)return;let _=s.trim()||h.defaultValue,T={...a,[h.key]:_};if(l(T),i(""),o<Oe.length-1){r(o+1);return}let D={name:T.name||Oe[0].defaultValue,envKey:T.envKey||Oe[1].defaultValue,model:T.model||Oe[2].defaultValue,baseUrl:T.baseUrl||Oe[3].defaultValue};await S(D)},[s,S,h,o,a]);$u((_,T)=>{if(!c){if(T.ctrl&&_==="c"){n();return}if(T.return){g();return}if(T.backspace||T.delete){i(D=>D.slice(0,-1));return}_&&i(D=>D+_)}});let E=Nu(()=>`Step ${o+1}/${Oe.length}`,[o]);return h?Ze(gt,{flexDirection:"column",children:[ve(Te,{bold:!0,children:"Memo setup"}),ve(Te,{color:"gray",children:"No provider config found. Complete setup to continue."}),Ze(Te,{color:"gray",children:["Config path: ",e]}),Ze(gt,{marginTop:1,flexDirection:"column",children:[ve(Te,{color:"cyan",children:E}),ve(Te,{children:h.label}),Ze(Te,{color:"gray",children:["Default: ",h.defaultValue]}),h.hint?ve(Te,{color:"gray",children:h.hint}):null]}),Ze(gt,{marginTop:1,children:[ve(Te,{children:"> "}),ve(Te,{children:s})]}),ve(gt,{marginTop:1,children:ve(Te,{color:"gray",children:"Enter to continue, Ctrl+C to exit."})}),p?ve(gt,{marginTop:1,children:Ze(Te,{color:"red",children:["Failed to save config: ",p]})}):null]}):null}function Qr(e){let t=[],n=[],o=[],r=e.split(`
111
+ `).map(l=>l.trim()).filter(Boolean),s=null,i=0,a=0;for(let l of r){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}),o.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}),o.push(`Assistant: ${u}`),s)){let p={index:s.steps.length,assistantText:u};s.steps=[...s.steps,p],s.finalText=u}continue}if(c.type==="action"&&s){let u=c.meta;if(u&&typeof u=="object"){let p=typeof u.tool=="string"?u.tool:"",d=u.input,h=typeof u.thinking=="string"?u.thinking:"",g=(Array.isArray(u.toolBlocks)?u.toolBlocks:[]).map(_=>{let T=typeof _?.name=="string"?_.name:"";return T?{tool:T,input:_?.input}:null}).filter(Boolean),E=s.steps[s.steps.length-1];E&&(g.length>1?(E.action=g[0],E.parallelActions=g):p&&(E.action={tool:p,input:d}),h&&(E.thinking=h))}continue}if(c.type==="observation"&&s){let u=typeof c.content=="string"?c.content:"",p=s.steps[s.steps.length-1];p&&(p.observation=u);continue}}}return{summary:o.join(`
112
+ `),messages:t,turns:n,maxSequence:a}}function On(){return{turns:[],historicalTurns:[],systemMessages:[],sequence:0}}function Du(e,t){return{index:e,userInput:"",steps:[],sequence:t}}function In(e,t){let n=e.slice();for(;n.length<=t;)n.push({index:n.length,assistantText:""});return n}function yt(e,t,n){let o=e.turns.slice(),r=o.findIndex(i=>i.index===t);if(r===-1){let i=e.sequence+1;return o.push(n(Du(t,i))),{turns:o,sequence:i}}let s=o[r];return s?(o[r]=n(s),{turns:o,sequence:e.sequence}):{turns:o,sequence:e.sequence}}function Uu(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 es(e,t){switch(t.type){case"append_system_message":{let n=e.sequence+1;return{...e,sequence:n,systemMessages:[...e.systemMessages,Uu({title:t.title,content:t.content,tone:t.tone,sequence:n})]}}case"turn_start":{let n=yt(e,t.turn,o=>({...o,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??o.contextPromptTokens}));return{...e,turns:n.turns,sequence:n.sequence}}case"assistant_chunk":{let n=yt(e,t.turn,o=>{let r=In(o.steps,t.step),s=r[t.step];return s?(r[t.step]={...s,assistantText:`${s.assistantText}${t.chunk}`},{...o,steps:r}):o});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_action":{let n=yt(e,t.turn,o=>{let r=In(o.steps,t.step),s=r[t.step];return s?(r[t.step]={...s,action:t.action,thinking:t.thinking,parallelActions:t.parallelActions&&t.parallelActions.length>1?t.parallelActions:void 0,toolStatus:Me.EXECUTING},{...o,steps:r}):o});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_observation":{let n=yt(e,t.turn,o=>{let r=In(o.steps,t.step),s=r[t.step];return s?(r[t.step]={...s,observation:t.observation,toolStatus:t.toolStatus,parallelToolStatuses:t.parallelToolStatuses},{...o,steps:r}):o});return{...e,turns:n.turns,sequence:n.sequence}}case"turn_final":{let n=yt(e,t.turn,o=>{let r=o.startedAt??Date.now(),s=Math.max(0,Date.now()-r),i=t.tokenUsage?.prompt??o.contextPromptTokens;return{...o,finalText:t.finalText,status:t.status,errorMessage:t.errorMessage,tokenUsage:t.turnUsage,contextPromptTokens:i,startedAt:r,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 On();default:return e}}import{dirname as Bt,join as ns,resolve as Hu}from"path";import{statSync as Fu,existsSync as os,readFileSync as ju}from"fs";import{readFile as Bu}from"fs/promises";import{get as Wu}from"https";import{fileURLToPath as zu}from"url";function ts(e){let t=e.trim().replace(/^v/i,""),[n="",o]=t.split("-",2),r=n.split(".").map(s=>Number(s));return r.length<3||r.some(s=>!Number.isFinite(s))?null:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,prerelease:o??null}}function qu(e,t){let n=ts(e),o=ts(t);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 rs(){try{let t=zu(import.meta.url);return Bt(t)}catch{}let e=Hu(process.argv[1]??process.cwd());try{return Fu(e).isFile()?Bt(e):e}catch{return process.cwd()}}async function Gu(e){let t=ns(e,"package.json");if(!os(t))return null;let n=await Bu(t,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}function Ku(e){let t=ns(e,"package.json");if(!os(t))return null;try{let n=ju(t,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}catch{return null}}async function Vu(){let e=rs();for(;;){let t=await Gu(e);if(t&&t.name==="@memo-code/memo")return t;let n=Bt(e);if(n===e)break;e=n}return null}function Wt(){let e=rs();for(;;){let t=Ku(e);if(t&&t.name==="@memo-code/memo")return t;let n=Bt(e);if(n===e)break;e=n}return null}async function Xu(e,t=1500){let o=`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`;return new Promise(r=>{let s=Wu(o,{timeout:t},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),r(null);return}let a=[];i.on("data",l=>a.push(l)),i.on("end",()=>{try{let l=JSON.parse(Buffer.concat(a).toString("utf8"));r(l.version??null)}catch{r(null)}})});s.on("timeout",()=>{s.destroy(),r(null)}),s.on("error",()=>r(null))})}async function ss(){let e=await Vu();if(!e)return null;let t=await Xu(e.name);return!t||!qu(t,e.version)?null:{current:e.version,latest:t}}import{jsx as Le,jsxs as np}from"react/jsx-runtime";function ep(e,t){if(e.length===0)return[];if(t===void 0)return[...e];if(t.length===0)return[];let n=new Set(e),o=t.filter(r=>n.has(r));return o.length>0?o:[...e]}function tp(e,t){if(e.length===0)return[];if(t.length===0)return[];let n=new Set(e);return t.filter(o=>n.has(o))}function as({sessionOptions:e,providerName:t,model:n,configPath:o,mcpServers:r,cwd:s,sessionsDir:i,providers:a,dangerous:l=!1,needsSetup:c=!1}){let{exit:u}=Qu(),p=zt(()=>Object.keys(r??{}).sort(),[r]),d=zt(()=>ep(p,e.activeMcpServers),[p,e.activeMcpServers]),h=e.toolPermissionMode??(l?I.FULL:I.ONCE),[S,g]=Yu(es,void 0,On),[E,_]=Y(t),[T,D]=Y(n),[J,W]=Y(a),[j,x]=Y(h),[N,C]=Y({...e,providerName:t,dangerous:h===I.FULL,toolPermissionMode:h}),[B,O]=Y(!1),[me,U]=Y([]),[b,k]=Y(null),[q,oe]=Y(null),[Se,fe]=Y(e.maxPromptTokens??Or),[je,re]=Y(0),[_e,$e]=Y(c),[v,V]=Y(!c&&p.length>0),[Gt,ge]=Y(d),[z,xe]=Y(null),[G,Qe]=Y(null),he=qt(null),w=qt(null),H=qt(null),[te,se]=Y(null),L=qt(null),F=zt(()=>Wt(),[]),$=K(f=>{g(f)},[]);Tt(()=>{_e||(ge(d),V(p.length>0))},[_e,d,p.length]);let R=K((f,y,M="info")=>{$({type:"append_system_message",title:f,content:y,tone:M})},[$]),Nn=zt(()=>({onAssistantStep:(f,y)=>{let M=w.current;M&&$({type:"assistant_chunk",turn:M,step:y,chunk:f})},requestApproval:j===I.FULL||j===I.NONE?void 0:f=>new Promise(y=>{se(f),L.current=y}),hooks:{onTurnStart:({turn:f,input:y,promptTokens:M})=>{w.current=f;let le=H.current;le&&(H.current=null);let Ne=le??y;M&&M>0&&re(M),$({type:"turn_start",turn:f,input:Ne,promptTokens:M})},onAction:({turn:f,step:y,action:M,thinking:le,parallelActions:Ne})=>{$({type:"tool_action",turn:f,step:y,action:M,thinking:le,parallelActions:Ne})},onObservation:({turn:f,step:y,observation:M,resultStatus:le,parallelResultStatuses:Ne})=>{$({type:"tool_observation",turn:f,step:y,observation:M,toolStatus:_n(le),parallelToolStatuses:xr(Ne)})},onFinal:({turn:f,finalText:y,status:M,errorMessage:le,turnUsage:Ne,tokenUsage:Es})=>{$({type:"turn_final",turn:f,finalText:y,status:M,errorMessage:le,turnUsage:Ne,tokenUsage:Es}),O(!1)}}}),[$,j]);Tt(()=>{let f=!1;return(async()=>{if(_e||v)return;let y=he.current;y&&await y.close();let M=await At(Nn,N);if(f){await M.close();return}he.current=M,Qe(M),k(M.historyFilePath??null)})(),()=>{f=!0}},[Nn,v,N,_e]),Tt(()=>{let f=!1;return(async()=>{let y=await ss();f||!y||R("Update",`Update available: v${y.latest}. Run: npm install -g @memo-code/memo@latest`)})(),()=>{f=!0}},[R]),Tt(()=>()=>{he.current&&he.current.close()},[]);let et=K(async()=>{he.current&&await he.current.close(),xe("Bye!"),setTimeout(()=>u(),250)},[u]),ds=K(()=>{$({type:"clear_current_timeline"}),oe(null),re(0)},[$]),ms=K(()=>{$({type:"reset_all"}),oe(null),re(0),w.current=null,C(f=>({...f,sessionId:Fe()})),R("New Session","Started a fresh session.")},[R,$]),Dn=K(async f=>{try{let y=await ee();await pe(y.configPath,{...y.config,current_provider:f})}catch(y){R("Config",`Failed to persist provider: ${y.message}`,"warning")}},[R]),fs=K(async f=>{if(B){R("Model switch","Cancel current run before switching models.","warning");return}if(f.name===E&&f.model===T){R("Model switch",`Already using ${f.name} (${f.model}).`);return}$({type:"reset_all"}),re(0),w.current=null,_(f.name),D(f.model),C(y=>({...y,sessionId:Fe(),providerName:f.name})),await Dn(f.name),R("Model switch",`Switched to ${f.name} (${f.model}).`)},[R,B,T,E,$,Dn]),Un=K(async f=>{try{let y=await ee();await pe(y.configPath,{...y.config,max_prompt_tokens:f})}catch(y){R("Context",`Failed to persist context limit: ${y.message}`,"warning")}},[R]),gs=K(f=>{fe(f),re(0),C(y=>({...y,maxPromptTokens:f,sessionId:Fe()})),R("Context",`Context window set to ${Math.floor(f/1e3)}k.`),Un(f)},[R,Un]),Kt=K(f=>f===I.NONE?"none (no tools)":f===I.ONCE?"once (approval required)":"full (no approval)",[]),hs=K(f=>{if(B){R("Tools","Cancel current run before changing tool permission mode.","warning");return}if(te){R("Tools","Resolve current approval request before changing tool permission mode.","warning");return}if(f===j){R("Tools",`Already using ${Kt(f)}.`);return}x(f),C(y=>({...y,sessionId:Fe(),dangerous:f===I.FULL,toolPermissionMode:f})),R("Tools",`Tool permission set to ${Kt(f)}.`)},[R,B,te,Kt,j]),Hn=K(async f=>{try{let y=await ee();await pe(y.configPath,{...y.config,active_mcp_servers:f})}catch(y){R("MCP",`Failed to persist active MCP servers: ${y.message}`,"warning")}},[R]),ys=K((f,y)=>{let M=tp(p,f);ge(M),V(!1),C(le=>({...le,sessionId:Fe(),activeMcpServers:M})),y&&Hn(M)},[p,Hn]),Ts=K(async f=>{try{let y=await Ju(f.sessionFile,"utf8"),M=Qr(y);$({type:"clear_current_timeline"}),$({type:"replace_history",turns:M.turns,maxSequence:M.maxSequence}),oe(M.messages),O(!1),Qe(null),k(null),re(0),w.current=null,C(le=>({...le,sessionId:Fe()})),R("History",M.summary||f.input)}catch(y){R("History",`Failed to load ${f.sessionFile}: ${y.message}`,"error")}},[R,$]),Ss=K(()=>{B&&G?.cancelCurrentTurn?.()},[B,G]),Fn=K(async()=>{if(!G||B)return;let f=`Please analyze the current project and create an AGENTS.md file at the project root.
68
113
 
69
114
  The AGENTS.md should include:
70
115
  1. Project name and brief description
@@ -80,7 +125,7 @@ Steps:
80
125
  3. Understand stack and conventions
81
126
  4. Create AGENTS.md using apply_patch
82
127
 
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=`
128
+ Keep the result concise and actionable.`,y=ae(P.INIT);U(M=>[...M,y]),O(!0);try{H.current=y,await G.runTurn(f)}catch{O(!1)}},[B,G]),_s=K(async f=>{let y=f.trim();if(y){if(y.toLowerCase()===Lr){await et();return}if(y===ae(P.INIT)){await Fn();return}if(!(!G||B)){U(M=>[...M,y]),O(!0);try{await G.runTurn(y)}catch{O(!1)}}}},[B,et,Fn,G]),vs=K(async()=>{try{let f=await ee(),y=De(f.config);W(f.config.providers),_(y.name),D(y.model),C(M=>({...M,sessionId:Fe(),providerName:y.name})),$e(!1),R("Setup",`Config saved to ${f.configPath}`)}catch(f){R("Setup",`Failed to reload config: ${f.message}`,"error")}},[R]);Tt(()=>{if(!G||!q?.length)return;let f=G.history[0];f&&(G.history.splice(0,G.history.length,f,...q),oe(null))},[q,G]);let xs=K(f=>{let y=L.current;y&&(y(f),L.current=null),se(null)},[]),bs=Cr(S.turns[S.turns.length-1]?.tokenUsage),Cs=br(je,Se);return z?Le(is,{children:Le(Zu,{color:"green",children:z})}):_e?Le(Zr,{configPath:o,onComplete:vs,onExit:et}):v?Le(Jr,{serverNames:p,defaultSelected:d,onConfirm:ys,onExit:()=>{et()}}):np(is,{flexDirection:"column",children:[Le(Ir,{header:{providerName:E,model:T,cwd:s,sessionId:N.sessionId??"unknown",mcpNames:Gt,version:F?.version??"unknown"},systemMessages:S.systemMessages,turns:S.turns,historicalTurns:S.historicalTurns}),Le(Wr,{disabled:!G||!!te,busy:B,history:me,cwd:s,sessionsDir:i,currentSessionFile:b??void 0,providers:J,configPath:o,providerName:E,model:T,contextLimit:Se,toolPermissionMode:j,mcpServers:r,onSubmit:f=>{_s(f)},onExit:()=>{et()},onClear:ds,onNewSession:ms,onCancelRun:Ss,onHistorySelect:f=>{Ts(f)},onModelSelect:f=>{fs(f)},onSetContextLimit:gs,onSetToolPermission:hs,onSystemMessage:R}),te?Le(Vr,{request:te,onDecision:xs}):null,Le(Gr,{busy:B,contextPercent:Cs,tokenLine:bs})]})}var op=`
84
129
  Usage:
85
130
  memo mcp list [--json]
86
131
  memo mcp get <name> [--json]
@@ -89,14 +134,14 @@ Usage:
89
134
  memo mcp remove <name>
90
135
  memo mcp login <name> [--scopes scope1,scope2]
91
136
  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()})}
137
+ `;function Ln(){console.log(op.trim())}function rp(e){let t=e.indexOf("=");if(t<=0)return null;let n=e.slice(0,t).trim(),o=e.slice(t+1);return n?{key:n,value:o}:null}function ls(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 o=t.http_headers??t.headers;o&&Object.keys(o).length>0&&n.push(` headers: ${Object.entries(o).map(([r,s])=>`${r}=${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(([o,r])=>`${o}=${r}`).join(", ")}`);return n.join(`
138
+ `)}function sp(e){let t=e.shift();if(!t)return{error:"Missing server name."};let n,o,r={},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."};o=l,i+=1;continue}if(a==="--env"){let l=e[i+1];if(!l)return{error:"Missing value for --env (KEY=VALUE)."};let c=rp(l);if(!c)return{error:"Invalid --env format. Use KEY=VALUE."};r[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(r).length>0?{error:"--env is only supported with stdio servers."}:{options:{name:t,url:n,bearerTokenEnvVar:o}}:o?{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(r).length>0?r:void 0}}}function ip(e){let[t,...n]=e;return!t||t==="--help"||t==="-h"||t==="help"?{command:"help",rest:[]}:{command:t,rest:n}}function $n(e,t=[]){let n=new Set(t);for(let o=0;o<e.length;o+=1){let r=e[o];if(r){if(r.startsWith("--")){n.has(r)&&(o+=1);continue}return r}}return null}async function cs(e){let{command:t,rest:n}=ip(e);if(t==="help"){Ln();return}if(t==="list"){let o=n.includes("--json"),s=(await ee()).config.mcp_servers??{};if(o){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(ls(a,l))}return}if(t==="get"){let o=n.includes("--json"),r=$n(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let i=(await ee()).config.mcp_servers?.[r];if(!i){console.error(`Unknown MCP server "${r}".`),process.exitCode=1;return}if(o){console.log(JSON.stringify(i,null,2));return}console.log(ls(r,i));return}if(t==="add"){let o=sp(n);if(o.error!==void 0){o.error&&(console.error(o.error),process.exitCode=1),Ln();return}let r=o.options;if(!r)return;if(r.url)try{new URL(r.url)}catch{console.error("Invalid URL."),process.exitCode=1;return}let s=await ee(),i={...s.config.mcp_servers??{}};if(i[r.name]){console.error(`MCP server "${r.name}" already exists.`),process.exitCode=1;return}let a;r.url?a={type:"streamable_http",url:r.url,...r.bearerTokenEnvVar?{bearer_token_env_var:r.bearerTokenEnvVar}:{}}:a={command:r.command,args:r.args&&r.args.length>0?r.args:void 0,env:r.env},i[r.name]=a,await pe(s.configPath,{...s.config,mcp_servers:i}),console.log(`Added MCP server "${r.name}".`);return}if(t==="remove"){let o=$n(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let r=await ee(),s={...r.config.mcp_servers??{}};if(!s[o]){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}delete s[o],await pe(r.configPath,{...r.config,mcp_servers:s}),console.log(`Removed MCP server "${o}".`);return}if(t==="login"||t==="logout"){let o=$n(n,["--scopes"]);if(!o){console.error("Missing server name."),process.exitCode=1;return}let s=(await ee()).config.mcp_servers?.[o];if(!s){console.error(`Unknown MCP server "${o}".`),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}`),Ln(),process.exitCode=1}import{jsx as hp}from"react/jsx-runtime";function pp(e){let t={dangerous:!1,showVersion:!1,removedOnceFlag:!1},n=[];for(let o=0;o<e.length;o++){let r=e[o];if(r!==void 0){if(r==="--version"||r==="-v"){t.showVersion=!0;continue}if(r==="--once"){t.removedOnceFlag=!0;continue}if(r==="--dangerous"||r==="-d"){t.dangerous=!0;continue}n.push(r)}}return{question:n.join(" "),options:t}}async function ps(e){let t=await ee();if(!t.needsSetup)return t;let n=t.config.providers[0],r=[n?.env_api_key,"OPENAI_API_KEY","DEEPSEEK_API_KEY"].filter(Boolean).some(a=>!!process.env[a]);if(n&&r)return await pe(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=ap({input:lp,output:cp}),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"),p={current_provider:a,providers:[{name:a,env_api_key:l,model:c,base_url:u||void 0}]};return await pe(t.configPath,p),console.log(`Config written to ${t.configPath}
139
+ `),{...t,config:p,needsSetup:!1}}finally{s.close()}}async function dp(e){let t=await ps("plain"),n=De(t.config),r={sessionId:us(),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(`
140
+ [approval required] ${l.toolName}: ${l.reason}`),console.log("[approval] Run with --dangerous to bypass approval"),Promise.resolve("deny")),hooks:{onAction:({action:l})=>{console.log(`
141
+ [tool] ${l.tool}`),l.input!==void 0&&console.log(`[input] ${JSON.stringify(l.input)}`)},onObservation:()=>{}}},i=await At(s,r),a=e.question;if(!a&&!process.stdin.isTTY&&(a=await gp()),!a){console.error("No input provided. Pass a question or use stdin."),await i.close();return}try{console.log(`User: ${a}
142
+ `);let l=await i.runTurn(a);console.log(`
143
+ ${l.finalText}`),console.log(`
144
+ [tokens] prompt=${l.tokenUsage.prompt} completion=${l.tokenUsage.completion} total=${l.tokenUsage.total}`),console.log(`
145
+ provider=${n.name} model=${n.model}`)}catch(l){console.error(`Run failed: ${l.message}`)}finally{await i.close()}}async function mp(e){let t=await ps("tui"),n=De(t.config),r={sessionId:us(),mode:"interactive",maxPromptTokens:t.config.max_prompt_tokens,activeMcpServers:t.config.active_mcp_servers,generateSessionTitle:!0,dangerous:e.options.dangerous},s=kt(t,r);e.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
146
+ `)),await up(hp(as,{sessionOptions:r,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 fp(){let e=process.argv.slice(2);if(e[0]==="mcp"||e[0]==="--"&&e[1]==="mcp"){let o=e[0]==="--"?2:1;await cs(e.slice(o));return}let t=pp(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 r=Wt()?.version??"unknown";console.log(r);return}if(!(process.stdin.isTTY&&process.stdout.isTTY)){await dp(t);return}await mp(t)}fp();async function gp(){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
147
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memo-code/memo",
3
- "version": "0.6.32",
3
+ "version": "0.6.55",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "A lightweight coding agent that runs in your terminal",