@memo-code/memo 0.4.2 → 0.5.1
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 +19 -1
- package/dist/index.js +74 -59
- package/dist/prompt.md +14 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,23 @@ url = "https://your-mcp-server.com/mcp"
|
|
|
85
85
|
# headers = { Authorization = "Bearer xxx" }
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
也可以通过 CLI 管理 MCP 配置(对齐 Codex CLI 风格):
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 列出 MCP servers
|
|
92
|
+
memo mcp list
|
|
93
|
+
|
|
94
|
+
# 添加本地 MCP server(stdio)
|
|
95
|
+
memo mcp add local_tools -- /path/to/mcp-server --flag
|
|
96
|
+
|
|
97
|
+
# 添加远程 MCP server(streamable HTTP)
|
|
98
|
+
memo mcp add remote --url https://your-mcp-server.com/mcp --bearer-token-env-var MCP_TOKEN
|
|
99
|
+
|
|
100
|
+
# 查看/删除
|
|
101
|
+
memo mcp get remote
|
|
102
|
+
memo mcp remove remote
|
|
103
|
+
```
|
|
104
|
+
|
|
88
105
|
## 内置工具
|
|
89
106
|
|
|
90
107
|
- `bash`:执行 shell 命令
|
|
@@ -192,8 +209,9 @@ memo-cli/
|
|
|
192
209
|
|
|
193
210
|
## 相关文档
|
|
194
211
|
|
|
212
|
+
- [用户指南](./docs/user/README.md) - 面向使用者的分模块说明
|
|
195
213
|
- [Core 架构](./docs/core.md) - 核心实现详解
|
|
196
|
-
- [
|
|
214
|
+
- [CLI 适配更新](./docs/cli-update.md) - Tool Use API 迁移说明
|
|
197
215
|
- [开发指南](./CONTRIBUTING.md) - 贡献指南
|
|
198
216
|
- [项目约定](./AGENTS.md) - 代码规范和开发流程
|
|
199
217
|
|
package/dist/index.js
CHANGED
|
@@ -1,58 +1,63 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`,"utf8")}async flush(){return Promise.resolve()}};function
|
|
2
|
+
var Kr=Object.create;var An=Object.defineProperty;var Jr=Object.getOwnPropertyDescriptor;var qr=Object.getOwnPropertyNames;var Xr=Object.getPrototypeOf,Yr=Object.prototype.hasOwnProperty;var Mn=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Zr=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of qr(e))!Yr.call(t,r)&&r!==n&&An(t,r,{get:()=>e[r],enumerable:!(o=Jr(e,r))||o.enumerable});return t};var Pn=(t,e,n)=>(n=t!=null?Kr(Xr(t)):{},Zr(e||!t||!t.__esModule?An(n,"default",{value:t,enumerable:!0}):n,t));var Fn=Mn((gu,Bn)=>{"use strict";function Ln(t){return Array.isArray(t)?t:[t]}var Ft="",Nn=" ",Ht="\\",ms=/^\s+$/,ds=/(?:[^\\]|^)\\$/,fs=/^\\!/,gs=/^\\#/,hs=/\r?\n/g,ys=/^\.*\/|^\.+$/,Bt="/",Un="node-ignore";typeof Symbol<"u"&&(Un=Symbol.for("node-ignore"));var On=Un,xs=(t,e,n)=>Object.defineProperty(t,e,{value:n}),vs=/([0-z])-([0-z])/g,jn=()=>!1,Ts=t=>t.replace(vs,(e,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?e:Ft),Ss=t=>{let{length:e}=t;return t.slice(0,e-e%2)},ks=[[/^\uFEFF/,()=>Ft],[/((?:\\\\)*?)(\\?\s+)$/,(t,e,n)=>e+(n.indexOf("\\")===0?Nn:Ft)],[/(\\+?)\s/g,(t,e)=>{let{length:n}=e;return e.slice(0,n-n%2)+Nn}],[/[\\$.|*+(){^]/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,()=>Ht],[/\\\\/g,()=>Ht],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(t,e,n,o,r)=>e===Ht?`\\[${n}${Ss(o)}${r}`:r==="]"&&o.length%2===0?`[${Ts(n)}${o}]`:"[]"],[/(?:[^*])$/,t=>/\/$/.test(t)?`${t}$`:`${t}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(t,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`]],Dn=Object.create(null),_s=(t,e)=>{let n=Dn[t];return n||(n=ks.reduce((o,[r,s])=>o.replace(r,s.bind(t)),t),Dn[t]=n),e?new RegExp(n,"i"):new RegExp(n)},zt=t=>typeof t=="string",bs=t=>t&&zt(t)&&!ms.test(t)&&!ds.test(t)&&t.indexOf("#")!==0,ws=t=>t.split(hs),Vt=class{constructor(e,n,o,r){this.origin=e,this.pattern=n,this.negative=o,this.regex=r}},Cs=(t,e)=>{let n=t,o=!1;t.indexOf("!")===0&&(o=!0,t=t.substr(1)),t=t.replace(fs,"!").replace(gs,"#");let r=_s(t,e);return new Vt(n,t,o,r)},Es=(t,e)=>{throw new e(t)},ge=(t,e,n)=>zt(t)?t?ge.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),Hn=t=>ys.test(t);ge.isNotRelative=Hn;ge.convert=t=>t;var Gt=class{constructor({ignorecase:e=!0,ignoreCase:n=e,allowRelativePaths:o=!1}={}){xs(this,On,!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[On]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(bs(e)){let n=Cs(e,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(e){return this._added=!1,Ln(zt(e)?ws(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,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(e)&&(o=!i,r=i)}),{ignored:o,unignored:r}}_test(e,n,o,r){let s=e&&ge.convert(e);return ge(s,e,this._allowRelativePaths?jn:Es),this._t(s,n,o,r)}_t(e,n,o,r){if(e in n)return n[e];if(r||(r=e.split(Bt)),r.pop(),!r.length)return n[e]=this._testOne(e,o);let s=this._t(r.join(Bt)+Bt,n,o,r);return n[e]=s.ignored?s:this._testOne(e,o)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return Ln(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},ut=t=>new Gt(t),As=t=>ge(t&&ge.convert(t),t,jn);ut.isPathValid=As;ut.default=ut;Bn.exports=ut;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,"/");ge.convert=t;let e=/^[a-z]:\//i;ge.isNotRelative=n=>e.test(n)||Hn(n)}});var nr=Mn((xd,Mt)=>{"use strict";function Xo(t){return Array.isArray(t)?t:[t]}var sc=void 0,dn="",Jo=" ",mn="\\",ic=/^\s+$/,ac=/(?:[^\\]|^)\\$/,cc=/^\\!/,lc=/^\\#/,uc=/\r?\n/g,pc=/^\.{0,2}\/|^\.{1,2}$/,mc=/\/$/,Ve="/",Yo="node-ignore";typeof Symbol<"u"&&(Yo=Symbol.for("node-ignore"));var Zo=Yo,Ge=(t,e,n)=>(Object.defineProperty(t,e,{value:n}),n),dc=/([0-z])-([0-z])/g,Qo=()=>!1,fc=t=>t.replace(dc,(e,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?e:dn),gc=t=>{let{length:e}=t;return t.slice(0,e-e%2)},hc=[[/^\uFEFF/,()=>dn],[/((?:\\\\)*?)(\\?\s+)$/,(t,e,n)=>e+(n.indexOf("\\")===0?Jo:dn)],[/(\\+?)\s/g,(t,e)=>{let{length:n}=e;return e.slice(0,n-n%2)+Jo}],[/[\\$.|*+(){^]/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,()=>mn],[/\\\\/g,()=>mn],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(t,e,n,o,r)=>e===mn?`\\[${n}${gc(o)}${r}`:r==="]"&&o.length%2===0?`[${fc(n)}${o}]`:"[]"],[/(?:[^*])$/,t=>/\/$/.test(t)?`${t}$`:`${t}(?=$|\\/$)`]],yc=/(^|\\\/)?\\\*$/,et="regex",Et="checkRegex",qo="_",xc={[et](t,e){return`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`},[Et](t,e){return`${e?`${e}[^/]*`:"[^/]*"}(?=$|\\/$)`}},vc=t=>hc.reduce((e,[n,o])=>e.replace(n,o.bind(t)),t),At=t=>typeof t=="string",Tc=t=>t&&At(t)&&!ic.test(t)&&!ac.test(t)&&t.indexOf("#")!==0,Sc=t=>t.split(uc).filter(Boolean),fn=class{constructor(e,n,o,r,s,i){this.pattern=e,this.mark=n,this.negative=s,Ge(this,"body",o),Ge(this,"ignoreCase",r),Ge(this,"regexPrefix",i)}get regex(){let e=qo+et;return this[e]?this[e]:this._make(et,e)}get checkRegex(){let e=qo+Et;return this[e]?this[e]:this._make(Et,e)}_make(e,n){let o=this.regexPrefix.replace(yc,xc[e]),r=this.ignoreCase?new RegExp(o,"i"):new RegExp(o);return Ge(this,n,r)}},kc=({pattern:t,mark:e},n)=>{let o=!1,r=t;r.indexOf("!")===0&&(o=!0,r=r.substr(1)),r=r.replace(cc,"!").replace(lc,"#");let s=vc(r);return new fn(t,e,r,n,o,s)},gn=class{constructor(e){this._ignoreCase=e,this._rules=[]}_add(e){if(e&&e[Zo]){this._rules=this._rules.concat(e._rules._rules),this._added=!0;return}if(At(e)&&(e={pattern:e}),Tc(e.pattern)){let n=kc(e,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(e){return this._added=!1,Xo(At(e)?Sc(e):e).forEach(this._add,this),this._added}test(e,n,o){let r=!1,s=!1,i;this._rules.forEach(c=>{let{negative:l}=c;s===l&&r!==s||l&&!r&&!s&&!n||!c[o].test(e)||(r=!l,s=l,i=l?sc:c)});let a={ignored:r,unignored:s};return i&&(a.rule=i),a}},_c=(t,e)=>{throw new e(t)},Se=(t,e,n)=>At(t)?t?Se.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),er=t=>pc.test(t);Se.isNotRelative=er;Se.convert=t=>t;var hn=class{constructor({ignorecase:e=!0,ignoreCase:n=e,allowRelativePaths:o=!1}={}){Ge(this,Zo,!0),this._rules=new gn(n),this._strictPathCheck=!o,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}add(e){return this._rules.add(e)&&this._initCache(),this}addPattern(e){return this.add(e)}_test(e,n,o,r){let s=e&&Se.convert(e);return Se(s,e,this._strictPathCheck?_c:Qo),this._t(s,n,o,r)}checkIgnore(e){if(!mc.test(e))return this.test(e);let n=e.split(Ve).filter(Boolean);if(n.pop(),n.length){let o=this._t(n.join(Ve)+Ve,this._testCache,!0,n);if(o.ignored)return o}return this._rules.test(e,!1,Et)}_t(e,n,o,r){if(e in n)return n[e];if(r||(r=e.split(Ve).filter(Boolean)),r.pop(),!r.length)return n[e]=this._rules.test(e,o,et);let s=this._t(r.join(Ve)+Ve,n,o,r);return n[e]=s.ignored?s:this._rules.test(e,o,et)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return Xo(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},yn=t=>new hn(t),bc=t=>Se(t&&Se.convert(t),t,Qo),tr=()=>{let t=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");Se.convert=t;let e=/^[a-z]:\//i;Se.isNotRelative=n=>e.test(n)||er(n)};typeof process<"u"&&process.platform==="win32"&&tr();Mt.exports=yn;yn.default=yn;Mt.exports.isPathValid=bc;Ge(Mt.exports,Symbol.for("setupWindows"),tr)});import{randomUUID as Nr}from"crypto";import{createInterface as Gl}from"readline/promises";import{stdin as zl,stdout as Wl}from"process";import{render as Kl}from"ink";import Qr from"os";import{readFile as es}from"fs/promises";import{join as ts,dirname as ns}from"path";import{fileURLToPath as os}from"url";var rs=/{{\s*([\w.-]+)\s*}}/g;function ss(t,e){return t.replace(rs,(n,o)=>e[o]??"")}function is(){try{return Qr.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}async function Rn(){let t=ns(os(import.meta.url)),e=ts(t,"prompt.md"),n=await es(e,"utf-8"),o={date:new Date().toISOString(),user:is(),pwd:process.cwd()};return ss(n,o)}import{appendFile as as,mkdir as cs}from"fs/promises";import{dirname as ls}from"path";var lt=class{constructor(e){this.filePath=e}ready=!1;async append(e){this.ready||(await cs(ls(this.filePath),{recursive:!0}),this.ready=!0),await as(this.filePath,`${JSON.stringify(e)}
|
|
3
|
+
`,"utf8")}async flush(){return Promise.resolve()}};function $n(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{spawn as us}from"child_process";import{z as jt}from"zod";function b(t,e=!1){return{content:[{type:"text",text:t}],isError:e}}var ps=jt.object({command:jt.string().min(1,"command \u4E0D\u80FD\u4E3A\u7A7A"),timeout:jt.number().int("timeout \u5FC5\u987B\u662F\u6574\u6570\u6BEB\u79D2").positive("timeout \u5FC5\u987B\u5927\u4E8E 0").max(3600*1e3,"timeout \u4E0D\u80FD\u8D85\u8FC7 1 \u5C0F\u65F6").optional()}).strict(),In={name:"bash",description:"\u5728 shell \u4E2D\u6267\u884C\u547D\u4EE4\uFF0C\u8FD4\u56DE exit/stdout/stderr",inputSchema:ps,execute:async({command:t,timeout:e})=>{let n=t.trim();if(!n)return b("bash \u9700\u8981\u8981\u6267\u884C\u7684\u547D\u4EE4",!0);try{let o=us("bash",["-lc",n],{env:process.env,stdio:["ignore","pipe","pipe"]}),r=m=>new Promise(_=>{if(!m)return _("");let y=[];m.setEncoding("utf8"),m.on("data",C=>y.push(C)),m.on("error",()=>_("")),m.on("end",()=>_(y.join("")))}),s=r(o.stdout),i=r(o.stderr),a,c=new Promise((m,_)=>{o.on("error",y=>_(y)),o.on("close",y=>m(typeof y=="number"?y:-1))}),l=e&&e>0?new Promise((m,_)=>{a=setTimeout(()=>{o.kill(),_(new Error(`bash \u8D85\u65F6 ${e}ms\uFF0C\u5DF2\u7EC8\u6B62\u8FDB\u7A0B`))},e)}):null,u=l?await Promise.race([c,l]):await c;a&&clearTimeout(a);let[p,v]=await Promise.all([s,i]);return b(`exit=${u} stdout="${p}" stderr="${v}"`)}catch(o){return b(`bash \u6267\u884C\u5931\u8D25: ${o.message}`,!0)}}};import{access as Bs,readFile as Fs,writeFile as Vs}from"fs/promises";var Wn=Pn(Fn(),1);import{normalize as Ms,resolve as zn,dirname as Vn,join as Wt,relative as Ps}from"path";import{existsSync as Kt,statSync as Rs}from"fs";import{readFile as $s}from"fs/promises";function pe(t){return Ms(zn(t))}var Is=["node_modules/",".git/","dist/","out/","build/","coverage/",".cache/",".idea/",".DS_Store",".next/",".turbo/",".pnpm/",".pnpm-store/","*.log","logs/","tmp/","temp/","vendor/"],Ls=100,Ns=1e4,Os="<system_hint>\u5F53\u524D\u67E5\u627E\u7ED3\u679C\u8FC7\u591A\uFF0C\u8BF7\u7EC6\u5316\u67E5\u627E\u8303\u56F4\uFF08\u7F29\u5C0F\u76EE\u5F55\u3001\u589E\u52A0\u66F4\u5177\u4F53\u7684 pattern/glob \u6216\u5173\u952E\u8BCD\uFF09\u3002</system_hint>",Gn=new Map;function Ds(t){return t.replace(/\\/g,"/")}function Us(t){let e=zn(t);try{Rs(e).isFile()&&(e=Vn(e))}catch{e=process.cwd()}let n=e;for(;;){if(Kt(Wt(e,".gitignore"))||Kt(Wt(e,".git")))return e;let o=Vn(e);if(o===e)return n;e=o}}async function js(t){let e=Wt(t,".gitignore");return Kt(e)?(await $s(e,"utf8")).split(/\r?\n/).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#")):[]}async function Hs(t){let e=(0,Wn.default)();e.add(Is);let n=await js(t);return n.length>0&&e.add(n),{root:t,ignores:o=>{let r=Ps(t,o);return!r||r.startsWith("..")?!1:e.ignores(Ds(r))}}}async function pt(t){let e=Us(t),n=Gn.get(e);if(n)return n;let o=Hs(e);return Gn.set(e,o),o}function mt(t,e){return e>Ls||t.length>Ns?`${t}
|
|
4
4
|
|
|
5
|
-
${
|
|
6
|
-
`).replace(
|
|
7
|
-
`).replace(
|
|
5
|
+
${Os}`:t}import{z as Je}from"zod";var Gs=Je.object({file_path:Je.string().min(1),old_string:Je.string().min(1,"old_string \u4E0D\u80FD\u4E3A\u7A7A"),new_string:Je.string(),replace_all:Je.boolean().optional()}).strict(),Kn={name:"edit",description:"\u5728\u6587\u4EF6\u4E2D\u66FF\u6362\u6587\u672C\uFF0C\u652F\u6301 replace_all",inputSchema:Gs,execute:async t=>{let e=pe(t.file_path),n=t.replace_all??!1;if(!t.old_string.trim())return b("old_string \u4E0D\u80FD\u4E3A\u7A7A",!0);try{await Bs(e);let o=await Fs(e,"utf8");if(!o.includes(t.old_string))return b("\u672A\u627E\u5230\u5F85\u66FF\u6362\u6587\u672C",!0);let r,s=0;if(n){let i=o.split(t.old_string);s=i.length-1,r=i.join(t.new_string)}else r=o.replace(t.old_string,t.new_string),s=1;return r===o?b("\u672A\u68C0\u6D4B\u5230\u5185\u5BB9\u53D8\u5316"):(await Vs(e,r,"utf8"),b(`\u66FF\u6362\u5B8C\u6210: file=${e} count=${s}`))}catch(o){return o.code==="ENOENT"?b(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`,!0):b(`edit \u5931\u8D25: ${o.message}`,!0)}}};import{z as Jn}from"zod";var zs=Jn.object({url:Jn.string().min(1)}).strict(),qn=1e4,qe=512e3,Jt=4e3,Ws=new Set(["http:","https:","data:"]),Ks=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,Js=/<\s*(br|hr)\s*\/?>/gi,qs=/<\s*li[^>]*>/gi,Xs=/<[^>]+>/g,Ys=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,Zs=t=>t.replace(/ /gi," ").replace(/</gi,"<").replace(/>/gi,">").replace(/&/gi,"&").replace(/"/gi,'"').replace(/'/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""}}),Qs=t=>{let o=t.replace(Ys," ").replace(qs,"- ").replace(Js,`
|
|
6
|
+
`).replace(Ks,`
|
|
7
|
+
`).replace(Xs," "),s=Zs(o).replace(/\r/g,"").split(`
|
|
8
8
|
`).map(a=>a.trim().replace(/[ \t]{2,}/g," "));return s.filter((a,c)=>a.length>0||c>0&&(s[c-1]?.length??0)>0).join(`
|
|
9
|
-
`).trim()},
|
|
10
|
-
`);return
|
|
11
|
-
`);return
|
|
9
|
+
`).trim()},ei=t=>t.replace(/\s+/g," ").trim(),Xn={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:zs,execute:async t=>{let e;try{e=new URL(t.url)}catch{return b(`\u65E0\u6548 URL: ${t.url}`,!0)}if(!Ws.has(e.protocol))return b(`\u4E0D\u652F\u6301\u7684\u534F\u8BAE: ${e.protocol}`,!0);let n=new AbortController,o=setTimeout(()=>n.abort(),qn);try{let r=await globalThis.fetch(e,{signal:n.signal}),s=r.headers.get("content-length"),i=s?Number(s):void 0;if(i&&i>qe)return b(`\u8BF7\u6C42\u88AB\u62D2\u7EDD: \u54CD\u5E94\u4F53\u8FC7\u5927\uFF08${i} bytes\uFF09`,!0);let a=0,c="";if(r.body&&r.body.getReader){let C=r.body.getReader(),P=[];for(;;){let{done:x,value:E}=await C.read();if(x)break;if(E){if(a+=E.byteLength,a>qe)return n.abort(),b(`\u8BF7\u6C42\u88AB\u4E2D\u6B62: \u54CD\u5E94\u4F53\u8D85\u8FC7 ${qe} bytes`,!0);P.push(E)}}let g=new Uint8Array(a),M=0;for(let x of P)g.set(x,M),M+=x.byteLength;c=new TextDecoder().decode(g)}else if(c=await r.text(),a=new TextEncoder().encode(c).byteLength,a>qe)return b(`\u8BF7\u6C42\u88AB\u62D2\u7EDD: \u54CD\u5E94\u4F53\u8D85\u8FC7 ${qe} bytes`,!0);let l=r.headers.get("content-type")||"",u=/text\/html/i.test(l)||/^\s*<!doctype html/i.test(c)||/^\s*<html[\s>]/i.test(c),p=u?Qs(c):c.trim(),v=ei(p),m=v.length>Jt?`${v.slice(0,Jt)}...`:v,_=v.length>Jt?" text_truncated=true":"",y=u?" source=html_stripped":"";return b(`status=${r.status} bytes=${a} text_chars=${v.length} text="${m}"${_}${y}`)}catch(r){return r.name==="AbortError"?b(`\u8BF7\u6C42\u8D85\u65F6\u6216\u88AB\u4E2D\u6B62\uFF08${qn}ms\uFF09`,!0):b(`\u8BF7\u6C42\u5931\u8D25: ${r.message}`,!0)}finally{clearTimeout(o)}}};import{z as qt}from"zod";import ti from"fast-glob";var ni=qt.object({pattern:qt.string().min(1),path:qt.string().optional()}).strict(),oi={name:"glob",description:"\u6309 glob \u6A21\u5F0F\u5339\u914D\u6587\u4EF6\uFF0C\u8FD4\u56DE\u7EDD\u5BF9\u8DEF\u5F84\u5217\u8868",inputSchema:ni,execute:async t=>{let e=t.path?pe(t.path):process.cwd();try{let n=await pt(e),r=(await ti(t.pattern,{cwd:e,absolute:!0,onlyFiles:!0})).filter(i=>!n.ignores(i));if(r.length===0)return b("\u672A\u627E\u5230\u5339\u914D\u6587\u4EF6");let s=r.join(`
|
|
10
|
+
`);return b(mt(s,r.length))}catch(n){return b(`glob \u5931\u8D25: ${n.message}`,!0)}}},Yn=oi;import{spawn as ri,spawnSync as si}from"child_process";import{z as he}from"zod";import{isAbsolute as Zn,resolve as Qn}from"path";var ii=he.object({pattern:he.string().min(1),path:he.string().optional(),output_mode:he.enum(["content","files_with_matches","count"]).optional(),glob:he.string().optional(),"-i":he.boolean().optional(),"-A":he.number().int().nonnegative().optional(),"-B":he.number().int().nonnegative().optional(),"-C":he.number().int().nonnegative().optional()}).strict(),eo={name:"grep",description:"\u57FA\u4E8E ripgrep \u67E5\u627E\u6587\u672C\uFF0C\u652F\u6301\u8F93\u51FA\u5339\u914D\u5185\u5BB9\u3001\u6587\u4EF6\u5217\u8868\u6216\u8BA1\u6570",inputSchema:ii,execute:async t=>{let e=si("rg",["--version"],{stdio:"ignore"});if(e.error||e.status!==0)return b("rg \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH",!0);let n=t.path?pe(t.path):process.cwd(),o=["--color","never"],r=t.output_mode??"content";r==="files_with_matches"?o.push("-l"):r==="count"?o.push("-c"):o.push("--line-number","--no-heading"),t["-i"]&&o.push("-i"),t.glob&&o.push("--glob",t.glob),t["-A"]!==void 0&&o.push("-A",String(t["-A"])),t["-B"]!==void 0&&o.push("-B",String(t["-B"])),t["-C"]!==void 0&&o.push("-C",String(t["-C"])),o.push(t.pattern,n);try{let s=await pt(n),i=ri("rg",o,{stdio:["ignore","pipe","pipe"]}),a=y=>new Promise(C=>{if(!y)return C("");let P=[];y.setEncoding("utf8"),y.on("data",g=>P.push(g)),y.on("error",()=>C("")),y.on("end",()=>C(P.join("")))}),[c,l]=await Promise.all([a(i.stdout),a(i.stderr)]);if(await new Promise((y,C)=>{i.on("error",P=>C(P)),i.on("close",P=>y(typeof P=="number"?P:-1))})===2)return b(`grep \u5931\u8D25(exit=2): ${l||c}`,!0);let m=(c||l||"").split(/\r?\n/).map(y=>y.trimEnd()).filter(y=>y.length>0).filter(y=>{if(r==="files_with_matches"){let M=y.trim(),x=Zn(M)?M:Qn(n,M);return!s.ignores(x)}let C=y.indexOf(":");if(C===-1)return!0;let P=y.slice(0,C),g=Zn(P)?P:Qn(n,P);return!s.ignores(g)});if(m.length===0)return b("\u672A\u627E\u5230\u5339\u914D");let _=m.join(`
|
|
11
|
+
`);return b(mt(_,m.length))}catch(s){return b(`grep \u6267\u884C\u5931\u8D25: ${s.message}`,!0)}}};import{mkdir as ai,readFile as ci,writeFile as li,access as ui}from"fs/promises";import{dirname as pi,join as to}from"path";import{homedir as mi}from"os";import{z as no}from"zod";var di=no.object({fact:no.string().min(1,"fact cannot be empty").max(120,"Please keep facts concise (\u2264120 characters)").describe('User-related identity traits or preferences, e.g., "User prefers Chinese responses", "User is a frontend engineer". Do not store project-specific technical details.')}).strict();function fi(){let t=process.env.MEMO_HOME?.trim()||to(mi(),".memo");return to(t,"Agents.md")}function gi(t){return t.replace(/\r?\n/g," ").replace(/\s+/g," ").trim()}function hi(t,e){let o=e.map(r=>r.trim()).filter(Boolean).map(r=>`- ${r}`);return`${t}
|
|
12
12
|
|
|
13
13
|
${o.join(`
|
|
14
14
|
`)}
|
|
15
|
-
`}var
|
|
16
|
-
`),
|
|
17
|
-
... (truncated, showing ${r} lines; max=${
|
|
15
|
+
`}var oo={name:"save_memory",description:"Save user-related identity traits or preferences (e.g., language habits, tech preferences) for cross-session reuse. Do not save project-specific technical details or file structures.",inputSchema:di,execute:async t=>{let e=gi(t.fact);if(!e)return b("fact cannot be empty",!0);let n=fi(),o=pi(n);try{await ai(o,{recursive:!0});let r="## Memo Added Memories";try{let s=await(async()=>{try{return await ui(n),await ci(n,"utf-8")}catch{return""}})(),[,i=""]=s.split(r),a=i.split(/\r?\n/).filter(u=>u.trim().startsWith("- ")).map(u=>u.replace(/^-+\s*/,"").trim());a.push(e);let c=a.slice(Math.max(0,a.length-50)),l=hi(r,c);await li(n,l,"utf-8")}catch(s){console.warn(`Memory maintenance failed: ${s.message}`)}return b(`Memory saved to: ${n}`)}catch(r){return b(`Failed to write memory: ${r.message}`,!0)}}};import{z as ye}from"zod";var dt=10,ie=[],yi=ye.object({type:ye.enum(["add","replace","update","remove"]),todos:ye.array(ye.object({content:ye.string().trim().min(1,"content \u4E0D\u80FD\u4E3A\u7A7A").max(200,"content \u6700\u957F 200 \u5B57\u7B26"),status:ye.enum(["pending","in_progress","completed"]).optional().default("pending"),id:ye.string().min(1,"id \u4E0D\u80FD\u4E3A\u7A7A").optional()})).optional(),ids:ye.array(ye.string().min(1,"id \u4E0D\u80FD\u4E3A\u7A7A")).optional()}).strict().refine(t=>{if(["add","replace","update"].includes(t.type)){if(!t.todos||t.todos.length===0)return!1;if(t.type==="update")return t.todos.every(e=>e.id)}return!(t.type==="remove"&&(!t.ids||t.ids.length===0))},{message:"add/replace/update \u9700\u8981 todos\uFF0Cremove \u9700\u8981 ids\uFF0Cupdate \u9700\u8981 id"});function ft(){return ie.map(t=>({...t}))}function xi(t){switch(t.type){case"add":{let e=t.todos,n=dt-ie.length;if(e.length>n)return{error:`\u4EFB\u52A1\u4E0A\u9650 ${dt}\uFF0C\u5F53\u524D\u5269\u4F59 ${n} \u6761\u7A7A\u4F4D`};let o=e.map(r=>({id:crypto.randomUUID(),content:r.content,status:r.status}));return ie.push(...o),{added:o,tasks:ft()}}case"replace":{let e=t.todos;if(e.length>dt)return{error:`\u4EFB\u52A1\u4E0A\u9650 ${dt}`};ie.splice(0,ie.length);let n=e.map(o=>({id:crypto.randomUUID(),content:o.content,status:o.status}));return ie.push(...n),{replaced:!0,tasks:ft()}}case"update":{let e=t.todos,n=e.map(s=>s.id);if(new Set(n).size!==n.length)return{error:"\u66F4\u65B0\u5217\u8868\u5B58\u5728\u91CD\u590D id"};let r=new Map(ie.map(s=>[s.id,s]));for(let s of e){let i=r.get(s.id);if(!i)return{error:`\u672A\u627E\u5230\u4EFB\u52A1 id=${s.id}`};i.content=s.content,s.status&&(i.status=s.status)}return{updated:n,tasks:ft()}}case"remove":{let e=t.ids,n=ie.length,o=new Set(e),r=ie.filter(s=>!o.has(s.id));return r.length===n?{error:"\u672A\u627E\u5230\u4EFB\u4F55\u53EF\u5220\u9664\u7684\u4EFB\u52A1 id"}:(ie.splice(0,ie.length,...r),{removed:e,tasks:ft()})}}}var ro={name:"todo",description:"\u7BA1\u7406\u5F85\u529E\u5217\u8868\uFF08add/update/remove/replace\uFF09\uFF0C\u6700\u591A 10 \u6761\uFF0C\u4E0D\u6301\u4E45\u5316",inputSchema:yi,execute:async t=>{let e=xi(t);if(e.error)return b(e.error,!0);let n={op:t.type,count:ie.length,tasks:e.tasks,added:e.added,updated:e.updated,removed:e.removed,replaced:!!e.replaced};return b(JSON.stringify(n))}};import{z as gt}from"zod";import{extname as vi}from"path";import{gzipSync as Ti}from"zlib";import{access as Si,readFile as ki}from"fs/promises";var so=512e3,io=2e6,_i=200,ao=1e3,bi=1024,Xt=4e3,wi=new Set([".png",".jpg",".jpeg",".gif",".webp",".bmp",".svg"]);function Ci(t){let e=vi(t).toLowerCase();return wi.has(e)}function Ei(t){return Buffer.from(t).toString("base64")}function Ai(t){try{let e=Ti(t,{level:6});if(e.byteLength<t.byteLength)return{data:new Uint8Array(e),encoding:"gzip+base64"}}catch{}return{data:t,encoding:"base64"}}function Mi(t){let e=t.truncated?" truncated=true":"";return`image_base64 (encoding=${t.encoding} original_bytes=${t.originalBytes} payload_bytes=${t.payloadBytes} base64_length=${t.base64.length}${e}): ${t.base64}`}var Pi=gt.object({file_path:gt.string().min(1),offset:gt.number().int().positive().optional(),limit:gt.number().int().positive().optional()}).strict(),co={name:"read",description:"\u8BFB\u53D6\u6307\u5B9A\u6587\u4EF6\u5185\u5BB9\uFF0C\u53EF\u6309 offset/limit \u622A\u53D6\u5E76\u9644\u5E26\u884C\u53F7",inputSchema:Pi,execute:async t=>{let e=pe(t.file_path),n=t.offset??1,o=t.limit??_i,r=Math.min(o,ao);try{await Si(e);let s=await ki(e),i=s.byteLength;if(Ci(e)){if(i>io)return b(`\u56FE\u7247\u8FC7\u5927\uFF08${i} bytes\uFF09\uFF0C\u8D85\u8FC7\u9608\u503C ${io} bytes\uFF0C\u5DF2\u62D2\u7EDD\u8BFB\u53D6`,!0);let x=new Uint8Array(s),{data:E,encoding:U}=Ai(x),$=Ei(E),V=$.length>Xt?`${$.slice(0,Xt)}...`:$,S=$.length>Xt;return b(Mi({encoding:U,base64:V,originalBytes:x.byteLength,payloadBytes:E.byteLength,truncated:S}))}if(i>so)return b(`\u6587\u4EF6\u8FC7\u5927\uFF08${i} bytes\uFF09\uFF0C\u5DF2\u62D2\u7EDD\u8BFB\u53D6\uFF0C\u9608\u503C ${so} bytes`,!0);let c=new Uint8Array(s),l=Math.min(c.length,bi);for(let x=0;x<l;x++)if(c[x]===0)return b("\u68C0\u6D4B\u5230\u4E8C\u8FDB\u5236\u5185\u5BB9\uFF0C\u5DF2\u62D2\u7EDD\u76F4\u63A5\u8BFB\u53D6",!0);let p=new TextDecoder().decode(c).split(/\r?\n/),v=Math.max(0,n-1),m=Math.min(p.length,v+r),y=p.slice(v,m).map((x,E)=>`${v+E+1}: ${x}`).join(`
|
|
16
|
+
`),C=m<p.length,M=o!==r||C&&t.limit===void 0?`
|
|
17
|
+
... (truncated, showing ${r} lines; max=${ao})`:"";return b(y+M)}catch(s){return b(`\u8BFB\u53D6\u5931\u8D25: ${s.message}`,!0)}}};import{z as Yt}from"zod";import{dirname as Ri}from"path";import{mkdir as $i,writeFile as Ii}from"fs/promises";var Li=Yt.object({file_path:Yt.string().min(1),content:Yt.any().optional()}).strict();function Ni(t){if(t instanceof Uint8Array)return{data:t,info:`bytes=${t.byteLength}`};if(t instanceof ArrayBuffer){let n=new Uint8Array(t);return{data:n,info:`bytes=${n.byteLength}`}}if(typeof t=="string")return{data:t,info:`text_length=${t.length}`};let e=JSON.stringify(t??"",null,2);return{data:e,info:`json_length=${e.length}`}}var lo={name:"write",description:"\u521B\u5EFA\u6216\u8986\u76D6\u6587\u4EF6\uFF0C\u4F20\u5165 file_path \u4E0E content",inputSchema:Li,execute:async t=>{let e=pe(t.file_path),{data:n,info:o}=Ni(t.content);try{return await $i(Ri(e),{recursive:!0}),await Ii(e,n instanceof Uint8Array?n:String(n)),b(`\u5DF2\u5199\u5165 ${e} (overwrite, ${o})`)}catch(r){return b(`\u5199\u5165\u5931\u8D25: ${r.message}`,!0)}}};function Oi(t){let e=t.toJSONSchema(),{$schema:n,...o}=e;return o}function Di(t){return{name:t.name,description:t.description,source:"native",inputSchema:Oi(t.inputSchema),execute:t.execute}}function uo(t){return t.map(Di)}var Ui={bash:In,read:co,write:lo,edit:Kn,glob:Yn,grep:eo,webfetch:Xn,save_memory:oo,todo:ro},ji=Object.values(Ui),po=uo(ji);import ua from"openai";import{encoding_for_model as Hi,get_encoding as Bi}from"@dqbd/tiktoken";var mo="cl100k_base";function Fi(t){let e=t?.trim()||mo;try{let n=()=>Hi(e);return n().free(),{model:e,factory:n}}catch{let n=mo,o=()=>Bi(n);return o().free(),{model:n,factory:o}}}function fo(t){let{model:e,factory:n}=Fi(t),o=n(),r=4,s=2,i=1,a=l=>l?o.encode(l).length:0;return{model:e,countText:a,countMessages:l=>{if(!l.length)return 0;let u=0;for(let p of l)u+=r,u+=a(p.content),p.name&&(u+=i);return u+=s,u},dispose:()=>o.free()}}import{mkdir as Vi,writeFile as Gi,readFile as zi,access as Wi}from"fs/promises";import{homedir as go}from"os";import{dirname as Ki,join as Pe}from"path";import{randomUUID as wp}from"crypto";import{parse as Ji}from"toml";var qi=Pe(go(),".memo"),Xi="sessions",Yi="Agents.md",Xe={current_provider:"deepseek",stream_output:!1,providers:[{name:"deepseek",env_api_key:"DEEPSEEK_API_KEY",model:"deepseek-chat",base_url:"https://api.deepseek.com"}],mcp_servers:{}};function Zi(t){return/^[A-Za-z0-9_-]+$/.test(t)?t:JSON.stringify(t)}function Qi(t){if(!t||typeof t!="object"||Array.isArray(t))return[];let e=[];for(let[n,o]of Object.entries(t)){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),e.push(i)}}return e}function ho(t){return t.startsWith("~")?Pe(go(),t.slice(1)):t}function ea(t){let e=t.providers.map(r=>{let s=typeof r?.name=="string"?r.name:"";if(!s)return"";let a=[`[[providers.${Zi(s)}]]`,`name = ${JSON.stringify(s)}`,`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(`
|
|
18
18
|
`)}).filter(Boolean).join(`
|
|
19
19
|
|
|
20
|
-
`),n="";return
|
|
20
|
+
`),n="";return t.mcp_servers&&Object.keys(t.mcp_servers).length>0&&(n=Object.entries(t.mcp_servers).map(([r,s])=>{if("url"in s){let v=[`[mcp_servers.${r}]`];v.push(`type = "${s.type??"streamable_http"}"`),v.push(`url = "${s.url}"`),"fallback_to_sse"in s&&s.fallback_to_sse!==void 0&&v.push(`fallback_to_sse = ${s.fallback_to_sse}`),s.bearer_token_env_var&&v.push(`bearer_token_env_var = ${JSON.stringify(s.bearer_token_env_var)}`);let m=s.http_headers??s.headers;if(m&&Object.keys(m).length>0){let _=Object.entries(m).map(([C,P])=>`${JSON.stringify(C)} = ${JSON.stringify(P)}`).join(", "),y=s.http_headers?"http_headers":"headers";v.push(`${y} = { ${_} }`)}return v.join(`
|
|
21
21
|
`)}let i=s.args?`args = ${JSON.stringify(s.args)}`:"",a=s.type?`type = "${s.type}"
|
|
22
|
-
`:""
|
|
22
|
+
`:"",c=s.stderr?`stderr = "${s.stderr}"
|
|
23
|
+
`:"",l=`[mcp_servers.${r}]
|
|
23
24
|
${a}command = "${s.command}"
|
|
24
|
-
${i}
|
|
25
|
+
${c}${i}`.trimEnd(),u=s.env?Object.entries(s.env):[];if(u.length===0)return l;let p=u.map(([v,m])=>`${JSON.stringify(v)} = ${JSON.stringify(m)}`).join(`
|
|
26
|
+
`);return`${l}
|
|
27
|
+
|
|
28
|
+
[mcp_servers.${r}.env]
|
|
29
|
+
${p}`}).join(`
|
|
25
30
|
|
|
26
31
|
`)),[`
|
|
27
|
-
current_provider = "${
|
|
28
|
-
stream_output = ${
|
|
29
|
-
`.trim(),
|
|
32
|
+
current_provider = "${t.current_provider}"
|
|
33
|
+
stream_output = ${t.stream_output??!1}
|
|
34
|
+
`.trim(),e,n].filter(Boolean).join(`
|
|
30
35
|
|
|
31
|
-
`)}async function
|
|
32
|
-
`)}formatToolDescription(
|
|
33
|
-
`)}groupByServer(
|
|
36
|
+
`)}async function me(t,e){await Vi(Ki(t),{recursive:!0}),await Gi(t,ea(e),"utf-8")}async function ne(){let t=process.env.MEMO_HOME?ho(process.env.MEMO_HOME):qi,e=Pe(t,"config.toml");try{await Wi(e);let n=await zi(e,"utf-8"),o=Ji(n),r=Qi(o.providers),s={current_provider:o.current_provider??Xe.current_provider,stream_output:o.stream_output??Xe.stream_output,providers:r,mcp_servers:o.mcp_servers??{}},i=!s.providers.length;return{config:i?Xe:s,home:t,configPath:e,needsSetup:i}}catch{return{config:Xe,home:t,configPath:e,needsSetup:!0}}}function Re(t,e){let n=e||t.current_provider,o=t.providers.find(r=>r.name===n);return o||(t.providers?.[0]??Xe.providers[0])}function ht(t,e){let n=e.historyDir??Pe(t.home,Xi);return ho(n)}function yo(t){return Pe(t.home,Yi)}function ta(t,e=100){return t.replace(/[\\/:\s]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,e)||"root"}function na(t,e=180){let n=[],o=0;for(let r of t){let s=r.slice(0,Math.max(1,e-o-(n.length>0?1:0)));if(n.push(s),o+=s.length+(n.length>1?1:0),o>=e)break}return n}function xo(t,e){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"),c=String(n.getSeconds()).padStart(2,"0"),l=vo(process.cwd()),u=`${o}-${r}-${s}_${i}${a}${c}_${e}.jsonl`;return Pe(t,l,u)}function vo(t){let e=t.split(/[/\\]+/).map(o=>ta(o));return na(e,180).join("-")||"root"}function To(t,e){return Pe(t,vo(e))}var yt=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 oa}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as So}from"@modelcontextprotocol/sdk/client/sse.js";import{StreamableHTTPClientTransport as ra}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as sa}from"@modelcontextprotocol/sdk/client/stdio.js";function xt(){return new oa({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function ia(t){if(!(!t||Object.keys(t).length===0))return{headers:t}}function aa(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 ca(t){let e=new URL(t.url),n=ia(aa(t));if(t.type==="sse"){let r=xt(),s=new So(e,{requestInit:n});return await r.connect(s),{client:r,transport:s}}let o=t.fallback_to_sse??!0;try{let r=xt(),s=new ra(e,{requestInit:n});return await r.connect(s),{client:r,transport:s}}catch(r){if(!o)throw r;try{let s=xt(),i=new So(e,{requestInit:n});return await s.connect(i),{client:s,transport:i}}catch(s){let i=`Failed to connect via streamable_http (${r.message}); SSE fallback failed (${s.message})`,a=new Error(i);throw a.cause={streamErr:r,sseErr:s},a}}}async function la(t){if("url"in t)return ca(t);let e={command:t.command,args:t.args,env:t.env?{...process.env,...t.env}:void 0,stderr:t.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},n=new sa(e),o=xt();return await o.connect(n),{client:o,transport:n}}var vt=class{connections=new Map;async connect(e,n){let o=this.connections.get(e);if(o)return o;let{client:r,transport:s}=await la(n),i=await r.listTools(),a={name:e,client:r,transport:s,tools:(i.tools||[]).map(c=>({name:`${e}_${c.name}`,description:c.description||`Tool from ${e}: ${c.name}`,source:"mcp",serverName:e,originalName:c.name,inputSchema:c.inputSchema,execute:async()=>({content:[]})}))};return this.connections.set(e,a),a}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 Tt=class{pool;tools=new Map;shouldLog;constructor(){this.pool=new vt,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,r])=>{try{let s=await this.pool.connect(o,r);for(let i of s.tools){let a={...i,execute:async c=>{let l=this.pool.get(i.serverName)?.client;if(!l)throw new Error(`MCP client for server '${i.serverName}' not found`);return l.callTool({name:i.originalName,arguments:c})}};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(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()}getPool(){return this.pool}};var St=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new yt,this.mcpRegistry=new Tt}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(s=>s.source==="native"),r=e.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 c of a)n.push(this.formatToolDescription(c));n.push("")}}return n.join(`
|
|
37
|
+
`)}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(`
|
|
38
|
+
`)}groupByServer(e){let n={};for(let o of e)if(o.source==="mcp"){let r=o.serverName;n[r]||(n[r]=[]),n[r].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()}};import{readFile as pa,access as ma}from"fs/promises";function da(t){try{return{ok:!0,data:JSON.parse(t)}}catch(e){return{ok:!1,raw:t,error:e.message}}}async function ko(t,e,n){let o=await ne(),r=o.config,s=new St;if(s.registerNativeTools(po),await s.loadMcpServers(r.mcp_servers),t.tools)for(let[m,_]of Object.entries(t.tools))s.registerNativeTool({name:m,description:_.description,source:"native",inputSchema:{type:"object"},execute:_.execute});let i=s.toRegistry(),a=async()=>{let m=await(t.loadPrompt??Rn)(),_=s.generateToolDescriptions();_&&(m+=`
|
|
34
39
|
|
|
35
|
-
${
|
|
40
|
+
${_}`);let y=yo(o);try{await ma(y);let C=(await pa(y,"utf-8")).trim();C&&(m+=`
|
|
36
41
|
|
|
37
42
|
# Long-Term Memory
|
|
38
|
-
${
|
|
39
|
-
`),{thinkingParts:n,cleaned:o}=
|
|
43
|
+
${C}`)}catch{}return m},c=s.generateToolDefinitions(),l=e.stream??r.stream_output??!1,u=ht(o,e),p=xo(u,n),v=new lt(p);return{tools:i,dispose:async()=>{t.dispose&&await t.dispose(),await s.dispose()},callLLM:t.callLLM??(async(m,_,y)=>{let C=Re(r,e.providerName),P=process.env[C.env_api_key]??process.env.OPENAI_API_KEY??process.env.DEEPSEEK_API_KEY;if(!P)throw new Error(`Missing env var ${C.env_api_key} (or OPENAI_API_KEY/DEEPSEEK_API_KEY)`);let g=new ua({apiKey:P,baseURL:C.base_url}),M=c.length>0?c.map(x=>({type:"function",function:{name:x.name,description:x.description,parameters:x.input_schema}})):void 0;if(l){let x=await g.chat.completions.create({model:C.model,messages:m,stream:!0},{signal:y?.signal}),E="";for await(let U of x){let $=U.choices?.[0]?.delta?.content;$&&(E+=$,_?.($))}return{content:E,streamed:!0}}else{let x=await g.chat.completions.create({model:C.model,messages:m,tools:M,tool_choice:M?"auto":void 0},{signal:y?.signal}),E=x.choices?.[0]?.message;if(E?.tool_calls&&E.tool_calls.length>0){let $=[];E.content&&$.push({type:"text",text:E.content});for(let S of E.tool_calls)if(S.type==="function"){let w=da(S.function.arguments);w.ok?$.push({type:"tool_use",id:S.id,name:S.function.name,input:w.data}):$.push({type:"text",text:`[tool_use parse error] ${w.error}; raw: ${w.raw}`})}let V=$.some(S=>S.type==="tool_use");return{content:$,stop_reason:V?"tool_use":"end_turn",usage:{prompt:x.usage?.prompt_tokens??void 0,completion:x.usage?.completion_tokens??void 0,total:x.usage?.total_tokens??void 0}}}let U=E?.content;if(typeof U!="string")throw new Error("OpenAI-compatible API returned empty content");return{content:[{type:"text",text:U}],stop_reason:"end_turn",usage:{prompt:x.usage?.prompt_tokens??void 0,completion:x.usage?.completion_tokens??void 0,total:x.usage?.total_tokens??void 0}}}}),loadPrompt:a,historySinks:t.historySinks??[v],tokenCounter:t.tokenCounter??fo(e.tokenizerModel),historyFilePath:p}}import{jsonrepair as fa}from"jsonrepair";function Zt(t){try{return JSON.parse(t)}catch{try{let e=fa(t);return JSON.parse(e)}catch{return null}}}function ga(t){let e=[],n=new Set,o=/```(?:json)?\s*([\s\S]*?)\s*```/g,r;for(;(r=o.exec(t))!==null;){let i=r[1]||"";if(!i)continue;let a=ha(i);if(!(!a||n.has(a)))try{let c=Zt(a);if(c===null)continue;e.push({json:a,start:r.index,end:r.index+r[0].length,obj:c}),n.add(a)}catch{}}let s=wo(t);for(let{json:i,start:a,end:c}of s)if(!n.has(i)&&!(!i.includes('"tool"')&&!i.includes('"final"')))try{let l=Zt(i);if(l===null)continue;e.push({json:i,start:a,end:c,obj:l}),n.add(i)}catch{}return e}function ha(t){return wo(t)[0]?.json??null}function wo(t){let e=[],n=0,o=-1,r=!1,s=!1;for(let i=0;i<t.length;i++){let a=t[i];if(s){s=!1;continue}if(a==="\\"&&r){s=!0;continue}if(a==='"'&&!r?r=!0:a==='"'&&r&&(r=!1),!r){if(a==="{")n===0&&(o=i),n++;else if(a==="}"&&(n--,n===0&&o!==-1)){let c=t.slice(o,i+1);e.push({json:c,start:o,end:i+1}),o=-1}}}return e}function ya(t){let e=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,o=t.replace(n,(r,s,i)=>{let a=(i??"").trim();return a&&e.push(a),a});return{thinkingParts:e,cleaned:o.trim()}}function Qt(t){if(t.length===0)return;let e=t.join(`
|
|
44
|
+
`),{thinkingParts:n,cleaned:o}=ya(e);return n.length>0?n.join(`
|
|
40
45
|
|
|
41
|
-
`):o||void 0}function
|
|
42
|
-
`),toolUseBlocks:n.map(o=>({id:o.id,name:o.name,input:o.input})),stopReason:"stop_reason"in
|
|
43
|
-
`)}function
|
|
46
|
+
`):o||void 0}function _o(t){return t!==null&&typeof t=="object"&&"tool"in t&&typeof t.tool=="string"}function bo(t){return t!==null&&typeof t=="object"&&"final"in t&&typeof t.final=="string"}function Co(t){let e={},n=ga(t);for(let{json:r,start:s,end:i,obj:a}of n){if(_o(a)){e.action={tool:a.tool.trim(),input:a.input};let c=t.slice(0,s).trim(),l=t.slice(i).trim(),u=[];c&&u.push(c),l&&u.push(l);let p=Qt(u);return p&&(e.thinking=p),e}if(bo(a))return e.final=a.final,e}let o=t.trim();if(o.startsWith("{")&&o.endsWith("}")){let r=Zt(o);if(r&&_o(r))return e.action={tool:r.tool,input:r.input},e;if(r&&bo(r))return e.final=r.final,e}return t.trim()&&(e.final=t),e}import{randomUUID as Ro}from"crypto";function xa(){return{onTurnStart:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[]}}function Eo(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 Ao(t){let e=xa();if(Eo(e,t.hooks),Array.isArray(t.middlewares))for(let n of t.middlewares)Eo(e,n);return e}async function Y(t,e,n){let o=t[e];if(o.length)for(let r of o)try{await r(n)}catch(s){console.warn(`Hook ${e} failed: ${s.message}`)}}function je(t){return t.map(e=>({...e}))}var en={read:"read",glob:"read",grep:"read",webfetch:"read",todo:"read",write:"write",edit:"write",save_memory:"write",bash:"execute"};var kt={read:0,write:1,execute:2},tn={read:t=>`${t} \u5C06\u8BFB\u53D6\u6587\u4EF6\u6216\u6570\u636E`,write:t=>`${t} \u5C06\u4FEE\u6539\u6216\u521B\u5EFA\u6587\u4EF6`,execute:t=>`${t} \u5C06\u6267\u884C\u7CFB\u7EDF\u547D\u4EE4`};function nn(t){let e={...en,...t?.customLevels};return{getRiskLevel(n){if(n in e)return e[n];let o=n.toLowerCase();return o.includes("exec")||o.includes("run")||o.includes("shell")||o.includes("bash")||o.includes("command")?"execute":o.includes("write")||o.includes("edit")||o.includes("create")||o.includes("delete")||o.includes("modify")||o.includes("update")?"write":o.includes("read")||o.includes("get")||o.includes("fetch")||o.includes("search")||o.includes("list")||o.includes("find")?"read":"write"},compareRisk(n,o){return kt[n]-kt[o]},needsApproval(n,o){return o==="strict"?!0:n==="write"||n==="execute"}}}import{createHash as va}from"crypto";function _t(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?"["+t.map(n=>_t(n)).join(",")+"]":`{${Object.entries(t).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${_t(o)}`).join(",")}}`}function on(t,e){let n=_t(e),o=`${t}:${n}`;return va("sha256").update(o).digest("hex").slice(0,16)}function rn(t){let{mode:e="auto",dangerous:n=!1,toolRiskLevels:o}=t||{};if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let r=nn({customLevels:o}),s={session:new Set,once:new Set,denied:new Set};return{get isDangerousMode(){return!1},getRiskLevel(i){return r.getRiskLevel(i)},check(i,a){let c=r.getRiskLevel(i);if(!r.needsApproval(c,e))return{needApproval:!1,decision:"auto-execute"};let l=on(i,a);return s.session.has(l)||s.once.has(l)?{needApproval:!1,decision:"auto-execute"}:s.denied.has(l)?{needApproval:!0,fingerprint:l,riskLevel:c,reason:"\u8BE5\u8BF7\u6C42\u5DF2\u88AB\u62D2\u7EDD",toolName:i,params:a}:{needApproval:!0,fingerprint:l,riskLevel:c,reason:tn[c](i),toolName:i,params:a}},recordDecision(i,a){switch(s.session.delete(i),s.once.delete(i),s.denied.delete(i),a){case"session":s.session.add(i);break;case"once":s.once.add(i);break;case"deny":s.denied.add(i);break}},isGranted(i){return s.session.has(i)||s.once.has(i)},clearOnceApprovals(){s.once.clear()},dispose(){s.session.clear(),s.once.clear(),s.denied.clear()}}}var $o="interactive";function Mo(){return{prompt:0,completion:0,total:0}}function Po(t,e){if(!e)return;let n=e.prompt??0,o=e.completion??0,r=e.total??n+o;t.prompt+=n,t.completion+=o,t.total+=r}function Ta(t){if(typeof t=="string")return{textContent:t,toolUseBlocks:[]};if("content"in t&&typeof t.content=="string")return{textContent:t.content,toolUseBlocks:[],usage:"usage"in t?t.usage:void 0,streamed:"streamed"in t?t.streamed:void 0};if("content"in t&&Array.isArray(t.content)){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(`
|
|
47
|
+
`),toolUseBlocks:n.map(o=>({id:o.id,name:o.name,input:o.input})),stopReason:"stop_reason"in t?t.stop_reason:void 0,usage:"usage"in t?t.usage:void 0}}return{textContent:"",toolUseBlocks:[]}}async function Sa(t,e){for(let n of e)try{await n.append(t)}catch(o){console.error(`Failed to write history event: ${o.message}`)}}function ka(t){return(t.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
|
|
48
|
+
`)}function _a(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`}:{ok:!0,data:n}}function ba(t){return t instanceof Error&&t.name==="AbortError"}function bt(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(n=>bt(n)).join(",")}]`:`{${Object.entries(t).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${bt(o)}`).join(",")}}`}var sn=class{constructor(e,n,o,r,s){this.deps=e;this.options=n;this.id=n.sessionId||Ro(),this.mode=n.mode||$o,this.history=[{role:"system",content:o}],this.tokenCounter=r,this.sinks=e.historySinks??[],this.hooks=Ao(e),this.historyFilePath=s,this.approvalManager=rn({dangerous:!1,mode:"auto"})}id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=Mo();startedAt=Date.now();hooks;closed=!1;sessionStartEmitted=!1;currentAbortController=null;cancelling=!1;lastActionSignature=null;repeatedActionCount=0;approvalManager;async init(){}resetActionRepetition(){this.lastActionSignature=null,this.repeatedActionCount=0}maybeWarnRepeatedAction(e,n){let o=`${e}:${bt(n)}`;if(this.lastActionSignature===o?this.repeatedActionCount+=1:(this.lastActionSignature=o,this.repeatedActionCount=1),this.repeatedActionCount===3){let r=bt(n).slice(0,200),s=`\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${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})}}async executeToolWithApproval(e,n,o,r){let s=this.approvalManager.check(e,n);if(!s.needApproval)return this.doExecuteTool(e,n);let i={toolName:s.toolName,params:s.params,fingerprint:s.fingerprint,riskLevel:s.riskLevel,reason:s.reason};await Y(this.hooks,"onApprovalRequest",{sessionId:this.id,turn:o,step:r,request:i});let a="deny";return this.deps.requestApproval?a=await this.deps.requestApproval(i):a="deny",this.approvalManager.recordDecision(s.fingerprint,a),await Y(this.hooks,"onApprovalResponse",{sessionId:this.id,turn:o,step:r,fingerprint:s.fingerprint,decision:a}),a==="deny"?{success:!1,observation:`\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C: ${e}`,rejected:!0}:this.doExecuteTool(e,n)}async doExecuteTool(e,n){let o=this.deps.tools[e];if(!o)return{success:!1,observation:`Unknown tool: ${e}`};try{let r=_a(o,n);if(!r.ok)return{success:!1,observation:r.error};let s=await o.execute(r.data);return{success:!0,observation:ka(s)||"(no tool output)"}}catch(r){return{success:!1,observation:`Tool execution failed: ${r.message}`}}}async runTurn(e){let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let o=this.turnIndex,r=[],s=Mo(),i=Date.now();this.sessionStartEmitted||(await this.emitEvent("session_start",{meta:{mode:this.mode,tokenizer:this.tokenCounter.model,warnPromptTokens:this.options.warnPromptTokens,maxPromptTokens:this.options.maxPromptTokens}}),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 Y(this.hooks,"onTurnStart",{sessionId:this.id,turn:o,input:e,promptTokens:a,history:je(this.history)});let c="",l="ok",u;for(let p=0;;p++){let v=this.tokenCounter.countMessages(this.history);if(this.options.maxPromptTokens&&v>this.options.maxPromptTokens){let S=`Context tokens (${v}) exceed the limit. Please shorten the input or restart the session.`,w=JSON.stringify({final:S});this.history.push({role:"assistant",content:w}),l="prompt_limit",c=S,u=S,await this.emitEvent("final",{turn:o,step:p,content:S,role:"assistant",meta:{tokens:{prompt:v}}}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:S,status:l,errorMessage:u,turnUsage:{...s},steps:r});break}this.options.warnPromptTokens&&v>this.options.warnPromptTokens&&console.warn(`Prompt tokens are near the limit: ${v}`);let m="",_=[],y,C=!1,P;try{let S=await this.deps.callLLM(this.history,j=>this.deps.onAssistantStep?.(j,p),{signal:n.signal}),w=Ta(S);m=w.textContent,_=w.toolUseBlocks,P=w.stopReason,y=w.usage,C=!!w.streamed}catch(S){if(this.cancelling&&ba(S)){l="cancelled",c="",u="Turn cancelled",await this.emitEvent("final",{turn:o,step:p,content:"",role:"assistant",meta:{cancelled:!0}}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,errorMessage:u,turnUsage:{...s},steps:r});break}let w=`LLM call failed: ${S.message}`,j=JSON.stringify({final:w});this.history.push({role:"assistant",content:j}),l="error",c=w,u=w,await this.emitEvent("final",{turn:o,content:w,role:"assistant"}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,errorMessage:u,turnUsage:{...s},steps:r});break}C||this.deps.onAssistantStep?.(m,p);let g;if(_.length>0){let S=_[0];if(S){let w=m?Qt([m]):void 0;g={action:{tool:S.name,input:S.input},thinking:w}}else g={}}else m?g=Co(m):g={};let M=g.action?JSON.stringify({tool:g.action.tool,input:g.action.input}):g.final?JSON.stringify({final:g.final}):m;this.history.push({role:"assistant",content:M});let x=this.tokenCounter.countText(m),E=y?.prompt??v,U=y?.completion??x,$=y?.total??E+U,V={prompt:E,completion:U,total:$};if(Po(s,V),Po(this.sessionUsage,V),r.push({index:p,assistantText:m,parsed:g,tokenUsage:V}),await this.emitEvent("assistant",{turn:o,step:p,content:m,role:"assistant",meta:{tokens:V}}),_.length>1){for(let H of _)this.maybeWarnRepeatedAction(H.name,H.input);await this.emitEvent("action",{turn:o,step:p,meta:{tools:_.map(H=>H.name),parallel:!0,thinking:g.thinking,toolBlocks:_.map(H=>({name:H.name,input:H.input}))}});let S=_[0];S&&await Y(this.hooks,"onAction",{sessionId:this.id,turn:o,step:p,action:{tool:S.name,input:S.input},parallelActions:_.map(H=>({tool:H.name,input:H.input})),thinking:g.thinking,history:je(this.history)});let w=[],j=!1;for(let[H,B]of _.entries()){let ue=await this.executeToolWithApproval(B.name,B.input,o,p);if(ue.rejected){j=!0,w.push(`[${B.name}]: ${ue.observation}`),await this.emitEvent("observation",{turn:o,step:p,content:ue.observation,meta:{tool:B.name,index:H}});break}w.push(`[${B.name}]: ${ue.observation}`),await this.emitEvent("observation",{turn:o,step:p,content:ue.observation,meta:{tool:B.name,index:H}})}let re=w.join(`
|
|
44
49
|
|
|
45
|
-
`);this.history.push({role:"user",content:JSON.stringify({observation:
|
|
46
|
-
`;case"checkbox":return
|
|
47
|
-
`).map(
|
|
48
|
-
`).trimEnd()}function
|
|
49
|
-
`)}function
|
|
50
|
+
`);this.history.push({role:"user",content:JSON.stringify({observation:re})});let J=r[r.length-1];if(J&&(J.observation=re),await Y(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:p,tool:_.map(H=>H.name).join(", "),observation:re,history:je(this.history)}),j){l="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:p,content:c,role:"assistant",meta:{rejected:!0}}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,tokenUsage:V,turnUsage:{...s},steps:r});break}continue}else if(g.action){this.maybeWarnRepeatedAction(g.action.tool,g.action.input),await this.emitEvent("action",{turn:o,step:p,meta:{tool:g.action.tool,input:g.action.input,thinking:g.thinking}}),await Y(this.hooks,"onAction",{sessionId:this.id,turn:o,step:p,action:g.action,thinking:g.thinking,history:je(this.history)});let S=await this.executeToolWithApproval(g.action.tool,g.action.input,o,p);if(S.rejected){l="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:p,content:c,role:"assistant",meta:{rejected:!0}}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,tokenUsage:V,turnUsage:{...s},steps:r});break}let w=S.observation;this.history.push({role:"user",content:JSON.stringify({observation:w,tool:g.action.tool})});let j=r[r.length-1];j&&(j.observation=w),await this.emitEvent("observation",{turn:o,step:p,content:w,meta:{tool:g.action.tool}}),await Y(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:p,tool:g.action.tool,observation:w,history:je(this.history)});continue}if(P==="end_turn"||g.final){this.resetActionRepetition(),c=g.final||m,g.final&&(g.final=c),await this.emitEvent("final",{turn:o,step:p,content:c,role:"assistant",meta:{tokens:V}}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,tokenUsage:V,turnUsage:{...s},steps:r});break}this.resetActionRepetition();break}if(!c&&l!=="cancelled"){l==="ok"&&(l="error"),c="Unable to produce a final answer. Please retry or adjust the request.",u=c;let p=JSON.stringify({final:c});this.history.push({role:"assistant",content:p}),await this.emitEvent("final",{turn:o,content:c,role:"assistant"}),await Y(this.hooks,"onFinal",{sessionId:this.id,turn:o,finalText:c,status:l,errorMessage:u,turnUsage:{...s},steps:r})}return await this.emitEvent("turn_end",{turn:o,meta:{status:l,stepCount:r.length,durationMs:Date.now()-i,tokens:s}}),{finalText:c,steps:r,status:l,errorMessage:u,tokenUsage:s}}finally{this.currentAbortController=null,this.cancelling=!1,this.approvalManager.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.approvalManager.dispose(),this.deps.dispose&&await this.deps.dispose()}async emitEvent(e,n){if(!this.sinks.length)return;let o=$n({sessionId:this.id,type:e,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await Sa(o,this.sinks)}};async function Ye(t,e={}){let n=e.sessionId||Ro(),o=await ko(t,{...e,sessionId:n},n),r=await o.loadPrompt(),s=new sn({...t,...o},{...e,sessionId:n,mode:e.mode??$o},r,o.tokenCounter,o.historyFilePath);return await s.init(),s}import{useCallback as ee,useEffect as It,useMemo as Pr,useRef as Lt,useState as W}from"react";import{readFile as Rl}from"fs/promises";import"path";import{randomUUID as Nt}from"crypto";import{exec as $l}from"child_process";import{promisify as Il}from"util";import{Box as Rr,useApp as Ll,Text as Nl}from"ink";import{Box as Io,Text as wa}from"ink";import{memo as Ca}from"react";import{jsx as Lo,jsxs as Ea}from"react/jsx-runtime";var No=Ca(function({contextPercent:e=0}){let n=e>0?` ${e.toFixed(1)}%`:" 0.0%";return Lo(Io,{justifyContent:"flex-end",children:Lo(Io,{marginTop:8,children:Ea(wa,{color:"gray",children:["context:",n]})})})});import{Box as ve,Static as Qa,Text as le}from"ink";import{memo as ec}from"react";import tc from"os";import{Box as Aa,Text as Oo}from"ink";import{memo as Ma}from"react";import{jsx as Pa,jsxs as Do}from"react/jsx-runtime";var Uo=Ma(function({message:e}){return Do(Aa,{flexDirection:"column",gap:0,children:[Do(Oo,{color:"cyan",children:["\u25CF ",e.title]}),Pa(Oo,{color:"gray",children:e.content})]})});import{Box as qa,Text as Xa}from"ink";import{memo as Ya}from"react";import{Box as Ze,Text as oe}from"ink";import{memo as Ba}from"react";import{Box as an,Text as z}from"ink";import{marked as Ra}from"marked";import{useMemo as jo,memo as $a}from"react";import{jsx as Z,jsxs as He}from"react/jsx-runtime";var Ia="#2b2b2b";function wt(t){return t?[{type:"text",raw:t,text:t}]:[]}function La(t,e,n){switch(t.type){case"text":return t.tokens&&t.tokens.length>0?xe(t.tokens,e,`${n}-text`):t.text;case"escape":return t.text;case"strong":return Z(z,{bold:!0,children:xe(t.tokens,e,`${n}-strong`)},n);case"em":return Z(z,{italic:!0,children:xe(t.tokens,e,`${n}-em`)},n);case"codespan":return Z(z,{color:e.codeColor,backgroundColor:Ia,children:t.text},n);case"del":return Z(z,{strikethrough:!0,children:xe(t.tokens,e,`${n}-del`)},n);case"link":{let o=t.tokens&&t.tokens.length>0?xe(t.tokens,e,`${n}-link`):t.text,r=t.href&&t.text&&t.text!==t.href?` (${t.href})`:"";return He(z,{underline:!0,color:e.linkColor,children:[o,r]},n)}case"image":{let o=t.text||"image";return He(z,{color:e.linkColor,children:["[",o,"](",t.href,")"]},n)}case"br":return`
|
|
51
|
+
`;case"checkbox":return t.checked?"[x]":"[ ]";case"html":return t.text;default:return"text"in t?t.text:t.raw}}function xe(t,e,n){return!t||t.length===0?[]:t.flatMap((o,r)=>{let s=`${n}-${r}`,i=La(o,e,s);return Array.isArray(i)?i:[i]})}function Na(t){let e=t.tokens[0];return e?.type==="paragraph"||e?.type==="text"?e.tokens??wt(e.text):t.tokens.length>0?t.tokens:wt(t.text)}function Oa(t){return t.split(`
|
|
52
|
+
`).map(e=>e.length>0?` ${e}`:"").join(`
|
|
53
|
+
`).trimEnd()}function Da(t){let e=t.header.map(r=>r.text).join(" | "),n=t.header.map(()=>"---").join(" | "),o=t.rows.map(r=>r.map(s=>s.text).join(" | "));return[e,n,...o].join(`
|
|
54
|
+
`)}function Ua(t){return t.type==="table"&&"header"in t&&"rows"in t&&"align"in t}function ja(t,e,n){switch(t.type){case"space":case"def":return null;case"heading":return Z(z,{bold:!0,color:e.textColor,children:xe(t.tokens,e,`${n}-heading`)},n);case"paragraph":{let o=t.tokens??wt(t.text);return Z(z,{color:e.textColor,children:xe(o,e,`${n}-para`)},n)}case"text":{let o=t.tokens??wt(t.text);return Z(z,{color:e.textColor,children:xe(o,e,`${n}-text`)},n)}case"code":{let o=Oa(t.text);return Z(z,{color:e.codeColor,children:o},n)}case"list":{let o=typeof t.start=="number"?t.start:1;return Z(an,{flexDirection:"column",children:t.items.map((r,s)=>{let i=t.ordered?`${o+s}.`:"-",a=r.task?r.checked?"[x] ":"[ ] ":"",c=Na(r);return He(an,{children:[He(z,{color:e.textColor,children:[i," "]}),He(z,{color:e.textColor,children:[a,xe(c,e,`${n}-item-${s}`)]})]},`${n}-item-${s}`)})},n)}case"blockquote":return He(z,{color:"gray",dimColor:!0,children:["> ",t.text.trim()]},n);case"hr":return Z(z,{color:"gray",children:"---"},n);case"table":return Ua(t)?Z(z,{color:e.textColor,children:Da(t)},n):Z(z,{color:e.textColor,children:"text"in t?t.text:t.raw},n);case"html":return Z(z,{color:e.textColor,children:t.text},n);default:return Z(z,{color:e.textColor,children:"text"in t?t.text:t.raw},n)}}function Ha(t,e,n){return t.flatMap((o,r)=>{let s=ja(o,e,`${n}-${r}`);return s?[s]:[]})}var Be=$a(function({text:e,tone:n="normal"}){let o=jo(()=>({textColor:n==="muted"?"gray":void 0,codeColor:n==="muted"?"gray":"cyan",linkColor:n==="muted"?"gray":"blue",muted:n==="muted"}),[n]),r=jo(()=>{let s=Ra.lexer(e,{gfm:!0,breaks:!0});return Ha(s,o,"markdown")},[e,o]);return Z(an,{flexDirection:"column",gap:1,children:r})});import{Fragment as cn,jsx as K,jsxs as Fe}from"react/jsx-runtime";function Ho(t){if(!t)return;if(typeof t=="string")return t.length>50?t.slice(0,47)+"...":t;if(typeof t!="object"||Array.isArray(t))return;let e=t,n=["file_path","path","file","filename","url","command","pattern","glob","query","content","cwd","dir"];for(let o of n)if(e[o]){let r=String(e[o]);return r.length>50?r.slice(0,47)+"...":r}for(let[o,r]of Object.entries(e))if(typeof r=="string"&&o!=="description")return r.length>50?r.slice(0,47)+"...":r}function Fa(t,e){let n=t.step,o=e.step;return!(n.index!==o.index||n.assistantText!==o.assistantText||n.thinking!==o.thinking||n.action?.tool!==o.action?.tool||JSON.stringify(n.action?.input)!==JSON.stringify(o.action?.input)||JSON.stringify(n.parallelActions)!==JSON.stringify(o.parallelActions)||n.toolStatus!==o.toolStatus)}var Bo=Ba(function({step:e}){let n=e.action?.tool,o=e.action?.input,r=Ho(o),s=e.parallelActions??[],i=s.length>1;return Fe(Ze,{flexDirection:"column",gap:0,children:[e.thinking&&Fe(Ze,{children:[K(oe,{color:"gray",children:"\u25CF "}),K(Ze,{flexDirection:"column",flexGrow:1,children:K(Be,{text:e.thinking,tone:"muted"})})]}),i&&K(cn,{children:s.map((a,c)=>{let l=Ho(a.input);return Fe(Ze,{children:[K(oe,{color:"green",children:"\u25CF "}),K(oe,{color:"gray",children:"Used "}),K(oe,{color:"cyan",children:a.tool}),l&&Fe(cn,{children:[K(oe,{color:"gray",children:" ("}),K(oe,{color:"cyan",children:l}),K(oe,{color:"gray",children:")"})]})]},c)})}),!i&&n&&Fe(Ze,{children:[K(oe,{color:"green",children:"\u25CF "}),K(oe,{color:"gray",children:"Used "}),K(oe,{color:"cyan",children:n}),r&&Fe(cn,{children:[K(oe,{color:"gray",children:" ("}),K(oe,{color:"cyan",children:r}),K(oe,{color:"gray",children:")"})]})]})]})},Fa);import{Box as Va,Text as Fo}from"ink";import{memo as Ga}from"react";import{jsx as Vo,jsxs as za}from"react/jsx-runtime";var Go=Ga(function({text:e}){return za(Va,{paddingY:1,children:[Vo(Fo,{color:"gray",children:"\u203A "}),Vo(Fo,{color:"white",children:e})]})});import{Box as Qe,Text as $e}from"ink";import{memo as ln,useMemo as Wa}from"react";import{Fragment as Ja,jsx as ae,jsxs as Ct}from"react/jsx-runtime";function Ka(t){let e=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,n=[],o,r=0,s=[];for(;(o=e.exec(t))!==null;){s.push({start:o.index,end:e.lastIndex});let a=o[2]?.trim();a&&n.push(a)}if(s.length===0)return{content:t,thinking:null};let i="";r=0;for(let{start:a,end:c}of s)i+=t.slice(r,a),r=c;return i+=t.slice(r),i=i.replace(/\n{3,}/g,`
|
|
50
55
|
|
|
51
56
|
`).trim(),{content:i,thinking:n.length>0?n.join(`
|
|
52
57
|
|
|
53
|
-
`):null}}var
|
|
58
|
+
`):null}}var zo=ln(function({text:e,isThinking:n=!1}){let{content:o,thinking:r}=Wa(()=>Ka(e),[e]);return n?ae(Qe,{flexDirection:"column",flexGrow:1,children:ae(Be,{text:e,tone:"muted"})}):Ct(Qe,{flexDirection:"column",flexGrow:1,gap:1,children:[r&&ae(Qe,{flexDirection:"column",paddingLeft:2,children:ae(Be,{text:r,tone:"muted"})}),ae(Be,{text:o,tone:"normal"})]})}),ed=ln(function({text:e}){return ae(Qe,{children:Ct($e,{color:"gray",children:["\u2022 ",e]})})}),td=ln(function({toolName:e,fileName:n}){return Ct(Qe,{children:[ae($e,{color:"green",children:"\u25CF "}),ae($e,{color:"gray",children:"Used "}),ae($e,{color:"cyan",children:e}),n&&Ct(Ja,{children:[ae($e,{color:"gray",children:" ("}),ae($e,{color:"cyan",children:n}),ae($e,{color:"gray",children:")"})]})]})});import{jsx as un,jsxs as Wo}from"react/jsx-runtime";function Za(t,e){let n=t.turn,o=e.turn;if(n.index!==o.index||n.userInput!==o.userInput||n.finalText!==o.finalText||n.status!==o.status||n.steps.length!==o.steps.length||n.tokenUsage?.total!==o.tokenUsage?.total)return!1;for(let r=0;r<n.steps.length;r++){let s=n.steps[r],i=o.steps[r];if(!s||!i||s.assistantText!==i.assistantText||s.thinking!==i.thinking||s.action?.tool!==i.action?.tool)return!1}return!0}var pn=Ya(function({turn:e}){let n=e.finalText?.trim()??"",o=n.length>0;return Wo(qa,{flexDirection:"column",children:[un(Go,{text:e.userInput}),e.steps.map(r=>un(Bo,{step:r},`step-${e.index}-${r.index}`)),o?un(zo,{text:n,isThinking:!1}):null,e.status&&e.status!=="ok"?Wo(Xa,{color:"red",children:["Status: ",e.status]}):null]})},Za);import{jsx as Q,jsxs as Te}from"react/jsx-runtime";function nc(t){let e=tc.homedir();return e&&t.startsWith(e)?`~${t.slice(e.length)}`:t}function oc(t){return t.length>16?`${t.slice(0,8)}...${t.slice(-4)}`:t}function rc(t,e){if(t.headerInfo?.sessionId!==e.headerInfo?.sessionId||t.headerInfo?.model!==e.headerInfo?.model||t.headerInfo?.providerName!==e.headerInfo?.providerName||t.headerInfo?.cwd!==e.headerInfo?.cwd||t.headerInfo?.mcpNames?.length!==e.headerInfo?.mcpNames?.length)return!1;if(t.headerInfo?.mcpNames&&e.headerInfo?.mcpNames){let n=t.headerInfo.mcpNames,o=e.headerInfo.mcpNames;for(let r=0;r<n.length;r++)if(n[r]!==o[r])return!1}if(t.systemMessages.length!==e.systemMessages.length)return!1;for(let n=0;n<t.systemMessages.length;n++)if(t.systemMessages[n]?.id!==e.systemMessages[n]?.id)return!1;if(t.turns.length!==e.turns.length)return!1;for(let n=0;n<t.turns.length;n++)if(t.turns[n]!==e.turns[n])return!1;return!0}var Ko=ec(function({systemMessages:e,turns:n,headerInfo:o}){let r=n.length>0?n[n.length-1]:void 0,s=r&&(r.finalText||r.status&&r.status!=="ok"),i=s?n:n.slice(0,-1),a=s?void 0:r,c=[];o&&c.push({type:"header",data:o});let l=[];for(let u of e)l.push({sequence:u.sequence,item:{type:"system",data:u}});for(let u of i){let p=u.sequence??0;l.push({sequence:p,item:{type:"turn",data:u}})}l.sort((u,p)=>u.sequence-p.sequence);for(let u of l)c.push(u.item);return Te(ve,{flexDirection:"column",gap:0,children:[Q(Qa,{items:c,children:u=>{if(u.type==="header"&&u.data){let p=u.data;return Te(ve,{borderStyle:"round",borderColor:"blueBright",paddingX:2,paddingY:1,flexDirection:"column",gap:1,children:[Q(ve,{gap:1,alignItems:"center",children:Te(ve,{flexDirection:"column",children:[Q(le,{bold:!0,children:"Welcome to Memo Code CLI!"}),Q(le,{color:"gray",children:"Send /help for help information."})]})}),Te(ve,{flexDirection:"column",gap:0,children:[Te(ve,{children:[Q(le,{color:"gray",children:"Directory: "}),Q(le,{color:"cyan",children:nc(p.cwd)})]}),Te(ve,{children:[Q(le,{color:"gray",children:"Session: "}),Q(le,{color:"cyan",children:oc(p.sessionId)})]}),Te(ve,{children:[Q(le,{color:"gray",children:"Model: "}),Q(le,{color:"cyan",children:p.model}),Te(le,{color:"gray",children:[" ","(powered by ",p.providerName,")"]})]}),Te(ve,{children:[Q(le,{color:"gray",children:"MCP: "}),Q(le,{color:"cyan",children:p.mcpNames.length>0?p.mcpNames.join(", "):"none"})]})]})]},"header")}return u.type==="system"?Q(Uo,{message:u.data},u.data.id):u.type==="turn"?Q(pn,{turn:u.data},`turn-${u.data.index}`):null}}),a&&Q(pn,{turn:a},`turn-live-${a.index}`)]})},rc);import{useCallback as yr,useEffect as vn,useMemo as Wc,useRef as Tn,useState as Ce}from"react";import{readFile as Kc,readdir as Jc,stat as qc}from"fs/promises";import{basename as Xc,join as Yc,resolve as xr}from"path";import{Box as $t,Text as Ie,useInput as Zc}from"ink";var rr=Pn(nr(),1);import{readFile as wc,readdir as Cc}from"fs/promises";import{join as or,relative as Ec,sep as Ac}from"path";var Mc=6,Pc=2500,sr=25,Rc=[".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs","*.log"],Pt=new Map;function $c(t){return t.split(Ac).join("/")}function Ic(t,e){return JSON.stringify({maxDepth:t.maxDepth,maxEntries:t.maxEntries,respectGitIgnore:t.respectGitIgnore,ignoreGlobs:t.ignoreGlobs,gitignore:e})}function Lc(t){return{maxDepth:typeof t.maxDepth=="number"?Math.max(1,t.maxDepth):Mc,maxEntries:typeof t.maxEntries=="number"?Math.max(100,t.maxEntries):Pc,limit:typeof t.limit=="number"?Math.max(1,t.limit):sr,respectGitIgnore:t.respectGitIgnore!==!1,ignoreGlobs:t.ignoreGlobs?.length?t.ignoreGlobs:[]}}async function Nc(t,e){if(!e)return"";try{return await wc(or(t,".gitignore"),"utf8")}catch{}return""}async function Oc(t,e){let n=await Nc(e,t.respectGitIgnore),o=(0,rr.default)();o.add(Rc),t.ignoreGlobs.length&&o.add(t.ignoreGlobs),n.trim()&&o.add(n);let r=Ic(t,n);return Object.assign(o,{__memoSignature:r})}async function Dc(t,e,n){let o=[],r=e.maxEntries,s=async(i,a)=>{if(o.length>=r)return;let c;try{c=await Cc(i,{withFileTypes:!0})}catch{return}for(let l of c){if(o.length>=r)break;if(l.isSymbolicLink())continue;let u=or(i,l.name),p=Ec(t,u);if(!p)continue;let v=$c(p);if(n.ignores(v))continue;let m=v.split("/").filter(Boolean),_=m.map(C=>C.toLowerCase()),y=l.isDirectory();if(o.push({path:v,pathLower:v.toLowerCase(),segments:m,segmentsLower:_,depth:a,isDir:y}),o.length>=r)break;y&&a<e.maxDepth&&await s(u,a+1)}};return await s(t,0),o.sort((i,a)=>i.path.localeCompare(a.path)),{entries:o,signature:n.__memoSignature}}async function Uc(t,e){let n=Lc(e),o=await Oc(n,t),r=o.__memoSignature,s=Pt.get(t);if(s&&s.signature===r)return s.pending?s.pending:s.entries;let i=Dc(t,n,o).then(a=>(Pt.set(t,{entries:a.entries,signature:a.signature}),a.entries)).catch(a=>{throw Pt.delete(t),a});return Pt.set(t,{entries:[],signature:r,pending:i}),i}function jc(t){return t.depth+(t.isDir?-.2:.2)}function Hc(t,e){if(!e.length)return jc(t);let n=t.depth,o=0;for(let r of e){let s=-1;for(let i=o;i<t.segmentsLower.length;i++){let a=t.segmentsLower[i];if(a.startsWith(r)){s=i,n+=(i-o)*1.5,n+=a.length-r.length;break}let c=a.indexOf(r);if(c!==-1){s=i,n+=(i-o)*2+c+2;break}}if(s===-1)return null;o=s+1}return t.isDir&&(n-=.5),n}function Bc(t,e,n){let s=e.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(a=>a.toLowerCase()),i=[];for(let a of t){let c=Hc(a,s);c!==null&&i.push({entry:a,score:c})}return i.sort((a,c)=>{let l=a.score-c.score;return l!==0?l:a.entry.path.localeCompare(c.entry.path)}),i.slice(0,n).map(({entry:a})=>({id:a.path,path:a.path,name:a.segments[a.segments.length-1]??a.path,parent:a.segments.length>1?a.segments.slice(0,-1).join("/"):void 0,isDir:a.isDir}))}async function ir(t){let e=await Uc(t.cwd,t),n=typeof t.limit=="number"?Math.max(1,t.limit):sr;return Bc(e,t.query,n)}import{mkdir as _d,readFile as bd,writeFile as wd}from"fs/promises";import{dirname as Ed}from"path";import{randomUUID as Md}from"crypto";import{Box as tt,Text as ze}from"ink";import{jsx as ke,jsxs as cr}from"react/jsx-runtime";var Fc="#3a3a3a",Rt="#2b2b2b",ar="#888888",Vc="#666666";function lr({items:t,activeIndex:e,loading:n}){return n?ke(tt,{flexDirection:"column",paddingX:1,backgroundColor:Rt,children:ke(ze,{color:"gray",children:"Loading..."})}):t.length?ke(tt,{flexDirection:"column",backgroundColor:Rt,children:t.map((o,r)=>{let s=r===e,i=s?Fc:Rt;return o.kind==="slash"?cr(tt,{flexDirection:"row",gap:2,paddingX:1,backgroundColor:i,children:[ke(ze,{color:s?"cyan":"white",bold:s,children:o.title}),o.subtitle?ke(ze,{color:ar,children:o.subtitle}):null]},o.id):cr(tt,{flexDirection:"row",gap:1,paddingX:1,backgroundColor:i,children:[ke(ze,{color:s?"cyan":"white",bold:s,children:o.title}),o.subtitle?ke(ze,{color:ar,children:o.subtitle}):null]},o.id)})}):ke(tt,{flexDirection:"column",paddingX:1,backgroundColor:Rt,children:ke(ze,{color:Vc,children:"No matches"})})}var ur={name:"new",description:"Start a new session",run:({closeSuggestions:t,setInputValue:e,clearScreen:n,showSystemMessage:o,newSession:r})=>{t(),e(""),n(),o("New Session","Starting a new session..."),r?.()}};var pr={name:"exit",description:"Exit the session",run:({closeSuggestions:t,exitApp:e})=>{t(),e()}};var mr={name:"resume",description:"Resume history",run:({closeSuggestions:t,setInputValue:e,showSystemMessage:n})=>{t(!1),e("resume "),n("Resume",'Type "resume" followed by keywords to filter and select from session history.')}};var dr={name:"models",description:"Select a model (from configured providers)",run:({closeSuggestions:t,setInputValue:e,showSystemMessage:n,data:o})=>{t(!1);let{providers:r,providerName:s,model:i}=o;if(!r.length){n("Models",`No providers configured. Check ${o.configPath}`),e("");return}let a=r.map(c=>{let l=c.name===s&&c.model===i?" (current)":"",u=c.base_url?` @ ${c.base_url}`:"";return`- ${c.name}: ${c.model}${u}${l}`});e("/models "),n("Models",`Available models:
|
|
54
59
|
${a.join(`
|
|
55
|
-
`)}`)}};var
|
|
60
|
+
`)}`)}};var Gc=`Available commands:
|
|
56
61
|
/help Show help and shortcuts
|
|
57
62
|
/exit Exit the session
|
|
58
63
|
exit Exit the session (no slash)
|
|
@@ -71,15 +76,15 @@ Shortcuts:
|
|
|
71
76
|
Ctrl+L Start a new session
|
|
72
77
|
Ctrl+C Exit
|
|
73
78
|
exit Type in input to exit
|
|
74
|
-
Esc Esc Cancel / Clear input`,
|
|
75
|
-
`)}var
|
|
76
|
-
|
|
77
|
-
Add servers to ${s}`),
|
|
78
|
-
`);for(let[c,l]of Object.entries(r))a.push(
|
|
79
|
-
`))}};var
|
|
80
|
-
`;
|
|
81
|
-
`),
|
|
82
|
-
`)){let n=
|
|
79
|
+
Esc Esc Cancel / Clear input`,fr={name:"help",description:"Show help",run:({closeSuggestions:t,setInputValue:e,showSystemMessage:n})=>{t(),e(""),n("Help",Gc)}};var gr={name:"context",description:"Set context length limit (80k/120k/150k/200k)",run:({closeSuggestions:t,setInputValue:e})=>{t(!1),e("/context ")}};function zc(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: ${e.bearer_token_env_var}`),e.type!=="sse"&&e.fallback_to_sse!==void 0&&n.push(` - Fallback to SSE: ${e.fallback_to_sse}`);let o=e.http_headers??e.headers;if(o&&Object.keys(o).length>0){let r=Object.entries(o).map(([s,i])=>`${s}=${i}`).join(", ");n.push(` - Headers: ${r}`)}}else if(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){let o=Object.entries(e.env).map(([r,s])=>`${r}=${s}`).join(", ");n.push(` - Env: ${o}`)}return n.join(`
|
|
80
|
+
`)}var hr={name:"mcp",description:"Show configured MCP servers",run:({closeSuggestions:t,setInputValue:e,showSystemMessage:n,data:o})=>{t();let{mcpServers:r,configPath:s}=o,i=Object.keys(r);if(i.length===0){n("MCP Servers",`No MCP servers configured.
|
|
81
|
+
|
|
82
|
+
Add servers to ${s}`),e("");return}let a=[];a.push(`Total: ${i.length} server(s)
|
|
83
|
+
`);for(let[c,l]of Object.entries(r))a.push(zc(c,l)),a.push("");e(""),n("MCP Servers",a.join(`
|
|
84
|
+
`))}};var xn=[fr,pr,ur,mr,dr,gr,hr];import{Fragment as ml,jsx as Ee,jsxs as nt}from"react/jsx-runtime";var Qc=400;function vr({disabled:t,onSubmit:e,onExit:n,onClear:o,onNewSession:r,onCancelRun:s,onModelSelect:i,onSystemMessage:a,onSetContextLimit:c,history:l,cwd:u,sessionsDir:p,currentSessionFile:v,onHistorySelect:m,providers:_,configPath:y,providerName:C,model:P,contextLimit:g,mcpServers:M}){let[x,E]=Ce(""),[U,$]=Ce(null),[V,S]=Ce(""),[w,j]=Ce("none"),[re,J]=Ce([]),[H,B]=Ce(0),[ue,fe]=Ce(!1),[Oe,be]=Ce(!1),q=Tn(0),De=Tn(0),D=Tn(""),we="\u203A ";vn(()=>{D.current=x,be(!1)},[x]);let F=Wc(()=>Oe||t?null:rl(x),[t,Oe,x]),X=yr((I=!0)=>{I&&be(!0),j("none"),J([]),B(0),fe(!1)},[]);vn(()=>{t&&X(!1)},[t,X]),vn(()=>{if(!F){j("none"),J([]),B(0),fe(!1);return}let I=!1,N=++q.current;return fe(!0),(async()=>{try{if(F.type==="file"){let h=await ir({cwd:u,query:F.query,limit:8});if(I||N!==q.current)return;let L=h.map(k=>{let A=k.isDir?`${k.path}/`:k.path;return{id:k.id,title:A,kind:"file",value:A,meta:{isDir:k.isDir}}});j("file"),J(L),B(k=>L.length?Math.min(k,L.length-1):0);return}if(F.type==="history"){let h=await el({sessionsDir:p,cwd:u,keyword:F.keyword,activeSessionFile:v});if(I||N!==q.current)return;let L=h.map(ul);j("history"),J(L),B(k=>L.length?Math.min(k,L.length-1):0);return}if(F.type==="models"){let h=F.keyword.toLowerCase(),k=(_??[]).filter(A=>{let se=A.name?.toLowerCase()??"",Me=A.model?.toLowerCase()??"";return h?se.includes(h)||Me.includes(h):!0}).map(A=>({id:A.name,title:`${A.name}: ${A.model}`,subtitle:A.base_url??A.env_api_key??"",kind:"model",value:`/models ${A.name}`,meta:{provider:A}}));j("model"),J(k),B(A=>k.length?Math.min(A,k.length-1):0);return}if(F.type==="context"){let L=[8e4,12e4,15e4,2e5].map(k=>({id:`${k}`,title:`${(k/1e3).toFixed(0)}k tokens`,subtitle:k===g?"Current":void 0,kind:"context",value:`/context ${(k/1e3).toFixed(0)}k`,meta:{contextValue:k}}));j("context"),J(L),B(k=>L.length?Math.min(k,L.length-1):0);return}if(F.type==="slash"){let h=F.keyword.toLowerCase(),k=(h?xn.filter(A=>A.matches?A.matches(h):A.name.startsWith(h)):xn).map(A=>({id:A.name,title:`/${A.name}`,subtitle:A.description,kind:"slash",value:`/${A.name} `,meta:{slashCommand:A}}));j("slash"),J(k),B(A=>k.length?Math.min(A,k.length-1):0);return}}catch{!I&&N===q.current&&J([])}finally{!I&&N===q.current&&fe(!1)}})(),()=>{I=!0}},[F,u,p,v,_,g]);let Ue=yr(I=>{if(I){if(w==="file"&&F?.type==="file"){let N=x.slice(0,F.tokenStart),h=x.slice(F.tokenStart+F.query.length),L=`${N}${I.value}${h}`;D.current=L,E(L),$(null),S(""),I.meta?.isDir||X();return}if(w==="history"){I.meta?.historyEntry&&m?.(I.meta.historyEntry),D.current=I.value,E(I.value),$(null),S(""),X();return}if(w==="model"&&I.meta?.provider){i?.(I.meta.provider),D.current="",E(""),$(null),S(""),X();return}if(w==="slash"&&I.meta?.slashCommand){I.meta.slashCommand.run({setInputValue:h=>{D.current=h,E(h),$(null),S("")},closeSuggestions:X,clearScreen:()=>{o()},newSession:()=>{r?.()},exitApp:()=>{n()},showSystemMessage:(h,L)=>{a?.(h,L)},switchModel:h=>{i?.(h)},setContextLimit:h=>{c?.(h)},loadHistory:h=>{m?.(h)},data:{configPath:y,providerName:C,model:P,contextLimit:g,providers:_,mcpServers:M}});return}if(w==="context"&&I.meta?.contextValue){let N=I.meta.contextValue;c?.(N),a?.("Context",`Context limit set to ${(N/1e3).toFixed(0)}k tokens`),D.current="",E(""),$(null),S(""),X();return}}},[X,o,n,i,a,c,m,w,F,x,y,C,P,g,_,M]);Zc((I,N)=>{if(N.ctrl&&I==="l"){D.current="",E(""),$(null),S(""),X(),o(),r?.();return}let h=w!=="none",L=h&&re.length>0;if(N.escape){let k=Date.now();if(k-De.current<=Qc){De.current=0,t?s():(D.current="",E(""),$(null),S(""),X());return}De.current=k,h&&X();return}if(!t){if(N.upArrow){if(L){B(se=>se<=0?re.length-1:se-1);return}if(!l.length)return;if(U===null){S(D.current);let se=l.length-1;$(se);let Me=l[se]??"";D.current=Me,E(Me);return}let k=Math.max(0,U-1);$(k);let A=l[k]??"";D.current=A,E(A);return}if(N.downArrow){if(L){B(se=>(se+1)%re.length);return}if(U===null)return;let k=U+1;if(k>=l.length){$(null),D.current=V,E(V),S("");return}$(k);let A=l[k]??"";D.current=A,E(A);return}if(N.tab&&L){Ue(re[H]);return}if(N.return){if(L){Ue(re[H]);return}if(N.shift){let A=D.current+`
|
|
85
|
+
`;D.current=A,E(A);return}let k=D.current.trim();k&&(e(k),D.current="",E(""),$(null),S(""),X(!1));return}if(N.backspace||N.delete){let k=D.current.slice(0,Math.max(0,D.current.length-1));D.current=k,E(k);return}if(I){let k=D.current+I;D.current=k,E(k)}}});let Ot=x,it=t?" ":"\u258A",ce=Ot.split(`
|
|
86
|
+
`),Ke=2,at=re.map(({value:I,meta:N,...h})=>h);return nt($t,{flexDirection:"column",gap:1,children:[nt($t,{flexDirection:"column",paddingY:1,children:[nt($t,{children:[Ee(Ie,{color:"gray",children:we}),t?Ee(Ie,{color:"gray",children:ce[0]}):nt(ml,{children:[Ee(Ie,{color:"white",children:ce[0]}),ce.length===1&&Ee(Ie,{color:"cyan",children:it})]})]}),ce.slice(1).map((I,N)=>nt($t,{children:[Ee(Ie,{color:"gray",children:" ".repeat(Ke)}),Ee(Ie,{color:"white",children:I}),N===ce.length-2&&Ee(Ie,{color:"cyan",children:it})]},`line-${N}`))]}),w!=="none"?Ee(lr,{items:at,activeIndex:H,loading:ue}):null]})}async function el(t){let e=To(t.sessionsDir,t.cwd),n;try{n=await Jc(e,{withFileTypes:!0})}catch(l){return l?.code==="ENOENT"?[]:[]}let o=t.activeSessionFile?xr(t.activeSessionFile):null,s=(await Promise.all(n.filter(l=>l.isFile()&&l.name.endsWith(".jsonl")).map(async l=>{let u=Yc(e,l.name);if(o&&xr(u)===o)return null;try{let p=await qc(u);return{path:u,mtimeMs:p.mtimeMs}}catch{return null}}))).filter(l=>!!l).sort((l,u)=>u.mtimeMs-l.mtimeMs),i=t.limit??10,a=t.keyword?.trim().toLowerCase(),c=[];for(let l of s){if(c.length>=i)break;let u=await tl(l.path,t.cwd,l.mtimeMs);if(u&&!(a&&!u.input.toLowerCase().includes(a))&&(c.push(u),c.length>=i))break}return c}async function tl(t,e,n){try{let o=await Kc(t,"utf8"),s=nl(o)?.trim()||ol(t);return{id:t,cwd:e,input:s,ts:n,sessionFile:t}}catch{return null}}function nl(t){for(let e of t.split(`
|
|
87
|
+
`)){let n=e.trim();if(!n)continue;let o;try{o=JSON.parse(n)}catch{continue}if(o&&typeof o=="object"&&o.type==="turn_start"){let r=typeof o.content=="string"?o.content.trim():"";if(r)return r}}return null}function ol(t){return Xc(t).replace(/\.jsonl$/i,"")}function rl(t){let e=cl(t);if(e)return e;let n=al(t);if(n)return n;let o=ll(t);if(o)return o;let r=sl(t);return r||il(t)}function sl(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 il(t){let e=t.trimStart(),n=t.length-e.length;if(e.length===0)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 s=o.slice(6);return s&&!s.startsWith(" ")?null:{type:"history",keyword:s.trim()}}function al(t){let e=t.trimStart();if(!e.startsWith("/models"))return null;let n=e.slice(7);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim()}}function cl(t){let e=t.trimStart();if(!e.startsWith("/context"))return null;let n=e.slice(8);return n&&!n.startsWith(" ")?null:{type:"context"}}function ll(t){let e=t.trimStart();if(!e.startsWith("/"))return null;let n=e.slice(1);return n.includes(" ")?null:/^[a-zA-Z]*$/.test(n)?{type:"slash",keyword:n.toLowerCase()}:n.length===0?{type:"slash",keyword:""}:null}function ul(t){return{id:t.id,title:t.input,subtitle:pl(t.ts),kind:"history",badge:"HIS",value:t.input,meta:{historyEntry:t}}}function pl(t){if(!t)return"";let e=new Date(t);if(Number.isNaN(e.getTime()))return"";let n=String(e.getFullYear()),o=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0"),s=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0");return`${n}-${o}-${r} ${s}:${i}`}import{Box as ot,Text as Sn,useInput as dl}from"ink";import{useState as fl,useCallback as gl}from"react";import{jsx as rt,jsxs as kn}from"react/jsx-runtime";function hl(t){if(typeof t!="object"||t===null)return String(t);let e=Object.entries(t);if(e.length===0)return"";let[n,o]=e[0],r=typeof o=="string"?o:JSON.stringify(o);return`${r.slice(0,40)}${r.length>40?"...":""}`}function Tr({request:t,onDecision:e}){let n=[{label:"Allow once",decision:"once"},{label:"Allow all session",decision:"session"},{label:"Reject this time",decision:"deny"}],[o,r]=fl(0);dl(gl((i,a)=>{a.upArrow?r(c=>c>0?c-1:n.length-1):a.downArrow?r(c=>c<n.length-1?c+1:0):a.return&&e(n[o].decision)},[o,e,n]));let s=hl(t.params);return kn(ot,{borderStyle:"single",borderColor:"gray",paddingX:2,flexDirection:"column",children:[rt(ot,{children:rt(Sn,{bold:!0,children:"Tool Approval:"})}),rt(ot,{marginTop:1,children:kn(Sn,{color:"cyan",children:[t.toolName,s?` (${s})`:""]})}),rt(ot,{flexDirection:"column",marginTop:1,children:n.map((i,a)=>rt(ot,{children:kn(Sn,{color:o===a?"green":"gray",children:[o===a?"> ":" ",i.label]})},i.decision))})]})}import gf from"string-width";function kr(t){if(!t)return"success";let e=t.toLowerCase();return e.includes("error")||e.includes("unknown")||e.includes("failed")?"error":"success"}var Sr={"gpt-4o-mini":128e3,"gpt-4o":128e3,"gpt-4":8192,"gpt-3.5":16384,"claude-3":2e5,claude:2e5,"deepseek-coder":64e3,"deepseek-chat":64e3,deepseek:64e3,"kimi-k2":2e5,kimi:2e5,default:12e4};function yl(t){let e=t.toLowerCase(),n=Object.entries(Sr).filter(([o])=>o!=="default");for(let[o,r]of n.sort((s,i)=>i[0].length-s[0].length))if(e.includes(o))return r;return Sr.default}function _r(t,e){if(t==null)return 0;let n=typeof t=="number"?t:t.prompt??t.total??0;if(n<=0)return 0;let o=e&&e>0?e:yl("");return Math.min(100,n/o*100)}function br(t){return t?`${t.total} tokens`:""}var xl=`Available commands:
|
|
83
88
|
/help Show help and shortcuts
|
|
84
89
|
/exit Exit the session
|
|
85
90
|
exit Exit the session (no slash)
|
|
@@ -99,16 +104,16 @@ Shortcuts:
|
|
|
99
104
|
Ctrl+C Exit
|
|
100
105
|
exit Type in input to exit
|
|
101
106
|
Ctrl+X Toggle mode
|
|
102
|
-
Ctrl+/ Show help`;function
|
|
103
|
-
Current provider: ${
|
|
104
|
-
Current model: ${
|
|
107
|
+
Ctrl+/ Show help`;function wr(t,e){let[n,...o]=t.trim().slice(1).split(/\s+/),r=(n??"").toLowerCase(),s=[8e4,12e4,15e4,2e5],i=a=>{if(!a)return null;let l=a.toLowerCase().replace(/,/g,"").match(/^(\d+)(k)?$/);if(!l)return null;let u=Number(l[1])*(l[2]?1e3:1);return Number.isFinite(u)?u:null};switch(r){case"exit":return{kind:"exit"};case"new":return{kind:"new"};case"help":return{kind:"message",title:"Help",content:xl};case"config":return{kind:"message",title:"Config",content:`Config file: ${e.configPath}
|
|
108
|
+
Current provider: ${e.providerName}
|
|
109
|
+
Current model: ${e.model}`};case"resume":return{kind:"message",title:"Resume",content:'Type "resume" to filter and select from session history.'};case"context":{let p=i(o[0]),v=s.map(m=>`${m/1e3}k`).join(", ");return p===null?{kind:"message",title:"Context",content:`Current: ${(e.contextLimit/1e3).toFixed(0)}k
|
|
105
110
|
Usage: /context <length>
|
|
106
|
-
Choices: ${
|
|
111
|
+
Choices: ${v}`}:s.includes(p)?{kind:"set_context_limit",limit:p}:{kind:"message",title:"Context",content:`Unsupported length: ${p}. Pick one of: ${v}`}}case"init":return{kind:"init_agents_md"};case"$":{let p=o.join(" ").trim();return p?{kind:"shell_command",command:p}:{kind:"message",title:"Shell Command",content:"Usage: $ <command> (e.g. $ git status)"}}case"models":if(!e.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${e.configPath}`};let a=o.join(" ").trim(),c=e.providers.find(p=>p.name===a)??e.providers.find(p=>p.model===a);if(c)return{kind:"switch_model",provider:c};let l=e.providers.map(p=>{let v=p.base_url?` @ ${p.base_url}`:"";return`- ${p.name}: ${p.model}${v}`});return{kind:"message",title:"Models",content:`${a?`Not found: ${a}, `:""}Available models:
|
|
107
112
|
${l.join(`
|
|
108
|
-
`)}`};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${
|
|
109
|
-
Type /help for available commands.`}}}import{dirname as
|
|
110
|
-
`)
|
|
111
|
-
`)
|
|
113
|
+
`)}`};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${t}
|
|
114
|
+
Type /help for available commands.`}}}import{dirname as Cr,join as vl,resolve as Tl}from"path";import{statSync as Sl,existsSync as kl}from"fs";import{readFile as _l}from"fs/promises";import{get as bl}from"https";function Er(t){let e=t.trim().replace(/^v/i,""),[n="",o]=e.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 wl(t,e){let n=Er(t),o=Er(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}async function Cl(t){let e=vl(t,"package.json");if(!kl(e))return null;let n=await _l(e,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}async function El(){let e=Tl(process.argv[1]??process.cwd());try{Sl(e).isFile()&&(e=Cr(e))}catch{e=process.cwd()}for(;;){let n=await Cl(e);if(n&&n.name==="@memo-code/memo")return n;let o=Cr(e);if(o===e)break;e=o}return null}async function Al(t,e=1500){let o=`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`;return new Promise(r=>{let s=bl(o,{timeout:e},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),r(null);return}let a=[];i.on("data",c=>a.push(c)),i.on("end",()=>{try{let c=JSON.parse(Buffer.concat(a).toString("utf8"));r(c.version??null)}catch{r(null)}})});s.on("timeout",()=>{s.destroy(),r(null)}),s.on("error",()=>r(null))})}async function Ar(){let t=await El();if(!t)return null;let e=await Al(t.name);return!e||!wl(e,t.version)?null:{current:t.version,latest:e}}import{Box as We,Text as de,useInput as Ml}from"ink";import{useCallback as _n,useMemo as Pl,useState as st}from"react";import{jsx as _e,jsxs as Le}from"react/jsx-runtime";var Ae=[{key:"name",label:"Provider name",hint:"Used in /model and config",defaultValue:"deepseek"},{key:"envKey",label:"API key env var",hint:"Memo reads this env var at runtime",defaultValue:"DEEPSEEK_API_KEY"},{key:"model",label:"Model name",hint:"Provider model ID",defaultValue:"deepseek-chat"},{key:"baseUrl",label:"Base URL",hint:"Leave default unless you have a custom endpoint",defaultValue:"https://api.deepseek.com"}];function Mr({configPath:t,onComplete:e,onExit:n}){let[o,r]=st(0),[s,i]=st(""),[a,c]=st({}),[l,u]=st(!1),[p,v]=st(null),m=Ae[o]??Ae[0],_=s||a[m.key]||"",y=_n(async g=>{u(!0),v(null);try{let M=g.name||Ae[0].defaultValue,x=g.envKey||Ae[1].defaultValue,E=g.model||Ae[2].defaultValue,U=g.baseUrl||Ae[3].defaultValue;await me(t,{current_provider:M,providers:[{name:M,env_api_key:x,model:E,base_url:U||void 0}]}),e()}catch(M){v(M.message),u(!1)}},[t,e]),C=_n(async()=>{let M=s.trim()||m.defaultValue,x={...a,[m.key]:M};if(c(x),i(""),o<Ae.length-1){r(o+1);return}await y(x)},[m.defaultValue,m.key,o,s,a,y]);Ml(_n((g,M)=>{if(!l){if(M.ctrl&&g==="c"){n();return}if(M.return){C();return}if(M.backspace||M.delete){i(x=>x.slice(0,-1));return}g&&i(x=>x+g)}},[C,n,l]));let P=Pl(()=>`Step ${o+1}/${Ae.length}`,[o]);return Le(We,{flexDirection:"column",children:[Le(We,{flexDirection:"column",marginBottom:1,children:[_e(de,{bold:!0,children:"Memo setup"}),_e(de,{color:"gray",children:"No provider config found. Create one to continue."}),Le(de,{color:"gray",children:["Config path: ",t]})]}),Le(We,{flexDirection:"column",marginBottom:1,children:[_e(de,{color:"cyan",children:P}),Le(de,{children:[m.label," (default: ",m.defaultValue,")"]}),m.hint?_e(de,{color:"gray",children:m.hint}):null]}),Le(We,{children:[_e(de,{children:"> "}),_e(de,{children:_})]}),_e(We,{marginTop:1,children:_e(de,{color:"gray",children:"Press Enter to continue. Ctrl+C to exit."})}),p?_e(We,{marginTop:1,children:Le(de,{color:"red",children:["Failed to write config: ",p]})}):null]})}import{jsx as Ne,jsxs as jl}from"react/jsx-runtime";var Ol=Il($l);function Dl(t){return{index:t,userInput:"",steps:[]}}function $r({sessionOptions:t,providerName:e,model:n,configPath:o,mcpServers:r,cwd:s,sessionsDir:i,providers:a,dangerous:c=!1,needsSetup:l=!1}){let{exit:u}=Ll(),[p,v]=W(e),[m,_]=W(n),[y,C]=W(a),[P,g]=W({...t,providerName:e}),[M,x]=W(null),[E,U]=W([]),[$,V]=W([]),[S,w]=W(!1),j=Lt(null),[re,J]=W([]),[H,B]=W(null),[ue,fe]=W([]),[Oe,be]=W(null),q=Lt(null),[De,D]=W(null),we=Lt(0),[F,X]=W(t.maxPromptTokens??12e4),[Ue,Ot]=W(l),[it,ce]=W(0),[Ke,at]=W(null),I=Lt(null),N=ee(()=>(we.current+=1,we.current),[]),h=ee((d,f)=>{let T=`${Date.now()}-${Math.random().toString(16).slice(2)}`,R=N();V(O=>[...O,{id:T,title:d,content:f,sequence:R}])},[N]),L=ee((d,f)=>{U(T=>{let R=[...T],O=R.findIndex(te=>te.index===d);O===-1&&(R.push(Dl(d)),O=R.length-1);let G=R[O];return G&&(R[O]=f(G)),R})},[]),k=Pr(()=>({onAssistantStep:(d,f)=>{let T=j.current;T&&L(T,R=>{let O=R.steps.slice();for(;O.length<=f;)O.push({index:O.length,assistantText:""});let G=O[f];if(!G)return R;let te={...G,assistantText:G.assistantText+d};return O[f]=te,{...R,steps:O}})},requestApproval:c?void 0:d=>new Promise(f=>{at(d),I.current=f}),hooks:{onTurnStart:({turn:d,input:f,promptTokens:T})=>{j.current=d,T&&T>0&&ce(T),L(d,R=>({...R,index:d,userInput:f,steps:[],startedAt:Date.now(),contextPromptTokens:T??R.contextPromptTokens}))},onAction:({turn:d,step:f,action:T,thinking:R,parallelActions:O})=>{L(d,G=>{let te=G.steps.slice();for(;te.length<=f;)te.push({index:te.length,assistantText:""});let ct=te[f];return ct?(te[f]={...ct,action:T,thinking:R,toolStatus:"executing",parallelActions:O&&O.length>1?O:void 0},{...G,steps:te}):G})},onObservation:({turn:d,step:f,observation:T})=>{L(d,R=>{let O=R.steps.slice();for(;O.length<=f;)O.push({index:O.length,assistantText:""});let G=O[f];return G?(O[f]={...G,observation:T,toolStatus:kr(T)},{...R,steps:O}):R})},onFinal:({turn:d,finalText:f,status:T,turnUsage:R,tokenUsage:O})=>{L(d,G=>{let te=G.startedAt??Date.now(),ct=Math.max(0,Date.now()-te),zr=O?.prompt??G.contextPromptTokens,Wr=G.sequence??N();return{...G,finalText:f,status:T,tokenUsage:R,contextPromptTokens:zr,startedAt:te,durationMs:ct,sequence:Wr}}),w(!1)}}}),[L,c,N]);It(()=>{let d=!1;return(async()=>{if(Ue)return;let f=q.current;f&&await f.close();let T=await Ye(k,P);if(d){await T.close();return}q.current=T,x(T),B(T.historyFilePath??null)})(),()=>{d=!0}},[k,P,Ue]),It(()=>{let d=!1;return(async()=>{let f=await Ar();d||!f||h("Update",`Update available: v${f.latest}. Run npm/pnpm/yarn/bun to update @memo-code/memo.`)})(),()=>{d=!0}},[h]),It(()=>()=>{q.current&&q.current.close()},[]);let A=ee(async()=>{q.current&&await q.current.close(),D("Bye!"),setTimeout(()=>{u()},300)},[u]),se=ee(()=>{U([]),V([]),fe([]),be(null),ce(0),we.current=0},[]),Me=ee(async()=>{U([]),V([]),fe([]),be(null),ce(0),we.current=0;let d=Nt(),f={...P,sessionId:d};q.current&&await q.current.close();let T=await Ye(k,f);q.current=T,x(T),B(T.historyFilePath??null),g(f),h("New Session","Started a new session with fresh context.")},[k,P,h]),Dr=ee(async d=>{if(!d.sessionFile){h("History","This entry has no context file to load.");return}try{let f=await Rl(d.sessionFile,"utf8"),T=Ul(f);fe(T.turns),be(T.messages),w(!1),U([]),x(null),B(null),ce(0),j.current=null,we.current=Math.max(we.current,T.maxSequence),g(R=>({...R,sessionId:Nt()})),h("History loaded",T.summary||d.input)}catch(f){h("Failed to load history",`Unable to read ${d.sessionFile}: ${f.message}`)}},[h]),Cn=ee(async d=>{try{let f=await ne(),T={...f.config,current_provider:d};await me(f.configPath,T)}catch(f){h("Failed to save config",`Failed to save model selection: ${f.message}`)}},[h]),Ur=ee(()=>{S&&M?.cancelCurrentTurn?.()},[S,M]),Dt=ee(async d=>{if(d.name===p&&d.model===m){h("Model switch",`Already using ${d.name} (${d.model})`);return}if(S){h("Model switch","Currently running. Press Esc Esc to cancel before switching models.");return}U([]),fe([]),be(null),ce(0),j.current=null,x(null),B(null),v(d.name),_(d.model),g(f=>({...f,sessionId:Nt(),providerName:d.name})),await Cn(d.name),h("Model switch",`Switched to ${d.name} (${d.model})`)},[h,S,m,p,Cn]),Ut=ee(async d=>{if(!d.trim()){h("Shell Command","Usage: $ <command> (e.g. $ git status)");return}w(!0);try{let{stdout:f,stderr:T}=await Ol(d,{cwd:s,maxBuffer:5242880}),R=[f?.trim(),T?.trim()].filter(Boolean).join(`
|
|
115
|
+
`);h("Shell Result",R||"(no output)")}catch(f){let T=f,O=[T.stdout?.trim(),T.stderr?.trim(),T.message].filter(Boolean).join(`
|
|
116
|
+
`);h("Shell Error",O||"Command failed")}finally{w(!1)}},[h,s]),En=ee(async d=>{let f=wr(d,{configPath:o,providerName:p,model:m,mcpServers:r,providers:y,contextLimit:F});if(f.kind==="exit"){await A();return}if(f.kind==="new"){await Me();return}if(f.kind==="switch_model"){await Dt(f.provider);return}if(f.kind==="set_context_limit"){X(f.limit),h("Context length",`Context limit set to ${(f.limit/1e3).toFixed(0)}k tokens`);return}if(f.kind==="init_agents_md"){h("Init","Analyzing project structure and generating AGENTS.md...");let T=`Please analyze the current project and create an AGENTS.md file at the project root.
|
|
112
117
|
|
|
113
118
|
The AGENTS.md should include:
|
|
114
119
|
1. Project name and brief description
|
|
@@ -124,16 +129,26 @@ Steps:
|
|
|
124
129
|
3. Understand the tech stack and conventions
|
|
125
130
|
4. Create the AGENTS.md file using the write tool
|
|
126
131
|
|
|
127
|
-
Make the AGENTS.md concise but informative, following best practices for AI agent guidelines.`;if(
|
|
128
|
-
`);return
|
|
129
|
-
`).map(c=>c.trim()).filter(Boolean),s=null,i=0,a=0;for(let c of r){let l;try{l=JSON.parse(c)}catch{continue}if(!(!l||typeof l!="object")){if(l.type==="turn_start"){let u=typeof l.content=="string"?l.content:"";s={index:-(i+1),userInput:u,steps:[],status:"ok",sequence:a+=1},n.push(s),u&&(
|
|
130
|
-
`),messages:
|
|
131
|
-
|
|
132
|
+
Make the AGENTS.md concise but informative, following best practices for AI agent guidelines.`;if(J(R=>[...R,"/init"]),!M){h("Error","Session not initialized");return}w(!0);try{await M.runTurn(T)}catch{w(!1)}return}if(f.kind==="shell_command"){await Ut(f.command);return}h(f.title,f.content)},[h,o,se,A,Dt,r,m,p,F,y,Ut]),jr=ee(async()=>{try{let d=await ne(),f=Re(d.config);C(d.config.providers),v(f.name),_(f.model),g(T=>({...T,sessionId:Nt(),providerName:f.name})),Ot(!1),h("Setup",`Config saved to ${d.configPath}`)}catch(d){h("Setup",`Failed to reload config: ${d.message}`)}},[h]);It(()=>{if(!M||!Oe?.length)return;let d=M.history[0];d&&(M.history.splice(0,M.history.length,d,...Oe),be(null))},[Oe,M]);let Hr=ee(async d=>{if(d.trim().toLowerCase()==="exit"){await A();return}if(!M||S)return;let f=d.trim();if(f.startsWith("$")){let T=f.slice(1).trim();J(R=>[...R,d]),await Ut(T);return}if(d.startsWith("/")){await En(d);return}J(T=>[...T,d]),w(!0);try{await M.runTurn(d)}catch{w(!1)}},[S,En,A,M]),Br=E[E.length-1],eu=br(Br?.tokenUsage),Fr=_r(it,F),Vr=Pr(()=>[...ue,...E],[ue,E]),Gr=ee(d=>{let f=I.current;f&&(f(d),I.current=null),at(null)},[]);if(De){let d=De.split(`
|
|
133
|
+
`);return Ne(Rr,{flexDirection:"column",children:d.map((f,T)=>Ne(Nl,{color:"green",children:f},T))})}return Ue?Ne(Mr,{configPath:o,onComplete:jr,onExit:A}):jl(Rr,{flexDirection:"column",children:[Ne(Ko,{systemMessages:$,turns:Vr,headerInfo:{providerName:p,model:m,cwd:s,sessionId:P.sessionId??"unknown",mcpNames:Object.keys(r??{}).sort()}}),Ne(vr,{disabled:!M||S||!!Ke,onSubmit:Hr,onExit:A,onClear:se,onNewSession:Me,onCancelRun:Ur,onHistorySelect:Dr,onModelSelect:Dt,onSystemMessage:h,onSetContextLimit:d=>{X(d),h("Context length",`Context limit set to ${(d/1e3).toFixed(0)}k tokens`)},history:re,cwd:s,sessionsDir:i,currentSessionFile:H??void 0,providers:y,configPath:o,providerName:p,model:m,contextLimit:F,mcpServers:r}),Ke&&Ne(Tr,{request:Ke,onDecision:Gr}),Ne(No,{contextPercent:Fr})]})}function Ul(t){let e=[],n=[],o=[],r=t.split(`
|
|
134
|
+
`).map(c=>c.trim()).filter(Boolean),s=null,i=0,a=0;for(let c of r){let l;try{l=JSON.parse(c)}catch{continue}if(!(!l||typeof l!="object")){if(l.type==="turn_start"){let u=typeof l.content=="string"?l.content:"";s={index:-(i+1),userInput:u,steps:[],status:"ok",sequence:a+=1},n.push(s),u&&(e.push({role:"user",content:u}),o.push(`User: ${u}`)),i+=1;continue}if(l.type==="assistant"){let u=typeof l.content=="string"?l.content:"";if(u&&(e.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(l.type==="action"&&s){let u=l.meta;if(u&&typeof u=="object"){let p=typeof u.tool=="string"?u.tool:"",v=u.input,m=typeof u.thinking=="string"?u.thinking:"",y=(Array.isArray(u.toolBlocks)?u.toolBlocks:[]).map(P=>{let g=typeof P?.name=="string"?P.name:"";return g?{tool:g,input:P?.input}:null}).filter(Boolean),C=s.steps[s.steps.length-1];C&&(y.length>1?(C.action=y[0],C.parallelActions=y):p&&(C.action={tool:p,input:v}),m&&(C.thinking=m))}continue}if(l.type==="observation"&&s){let u=typeof l.content=="string"?l.content:"",p=s.steps[s.steps.length-1];p&&(p.observation=u);continue}}}return{summary:o.join(`
|
|
135
|
+
`),messages:e,turns:n,maxSequence:a}}var Hl=`
|
|
136
|
+
Usage:
|
|
137
|
+
memo mcp list [--json]
|
|
138
|
+
memo mcp get <name> [--json]
|
|
139
|
+
memo mcp add <name> -- <command...> [--env KEY=VALUE]...
|
|
140
|
+
memo mcp add <name> --url <value> [--bearer-token-env-var ENV_VAR]
|
|
141
|
+
memo mcp remove <name>
|
|
142
|
+
memo mcp login <name> [--scopes scope1,scope2]
|
|
143
|
+
memo mcp logout <name>
|
|
144
|
+
`;function bn(){console.log(Hl.trim())}function Bl(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 Ir(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(([r,s])=>`${r}=${s}`).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,r])=>`${o}=${r}`).join(", ")}`);return n.join(`
|
|
145
|
+
`)}function Fl(t){let e=t.shift();if(!e)return{error:"Missing server name."};let n,o,r={},s=[];for(let i=0;i<t.length;i+=1){let a=t[i];if(a){if(a==="--"){s=t.slice(i+1);break}if(a==="--url"){let c=t[i+1];if(!c)return{error:"Missing value for --url."};n=c,i+=1;continue}if(a==="--bearer-token-env-var"){let c=t[i+1];if(!c)return{error:"Missing value for --bearer-token-env-var."};o=c,i+=1;continue}if(a==="--env"){let c=t[i+1];if(!c)return{error:"Missing value for --env (KEY=VALUE)."};let l=Bl(c);if(!l)return{error:"Invalid --env format. Use KEY=VALUE."};r[l.key]=l.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:e,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:e,command:s[0],args:s.slice(1),env:Object.keys(r).length>0?r:void 0}}}function Vl(t){let[e,...n]=t;return!e||e==="--help"||e==="-h"||e==="help"?{command:"help",rest:[]}:{command:e,rest:n}}function wn(t,e=[]){let n=new Set(e);for(let o=0;o<t.length;o+=1){let r=t[o];if(r){if(r.startsWith("--")){n.has(r)&&(o+=1);continue}return r}}return null}async function Lr(t){let{command:e,rest:n}=Vl(t);if(e==="help"){bn();return}if(e==="list"){let o=n.includes("--json"),s=(await ne()).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 c=s[a];c&&console.log(Ir(a,c))}return}if(e==="get"){let o=n.includes("--json"),r=wn(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let i=(await ne()).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(Ir(r,i));return}if(e==="add"){let o=Fl(n);if(o.error!==void 0){o.error&&(console.error(o.error),process.exitCode=1),bn();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 ne(),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 me(s.configPath,{...s.config,mcp_servers:i}),console.log(`Added MCP server "${r.name}".`);return}if(e==="remove"){let o=wn(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let r=await ne(),s={...r.config.mcp_servers??{}};if(!s[o]){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}delete s[o],await me(r.configPath,{...r.config,mcp_servers:s}),console.log(`Removed MCP server "${o}".`);return}if(e==="login"||e==="logout"){let o=wn(n,["--scopes"]);if(!o){console.error("Missing server name."),process.exitCode=1;return}let s=(await ne()).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: ${e}`),bn(),process.exitCode=1}import{jsx as Ql}from"react/jsx-runtime";function Jl(t){let e={once:!1,dangerous:!1},n=[];for(let o=0;o<t.length;o++){let r=t[o];if(r!==void 0){if(r==="--once"){e.once=!0;continue}if(r==="--dangerous"||r==="-d"){e.dangerous=!0;continue}n.push(r)}}return{question:n.join(" "),options:e}}async function Or(t){let e=await ne();if(!e.needsSetup)return e;let n=e.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 me(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 s=Gl({input:zl,output:Wl}),i=async(a,c)=>(await s.question(a)).trim()||c;try{console.log("No provider config found. Please answer the prompts:");let a=await i("Provider name [deepseek]: ","deepseek"),c=await i("API key env var [DEEPSEEK_API_KEY]: ","DEEPSEEK_API_KEY"),l=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:c,model:l,base_url:u||void 0}]};return await me(e.configPath,p),console.log(`Config written to ${e.configPath}
|
|
146
|
+
`),{...e,config:p,needsSetup:!1}}finally{s.close()}}async function ql(t){let e=await Or("plain"),n=Re(e.config),r={sessionId:Nr(),mode:"once",stream:e.config.stream_output??!1};t.options.dangerous&&console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!");let s={onAssistantStep:c=>{process.stdout.write(c)},requestApproval:t.options.dangerous?void 0:c=>(console.log(`
|
|
132
147
|
[approval required] ${c.toolName}: ${c.reason}`),console.log("[approval] Run with --dangerous to bypass approval"),Promise.resolve("deny")),hooks:{onAction:({action:c})=>{console.log(`
|
|
133
|
-
[tool] ${c.tool}`),c.input!==void 0&&console.log(`[input] ${JSON.stringify(c.input)}`)},onObservation:()=>{}}},i=await
|
|
134
|
-
`);let c=await i.runTurn(a);
|
|
148
|
+
[tool] ${c.tool}`),c.input!==void 0&&console.log(`[input] ${JSON.stringify(c.input)}`)},onObservation:()=>{}}},i=await Ye(s,r),a=t.question;if(!a&&!process.stdin.isTTY&&(a=await Zl()),!a&&t.options.once&&(a="Give me a quick self-introduction."),!a){console.error("No input provided. Pass a question or use stdin."),await i.close();return}try{console.log(`User: ${a}
|
|
149
|
+
`);let c=await i.runTurn(a);e.config.stream_output||console.log(`
|
|
135
150
|
${c.finalText}`),console.log(`
|
|
136
151
|
[tokens] prompt=${c.tokenUsage.prompt} completion=${c.tokenUsage.completion} total=${c.tokenUsage.total}`),console.log(`
|
|
137
|
-
provider=${n.name} model=${n.model}`)}catch(c){console.error(`Run failed: ${c.message}`)}finally{await i.close()}}async function
|
|
138
|
-
`)),await
|
|
152
|
+
provider=${n.name} model=${n.model}`)}catch(c){console.error(`Run failed: ${c.message}`)}finally{await i.close()}}async function Xl(t){let e=await Or("tui"),n=Re(e.config),r={sessionId:Nr(),mode:"interactive",stream:e.config.stream_output??!1},s=ht(e,r);t.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
|
|
153
|
+
`)),await Kl(Ql($r,{sessionOptions:r,providerName:n.name,model:n.model,configPath:e.configPath,mcpServers:e.config.mcp_servers??{},cwd:process.cwd(),sessionsDir:s,providers:e.config.providers,dangerous:t.options.dangerous,needsSetup:e.needsSetup}),{exitOnCtrlC:!1,patchConsole:!1}).waitUntilExit()}async function Yl(){let t=process.argv.slice(2);if(t[0]==="mcp"||t[0]==="--"&&t[1]==="mcp"){let o=t[0]==="--"?2:1;await Lr(t.slice(o));return}let e=Jl(t);if(!(process.stdin.isTTY&&process.stdout.isTTY)||e.options.once){await ql(e);return}await Xl(e)}Yl();async function Zl(){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()})}
|
|
139
154
|
//# sourceMappingURL=index.js.map
|
package/dist/prompt.md
CHANGED
|
@@ -7,11 +7,11 @@ You are **Memo Code**, an interactive CLI tool that helps users with software en
|
|
|
7
7
|
# Core Identity
|
|
8
8
|
|
|
9
9
|
- **Local First**: You operate directly on the user's machine. File operations and commands happen in the real environment.
|
|
10
|
-
- **Project Aware**: Read and follow `
|
|
10
|
+
- **Project Aware**: Read and follow `AGENTS.md` (or `CLAUDE.md`) files containing project structure, conventions, and preferences.
|
|
11
11
|
- **Tool Rich**: Use your comprehensive toolkit liberally to gather information and complete tasks.
|
|
12
12
|
- **Safety Conscious**: The environment is NOT sandboxed. Your actions have immediate effects.
|
|
13
13
|
|
|
14
|
-
# Session Context
|
|
14
|
+
# Session Context
|
|
15
15
|
|
|
16
16
|
- Date: {{date}}
|
|
17
17
|
- User: {{user}}
|
|
@@ -170,7 +170,7 @@ For software engineering tasks (bugs, features, refactoring, explaining):
|
|
|
170
170
|
**CRITICAL - Code Quality**:
|
|
171
171
|
|
|
172
172
|
- After completing tasks, you MUST run lint and typecheck commands (e.g., `npm run lint`, `npm run typecheck`)
|
|
173
|
-
- If commands unknown, ask user and suggest adding to
|
|
173
|
+
- If commands unknown, ask user and suggest adding to AGENTS.md
|
|
174
174
|
- NEVER commit changes unless explicitly asked
|
|
175
175
|
|
|
176
176
|
**Following Conventions**:
|
|
@@ -231,9 +231,9 @@ Balance between:
|
|
|
231
231
|
- Avoid superuser commands unless instructed
|
|
232
232
|
- Validate inputs before shell commands
|
|
233
233
|
|
|
234
|
-
## Project Context (
|
|
234
|
+
## Project Context (AGENTS.md / CLAUDE.md)
|
|
235
235
|
|
|
236
|
-
Files named `
|
|
236
|
+
Files named `AGENTS.md` or `CLAUDE.md` may exist with project-specific guidance:
|
|
237
237
|
|
|
238
238
|
- Project structure and conventions
|
|
239
239
|
- Build, test, and development workflows
|
|
@@ -332,6 +332,15 @@ Common tools include:
|
|
|
332
332
|
- **grep**: Search file contents
|
|
333
333
|
- **todo**: Manage task lists
|
|
334
334
|
- **webfetch**: Fetch web pages
|
|
335
|
+
- **save_memory**: Save user-related identity traits or preferences for cross-session reuse
|
|
336
|
+
|
|
337
|
+
## Memory Tool Usage
|
|
338
|
+
|
|
339
|
+
Use the `save_memory` tool to store user preferences and identity traits that persist across sessions:
|
|
340
|
+
|
|
341
|
+
- **What to save**: Language preferences, technical preferences (e.g., "User prefers Chinese responses", "User is a frontend engineer")
|
|
342
|
+
- **What NOT to save**: Project-specific technical details, file structures, or ephemeral session information
|
|
343
|
+
- **Usage**: Save concise facts (max 50 chars) about user identity and preferences
|
|
335
344
|
|
|
336
345
|
---
|
|
337
346
|
|