@memo-code/memo 0.4.5 → 0.5.12
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 +64 -49
- 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 Zr=Object.create;var Rn=Object.defineProperty;var Qr=Object.getOwnPropertyDescriptor;var es=Object.getOwnPropertyNames;var ts=Object.getPrototypeOf,ns=Object.prototype.hasOwnProperty;var $n=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var os=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of es(t))!ns.call(e,r)&&r!==n&&Rn(e,r,{get:()=>t[r],enumerable:!(o=Qr(t,r))||o.enumerable});return e};var In=(e,t,n)=>(n=e!=null?Zr(ts(e)):{},os(t||!e||!e.__esModule?Rn(n,"default",{value:e,enumerable:!0}):n,e));var zn=$n((Su,Gn)=>{"use strict";function Dn(e){return Array.isArray(e)?e:[e]}var Vt="",Un=" ",Bt="\\",ys=/^\s+$/,xs=/(?:[^\\]|^)\\$/,vs=/^\\!/,Ts=/^\\#/,Ss=/\r?\n/g,ks=/^\.*\/|^\.+$/,Ft="/",Bn="node-ignore";typeof Symbol<"u"&&(Bn=Symbol.for("node-ignore"));var jn=Bn,bs=(e,t,n)=>Object.defineProperty(e,t,{value:n}),_s=/([0-z])-([0-z])/g,Fn=()=>!1,ws=e=>e.replace(_s,(t,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?t:Vt),Cs=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Es=[[/^\uFEFF/,()=>Vt],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?Un:Vt)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+Un}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let o=n.replace(/\\\*/g,"[^\\/]*");return t+o}],[/\\\\\\(?=[$.|*+(){^])/g,()=>Bt],[/\\\\/g,()=>Bt],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,o,r)=>t===Bt?`\\[${n}${Cs(o)}${r}`:r==="]"&&o.length%2===0?`[${ws(n)}${o}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`]],Hn=Object.create(null),As=(e,t)=>{let n=Hn[e];return n||(n=Es.reduce((o,[r,s])=>o.replace(r,s.bind(e)),e),Hn[e]=n),t?new RegExp(n,"i"):new RegExp(n)},Wt=e=>typeof e=="string",Ms=e=>e&&Wt(e)&&!ys.test(e)&&!xs.test(e)&&e.indexOf("#")!==0,Ps=e=>e.split(Ss),Gt=class{constructor(t,n,o,r){this.origin=t,this.pattern=n,this.negative=o,this.regex=r}},Rs=(e,t)=>{let n=e,o=!1;e.indexOf("!")===0&&(o=!0,e=e.substr(1)),e=e.replace(vs,"!").replace(Ts,"#");let r=As(e,t);return new Gt(n,e,o,r)},$s=(e,t)=>{throw new t(e)},ye=(e,t,n)=>Wt(e)?e?ye.isNotRelative(e)?n(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:n("path must not be empty",TypeError):n(`path must be a string, but got \`${t}\``,TypeError),Vn=e=>ks.test(e);ye.isNotRelative=Vn;ye.convert=e=>e;var zt=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:o=!1}={}){bs(this,jn,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=o,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(t){if(t&&t[jn]){this._rules=this._rules.concat(t._rules),this._added=!0;return}if(Ms(t)){let n=Rs(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,Dn(Wt(t)?Ps(t):t).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(t){return this.add(t)}_testOne(t,n){let o=!1,r=!1;return this._rules.forEach(s=>{let{negative:i}=s;if(r===i&&o!==r||i&&!o&&!r&&!n)return;s.regex.test(t)&&(o=!i,r=i)}),{ignored:o,unignored:r}}_test(t,n,o,r){let s=t&&ye.convert(t);return ye(s,t,this._allowRelativePaths?Fn:$s),this._t(s,n,o,r)}_t(t,n,o,r){if(t in n)return n[t];if(r||(r=t.split(Ft)),r.pop(),!r.length)return n[t]=this._testOne(t,o);let s=this._t(r.join(Ft)+Ft,n,o,r);return n[t]=s.ignored?s:this._testOne(t,o)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return Dn(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},lt=e=>new zt(e),Is=e=>ye(e&&ye.convert(e),e,Fn);lt.isPathValid=Is;lt.default=lt;Gn.exports=lt;if(typeof process<"u"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");ye.convert=e;let t=/^[a-z]:\//i;ye.isNotRelative=n=>t.test(n)||Vn(n)}});var sr=$n((_d,At)=>{"use strict";function Qo(e){return Array.isArray(e)?e:[e]}var uc=void 0,fn="",Yo=" ",dn="\\",pc=/^\s+$/,mc=/(?:[^\\]|^)\\$/,dc=/^\\!/,fc=/^\\#/,gc=/\r?\n/g,hc=/^\.{0,2}\/|^\.{1,2}$/,yc=/\/$/,Ve="/",er="node-ignore";typeof Symbol<"u"&&(er=Symbol.for("node-ignore"));var tr=er,Ge=(e,t,n)=>(Object.defineProperty(e,t,{value:n}),n),xc=/([0-z])-([0-z])/g,nr=()=>!1,vc=e=>e.replace(xc,(t,n,o)=>n.charCodeAt(0)<=o.charCodeAt(0)?t:fn),Tc=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Sc=[[/^\uFEFF/,()=>fn],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?Yo:fn)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+Yo}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let o=n.replace(/\\\*/g,"[^\\/]*");return t+o}],[/\\\\\\(?=[$.|*+(){^])/g,()=>dn],[/\\\\/g,()=>dn],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,o,r)=>t===dn?`\\[${n}${Tc(o)}${r}`:r==="]"&&o.length%2===0?`[${vc(n)}${o}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`]],kc=/(^|\\\/)?\\\*$/,et="regex",Ct="checkRegex",Zo="_",bc={[et](e,t){return`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`},[Ct](e,t){return`${t?`${t}[^/]*`:"[^/]*"}(?=$|\\/$)`}},_c=e=>Sc.reduce((t,[n,o])=>t.replace(n,o.bind(e)),e),Et=e=>typeof e=="string",wc=e=>e&&Et(e)&&!pc.test(e)&&!mc.test(e)&&e.indexOf("#")!==0,Cc=e=>e.split(gc).filter(Boolean),gn=class{constructor(t,n,o,r,s,i){this.pattern=t,this.mark=n,this.negative=s,Ge(this,"body",o),Ge(this,"ignoreCase",r),Ge(this,"regexPrefix",i)}get regex(){let t=Zo+et;return this[t]?this[t]:this._make(et,t)}get checkRegex(){let t=Zo+Ct;return this[t]?this[t]:this._make(Ct,t)}_make(t,n){let o=this.regexPrefix.replace(kc,bc[t]),r=this.ignoreCase?new RegExp(o,"i"):new RegExp(o);return Ge(this,n,r)}},Ec=({pattern:e,mark:t},n)=>{let o=!1,r=e;r.indexOf("!")===0&&(o=!0,r=r.substr(1)),r=r.replace(dc,"!").replace(fc,"#");let s=_c(r);return new gn(e,t,r,n,o,s)},hn=class{constructor(t){this._ignoreCase=t,this._rules=[]}_add(t){if(t&&t[tr]){this._rules=this._rules.concat(t._rules._rules),this._added=!0;return}if(Et(t)&&(t={pattern:t}),wc(t.pattern)){let n=Ec(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,Qo(Et(t)?Cc(t):t).forEach(this._add,this),this._added}test(t,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(t)||(r=!l,s=l,i=l?uc:c)});let a={ignored:r,unignored:s};return i&&(a.rule=i),a}},Ac=(e,t)=>{throw new t(e)},Se=(e,t,n)=>Et(e)?e?Se.isNotRelative(e)?n(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:n("path must not be empty",TypeError):n(`path must be a string, but got \`${t}\``,TypeError),or=e=>hc.test(e);Se.isNotRelative=or;Se.convert=e=>e;var yn=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:o=!1}={}){Ge(this,tr,!0),this._rules=new hn(n),this._strictPathCheck=!o,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}add(t){return this._rules.add(t)&&this._initCache(),this}addPattern(t){return this.add(t)}_test(t,n,o,r){let s=t&&Se.convert(t);return Se(s,t,this._strictPathCheck?Ac:nr),this._t(s,n,o,r)}checkIgnore(t){if(!yc.test(t))return this.test(t);let n=t.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(t,!1,Ct)}_t(t,n,o,r){if(t in n)return n[t];if(r||(r=t.split(Ve).filter(Boolean)),r.pop(),!r.length)return n[t]=this._rules.test(t,o,et);let s=this._t(r.join(Ve)+Ve,n,o,r);return n[t]=s.ignored?s:this._rules.test(t,o,et)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return Qo(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},xn=e=>new yn(e),Mc=e=>Se(e&&Se.convert(e),e,nr),rr=()=>{let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");Se.convert=e;let t=/^[a-z]:\//i;Se.isNotRelative=n=>t.test(n)||or(n)};typeof process<"u"&&process.platform==="win32"&&rr();At.exports=xn;xn.default=xn;At.exports.isPathValid=Mc;Ge(At.exports,Symbol.for("setupWindows"),rr)});import{randomUUID as Hr}from"crypto";import{createInterface as Xl}from"readline/promises";import{stdin as Yl,stdout as Zl}from"process";import{render as Ql}from"ink";import rs from"os";import{readFile as ss}from"fs/promises";import{join as is,dirname as as}from"path";import{fileURLToPath as cs}from"url";var ls=/{{\s*([\w.-]+)\s*}}/g;function us(e,t){return e.replace(ls,(n,o)=>t[o]??"")}function ps(){try{return rs.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}async function Ln(){let e=as(cs(import.meta.url)),t=is(e,"prompt.md"),n=await ss(t,"utf-8"),o={date:new Date().toISOString(),user:ps(),pwd:process.cwd()};return us(n,o)}import{appendFile as ms,mkdir as ds}from"fs/promises";import{dirname as fs}from"path";var ct=class{constructor(t){this.filePath=t}ready=!1;async append(t){this.ready||(await ds(fs(this.filePath),{recursive:!0}),this.ready=!0),await ms(this.filePath,`${JSON.stringify(t)}
|
|
3
|
+
`,"utf8")}async flush(){return Promise.resolve()}};function Nn(e){return{ts:new Date().toISOString(),sessionId:e.sessionId,turn:e.turn,step:e.step,type:e.type,content:e.content,role:e.role,meta:e.meta}}import{spawn as gs}from"child_process";import{z as Ht}from"zod";function _(e,t=!1){return{content:[{type:"text",text:e}],isError:t}}var hs=Ht.object({command:Ht.string().min(1,"command \u4E0D\u80FD\u4E3A\u7A7A"),timeout:Ht.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(),On={name:"bash",description:"\u5728 shell \u4E2D\u6267\u884C\u547D\u4EE4\uFF0C\u8FD4\u56DE exit/stdout/stderr",inputSchema:hs,execute:async({command:e,timeout:t})=>{let n=e.trim();if(!n)return _("bash \u9700\u8981\u8981\u6267\u884C\u7684\u547D\u4EE4",!0);try{let o=gs("bash",["-lc",n],{env:process.env,stdio:["ignore","pipe","pipe"]}),r=m=>new Promise(b=>{if(!m)return b("");let h=[];m.setEncoding("utf8"),m.on("data",C=>h.push(C)),m.on("error",()=>b("")),m.on("end",()=>b(h.join("")))}),s=r(o.stdout),i=r(o.stderr),a,c=new Promise((m,b)=>{o.on("error",h=>b(h)),o.on("close",h=>m(typeof h=="number"?h:-1))}),l=t&&t>0?new Promise((m,b)=>{a=setTimeout(()=>{o.kill(),b(new Error(`bash \u8D85\u65F6 ${t}ms\uFF0C\u5DF2\u7EC8\u6B62\u8FDB\u7A0B`))},t)}):null,u=l?await Promise.race([c,l]):await c;a&&clearTimeout(a);let[p,v]=await Promise.all([s,i]);return _(`exit=${u} stdout="${p}" stderr="${v}"`)}catch(o){return _(`bash \u6267\u884C\u5931\u8D25: ${o.message}`,!0)}}};import{access as Ws,readFile as Ks,writeFile as Js}from"fs/promises";var qn=In(zn(),1);import{normalize as Ls,resolve as Jn,dirname as Wn,join as Kt,relative as Ns}from"path";import{existsSync as Jt,statSync as Os}from"fs";import{readFile as Ds}from"fs/promises";function me(e){return Ls(Jn(e))}var Us=["node_modules/",".git/","dist/","out/","build/","coverage/",".cache/",".idea/",".DS_Store",".next/",".turbo/",".pnpm/",".pnpm-store/","*.log","logs/","tmp/","temp/","vendor/"],js=100,Hs=1e4,Bs="<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>",Kn=new Map;function Fs(e){return e.replace(/\\/g,"/")}function Vs(e){let t=Jn(e);try{Os(t).isFile()&&(t=Wn(t))}catch{t=process.cwd()}let n=t;for(;;){if(Jt(Kt(t,".gitignore"))||Jt(Kt(t,".git")))return t;let o=Wn(t);if(o===t)return n;t=o}}async function Gs(e){let t=Kt(e,".gitignore");return Jt(t)?(await Ds(t,"utf8")).split(/\r?\n/).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#")):[]}async function zs(e){let t=(0,qn.default)();t.add(Us);let n=await Gs(e);return n.length>0&&t.add(n),{root:e,ignores:o=>{let r=Ns(e,o);return!r||r.startsWith("..")?!1:t.ignores(Fs(r))}}}async function ut(e){let t=Vs(e),n=Kn.get(t);if(n)return n;let o=zs(t);return Kn.set(t,o),o}function pt(e,t){return t>js||e.length>Hs?`${e}
|
|
4
4
|
|
|
5
|
-
${
|
|
6
|
-
`).replace(
|
|
7
|
-
`).replace(
|
|
5
|
+
${Bs}`:e}import{z as Je}from"zod";var qs=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(),Xn={name:"edit",description:"\u5728\u6587\u4EF6\u4E2D\u66FF\u6362\u6587\u672C\uFF0C\u652F\u6301 replace_all",inputSchema:qs,execute:async e=>{let t=me(e.file_path),n=e.replace_all??!1;if(!e.old_string.trim())return _("old_string \u4E0D\u80FD\u4E3A\u7A7A",!0);try{await Ws(t);let o=await Ks(t,"utf8");if(!o.includes(e.old_string))return _("\u672A\u627E\u5230\u5F85\u66FF\u6362\u6587\u672C",!0);let r,s=0;if(n){let i=o.split(e.old_string);s=i.length-1,r=i.join(e.new_string)}else r=o.replace(e.old_string,e.new_string),s=1;return r===o?_("\u672A\u68C0\u6D4B\u5230\u5185\u5BB9\u53D8\u5316"):(await Js(t,r,"utf8"),_(`\u66FF\u6362\u5B8C\u6210: file=${t} count=${s}`))}catch(o){return o.code==="ENOENT"?_(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${t}`,!0):_(`edit \u5931\u8D25: ${o.message}`,!0)}}};import{z as Yn}from"zod";var Xs=Yn.object({url:Yn.string().min(1)}).strict(),Zn=1e4,qe=512e3,qt=4e3,Ys=new Set(["http:","https:","data:"]),Zs=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,Qs=/<\s*(br|hr)\s*\/?>/gi,ei=/<\s*li[^>]*>/gi,ti=/<[^>]+>/g,ni=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,oi=e=>e.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""}}),ri=e=>{let o=e.replace(ni," ").replace(ei,"- ").replace(Qs,`
|
|
6
|
+
`).replace(Zs,`
|
|
7
|
+
`).replace(ti," "),s=oi(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()},si=e=>e.replace(/\s+/g," ").trim(),Qn={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:Xs,execute:async e=>{let t;try{t=new URL(e.url)}catch{return _(`\u65E0\u6548 URL: ${e.url}`,!0)}if(!Ys.has(t.protocol))return _(`\u4E0D\u652F\u6301\u7684\u534F\u8BAE: ${t.protocol}`,!0);let n=new AbortController,o=setTimeout(()=>n.abort(),Zn);try{let r=await globalThis.fetch(t,{signal:n.signal}),s=r.headers.get("content-length"),i=s?Number(s):void 0;if(i&&i>qe)return _(`\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:y,value:E}=await C.read();if(y)break;if(E){if(a+=E.byteLength,a>qe)return n.abort(),_(`\u8BF7\u6C42\u88AB\u4E2D\u6B62: \u54CD\u5E94\u4F53\u8D85\u8FC7 ${qe} bytes`,!0);P.push(E)}}let g=new Uint8Array(a),A=0;for(let y of P)g.set(y,A),A+=y.byteLength;c=new TextDecoder().decode(g)}else if(c=await r.text(),a=new TextEncoder().encode(c).byteLength,a>qe)return _(`\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?ri(c):c.trim(),v=si(p),m=v.length>qt?`${v.slice(0,qt)}...`:v,b=v.length>qt?" text_truncated=true":"",h=u?" source=html_stripped":"";return _(`status=${r.status} bytes=${a} text_chars=${v.length} text="${m}"${b}${h}`)}catch(r){return r.name==="AbortError"?_(`\u8BF7\u6C42\u8D85\u65F6\u6216\u88AB\u4E2D\u6B62\uFF08${Zn}ms\uFF09`,!0):_(`\u8BF7\u6C42\u5931\u8D25: ${r.message}`,!0)}finally{clearTimeout(o)}}};import{z as Xt}from"zod";import ii from"fast-glob";var ai=Xt.object({pattern:Xt.string().min(1),path:Xt.string().optional()}).strict(),ci={name:"glob",description:"\u6309 glob \u6A21\u5F0F\u5339\u914D\u6587\u4EF6\uFF0C\u8FD4\u56DE\u7EDD\u5BF9\u8DEF\u5F84\u5217\u8868",inputSchema:ai,execute:async e=>{let t=e.path?me(e.path):process.cwd();try{let n=await ut(t),r=(await ii(e.pattern,{cwd:t,absolute:!0,onlyFiles:!0})).filter(i=>!n.ignores(i));if(r.length===0)return _("\u672A\u627E\u5230\u5339\u914D\u6587\u4EF6");let s=r.join(`
|
|
10
|
+
`);return _(pt(s,r.length))}catch(n){return _(`glob \u5931\u8D25: ${n.message}`,!0)}}},eo=ci;import{spawn as li,spawnSync as ui}from"child_process";import{z as xe}from"zod";import{isAbsolute as to,resolve as no}from"path";var pi=xe.object({pattern:xe.string().min(1),path:xe.string().optional(),output_mode:xe.enum(["content","files_with_matches","count"]).optional(),glob:xe.string().optional(),"-i":xe.boolean().optional(),"-A":xe.number().int().nonnegative().optional(),"-B":xe.number().int().nonnegative().optional(),"-C":xe.number().int().nonnegative().optional()}).strict(),oo={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:pi,execute:async e=>{let t=ui("rg",["--version"],{stdio:"ignore"});if(t.error||t.status!==0)return _("rg \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH",!0);let n=e.path?me(e.path):process.cwd(),o=["--color","never"],r=e.output_mode??"content";r==="files_with_matches"?o.push("-l"):r==="count"?o.push("-c"):o.push("--line-number","--no-heading"),e["-i"]&&o.push("-i"),e.glob&&o.push("--glob",e.glob),e["-A"]!==void 0&&o.push("-A",String(e["-A"])),e["-B"]!==void 0&&o.push("-B",String(e["-B"])),e["-C"]!==void 0&&o.push("-C",String(e["-C"])),o.push(e.pattern,n);try{let s=await ut(n),i=li("rg",o,{stdio:["ignore","pipe","pipe"]}),a=h=>new Promise(C=>{if(!h)return C("");let P=[];h.setEncoding("utf8"),h.on("data",g=>P.push(g)),h.on("error",()=>C("")),h.on("end",()=>C(P.join("")))}),[c,l]=await Promise.all([a(i.stdout),a(i.stderr)]);if(await new Promise((h,C)=>{i.on("error",P=>C(P)),i.on("close",P=>h(typeof P=="number"?P:-1))})===2)return _(`grep \u5931\u8D25(exit=2): ${l||c}`,!0);let m=(c||l||"").split(/\r?\n/).map(h=>h.trimEnd()).filter(h=>h.length>0).filter(h=>{if(r==="files_with_matches"){let A=h.trim(),y=to(A)?A:no(n,A);return!s.ignores(y)}let C=h.indexOf(":");if(C===-1)return!0;let P=h.slice(0,C),g=to(P)?P:no(n,P);return!s.ignores(g)});if(m.length===0)return _("\u672A\u627E\u5230\u5339\u914D");let b=m.join(`
|
|
11
|
+
`);return _(pt(b,m.length))}catch(s){return _(`grep \u6267\u884C\u5931\u8D25: ${s.message}`,!0)}}};import{mkdir as mi,readFile as di,writeFile as fi,access as gi}from"fs/promises";import{dirname as hi,join as ro}from"path";import{homedir as yi}from"os";import{z as so}from"zod";var xi=so.object({fact:so.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 vi(){let e=process.env.MEMO_HOME?.trim()||ro(yi(),".memo");return ro(e,"Agents.md")}function Ti(e){return e.replace(/\r?\n/g," ").replace(/\s+/g," ").trim()}function Si(e,t){let o=t.map(r=>r.trim()).filter(Boolean).map(r=>`- ${r}`);return`${e}
|
|
12
12
|
|
|
13
13
|
${o.join(`
|
|
14
14
|
`)}
|
|
15
|
-
`}var
|
|
16
|
-
`),
|
|
17
|
-
... (truncated, showing ${r} lines; max=${
|
|
15
|
+
`}var io={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:xi,execute:async e=>{let t=Ti(e.fact);if(!t)return _("fact cannot be empty",!0);let n=vi(),o=hi(n);try{await mi(o,{recursive:!0});let r="## Memo Added Memories";try{let s=await(async()=>{try{return await gi(n),await di(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(t);let c=a.slice(Math.max(0,a.length-50)),l=Si(r,c);await fi(n,l,"utf-8")}catch(s){console.warn(`Memory maintenance failed: ${s.message}`)}return _(`Memory saved to: ${n}`)}catch(r){return _(`Failed to write memory: ${r.message}`,!0)}}};import{z as ve}from"zod";var mt=10,ae=[],ki=ve.object({type:ve.enum(["add","replace","update","remove"]),todos:ve.array(ve.object({content:ve.string().trim().min(1,"content \u4E0D\u80FD\u4E3A\u7A7A").max(200,"content \u6700\u957F 200 \u5B57\u7B26"),status:ve.enum(["pending","in_progress","completed"]).optional().default("pending"),id:ve.string().min(1,"id \u4E0D\u80FD\u4E3A\u7A7A").optional()})).optional(),ids:ve.array(ve.string().min(1,"id \u4E0D\u80FD\u4E3A\u7A7A")).optional()}).strict().refine(e=>{if(["add","replace","update"].includes(e.type)){if(!e.todos||e.todos.length===0)return!1;if(e.type==="update")return e.todos.every(t=>t.id)}return!(e.type==="remove"&&(!e.ids||e.ids.length===0))},{message:"add/replace/update \u9700\u8981 todos\uFF0Cremove \u9700\u8981 ids\uFF0Cupdate \u9700\u8981 id"});function dt(){return ae.map(e=>({...e}))}function bi(e){switch(e.type){case"add":{let t=e.todos,n=mt-ae.length;if(t.length>n)return{error:`\u4EFB\u52A1\u4E0A\u9650 ${mt}\uFF0C\u5F53\u524D\u5269\u4F59 ${n} \u6761\u7A7A\u4F4D`};let o=t.map(r=>({id:crypto.randomUUID(),content:r.content,status:r.status}));return ae.push(...o),{added:o,tasks:dt()}}case"replace":{let t=e.todos;if(t.length>mt)return{error:`\u4EFB\u52A1\u4E0A\u9650 ${mt}`};ae.splice(0,ae.length);let n=t.map(o=>({id:crypto.randomUUID(),content:o.content,status:o.status}));return ae.push(...n),{replaced:!0,tasks:dt()}}case"update":{let t=e.todos,n=t.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(ae.map(s=>[s.id,s]));for(let s of t){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:dt()}}case"remove":{let t=e.ids,n=ae.length,o=new Set(t),r=ae.filter(s=>!o.has(s.id));return r.length===n?{error:"\u672A\u627E\u5230\u4EFB\u4F55\u53EF\u5220\u9664\u7684\u4EFB\u52A1 id"}:(ae.splice(0,ae.length,...r),{removed:t,tasks:dt()})}}}var ao={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:ki,execute:async e=>{let t=bi(e);if(t.error)return _(t.error,!0);let n={op:e.type,count:ae.length,tasks:t.tasks,added:t.added,updated:t.updated,removed:t.removed,replaced:!!t.replaced};return _(JSON.stringify(n))}};import{z as ft}from"zod";import{extname as _i}from"path";import{gzipSync as wi}from"zlib";import{access as Ci,readFile as Ei}from"fs/promises";var co=512e3,lo=2e6,Ai=200,uo=1e3,Mi=1024,Yt=4e3,Pi=new Set([".png",".jpg",".jpeg",".gif",".webp",".bmp",".svg"]);function Ri(e){let t=_i(e).toLowerCase();return Pi.has(t)}function $i(e){return Buffer.from(e).toString("base64")}function Ii(e){try{let t=wi(e,{level:6});if(t.byteLength<e.byteLength)return{data:new Uint8Array(t),encoding:"gzip+base64"}}catch{}return{data:e,encoding:"base64"}}function Li(e){let t=e.truncated?" truncated=true":"";return`image_base64 (encoding=${e.encoding} original_bytes=${e.originalBytes} payload_bytes=${e.payloadBytes} base64_length=${e.base64.length}${t}): ${e.base64}`}var Ni=ft.object({file_path:ft.string().min(1),offset:ft.number().int().positive().optional(),limit:ft.number().int().positive().optional()}).strict(),po={name:"read",description:"\u8BFB\u53D6\u6307\u5B9A\u6587\u4EF6\u5185\u5BB9\uFF0C\u53EF\u6309 offset/limit \u622A\u53D6\u5E76\u9644\u5E26\u884C\u53F7",inputSchema:Ni,execute:async e=>{let t=me(e.file_path),n=e.offset??1,o=e.limit??Ai,r=Math.min(o,uo);try{await Ci(t);let s=await Ei(t),i=s.byteLength;if(Ri(t)){if(i>lo)return _(`\u56FE\u7247\u8FC7\u5927\uFF08${i} bytes\uFF09\uFF0C\u8D85\u8FC7\u9608\u503C ${lo} bytes\uFF0C\u5DF2\u62D2\u7EDD\u8BFB\u53D6`,!0);let y=new Uint8Array(s),{data:E,encoding:U}=Ii(y),I=$i(E),V=I.length>Yt?`${I.slice(0,Yt)}...`:I,k=I.length>Yt;return _(Li({encoding:U,base64:V,originalBytes:y.byteLength,payloadBytes:E.byteLength,truncated:k}))}if(i>co)return _(`\u6587\u4EF6\u8FC7\u5927\uFF08${i} bytes\uFF09\uFF0C\u5DF2\u62D2\u7EDD\u8BFB\u53D6\uFF0C\u9608\u503C ${co} bytes`,!0);let c=new Uint8Array(s),l=Math.min(c.length,Mi);for(let y=0;y<l;y++)if(c[y]===0)return _("\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),h=p.slice(v,m).map((y,E)=>`${v+E+1}: ${y}`).join(`
|
|
16
|
+
`),C=m<p.length,A=o!==r||C&&e.limit===void 0?`
|
|
17
|
+
... (truncated, showing ${r} lines; max=${uo})`:"";return _(h+A)}catch(s){return _(`\u8BFB\u53D6\u5931\u8D25: ${s.message}`,!0)}}};import{z as Zt}from"zod";import{dirname as Oi}from"path";import{mkdir as Di,writeFile as Ui}from"fs/promises";var ji=Zt.object({file_path:Zt.string().min(1),content:Zt.any().optional()}).strict();function Hi(e){if(e instanceof Uint8Array)return{data:e,info:`bytes=${e.byteLength}`};if(e instanceof ArrayBuffer){let n=new Uint8Array(e);return{data:n,info:`bytes=${n.byteLength}`}}if(typeof e=="string")return{data:e,info:`text_length=${e.length}`};let t=JSON.stringify(e??"",null,2);return{data:t,info:`json_length=${t.length}`}}var mo={name:"write",description:"\u521B\u5EFA\u6216\u8986\u76D6\u6587\u4EF6\uFF0C\u4F20\u5165 file_path \u4E0E content",inputSchema:ji,execute:async e=>{let t=me(e.file_path),{data:n,info:o}=Hi(e.content);try{return await Di(Oi(t),{recursive:!0}),await Ui(t,n instanceof Uint8Array?n:String(n)),_(`\u5DF2\u5199\u5165 ${t} (overwrite, ${o})`)}catch(r){return _(`\u5199\u5165\u5931\u8D25: ${r.message}`,!0)}}};function Bi(e){let t=e.toJSONSchema(),{$schema:n,...o}=t;return o}function Fi(e){return{name:e.name,description:e.description,source:"native",inputSchema:Bi(e.inputSchema),execute:e.execute}}function fo(e){return e.map(Fi)}var Vi={bash:On,read:po,write:mo,edit:Xn,glob:eo,grep:oo,webfetch:Qn,save_memory:io,todo:ao},Gi=Object.values(Vi),go=fo(Gi);import ga from"openai";import{encoding_for_model as zi,get_encoding as Wi}from"@dqbd/tiktoken";var ho="cl100k_base";function Ki(e){let t=e?.trim()||ho;try{let n=()=>zi(t);return n().free(),{model:t,factory:n}}catch{let n=ho,o=()=>Wi(n);return o().free(),{model:n,factory:o}}}function yo(e){let{model:t,factory:n}=Ki(e),o=n(),r=4,s=2,i=1,a=l=>l?o.encode(l).length:0;return{model:t,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 Ji,writeFile as qi,readFile as Xi,access as Yi}from"fs/promises";import{homedir as xo}from"os";import{dirname as Zi,join as Pe}from"path";import{randomUUID as Rp}from"crypto";import{parse as Qi}from"toml";var ea=Pe(xo(),".memo"),ta="sessions",na="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 oa(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:JSON.stringify(e)}function ra(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=[];for(let[n,o]of Object.entries(e)){if(!o)continue;let r=Array.isArray(o)?o:[o];for(let s of r){if(!s||typeof s!="object")continue;let i={...s};(typeof i.name!="string"||i.name.length===0)&&n&&(i.name=n),t.push(i)}}return t}function vo(e){return e.startsWith("~")?Pe(xo(),e.slice(1)):e}function sa(e){let t=e.providers.map(r=>{let s=typeof r?.name=="string"?r.name:"";if(!s)return"";let a=[`[[providers.${oa(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 e.mcp_servers&&Object.keys(e.mcp_servers).length>0&&(n=Object.entries(e.mcp_servers).map(([r,s])=>{if("url"in s){let
|
|
20
|
+
`),n="";return e.mcp_servers&&Object.keys(e.mcp_servers).length>0&&(n=Object.entries(e.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 b=Object.entries(m).map(([C,P])=>`${JSON.stringify(C)} = ${JSON.stringify(P)}`).join(", "),h=s.http_headers?"http_headers":"headers";v.push(`${h} = { ${b} }`)}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
32
|
current_provider = "${e.current_provider}"
|
|
28
33
|
stream_output = ${e.stream_output??!1}
|
|
29
34
|
`.trim(),t,n].filter(Boolean).join(`
|
|
30
35
|
|
|
31
|
-
`)}async function
|
|
36
|
+
`)}async function de(e,t){await Ji(Zi(e),{recursive:!0}),await qi(e,sa(t),"utf-8")}async function oe(){let e=process.env.MEMO_HOME?vo(process.env.MEMO_HOME):ea,t=Pe(e,"config.toml");try{await Yi(t);let n=await Xi(t,"utf-8"),o=Qi(n),r=ra(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:e,configPath:t,needsSetup:i}}catch{return{config:Xe,home:e,configPath:t,needsSetup:!0}}}function Re(e,t){let n=t||e.current_provider,o=e.providers.find(r=>r.name===n);return o||(e.providers?.[0]??Xe.providers[0])}function gt(e,t){let n=t.historyDir??Pe(e.home,ta);return vo(n)}function To(e){return Pe(e.home,na)}function ia(e,t=100){return e.replace(/[\\/:\s]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,t)||"root"}function aa(e,t=180){let n=[],o=0;for(let r of e){let s=r.slice(0,Math.max(1,t-o-(n.length>0?1:0)));if(n.push(s),o+=s.length+(n.length>1?1:0),o>=t)break}return n}function So(e,t){let n=new Date,o=String(n.getFullYear()),r=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),a=String(n.getMinutes()).padStart(2,"0"),c=String(n.getSeconds()).padStart(2,"0"),l=ko(process.cwd()),u=`${o}-${r}-${s}_${i}${a}${c}_${t}.jsonl`;return Pe(e,l,u)}function ko(e){let t=e.split(/[/\\]+/).map(o=>ia(o));return aa(t,180).join("-")||"root"}function bo(e,t){return Pe(e,ko(t))}var ht=class{tools=new Map;register(t){this.tools.set(t.name,t)}registerMany(t){for(let n of t)this.register(n)}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,o]of this.tools)t[n]=o;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}};import{Client as ca}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as _o}from"@modelcontextprotocol/sdk/client/sse.js";import{StreamableHTTPClientTransport as la}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as ua}from"@modelcontextprotocol/sdk/client/stdio.js";function yt(){return new ca({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function pa(e){if(!(!e||Object.keys(e).length===0))return{headers:e}}function ma(e){let t={...e.http_headers??e.headers??{}};if(e.bearer_token_env_var){let n=process.env[e.bearer_token_env_var];n&&!t.Authorization&&(t.Authorization=`Bearer ${n}`)}return t}async function da(e){let t=new URL(e.url),n=pa(ma(e));if(e.type==="sse"){let r=yt(),s=new _o(t,{requestInit:n});return await r.connect(s),{client:r,transport:s}}let o=e.fallback_to_sse??!0;try{let r=yt(),s=new la(t,{requestInit:n});return await r.connect(s),{client:r,transport:s}}catch(r){if(!o)throw r;try{let s=yt(),i=new _o(t,{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 fa(e){if("url"in e)return da(e);let t={command:e.command,args:e.args,env:e.env?{...process.env,...e.env}:void 0,stderr:e.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},n=new ua(t),o=yt();return await o.connect(n),{client:o,transport:n}}var xt=class{connections=new Map;async connect(t,n){let o=this.connections.get(t);if(o)return o;let{client:r,transport:s}=await fa(n),i=await r.listTools(),a={name:t,client:r,transport:s,tools:(i.tools||[]).map(c=>({name:`${t}_${c.name}`,description:c.description||`Tool from ${t}: ${c.name}`,source:"mcp",serverName:t,originalName:c.name,inputSchema:c.inputSchema,execute:async()=>({content:[]})}))};return this.connections.set(t,a),a}get(t){return this.connections.get(t)}getAll(){return Array.from(this.connections.values())}getAllTools(){let t=[];for(let n of this.connections.values())for(let o of n.tools)t.push({name:o.name,description:o.description,serverName:o.serverName,originalName:o.originalName,inputSchema:o.inputSchema,client:n.client});return t}async closeAll(){let t=Array.from(this.connections.values()).map(async n=>{try{await n.client.close()}catch(o){console.error(`[MCP] Error closing client ${n.name}:`,o)}});await Promise.all(t),this.connections.clear()}get size(){return this.connections.size}};var vt=class{pool;tools=new Map;shouldLog;constructor(){this.pool=new xt,this.shouldLog=process.env.MEMO_MCP_LOG==="1"||!(process.stdout.isTTY&&process.stdin.isTTY)}async loadServers(t){if(!t||Object.keys(t).length===0)return 0;let n=0;return await Promise.all(Object.entries(t).map(async([o,r])=>{try{let s=await this.pool.connect(o,r);for(let i of s.tools){let a={...i,execute:async 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(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,o]of this.tools)t[n]=o;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}async dispose(){await this.pool.closeAll(),this.tools.clear()}getPool(){return this.pool}};var Tt=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new ht,this.mcpRegistry=new vt}registerNativeTool(t){this.nativeRegistry.register(t)}registerNativeTools(t){for(let n of t)this.registerNativeTool(n)}async loadMcpServers(t){return this.mcpRegistry.loadServers(t)}getTool(t){return this.nativeRegistry.get(t)??this.mcpRegistry.get(t)}getAllTools(){return[...this.nativeRegistry.getAll(),...this.mcpRegistry.getAll()]}toRegistry(){return{...this.nativeRegistry.toRegistry(),...this.mcpRegistry.toRegistry()}}hasTool(t){return this.nativeRegistry.has(t)||this.mcpRegistry.has(t)}getToolCount(){let t=this.nativeRegistry.size,n=this.mcpRegistry.size;return{native:t,mcp:n,total:t+n}}async execute(t,n){let o=this.getTool(t);if(!o)throw new Error(`Tool '${t}' not found`);return o.execute(n)}generateToolDefinitions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema||{type:"object",properties:{}}}))}generateToolDescriptions(){let t=this.getAllTools();if(t.length===0)return"";let n=[];n.push("## Available Tools"),n.push("");let o=t.filter(s=>s.source==="native"),r=t.filter(s=>s.source==="mcp");if(o.length>0){n.push("### Built-in Tools"),n.push("");for(let s of o)n.push(this.formatToolDescription(s));n.push("")}if(r.length>0){n.push("### External MCP Tools"),n.push("");let s=this.groupByServer(r);for(let[i,a]of Object.entries(s)){n.push(`**Server: ${i}**`),n.push("");for(let c of a)n.push(this.formatToolDescription(c));n.push("")}}return n.join(`
|
|
32
37
|
`)}formatToolDescription(t){let n=[];return n.push(`#### ${t.name}`),n.push(`- **Description**: ${t.description}`),t.inputSchema&&Object.keys(t.inputSchema).length>0&&n.push(`- **Input Schema**: ${JSON.stringify(t.inputSchema)}`),n.join(`
|
|
33
|
-
`)}groupByServer(t){let n={};for(let o of t)if(o.source==="mcp"){let r=o.serverName;n[r]||(n[r]=[]),n[r].push(o)}return n}getToolDescriptions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,source:t.source,serverName:t.source==="mcp"?t.serverName:void 0,inputSchema:t.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};import{readFile as
|
|
38
|
+
`)}groupByServer(t){let n={};for(let o of t)if(o.source==="mcp"){let r=o.serverName;n[r]||(n[r]=[]),n[r].push(o)}return n}getToolDescriptions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,source:t.source,serverName:t.source==="mcp"?t.serverName:void 0,inputSchema:t.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};import{readFile as ha,access as ya}from"fs/promises";function xa(e){try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,raw:e,error:t.message}}}async function wo(e,t,n){let o=await oe(),r=o.config,s=new Tt;if(s.registerNativeTools(go),await s.loadMcpServers(r.mcp_servers),e.tools)for(let[m,b]of Object.entries(e.tools))s.registerNativeTool({name:m,description:b.description,source:"native",inputSchema:{type:"object"},execute:b.execute});let i=s.toRegistry(),a=async()=>{let m=await(e.loadPrompt??Ln)(),b=s.generateToolDescriptions();b&&(m+=`
|
|
34
39
|
|
|
35
|
-
${
|
|
40
|
+
${b}`);let h=To(o);try{await ya(h);let C=(await ha(h,"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=t.stream??r.stream_output??!1,u=gt(o,t),p=So(u,n),v=new ct(p);return{tools:i,dispose:async()=>{e.dispose&&await e.dispose(),await s.dispose()},callLLM:e.callLLM??(async(m,b,h)=>{let C=Re(r,t.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 ga({apiKey:P,baseURL:C.base_url}),A=c.length>0?c.map(y=>({type:"function",function:{name:y.name,description:y.description,parameters:y.input_schema}})):void 0;if(l){let y=await g.chat.completions.create({model:C.model,messages:m,stream:!0},{signal:h?.signal}),E="";for await(let U of y){let I=U.choices?.[0]?.delta?.content;I&&(E+=I,b?.(I))}return{content:E,streamed:!0}}else{let y=await g.chat.completions.create({model:C.model,messages:m,tools:A,tool_choice:A?"auto":void 0},{signal:h?.signal}),E=y.choices?.[0]?.message;if(E?.tool_calls&&E.tool_calls.length>0){let I=[];E.content&&I.push({type:"text",text:E.content});for(let k of E.tool_calls)if(k.type==="function"){let w=xa(k.function.arguments);w.ok?I.push({type:"tool_use",id:k.id,name:k.function.name,input:w.data}):I.push({type:"text",text:`[tool_use parse error] ${w.error}; raw: ${w.raw}`})}let V=I.some(k=>k.type==="tool_use");return{content:I,stop_reason:V?"tool_use":"end_turn",usage:{prompt:y.usage?.prompt_tokens??void 0,completion:y.usage?.completion_tokens??void 0,total:y.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:y.usage?.prompt_tokens??void 0,completion:y.usage?.completion_tokens??void 0,total:y.usage?.total_tokens??void 0}}}}),loadPrompt:a,historySinks:e.historySinks??[v],tokenCounter:e.tokenCounter??yo(t.tokenizerModel),historyFilePath:p}}import{jsonrepair as va}from"jsonrepair";function Qt(e){try{return JSON.parse(e)}catch{try{let t=va(e);return JSON.parse(t)}catch{return null}}}function Ta(e){let t=[],n=new Set,o=/```(?:json)?\s*([\s\S]*?)\s*```/g,r;for(;(r=o.exec(e))!==null;){let i=r[1]||"";if(!i)continue;let a=Sa(i);if(!(!a||n.has(a)))try{let c=Qt(a);if(c===null)continue;t.push({json:a,start:r.index,end:r.index+r[0].length,obj:c}),n.add(a)}catch{}}let s=Ao(e);for(let{json:i,start:a,end:c}of s)if(!n.has(i)&&!(!i.includes('"tool"')&&!i.includes('"final"')))try{let l=Qt(i);if(l===null)continue;t.push({json:i,start:a,end:c,obj:l}),n.add(i)}catch{}return t}function Sa(e){return Ao(e)[0]?.json??null}function Ao(e){let t=[],n=0,o=-1,r=!1,s=!1;for(let i=0;i<e.length;i++){let a=e[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=e.slice(o,i+1);t.push({json:c,start:o,end:i+1}),o=-1}}}return t}function ka(e){let t=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,o=e.replace(n,(r,s,i)=>{let a=(i??"").trim();return a&&t.push(a),a});return{thinkingParts:t,cleaned:o.trim()}}function en(e){if(e.length===0)return;let t=e.join(`
|
|
44
|
+
`),{thinkingParts:n,cleaned:o}=ka(t);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 e?e.stop_reason:void 0,usage:"usage"in e?e.usage:void 0}}return{textContent:"",toolUseBlocks:[]}}async function
|
|
43
|
-
`)}function
|
|
46
|
+
`):o||void 0}function Co(e){return e!==null&&typeof e=="object"&&"tool"in e&&typeof e.tool=="string"}function Eo(e){return e!==null&&typeof e=="object"&&"final"in e&&typeof e.final=="string"}function Mo(e){let t={},n=Ta(e);for(let{json:r,start:s,end:i,obj:a}of n){if(Co(a)){t.action={tool:a.tool.trim(),input:a.input};let c=e.slice(0,s).trim(),l=e.slice(i).trim(),u=[];c&&u.push(c),l&&u.push(l);let p=en(u);return p&&(t.thinking=p),t}if(Eo(a))return t.final=a.final,t}let o=e.trim();if(o.startsWith("{")&&o.endsWith("}")){let r=Qt(o);if(r&&Co(r))return t.action={tool:r.tool,input:r.input},t;if(r&&Eo(r))return t.final=r.final,t}return e.trim()&&(t.final=e),t}import{randomUUID as Lo}from"crypto";function ba(){return{onTurnStart:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[]}}function Po(e,t){t&&(t.onTurnStart&&e.onTurnStart.push(t.onTurnStart),t.onAction&&e.onAction.push(t.onAction),t.onObservation&&e.onObservation.push(t.onObservation),t.onFinal&&e.onFinal.push(t.onFinal),t.onApprovalRequest&&e.onApprovalRequest.push(t.onApprovalRequest),t.onApprovalResponse&&e.onApprovalResponse.push(t.onApprovalResponse))}function Ro(e){let t=ba();if(Po(t,e.hooks),Array.isArray(e.middlewares))for(let n of e.middlewares)Po(t,n);return t}async function Q(e,t,n){let o=e[t];if(o.length)for(let r of o)try{await r(n)}catch(s){console.warn(`Hook ${t} failed: ${s.message}`)}}function je(e){return e.map(t=>({...t}))}var tn={read:"read",glob:"read",grep:"read",webfetch:"read",todo:"read",write:"write",edit:"write",save_memory:"write",bash:"execute"};var St={read:0,write:1,execute:2},nn={read:e=>`${e} \u5C06\u8BFB\u53D6\u6587\u4EF6\u6216\u6570\u636E`,write:e=>`${e} \u5C06\u4FEE\u6539\u6216\u521B\u5EFA\u6587\u4EF6`,execute:e=>`${e} \u5C06\u6267\u884C\u7CFB\u7EDF\u547D\u4EE4`};function on(e){let t={...tn,...e?.customLevels};return{getRiskLevel(n){if(n in t)return t[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 St[n]-St[o]},needsApproval(n,o){return o==="strict"?!0:n==="write"||n==="execute"}}}import{createHash as _a}from"crypto";function kt(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map(n=>kt(n)).join(",")+"]":`{${Object.entries(e).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${kt(o)}`).join(",")}}`}function rn(e,t){let n=kt(t),o=`${e}:${n}`;return _a("sha256").update(o).digest("hex").slice(0,16)}function sn(e){let{mode:t="auto",dangerous:n=!1,toolRiskLevels:o}=e||{};if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let r=on({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,t))return{needApproval:!1,decision:"auto-execute"};let l=rn(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:nn[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 No="interactive";function $o(){return{prompt:0,completion:0,total:0}}function Io(e,t){if(!t)return;let n=t.prompt??0,o=t.completion??0,r=t.total??n+o;e.prompt+=n,e.completion+=o,e.total+=r}function wa(e){if(typeof e=="string")return{textContent:e,toolUseBlocks:[]};if("content"in e&&typeof e.content=="string")return{textContent:e.content,toolUseBlocks:[],usage:"usage"in e?e.usage:void 0,streamed:"streamed"in e?e.streamed:void 0};if("content"in e&&Array.isArray(e.content)){let t=e.content.filter(o=>o.type==="text"),n=e.content.filter(o=>o.type==="tool_use");return{textContent:t.map(o=>o.text).join(`
|
|
47
|
+
`),toolUseBlocks:n.map(o=>({id:o.id,name:o.name,input:o.input})),stopReason:"stop_reason"in e?e.stop_reason:void 0,usage:"usage"in e?e.usage:void 0}}return{textContent:"",toolUseBlocks:[]}}async function Ca(e,t){for(let n of t)try{await n.append(e)}catch(o){console.error(`Failed to write history event: ${o.message}`)}}function Ea(e){return(e.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
|
|
48
|
+
`)}function Aa(e,t){let n=t;if(typeof t=="string"){let o=t.trim();if(o)try{n=JSON.parse(o)}catch{n=o}else n={}}return typeof n!="object"||n===null?{ok:!1,error:`${e.name} invalid input: expected object`}:{ok:!0,data:n}}function Ma(e){return e instanceof Error&&e.name==="AbortError"}function bt(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(n=>bt(n)).join(",")}]`:`{${Object.entries(e).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${JSON.stringify(n)}:${bt(o)}`).join(",")}}`}var an=class{constructor(t,n,o,r,s){this.deps=t;this.options=n;this.id=n.sessionId||Lo(),this.mode=n.mode||No,this.history=[{role:"system",content:o}],this.tokenCounter=r,this.sinks=t.historySinks??[],this.hooks=Ro(t),this.historyFilePath=s,this.approvalManager=sn({dangerous:!1,mode:"auto"})}id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=$o();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(t,n){let o=`${t}:${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${t}\u300D\u4E14\u53C2\u6570\u76F8\u540C\uFF08${r}${r.length>=200?"\u2026":""}\uFF09\u3002\u8BF7\u786E\u8BA4\u662F\u5426\u9677\u5165\u5FAA\u73AF\uFF0C\u5FC5\u8981\u65F6\u76F4\u63A5\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\u6216\u8C03\u6574\u53C2\u6570\u3002`;this.history.push({role:"system",content:s})}}async executeToolWithApproval(t,n,o,r){let s=this.approvalManager.check(t,n);if(!s.needApproval)return this.doExecuteTool(t,n);let i={toolName:s.toolName,params:s.params,fingerprint:s.fingerprint,riskLevel:s.riskLevel,reason:s.reason};await Q(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 Q(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: ${t}`,rejected:!0}:this.doExecuteTool(t,n)}async doExecuteTool(t,n){let o=this.deps.tools[t];if(!o)return{success:!1,observation:`Unknown tool: ${t}`};try{let r=Aa(o,n);if(!r.ok)return{success:!1,observation:r.error};let s=await o.execute(r.data);return{success:!0,observation:Ea(s)||"(no tool output)"}}catch(r){return{success:!1,observation:`Tool execution failed: ${r.message}`}}}async runTurn(t){let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let o=this.turnIndex,r=[],s=$o(),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:t});try{let a=this.tokenCounter.countMessages(this.history);await this.emitEvent("turn_start",{turn:o,content:t,meta:{tokens:{prompt:a}}}),await Q(this.hooks,"onTurnStart",{sessionId:this.id,turn:o,input:t,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 k=`Context tokens (${v}) exceed the limit. Please shorten the input or restart the session.`,w=JSON.stringify({final:k});this.history.push({role:"assistant",content:w}),l="prompt_limit",c=k,u=k,await this.emitEvent("final",{turn:o,step:p,content:k,role:"assistant",meta:{tokens:{prompt:v}}}),await Q(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:k,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="",b=[],h,C=!1,P;try{let k=await this.deps.callLLM(this.history,j=>this.deps.onAssistantStep?.(j,p),{signal:n.signal}),w=wa(k);m=w.textContent,b=w.toolUseBlocks,P=w.stopReason,h=w.usage,C=!!w.streamed}catch(k){if(this.cancelling&&Ma(k)){l="cancelled",c="",u="Turn cancelled",await this.emitEvent("final",{turn:o,step:p,content:"",role:"assistant",meta:{cancelled:!0}}),await Q(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: ${k.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 Q(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(b.length>0){let k=b[0];if(k){let w=m?en([m]):void 0;g={action:{tool:k.name,input:k.input},thinking:w}}else g={}}else m?g=Mo(m):g={};let A=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:A});let y=this.tokenCounter.countText(m),E=h?.prompt??v,U=h?.completion??y,I=h?.total??E+U,V={prompt:E,completion:U,total:I};if(Io(s,V),Io(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}}),b.length>1){for(let H of b)this.maybeWarnRepeatedAction(H.name,H.input);await this.emitEvent("action",{turn:o,step:p,meta:{tools:b.map(H=>H.name),parallel:!0,thinking:g.thinking,toolBlocks:b.map(H=>({name:H.name,input:H.input}))}});let k=b[0];k&&await Q(this.hooks,"onAction",{sessionId:this.id,turn:o,step:p,action:{tool:k.name,input:k.input},parallelActions:b.map(H=>({tool:H.name,input:H.input})),thinking:g.thinking,history:je(this.history)});let w=[],j=!1;for(let[H,B]of b.entries()){let pe=await this.executeToolWithApproval(B.name,B.input,o,p);if(pe.rejected){j=!0,w.push(`[${B.name}]: ${pe.observation}`),await this.emitEvent("observation",{turn:o,step:p,content:pe.observation,meta:{tool:B.name,index:H}});break}w.push(`[${B.name}]: ${pe.observation}`),await this.emitEvent("observation",{turn:o,step:p,content:pe.observation,meta:{tool:B.name,index:H}})}let ie=w.join(`
|
|
44
49
|
|
|
45
|
-
`);this.history.push({role:"user",content:JSON.stringify({observation:
|
|
46
|
-
`;case"checkbox":return e.checked?"[x]":"[ ]";case"html":return e.text;default:return"text"in e?e.text:e.raw}}function
|
|
50
|
+
`);this.history.push({role:"user",content:JSON.stringify({observation:ie})});let X=r[r.length-1];if(X&&(X.observation=ie),await Q(this.hooks,"onObservation",{sessionId:this.id,turn:o,step:p,tool:b.map(H=>H.name).join(", "),observation:ie,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 Q(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 Q(this.hooks,"onAction",{sessionId:this.id,turn:o,step:p,action:g.action,thinking:g.thinking,history:je(this.history)});let k=await this.executeToolWithApproval(g.action.tool,g.action.input,o,p);if(k.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 Q(this.hooks,"onFinal",{sessionId:this.id,turn:o,step:p,finalText:c,status:l,tokenUsage:V,turnUsage:{...s},steps:r});break}let w=k.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 Q(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 Q(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 Q(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(t,n){if(!this.sinks.length)return;let o=Nn({sessionId:this.id,type:t,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await Ca(o,this.sinks)}};async function Ye(e,t={}){let n=t.sessionId||Lo(),o=await wo(e,{...t,sessionId:n},n),r=await o.loadPrompt(),s=new an({...e,...o},{...t,sessionId:n,mode:t.mode??No},r,o.tokenCounter,o.historyFilePath);return await s.init(),s}import{useCallback as te,useEffect as It,useMemo as wn,useRef as Lt,useState as W}from"react";import{readFile as Dl}from"fs/promises";import"path";import{randomUUID as Nt}from"crypto";import{exec as Ul}from"child_process";import{promisify as jl}from"util";import{Box as Or,useApp as Hl,Text as Bl}from"ink";import{Box as Oo,Text as Pa}from"ink";import{memo as Ra}from"react";import{jsx as Do,jsxs as $a}from"react/jsx-runtime";var Uo=Ra(function({contextPercent:t=0}){let n=t>0?` ${t.toFixed(1)}%`:" 0.0%";return Do(Oo,{justifyContent:"flex-end",children:Do(Oo,{marginTop:8,children:$a(Pa,{color:"gray",children:["context:",n]})})})});import{Box as fe,Static as rc,Text as se}from"ink";import{memo as sc}from"react";import ic from"os";import{Box as Ia,Text as jo}from"ink";import{memo as La}from"react";import{jsx as Na,jsxs as Ho}from"react/jsx-runtime";var Bo=La(function({message:t}){return Ho(Ia,{flexDirection:"column",gap:0,children:[Ho(jo,{color:"cyan",children:["\u25CF ",t.title]}),Na(jo,{color:"gray",children:t.content})]})});import{Box as ec,Text as tc}from"ink";import{memo as nc}from"react";import{Box as Ze,Text as re}from"ink";import{memo as Wa}from"react";import{Box as cn,Text as z}from"ink";import{marked as Oa}from"marked";import{useMemo as Fo,memo as Da}from"react";import{jsx as ee,jsxs as He}from"react/jsx-runtime";var Ua="#2b2b2b";function _t(e){return e?[{type:"text",raw:e,text:e}]:[]}function ja(e,t,n){switch(e.type){case"text":return e.tokens&&e.tokens.length>0?Te(e.tokens,t,`${n}-text`):e.text;case"escape":return e.text;case"strong":return ee(z,{bold:!0,children:Te(e.tokens,t,`${n}-strong`)},n);case"em":return ee(z,{italic:!0,children:Te(e.tokens,t,`${n}-em`)},n);case"codespan":return ee(z,{color:t.codeColor,backgroundColor:Ua,children:e.text},n);case"del":return ee(z,{strikethrough:!0,children:Te(e.tokens,t,`${n}-del`)},n);case"link":{let o=e.tokens&&e.tokens.length>0?Te(e.tokens,t,`${n}-link`):e.text,r=e.href&&e.text&&e.text!==e.href?` (${e.href})`:"";return He(z,{underline:!0,color:t.linkColor,children:[o,r]},n)}case"image":{let o=e.text||"image";return He(z,{color:t.linkColor,children:["[",o,"](",e.href,")"]},n)}case"br":return`
|
|
51
|
+
`;case"checkbox":return e.checked?"[x]":"[ ]";case"html":return e.text;default:return"text"in e?e.text:e.raw}}function Te(e,t,n){return!e||e.length===0?[]:e.flatMap((o,r)=>{let s=`${n}-${r}`,i=ja(o,t,s);return Array.isArray(i)?i:[i]})}function Ha(e){let t=e.tokens[0];return t?.type==="paragraph"||t?.type==="text"?t.tokens??_t(t.text):e.tokens.length>0?e.tokens:_t(e.text)}function Ba(e){return e.split(`
|
|
47
52
|
`).map(t=>t.length>0?` ${t}`:"").join(`
|
|
48
|
-
`).trimEnd()}function
|
|
49
|
-
`)}function
|
|
53
|
+
`).trimEnd()}function Fa(e){let t=e.header.map(r=>r.text).join(" | "),n=e.header.map(()=>"---").join(" | "),o=e.rows.map(r=>r.map(s=>s.text).join(" | "));return[t,n,...o].join(`
|
|
54
|
+
`)}function Va(e){return e.type==="table"&&"header"in e&&"rows"in e&&"align"in e}function Ga(e,t,n){switch(e.type){case"space":case"def":return null;case"heading":return ee(z,{bold:!0,color:t.textColor,children:Te(e.tokens,t,`${n}-heading`)},n);case"paragraph":{let o=e.tokens??_t(e.text);return ee(z,{color:t.textColor,children:Te(o,t,`${n}-para`)},n)}case"text":{let o=e.tokens??_t(e.text);return ee(z,{color:t.textColor,children:Te(o,t,`${n}-text`)},n)}case"code":{let o=Ba(e.text);return ee(z,{color:t.codeColor,children:o},n)}case"list":{let o=typeof e.start=="number"?e.start:1;return ee(cn,{flexDirection:"column",children:e.items.map((r,s)=>{let i=e.ordered?`${o+s}.`:"-",a=r.task?r.checked?"[x] ":"[ ] ":"",c=Ha(r);return He(cn,{children:[He(z,{color:t.textColor,children:[i," "]}),He(z,{color:t.textColor,children:[a,Te(c,t,`${n}-item-${s}`)]})]},`${n}-item-${s}`)})},n)}case"blockquote":return He(z,{color:"gray",dimColor:!0,children:["> ",e.text.trim()]},n);case"hr":return ee(z,{color:"gray",children:"---"},n);case"table":return Va(e)?ee(z,{color:t.textColor,children:Fa(e)},n):ee(z,{color:t.textColor,children:"text"in e?e.text:e.raw},n);case"html":return ee(z,{color:t.textColor,children:e.text},n);default:return ee(z,{color:t.textColor,children:"text"in e?e.text:e.raw},n)}}function za(e,t,n){return e.flatMap((o,r)=>{let s=Ga(o,t,`${n}-${r}`);return s?[s]:[]})}var Be=Da(function({text:t,tone:n="normal"}){let o=Fo(()=>({textColor:n==="muted"?"gray":void 0,codeColor:n==="muted"?"gray":"cyan",linkColor:n==="muted"?"gray":"blue",muted:n==="muted"}),[n]),r=Fo(()=>{let s=Oa.lexer(t,{gfm:!0,breaks:!0});return za(s,o,"markdown")},[t,o]);return ee(cn,{flexDirection:"column",gap:1,children:r})});import{Fragment as ln,jsx as J,jsxs as Fe}from"react/jsx-runtime";function Vo(e){if(!e)return;if(typeof e=="string")return e.length>50?e.slice(0,47)+"...":e;if(typeof e!="object"||Array.isArray(e))return;let t=e,n=["file_path","path","file","filename","url","command","pattern","glob","query","content","cwd","dir"];for(let o of n)if(t[o]){let r=String(t[o]);return r.length>50?r.slice(0,47)+"...":r}for(let[o,r]of Object.entries(t))if(typeof r=="string"&&o!=="description")return r.length>50?r.slice(0,47)+"...":r}function Ka(e,t){let n=e.step,o=t.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 Go=Wa(function({step:t}){let n=t.action?.tool,o=t.action?.input,r=Vo(o),s=t.parallelActions??[],i=s.length>1;return Fe(Ze,{flexDirection:"column",gap:0,children:[t.thinking&&Fe(Ze,{children:[J(re,{color:"gray",children:"\u25CF "}),J(Ze,{flexDirection:"column",flexGrow:1,children:J(Be,{text:t.thinking,tone:"muted"})})]}),i&&J(ln,{children:s.map((a,c)=>{let l=Vo(a.input);return Fe(Ze,{children:[J(re,{color:"green",children:"\u25CF "}),J(re,{color:"gray",children:"Used "}),J(re,{color:"cyan",children:a.tool}),l&&Fe(ln,{children:[J(re,{color:"gray",children:" ("}),J(re,{color:"cyan",children:l}),J(re,{color:"gray",children:")"})]})]},c)})}),!i&&n&&Fe(Ze,{children:[J(re,{color:"green",children:"\u25CF "}),J(re,{color:"gray",children:"Used "}),J(re,{color:"cyan",children:n}),r&&Fe(ln,{children:[J(re,{color:"gray",children:" ("}),J(re,{color:"cyan",children:r}),J(re,{color:"gray",children:")"})]})]})]})},Ka);import{Box as Ja,Text as zo}from"ink";import{memo as qa}from"react";import{jsx as Wo,jsxs as Xa}from"react/jsx-runtime";var Ko=qa(function({text:t}){return Xa(Ja,{paddingY:1,children:[Wo(zo,{color:"gray",children:"\u203A "}),Wo(zo,{color:"white",children:t})]})});import{Box as Qe,Text as $e}from"ink";import{memo as un,useMemo as Ya}from"react";import{Fragment as Qa,jsx as ce,jsxs as wt}from"react/jsx-runtime";function Za(e){let t=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,n=[],o,r=0,s=[];for(;(o=t.exec(e))!==null;){s.push({start:o.index,end:t.lastIndex});let a=o[2]?.trim();a&&n.push(a)}if(s.length===0)return{content:e,thinking:null};let i="";r=0;for(let{start:a,end:c}of s)i+=e.slice(r,a),r=c;return i+=e.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 Jo=un(function({text:t,isThinking:n=!1}){let{content:o,thinking:r}=Ya(()=>Za(t),[t]);return n?ce(Qe,{flexDirection:"column",flexGrow:1,children:ce(Be,{text:t,tone:"muted"})}):wt(Qe,{flexDirection:"column",flexGrow:1,gap:1,children:[r&&ce(Qe,{flexDirection:"column",paddingLeft:2,children:ce(Be,{text:r,tone:"muted"})}),ce(Be,{text:o,tone:"normal"})]})}),id=un(function({text:t}){return ce(Qe,{children:wt($e,{color:"gray",children:["\u2022 ",t]})})}),ad=un(function({toolName:t,fileName:n}){return wt(Qe,{children:[ce($e,{color:"green",children:"\u25CF "}),ce($e,{color:"gray",children:"Used "}),ce($e,{color:"cyan",children:t}),n&&wt(Qa,{children:[ce($e,{color:"gray",children:" ("}),ce($e,{color:"cyan",children:n}),ce($e,{color:"gray",children:")"})]})]})});import{jsx as pn,jsxs as qo}from"react/jsx-runtime";function oc(e,t){let n=e.turn,o=t.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 mn=nc(function({turn:t}){let n=t.finalText?.trim()??"",o=n.length>0;return qo(ec,{flexDirection:"column",children:[pn(Ko,{text:t.userInput}),t.steps.map(r=>pn(Go,{step:r},`step-${t.index}-${r.index}`)),o?pn(Jo,{text:n,isThinking:!1}):null,t.status&&t.status!=="ok"?qo(tc,{color:"red",children:["Status: ",t.status]}):null]})},oc);import{jsx as q,jsxs as ue}from"react/jsx-runtime";function ac(e){let t=ic.homedir();return t&&e.startsWith(t)?`~${e.slice(t.length)}`:e}function cc(e){return e.length>16?`${e.slice(0,8)}...${e.slice(-4)}`:e}function lc(e,t){if(e.headerInfo?.sessionId!==t.headerInfo?.sessionId||e.headerInfo?.model!==t.headerInfo?.model||e.headerInfo?.providerName!==t.headerInfo?.providerName||e.headerInfo?.cwd!==t.headerInfo?.cwd||e.headerInfo?.version!==t.headerInfo?.version||e.headerInfo?.mcpNames?.length!==t.headerInfo?.mcpNames?.length)return!1;if(e.headerInfo?.mcpNames&&t.headerInfo?.mcpNames){let n=e.headerInfo.mcpNames,o=t.headerInfo.mcpNames;for(let r=0;r<n.length;r++)if(n[r]!==o[r])return!1}if(e.systemMessages.length!==t.systemMessages.length)return!1;for(let n=0;n<e.systemMessages.length;n++)if(e.systemMessages[n]?.id!==t.systemMessages[n]?.id)return!1;if(e.turns.length!==t.turns.length)return!1;for(let n=0;n<e.turns.length;n++)if(e.turns[n]!==t.turns[n])return!1;return!0}var Xo=sc(function({systemMessages:t,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 t)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 ue(fe,{flexDirection:"column",gap:0,children:[q(rc,{items:c,children:u=>{if(u.type==="header"&&u.data){let p=u.data;return ue(fe,{borderStyle:"round",borderColor:"blueBright",paddingX:2,paddingY:1,flexDirection:"column",gap:1,children:[q(fe,{gap:1,alignItems:"center",children:ue(fe,{flexDirection:"column",children:[q(se,{bold:!0,children:"Welcome to Memo Code CLI!"}),q(se,{color:"gray",children:"Send /help for help information."})]})}),ue(fe,{flexDirection:"column",gap:0,children:[ue(fe,{children:[q(se,{color:"gray",children:"Directory: "}),q(se,{color:"cyan",children:ac(p.cwd)})]}),ue(fe,{children:[q(se,{color:"gray",children:"Session: "}),q(se,{color:"cyan",children:cc(p.sessionId)})]}),ue(fe,{children:[q(se,{color:"gray",children:"Model: "}),q(se,{color:"cyan",children:p.model}),ue(se,{color:"gray",children:[" ","(powered by ",p.providerName,")"]})]}),ue(fe,{children:[q(se,{color:"gray",children:"Version: "}),ue(se,{color:"cyan",children:["v",p.version]})]}),ue(fe,{children:[q(se,{color:"gray",children:"MCP: "}),q(se,{color:"cyan",children:p.mcpNames.length>0?p.mcpNames.join(", "):"none"})]})]})]},"header")}return u.type==="system"?q(Bo,{message:u.data},u.data.id):u.type==="turn"?q(mn,{turn:u.data},`turn-${u.data.index}`):null}}),a&&q(mn,{turn:a},`turn-live-${a.index}`)]})},lc);import{useCallback as Tr,useEffect as Tn,useMemo as Yc,useRef as Sn,useState as Ce}from"react";import{readFile as Zc,readdir as Qc,stat as el}from"fs/promises";import{basename as tl,join as nl,resolve as Sr}from"path";import{Box as Rt,Text as Ie,useInput as ol}from"ink";var ar=In(sr(),1);import{readFile as Pc,readdir as Rc}from"fs/promises";import{join as ir,relative as $c,sep as Ic}from"path";var Lc=6,Nc=2500,cr=25,Oc=[".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs","*.log"],Mt=new Map;function Dc(e){return e.split(Ic).join("/")}function Uc(e,t){return JSON.stringify({maxDepth:e.maxDepth,maxEntries:e.maxEntries,respectGitIgnore:e.respectGitIgnore,ignoreGlobs:e.ignoreGlobs,gitignore:t})}function jc(e){return{maxDepth:typeof e.maxDepth=="number"?Math.max(1,e.maxDepth):Lc,maxEntries:typeof e.maxEntries=="number"?Math.max(100,e.maxEntries):Nc,limit:typeof e.limit=="number"?Math.max(1,e.limit):cr,respectGitIgnore:e.respectGitIgnore!==!1,ignoreGlobs:e.ignoreGlobs?.length?e.ignoreGlobs:[]}}async function Hc(e,t){if(!t)return"";try{return await Pc(ir(e,".gitignore"),"utf8")}catch{}return""}async function Bc(e,t){let n=await Hc(t,e.respectGitIgnore),o=(0,ar.default)();o.add(Oc),e.ignoreGlobs.length&&o.add(e.ignoreGlobs),n.trim()&&o.add(n);let r=Uc(e,n);return Object.assign(o,{__memoSignature:r})}async function Fc(e,t,n){let o=[],r=t.maxEntries,s=async(i,a)=>{if(o.length>=r)return;let c;try{c=await Rc(i,{withFileTypes:!0})}catch{return}for(let l of c){if(o.length>=r)break;if(l.isSymbolicLink())continue;let u=ir(i,l.name),p=$c(e,u);if(!p)continue;let v=Dc(p);if(n.ignores(v))continue;let m=v.split("/").filter(Boolean),b=m.map(C=>C.toLowerCase()),h=l.isDirectory();if(o.push({path:v,pathLower:v.toLowerCase(),segments:m,segmentsLower:b,depth:a,isDir:h}),o.length>=r)break;h&&a<t.maxDepth&&await s(u,a+1)}};return await s(e,0),o.sort((i,a)=>i.path.localeCompare(a.path)),{entries:o,signature:n.__memoSignature}}async function Vc(e,t){let n=jc(t),o=await Bc(n,e),r=o.__memoSignature,s=Mt.get(e);if(s&&s.signature===r)return s.pending?s.pending:s.entries;let i=Fc(e,n,o).then(a=>(Mt.set(e,{entries:a.entries,signature:a.signature}),a.entries)).catch(a=>{throw Mt.delete(e),a});return Mt.set(e,{entries:[],signature:r,pending:i}),i}function Gc(e){return e.depth+(e.isDir?-.2:.2)}function zc(e,t){if(!t.length)return Gc(e);let n=e.depth,o=0;for(let r of t){let s=-1;for(let i=o;i<e.segmentsLower.length;i++){let a=e.segmentsLower[i];if(a.startsWith(r)){s=i,n+=(i-o)*1.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 e.isDir&&(n-=.5),n}function Wc(e,t,n){let s=t.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(a=>a.toLowerCase()),i=[];for(let a of e){let c=zc(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 lr(e){let t=await Vc(e.cwd,e),n=typeof e.limit=="number"?Math.max(1,e.limit):cr;return Wc(t,e.query,n)}import{mkdir as Md,readFile as Pd,writeFile as Rd}from"fs/promises";import{dirname as Id}from"path";import{randomUUID as Nd}from"crypto";import{Box as tt,Text as ze}from"ink";import{jsx as ke,jsxs as pr}from"react/jsx-runtime";var Kc="#3a3a3a",Pt="#2b2b2b",ur="#888888",Jc="#666666";function mr({items:e,activeIndex:t,loading:n}){return n?ke(tt,{flexDirection:"column",paddingX:1,backgroundColor:Pt,children:ke(ze,{color:"gray",children:"Loading..."})}):e.length?ke(tt,{flexDirection:"column",backgroundColor:Pt,children:e.map((o,r)=>{let s=r===t,i=s?Kc:Pt;return o.kind==="slash"?pr(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:ur,children:o.subtitle}):null]},o.id):pr(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:ur,children:o.subtitle}):null]},o.id)})}):ke(tt,{flexDirection:"column",paddingX:1,backgroundColor:Pt,children:ke(ze,{color:Jc,children:"No matches"})})}var dr={name:"new",description:"Start a new session",run:({closeSuggestions:e,setInputValue:t,clearScreen:n,showSystemMessage:o,newSession:r})=>{e(),t(""),n(),o("New Session","Starting a new session..."),r?.()}};var fr={name:"exit",description:"Exit the session",run:({closeSuggestions:e,exitApp:t})=>{e(),t()}};var gr={name:"resume",description:"Resume history",run:({closeSuggestions:e,setInputValue:t,showSystemMessage:n})=>{e(!1),t("resume "),n("Resume",'Type "resume" followed by keywords to filter and select from session history.')}};var hr={name:"models",description:"Select a model (from configured providers)",run:({closeSuggestions:e,setInputValue:t,showSystemMessage:n,data:o})=>{e(!1);let{providers:r,providerName:s,model:i}=o;if(!r.length){n("Models",`No providers configured. Check ${o.configPath}`),t("");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}`});t("/models "),n("Models",`Available models:
|
|
54
59
|
${a.join(`
|
|
55
|
-
`)}`)}};var
|
|
60
|
+
`)}`)}};var qc=`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
|
|
79
|
+
Esc Esc Cancel / Clear input`,yr={name:"help",description:"Show help",run:({closeSuggestions:e,setInputValue:t,showSystemMessage:n})=>{e(),t(""),n("Help",qc)}};var xr={name:"context",description:"Set context length limit (80k/120k/150k/200k)",run:({closeSuggestions:e,setInputValue:t})=>{e(!1),t("/context ")}};function Xc(e,t){let n=[];if(n.push(`- **${e}**`),"url"in t){n.push(` - Type: ${t.type??"streamable_http"}`),n.push(` - URL: ${t.url}`),t.bearer_token_env_var&&n.push(` - Bearer token env: ${t.bearer_token_env_var}`),t.type!=="sse"&&t.fallback_to_sse!==void 0&&n.push(` - Fallback to SSE: ${t.fallback_to_sse}`);let o=t.http_headers??t.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: ${t.type??"stdio"}`),n.push(` - Command: ${t.command}`),t.args&&t.args.length>0&&n.push(` - Args: ${t.args.join(" ")}`),t.env&&Object.keys(t.env).length>0){let o=Object.entries(t.env).map(([r,s])=>`${r}=${s}`).join(", ");n.push(` - Env: ${o}`)}return n.join(`
|
|
80
|
+
`)}var vr={name:"mcp",description:"Show configured MCP servers",run:({closeSuggestions:e,setInputValue:t,showSystemMessage:n,data:o})=>{e();let{mcpServers:r,configPath:s}=o,i=Object.keys(r);if(i.length===0){n("MCP Servers",`No MCP servers configured.
|
|
76
81
|
|
|
77
82
|
Add servers to ${s}`),t("");return}let a=[];a.push(`Total: ${i.length} server(s)
|
|
78
|
-
`);for(let[c,l]of Object.entries(r))a.push(
|
|
79
|
-
`))}};var
|
|
80
|
-
`;
|
|
81
|
-
`),
|
|
82
|
-
`)){let n=t.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
|
|
83
|
+
`);for(let[c,l]of Object.entries(r))a.push(Xc(c,l)),a.push("");t(""),n("MCP Servers",a.join(`
|
|
84
|
+
`))}};var vn=[yr,fr,dr,gr,hr,xr,vr];import{Fragment as yl,jsx as Ee,jsxs as nt}from"react/jsx-runtime";var rl=400;function kr({disabled:e,onSubmit:t,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:b,configPath:h,providerName:C,model:P,contextLimit:g,mcpServers:A}){let[y,E]=Ce(""),[U,I]=Ce(null),[V,k]=Ce(""),[w,j]=Ce("none"),[ie,X]=Ce([]),[H,B]=Ce(0),[pe,he]=Ce(!1),[Oe,_e]=Ce(!1),Y=Sn(0),De=Sn(0),D=Sn(""),we="\u203A ";Tn(()=>{D.current=y,_e(!1)},[y]);let F=Yc(()=>Oe||e?null:ll(y),[e,Oe,y]),Z=Tr((L=!0)=>{L&&_e(!0),j("none"),X([]),B(0),he(!1)},[]);Tn(()=>{e&&Z(!1)},[e,Z]),Tn(()=>{if(!F){j("none"),X([]),B(0),he(!1);return}let L=!1,N=++Y.current;return he(!0),(async()=>{try{if(F.type==="file"){let R=await lr({cwd:u,query:F.query,limit:8});if(L||N!==Y.current)return;let x=R.map(T=>{let M=T.isDir?`${T.path}/`:T.path;return{id:T.id,title:M,kind:"file",value:M,meta:{isDir:T.isDir}}});j("file"),X(x),B(T=>x.length?Math.min(T,x.length-1):0);return}if(F.type==="history"){let R=await sl({sessionsDir:p,cwd:u,keyword:F.keyword,activeSessionFile:v});if(L||N!==Y.current)return;let x=R.map(gl);j("history"),X(x),B(T=>x.length?Math.min(T,x.length-1):0);return}if(F.type==="models"){let R=F.keyword.toLowerCase(),T=(b??[]).filter(M=>{let K=M.name?.toLowerCase()??"",Me=M.model?.toLowerCase()??"";return R?K.includes(R)||Me.includes(R):!0}).map(M=>({id:M.name,title:`${M.name}: ${M.model}`,subtitle:M.base_url??M.env_api_key??"",kind:"model",value:`/models ${M.name}`,meta:{provider:M}}));j("model"),X(T),B(M=>T.length?Math.min(M,T.length-1):0);return}if(F.type==="context"){let x=[8e4,12e4,15e4,2e5].map(T=>({id:`${T}`,title:`${(T/1e3).toFixed(0)}k tokens`,subtitle:T===g?"Current":void 0,kind:"context",value:`/context ${(T/1e3).toFixed(0)}k`,meta:{contextValue:T}}));j("context"),X(x),B(T=>x.length?Math.min(T,x.length-1):0);return}if(F.type==="slash"){let R=F.keyword.toLowerCase(),T=(R?vn.filter(M=>M.matches?M.matches(R):M.name.startsWith(R)):vn).map(M=>({id:M.name,title:`/${M.name}`,subtitle:M.description,kind:"slash",value:`/${M.name} `,meta:{slashCommand:M}}));j("slash"),X(T),B(M=>T.length?Math.min(M,T.length-1):0);return}}catch{!L&&N===Y.current&&X([])}finally{!L&&N===Y.current&&he(!1)}})(),()=>{L=!0}},[F,u,p,v,b,g]);let Ue=Tr(L=>{if(L){if(w==="file"&&F?.type==="file"){let N=y.slice(0,F.tokenStart),R=y.slice(F.tokenStart+F.query.length),x=`${N}${L.value}${R}`;D.current=x,E(x),I(null),k(""),L.meta?.isDir||Z();return}if(w==="history"){L.meta?.historyEntry&&m?.(L.meta.historyEntry),D.current=L.value,E(L.value),I(null),k(""),Z();return}if(w==="model"&&L.meta?.provider){i?.(L.meta.provider),D.current="",E(""),I(null),k(""),Z();return}if(w==="slash"&&L.meta?.slashCommand){L.meta.slashCommand.run({setInputValue:R=>{D.current=R,E(R),I(null),k("")},closeSuggestions:Z,clearScreen:()=>{o()},newSession:()=>{r?.()},exitApp:()=>{n()},showSystemMessage:(R,x)=>{a?.(R,x)},switchModel:R=>{i?.(R)},setContextLimit:R=>{c?.(R)},loadHistory:R=>{m?.(R)},data:{configPath:h,providerName:C,model:P,contextLimit:g,providers:b,mcpServers:A}});return}if(w==="context"&&L.meta?.contextValue){let N=L.meta.contextValue;c?.(N),a?.("Context",`Context limit set to ${(N/1e3).toFixed(0)}k tokens`),D.current="",E(""),I(null),k(""),Z();return}}},[Z,o,n,i,a,c,m,w,F,y,h,C,P,g,b,A]);ol((L,N)=>{if(N.ctrl&&L==="l"){D.current="",E(""),I(null),k(""),Z(),o(),r?.();return}let R=w!=="none",x=R&&ie.length>0;if(N.escape){let T=Date.now();if(T-De.current<=rl){De.current=0,e?s():(D.current="",E(""),I(null),k(""),Z());return}De.current=T,R&&Z();return}if(!e){if(N.upArrow){if(x){B(K=>K<=0?ie.length-1:K-1);return}if(!l.length)return;if(U===null){k(D.current);let K=l.length-1;I(K);let Me=l[K]??"";D.current=Me,E(Me);return}let T=Math.max(0,U-1);I(T);let M=l[T]??"";D.current=M,E(M);return}if(N.downArrow){if(x){B(K=>(K+1)%ie.length);return}if(U===null)return;let T=U+1;if(T>=l.length){I(null),D.current=V,E(V),k("");return}I(T);let M=l[T]??"";D.current=M,E(M);return}if(N.tab&&x){Ue(ie[H]);return}if(N.return){if(x){Ue(ie[H]);return}if(N.shift){let M=D.current+`
|
|
85
|
+
`;D.current=M,E(M);return}let T=D.current.trim();T&&(t(T),D.current="",E(""),I(null),k(""),Z(!1));return}if(N.backspace||N.delete){let T=D.current.slice(0,Math.max(0,D.current.length-1));D.current=T,E(T);return}if(L){let T=D.current+L;D.current=T,E(T)}}});let Ot=y,it=e?" ":"\u258A",le=Ot.split(`
|
|
86
|
+
`),Dt=2,Ke=ie.map(({value:L,meta:N,...R})=>R);return nt(Rt,{flexDirection:"column",gap:1,children:[nt(Rt,{flexDirection:"column",paddingY:1,children:[nt(Rt,{children:[Ee(Ie,{color:"gray",children:we}),e?Ee(Ie,{color:"gray",children:le[0]}):nt(yl,{children:[Ee(Ie,{color:"white",children:le[0]}),le.length===1&&Ee(Ie,{color:"cyan",children:it})]})]}),le.slice(1).map((L,N)=>nt(Rt,{children:[Ee(Ie,{color:"gray",children:" ".repeat(Dt)}),Ee(Ie,{color:"white",children:L}),N===le.length-2&&Ee(Ie,{color:"cyan",children:it})]},`line-${N}`))]}),w!=="none"?Ee(mr,{items:Ke,activeIndex:H,loading:pe}):null]})}async function sl(e){let t=bo(e.sessionsDir,e.cwd),n;try{n=await Qc(t,{withFileTypes:!0})}catch(l){return l?.code==="ENOENT"?[]:[]}let o=e.activeSessionFile?Sr(e.activeSessionFile):null,s=(await Promise.all(n.filter(l=>l.isFile()&&l.name.endsWith(".jsonl")).map(async l=>{let u=nl(t,l.name);if(o&&Sr(u)===o)return null;try{let p=await el(u);return{path:u,mtimeMs:p.mtimeMs}}catch{return null}}))).filter(l=>!!l).sort((l,u)=>u.mtimeMs-l.mtimeMs),i=e.limit??10,a=e.keyword?.trim().toLowerCase(),c=[];for(let l of s){if(c.length>=i)break;let u=await il(l.path,e.cwd,l.mtimeMs);if(u&&!(a&&!u.input.toLowerCase().includes(a))&&(c.push(u),c.length>=i))break}return c}async function il(e,t,n){try{let o=await Zc(e,"utf8"),s=al(o)?.trim()||cl(e);return{id:e,cwd:t,input:s,ts:n,sessionFile:e}}catch{return null}}function al(e){for(let t of e.split(`
|
|
87
|
+
`)){let n=t.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 cl(e){return tl(e).replace(/\.jsonl$/i,"")}function ll(e){let t=dl(e);if(t)return t;let n=ml(e);if(n)return n;let o=fl(e);if(o)return o;let r=ul(e);return r||pl(e)}function ul(e){let t=e.lastIndexOf("@");if(t===-1)return null;if(t>0){let o=e[t-1];if(o&&!/\s/.test(o))return null}let n=e.slice(t+1);return/\s/.test(n)?null:{type:"file",query:n,tokenStart:t+1}}function pl(e){let t=e.trimStart(),n=e.length-t.length;if(t.length===0)return null;let o=t;if(o.startsWith("/")&&(o=o.slice(1)),!o.toLowerCase().startsWith("resume")||e.slice(0,n).trim().length>0)return null;let s=o.slice(6);return s&&!s.startsWith(" ")?null:{type:"history",keyword:s.trim()}}function ml(e){let t=e.trimStart();if(!t.startsWith("/models"))return null;let n=t.slice(7);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim()}}function dl(e){let t=e.trimStart();if(!t.startsWith("/context"))return null;let n=t.slice(8);return n&&!n.startsWith(" ")?null:{type:"context"}}function fl(e){let t=e.trimStart();if(!t.startsWith("/"))return null;let n=t.slice(1);return n.includes(" ")?null:/^[a-zA-Z]*$/.test(n)?{type:"slash",keyword:n.toLowerCase()}:n.length===0?{type:"slash",keyword:""}:null}function gl(e){return{id:e.id,title:e.input,subtitle:hl(e.ts),kind:"history",badge:"HIS",value:e.input,meta:{historyEntry:e}}}function hl(e){if(!e)return"";let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let n=String(t.getFullYear()),o=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${n}-${o}-${r} ${s}:${i}`}import{Box as ot,Text as kn,useInput as xl}from"ink";import{useState as vl,useCallback as Tl}from"react";import{jsx as rt,jsxs as bn}from"react/jsx-runtime";function Sl(e){if(typeof e!="object"||e===null)return String(e);let t=Object.entries(e);if(t.length===0)return"";let[n,o]=t[0],r=typeof o=="string"?o:JSON.stringify(o);return`${r.slice(0,40)}${r.length>40?"...":""}`}function br({request:e,onDecision:t}){let n=[{label:"Allow once",decision:"once"},{label:"Allow all session",decision:"session"},{label:"Reject this time",decision:"deny"}],[o,r]=vl(0);xl(Tl((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&&t(n[o].decision)},[o,t,n]));let s=Sl(e.params);return bn(ot,{borderStyle:"single",borderColor:"gray",paddingX:2,flexDirection:"column",children:[rt(ot,{children:rt(kn,{bold:!0,children:"Tool Approval:"})}),rt(ot,{marginTop:1,children:bn(kn,{color:"cyan",children:[e.toolName,s?` (${s})`:""]})}),rt(ot,{flexDirection:"column",marginTop:1,children:n.map((i,a)=>rt(ot,{children:bn(kn,{color:o===a?"green":"gray",children:[o===a?"> ":" ",i.label]})},i.decision))})]})}import Sf from"string-width";function wr(e){if(!e)return"success";let t=e.toLowerCase();return t.includes("error")||t.includes("unknown")||t.includes("failed")?"error":"success"}var _r={"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 kl(e){let t=e.toLowerCase(),n=Object.entries(_r).filter(([o])=>o!=="default");for(let[o,r]of n.sort((s,i)=>i[0].length-s[0].length))if(t.includes(o))return r;return _r.default}function Cr(e,t){if(e==null)return 0;let n=typeof e=="number"?e:e.prompt??e.total??0;if(n<=0)return 0;let o=t&&t>0?t:kl("");return Math.min(100,n/o*100)}function Er(e){return e?`${e.total} tokens`:""}var bl=`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
|
|
107
|
+
Ctrl+/ Show help`;function Ar(e,t){let[n,...o]=e.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:bl};case"config":return{kind:"message",title:"Config",content:`Config file: ${t.configPath}
|
|
103
108
|
Current provider: ${t.providerName}
|
|
104
|
-
Current model: ${t.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]),
|
|
109
|
+
Current model: ${t.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: ${(t.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(!t.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${t.configPath}`};let a=o.join(" ").trim(),c=t.providers.find(p=>p.name===a)??t.providers.find(p=>p.model===a);if(c)return{kind:"switch_model",provider:c};let l=t.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
113
|
`)}`};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${e}
|
|
109
|
-
Type /help for available commands.`}}}import{dirname as
|
|
110
|
-
`)
|
|
111
|
-
`)
|
|
114
|
+
Type /help for available commands.`}}}import{dirname as $t,join as Pr,resolve as _l}from"path";import{statSync as wl,existsSync as Rr,readFileSync as Cl}from"fs";import{readFile as El}from"fs/promises";import{get as Al}from"https";import{fileURLToPath as Ml}from"url";function Mr(e){let t=e.trim().replace(/^v/i,""),[n="",o]=t.split("-",2),r=n.split(".").map(s=>Number(s));return r.length<3||r.some(s=>!Number.isFinite(s))?null:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,prerelease:o??null}}function Pl(e,t){let n=Mr(e),o=Mr(t);return!n||!o?!1:n.major!==o.major?n.major>o.major:n.minor!==o.minor?n.minor>o.minor:n.patch!==o.patch?n.patch>o.patch:n.prerelease&&!o.prerelease?!1:!n.prerelease&&o.prerelease?!0:n.prerelease&&o.prerelease?n.prerelease>o.prerelease:!1}function $r(){try{let t=Ml(import.meta.url);return $t(t)}catch{}let e=_l(process.argv[1]??process.cwd());try{return wl(e).isFile()?$t(e):e}catch{return process.cwd()}}async function Rl(e){let t=Pr(e,"package.json");if(!Rr(t))return null;let n=await El(t,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}function $l(e){let t=Pr(e,"package.json");if(!Rr(t))return null;try{let n=Cl(t,"utf8"),o=JSON.parse(n);return!o.name||!o.version?null:{name:o.name,version:o.version}}catch{return null}}async function Il(){let e=$r();for(;;){let t=await Rl(e);if(t&&t.name==="@memo-code/memo")return t;let n=$t(e);if(n===e)break;e=n}return null}function Ir(){let e=$r();for(;;){let t=$l(e);if(t&&t.name==="@memo-code/memo")return t;let n=$t(e);if(n===e)break;e=n}return null}async function Ll(e,t=1500){let o=`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`;return new Promise(r=>{let s=Al(o,{timeout:t},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 Lr(){let e=await Il();if(!e)return null;let t=await Ll(e.name);return!t||!Pl(t,e.version)?null:{current:e.version,latest:t}}import{Box as We,Text as ge,useInput as Nl}from"ink";import{useCallback as _n,useMemo as Ol,useState as st}from"react";import{jsx as be,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 Nr({configPath:e,onComplete:t,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],b=s||a[m.key]||"",h=_n(async g=>{u(!0),v(null);try{let A=g.name||Ae[0].defaultValue,y=g.envKey||Ae[1].defaultValue,E=g.model||Ae[2].defaultValue,U=g.baseUrl||Ae[3].defaultValue;await de(e,{current_provider:A,providers:[{name:A,env_api_key:y,model:E,base_url:U||void 0}]}),t()}catch(A){v(A.message),u(!1)}},[e,t]),C=_n(async()=>{let A=s.trim()||m.defaultValue,y={...a,[m.key]:A};if(c(y),i(""),o<Ae.length-1){r(o+1);return}await h(y)},[m.defaultValue,m.key,o,s,a,h]);Nl(_n((g,A)=>{if(!l){if(A.ctrl&&g==="c"){n();return}if(A.return){C();return}if(A.backspace||A.delete){i(y=>y.slice(0,-1));return}g&&i(y=>y+g)}},[C,n,l]));let P=Ol(()=>`Step ${o+1}/${Ae.length}`,[o]);return Le(We,{flexDirection:"column",children:[Le(We,{flexDirection:"column",marginBottom:1,children:[be(ge,{bold:!0,children:"Memo setup"}),be(ge,{color:"gray",children:"No provider config found. Create one to continue."}),Le(ge,{color:"gray",children:["Config path: ",e]})]}),Le(We,{flexDirection:"column",marginBottom:1,children:[be(ge,{color:"cyan",children:P}),Le(ge,{children:[m.label," (default: ",m.defaultValue,")"]}),m.hint?be(ge,{color:"gray",children:m.hint}):null]}),Le(We,{children:[be(ge,{children:"> "}),be(ge,{children:b})]}),be(We,{marginTop:1,children:be(ge,{color:"gray",children:"Press Enter to continue. Ctrl+C to exit."})}),p?be(We,{marginTop:1,children:Le(ge,{color:"red",children:["Failed to write config: ",p]})}):null]})}import{jsx as Ne,jsxs as zl}from"react/jsx-runtime";var Fl=jl(Ul);function Vl(e){return{index:e,userInput:"",steps:[]}}function Dr({sessionOptions:e,providerName:t,model:n,configPath:o,mcpServers:r,cwd:s,sessionsDir:i,providers:a,dangerous:c=!1,needsSetup:l=!1}){let{exit:u}=Hl(),[p,v]=W(t),[m,b]=W(n),[h,C]=W(a),[P,g]=W({...e,providerName:t}),[A,y]=W(null),[E,U]=W([]),[I,V]=W([]),[k,w]=W(!1),j=Lt(null),[ie,X]=W([]),[H,B]=W(null),[pe,he]=W([]),[Oe,_e]=W(null),Y=Lt(null),[De,D]=W(null),we=Lt(0),[F,Z]=W(e.maxPromptTokens??12e4),[Ue,Ot]=W(l),[it,le]=W(0),Dt=wn(()=>Ir(),[]),[Ke,L]=W(null),N=Lt(null),R=te(()=>(we.current+=1,we.current),[]),x=te((d,f)=>{let S=`${Date.now()}-${Math.random().toString(16).slice(2)}`,$=R();V(O=>[...O,{id:S,title:d,content:f,sequence:$}])},[R]),T=te((d,f)=>{U(S=>{let $=[...S],O=$.findIndex(ne=>ne.index===d);O===-1&&($.push(Vl(d)),O=$.length-1);let G=$[O];return G&&($[O]=f(G)),$})},[]),M=wn(()=>({onAssistantStep:(d,f)=>{let S=j.current;S&&T(S,$=>{let O=$.steps.slice();for(;O.length<=f;)O.push({index:O.length,assistantText:""});let G=O[f];if(!G)return $;let ne={...G,assistantText:G.assistantText+d};return O[f]=ne,{...$,steps:O}})},requestApproval:c?void 0:d=>new Promise(f=>{L(d),N.current=f}),hooks:{onTurnStart:({turn:d,input:f,promptTokens:S})=>{j.current=d,S&&S>0&&le(S),T(d,$=>({...$,index:d,userInput:f,steps:[],startedAt:Date.now(),contextPromptTokens:S??$.contextPromptTokens}))},onAction:({turn:d,step:f,action:S,thinking:$,parallelActions:O})=>{T(d,G=>{let ne=G.steps.slice();for(;ne.length<=f;)ne.push({index:ne.length,assistantText:""});let at=ne[f];return at?(ne[f]={...at,action:S,thinking:$,toolStatus:"executing",parallelActions:O&&O.length>1?O:void 0},{...G,steps:ne}):G})},onObservation:({turn:d,step:f,observation:S})=>{T(d,$=>{let O=$.steps.slice();for(;O.length<=f;)O.push({index:O.length,assistantText:""});let G=O[f];return G?(O[f]={...G,observation:S,toolStatus:wr(S)},{...$,steps:O}):$})},onFinal:({turn:d,finalText:f,status:S,turnUsage:$,tokenUsage:O})=>{T(d,G=>{let ne=G.startedAt??Date.now(),at=Math.max(0,Date.now()-ne),Xr=O?.prompt??G.contextPromptTokens,Yr=G.sequence??R();return{...G,finalText:f,status:S,tokenUsage:$,contextPromptTokens:Xr,startedAt:ne,durationMs:at,sequence:Yr}}),w(!1)}}}),[T,c,R]);It(()=>{let d=!1;return(async()=>{if(Ue)return;let f=Y.current;f&&await f.close();let S=await Ye(M,P);if(d){await S.close();return}Y.current=S,y(S),B(S.historyFilePath??null)})(),()=>{d=!0}},[M,P,Ue]),It(()=>{let d=!1;return(async()=>{let f=await Lr();d||!f||x("Update",`Update available: v${f.latest}. Run npm/pnpm/yarn/bun to update @memo-code/memo.`)})(),()=>{d=!0}},[x]),It(()=>()=>{Y.current&&Y.current.close()},[]);let K=te(async()=>{Y.current&&await Y.current.close(),D("Bye!"),setTimeout(()=>{u()},300)},[u]),Me=te(()=>{U([]),V([]),he([]),_e(null),le(0),we.current=0},[]),An=te(async()=>{U([]),V([]),he([]),_e(null),le(0),we.current=0;let d=Nt(),f={...P,sessionId:d};Y.current&&await Y.current.close();let S=await Ye(M,f);Y.current=S,y(S),B(S.historyFilePath??null),g(f),x("New Session","Started a new session with fresh context.")},[M,P,x]),Fr=te(async d=>{if(!d.sessionFile){x("History","This entry has no context file to load.");return}try{let f=await Dl(d.sessionFile,"utf8"),S=Gl(f);he(S.turns),_e(S.messages),w(!1),U([]),y(null),B(null),le(0),j.current=null,we.current=Math.max(we.current,S.maxSequence),g($=>({...$,sessionId:Nt()})),x("History loaded",S.summary||d.input)}catch(f){x("Failed to load history",`Unable to read ${d.sessionFile}: ${f.message}`)}},[x]),Mn=te(async d=>{try{let f=await oe(),S={...f.config,current_provider:d};await de(f.configPath,S)}catch(f){x("Failed to save config",`Failed to save model selection: ${f.message}`)}},[x]),Vr=te(()=>{k&&A?.cancelCurrentTurn?.()},[k,A]),Ut=te(async d=>{if(d.name===p&&d.model===m){x("Model switch",`Already using ${d.name} (${d.model})`);return}if(k){x("Model switch","Currently running. Press Esc Esc to cancel before switching models.");return}U([]),he([]),_e(null),le(0),j.current=null,y(null),B(null),v(d.name),b(d.model),g(f=>({...f,sessionId:Nt(),providerName:d.name})),await Mn(d.name),x("Model switch",`Switched to ${d.name} (${d.model})`)},[x,k,m,p,Mn]),jt=te(async d=>{if(!d.trim()){x("Shell Command","Usage: $ <command> (e.g. $ git status)");return}w(!0);try{let{stdout:f,stderr:S}=await Fl(d,{cwd:s,maxBuffer:5242880}),$=[f?.trim(),S?.trim()].filter(Boolean).join(`
|
|
115
|
+
`);x("Shell Result",$||"(no output)")}catch(f){let S=f,O=[S.stdout?.trim(),S.stderr?.trim(),S.message].filter(Boolean).join(`
|
|
116
|
+
`);x("Shell Error",O||"Command failed")}finally{w(!1)}},[x,s]),Pn=te(async d=>{let f=Ar(d,{configPath:o,providerName:p,model:m,mcpServers:r,providers:h,contextLimit:F});if(f.kind==="exit"){await K();return}if(f.kind==="new"){await An();return}if(f.kind==="switch_model"){await Ut(f.provider);return}if(f.kind==="set_context_limit"){Z(f.limit),x("Context length",`Context limit set to ${(f.limit/1e3).toFixed(0)}k tokens`);return}if(f.kind==="init_agents_md"){x("Init","Analyzing project structure and generating AGENTS.md...");let S=`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&&(t.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&&(t.push({role:"assistant",content:u}),o.push(`Assistant: ${u}`),s)){let p={index:s.steps.length,assistantText:u};s.steps=[...s.steps,p],s.finalText=u}continue}if(l.type==="action"&&s){let u=l.meta;if(u&&typeof u=="object"){let p=typeof u.tool=="string"?u.tool:"",
|
|
130
|
-
`),messages:t,turns:n,maxSequence:a}}
|
|
131
|
-
|
|
132
|
+
Make the AGENTS.md concise but informative, following best practices for AI agent guidelines.`;if(X($=>[...$,"/init"]),!A){x("Error","Session not initialized");return}w(!0);try{await A.runTurn(S)}catch{w(!1)}return}if(f.kind==="shell_command"){await jt(f.command);return}x(f.title,f.content)},[x,o,Me,K,Ut,r,m,p,F,h,jt]),Gr=te(async()=>{try{let d=await oe(),f=Re(d.config);C(d.config.providers),v(f.name),b(f.model),g(S=>({...S,sessionId:Nt(),providerName:f.name})),Ot(!1),x("Setup",`Config saved to ${d.configPath}`)}catch(d){x("Setup",`Failed to reload config: ${d.message}`)}},[x]);It(()=>{if(!A||!Oe?.length)return;let d=A.history[0];d&&(A.history.splice(0,A.history.length,d,...Oe),_e(null))},[Oe,A]);let zr=te(async d=>{if(d.trim().toLowerCase()==="exit"){await K();return}if(!A||k)return;let f=d.trim();if(f.startsWith("$")){let S=f.slice(1).trim();X($=>[...$,d]),await jt(S);return}if(d.startsWith("/")){await Pn(d);return}X(S=>[...S,d]),w(!0);try{await A.runTurn(d)}catch{w(!1)}},[k,Pn,K,A]),Wr=E[E.length-1],iu=Er(Wr?.tokenUsage),Kr=Cr(it,F),Jr=wn(()=>[...pe,...E],[pe,E]),qr=te(d=>{let f=N.current;f&&(f(d),N.current=null),L(null)},[]);if(De){let d=De.split(`
|
|
133
|
+
`);return Ne(Or,{flexDirection:"column",children:d.map((f,S)=>Ne(Bl,{color:"green",children:f},S))})}return Ue?Ne(Nr,{configPath:o,onComplete:Gr,onExit:K}):zl(Or,{flexDirection:"column",children:[Ne(Xo,{systemMessages:I,turns:Jr,headerInfo:{providerName:p,model:m,cwd:s,sessionId:P.sessionId??"unknown",mcpNames:Object.keys(r??{}).sort(),version:Dt?.version??"unknown"}}),Ne(kr,{disabled:!A||k||!!Ke,onSubmit:zr,onExit:K,onClear:Me,onNewSession:An,onCancelRun:Vr,onHistorySelect:Fr,onModelSelect:Ut,onSystemMessage:x,onSetContextLimit:d=>{Z(d),x("Context length",`Context limit set to ${(d/1e3).toFixed(0)}k tokens`)},history:ie,cwd:s,sessionsDir:i,currentSessionFile:H??void 0,providers:h,configPath:o,providerName:p,model:m,contextLimit:F,mcpServers:r}),Ke&&Ne(br,{request:Ke,onDecision:qr}),Ne(Uo,{contextPercent:Kr})]})}function Gl(e){let t=[],n=[],o=[],r=e.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&&(t.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&&(t.push({role:"assistant",content:u}),o.push(`Assistant: ${u}`),s)){let p={index:s.steps.length,assistantText:u};s.steps=[...s.steps,p],s.finalText=u}continue}if(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:"",h=(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&&(h.length>1?(C.action=h[0],C.parallelActions=h):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:t,turns:n,maxSequence:a}}var Wl=`
|
|
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 Cn(){console.log(Wl.trim())}function Kl(e){let t=e.indexOf("=");if(t<=0)return null;let n=e.slice(0,t).trim(),o=e.slice(t+1);return n?{key:n,value:o}:null}function Ur(e,t){let n=[];if(n.push(`${e}`),"url"in t){n.push(` type: ${t.type??"streamable_http"}`),n.push(` url: ${t.url}`),t.bearer_token_env_var&&n.push(` bearer_token_env_var: ${t.bearer_token_env_var}`);let o=t.http_headers??t.headers;o&&Object.keys(o).length>0&&n.push(` headers: ${Object.entries(o).map(([r,s])=>`${r}=${s}`).join(", ")}`)}else n.push(` type: ${t.type??"stdio"}`),n.push(` command: ${t.command}`),t.args&&t.args.length>0&&n.push(` args: ${t.args.join(" ")}`),t.env&&Object.keys(t.env).length>0&&n.push(` env: ${Object.entries(t.env).map(([o,r])=>`${o}=${r}`).join(", ")}`);return n.join(`
|
|
145
|
+
`)}function Jl(e){let t=e.shift();if(!t)return{error:"Missing server name."};let n,o,r={},s=[];for(let i=0;i<e.length;i+=1){let a=e[i];if(a){if(a==="--"){s=e.slice(i+1);break}if(a==="--url"){let c=e[i+1];if(!c)return{error:"Missing value for --url."};n=c,i+=1;continue}if(a==="--bearer-token-env-var"){let c=e[i+1];if(!c)return{error:"Missing value for --bearer-token-env-var."};o=c,i+=1;continue}if(a==="--env"){let c=e[i+1];if(!c)return{error:"Missing value for --env (KEY=VALUE)."};let l=Kl(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:t,url:n,bearerTokenEnvVar:o}}:o?{error:"--bearer-token-env-var is only supported with HTTP servers."}:s.length===0?{error:"Missing stdio command. Use `-- <command...>`."}:{options:{name:t,command:s[0],args:s.slice(1),env:Object.keys(r).length>0?r:void 0}}}function ql(e){let[t,...n]=e;return!t||t==="--help"||t==="-h"||t==="help"?{command:"help",rest:[]}:{command:t,rest:n}}function En(e,t=[]){let n=new Set(t);for(let o=0;o<e.length;o+=1){let r=e[o];if(r){if(r.startsWith("--")){n.has(r)&&(o+=1);continue}return r}}return null}async function jr(e){let{command:t,rest:n}=ql(e);if(t==="help"){Cn();return}if(t==="list"){let o=n.includes("--json"),s=(await oe()).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(Ur(a,c))}return}if(t==="get"){let o=n.includes("--json"),r=En(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let i=(await oe()).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(Ur(r,i));return}if(t==="add"){let o=Jl(n);if(o.error!==void 0){o.error&&(console.error(o.error),process.exitCode=1),Cn();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 oe(),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 de(s.configPath,{...s.config,mcp_servers:i}),console.log(`Added MCP server "${r.name}".`);return}if(t==="remove"){let o=En(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let r=await oe(),s={...r.config.mcp_servers??{}};if(!s[o]){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}delete s[o],await de(r.configPath,{...r.config,mcp_servers:s}),console.log(`Removed MCP server "${o}".`);return}if(t==="login"||t==="logout"){let o=En(n,["--scopes"]);if(!o){console.error("Missing server name."),process.exitCode=1;return}let s=(await oe()).config.mcp_servers?.[o];if(!s){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}if(!("url"in s)){console.error("OAuth login/logout only applies to streamable HTTP servers."),process.exitCode=1;return}console.error("OAuth login/logout is not supported in memo yet. Configure a bearer token env var instead."),process.exitCode=1;return}console.error(`Unknown subcommand: ${t}`),Cn(),process.exitCode=1}import{jsx as su}from"react/jsx-runtime";function eu(e){let t={once:!1,dangerous:!1},n=[];for(let o=0;o<e.length;o++){let r=e[o];if(r!==void 0){if(r==="--once"){t.once=!0;continue}if(r==="--dangerous"||r==="-d"){t.dangerous=!0;continue}n.push(r)}}return{question:n.join(" "),options:t}}async function Br(e){let t=await oe();if(!t.needsSetup)return t;let n=t.config.providers[0],r=[n?.env_api_key,"OPENAI_API_KEY","DEEPSEEK_API_KEY"].filter(Boolean).some(a=>!!process.env[a]);if(n&&r)return await de(t.configPath,t.config),console.log(`Detected API key in env. Wrote default provider (${n.name}) to ${t.configPath}`),{...t,needsSetup:!1};if(e==="tui")return t;let s=Xl({input:Yl,output:Zl}),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 de(t.configPath,p),console.log(`Config written to ${t.configPath}
|
|
146
|
+
`),{...t,config:p,needsSetup:!1}}finally{s.close()}}async function tu(e){let t=await Br("plain"),n=Re(t.config),r={sessionId:Hr(),mode:"once",stream:t.config.stream_output??!1};e.options.dangerous&&console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!");let s={onAssistantStep:c=>{process.stdout.write(c)},requestApproval:e.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
|
|
148
|
+
[tool] ${c.tool}`),c.input!==void 0&&console.log(`[input] ${JSON.stringify(c.input)}`)},onObservation:()=>{}}},i=await Ye(s,r),a=e.question;if(!a&&!process.stdin.isTTY&&(a=await ru()),!a&&e.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}
|
|
134
149
|
`);let c=await i.runTurn(a);t.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 nu(e){let t=await Br("tui"),n=Re(t.config),r={sessionId:Hr(),mode:"interactive",stream:t.config.stream_output??!1},s=gt(t,r);e.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
|
|
153
|
+
`)),await Ql(su(Dr,{sessionOptions:r,providerName:n.name,model:n.model,configPath:t.configPath,mcpServers:t.config.mcp_servers??{},cwd:process.cwd(),sessionsDir:s,providers:t.config.providers,dangerous:e.options.dangerous,needsSetup:t.needsSetup}),{exitOnCtrlC:!1,patchConsole:!1}).waitUntilExit()}async function ou(){let e=process.argv.slice(2);if(e[0]==="mcp"||e[0]==="--"&&e[1]==="mcp"){let o=e[0]==="--"?2:1;await jr(e.slice(o));return}let t=eu(e);if(!(process.stdin.isTTY&&process.stdout.isTTY)||t.options.once){await tu(t);return}await nu(t)}ou();async function ru(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t.trim())}),process.stdin.resume()})}
|
|
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
|
|