@memo-code/memo 0.8.7 → 0.8.8
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/dist/index.js +75 -75
- package/dist/web/server/main.cjs +25 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var gl=Object.create;var ur=Object.defineProperty;var hl=Object.getOwnPropertyDescriptor;var yl=Object.getOwnPropertyNames;var _l=Object.getPrototypeOf,Sl=Object.prototype.hasOwnProperty;var Xo=(e,t)=>()=>(e&&(t=e(e=0)),t);var Jo=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),vl=(e,t)=>{for(var n in t)ur(e,n,{get:t[n],enumerable:!0})},Tl=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of yl(t))!Sl.call(e,o)&&o!==n&&ur(e,o,{get:()=>t[o],enumerable:!(r=hl(t,o))||r.enumerable});return e};var Yo=(e,t,n)=>(n=e!=null?gl(_l(e)):{},Tl(t||!e||!e.__esModule?ur(n,"default",{value:e,enumerable:!0}):n,e));var Cs=Jo((yS,hn)=>{"use strict";function ys(e){return Array.isArray(e)?e:[e]}var xu=void 0,hr="",gs=" ",gr="\\",Mu=/^\s+$/,ku=/(?:[^\\]|^)\\$/,Au=/^\\!/,Pu=/^\\#/,Eu=/\r?\n/g,Ru=/^\.{0,2}\/|^\.{1,2}$/,Iu=/\/$/,gt="/",_s="node-ignore";typeof Symbol<"u"&&(_s=Symbol.for("node-ignore"));var Ss=_s,ht=(e,t,n)=>(Object.defineProperty(e,t,{value:n}),n),Ou=/([0-z])-([0-z])/g,vs=()=>!1,Lu=e=>e.replace(Ou,(t,n,r)=>n.charCodeAt(0)<=r.charCodeAt(0)?t:hr),Nu=e=>{let{length:t}=e;return e.slice(0,t-t%2)},$u=[[/^\uFEFF/,()=>hr],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?gs:hr)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+gs}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let r=n.replace(/\\\*/g,"[^\\/]*");return t+r}],[/\\\\\\(?=[$.|*+(){^])/g,()=>gr],[/\\\\/g,()=>gr],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,r,o)=>t===gr?`\\[${n}${Nu(r)}${o}`:o==="]"&&r.length%2===0?`[${Lu(n)}${r}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`]],Du=/(^|\\\/)?\\\*$/,Ft="regex",fn="checkRegex",hs="_",Uu={[Ft](e,t){return`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`},[fn](e,t){return`${t?`${t}[^/]*`:"[^/]*"}(?=$|\\/$)`}},Fu=e=>$u.reduce((t,[n,r])=>t.replace(n,r.bind(e)),e),gn=e=>typeof e=="string",Hu=e=>e&&gn(e)&&!Mu.test(e)&&!ku.test(e)&&e.indexOf("#")!==0,Bu=e=>e.split(Eu).filter(Boolean),yr=class{constructor(t,n,r,o,s,i){this.pattern=t,this.mark=n,this.negative=s,ht(this,"body",r),ht(this,"ignoreCase",o),ht(this,"regexPrefix",i)}get regex(){let t=hs+Ft;return this[t]?this[t]:this._make(Ft,t)}get checkRegex(){let t=hs+fn;return this[t]?this[t]:this._make(fn,t)}_make(t,n){let r=this.regexPrefix.replace(Du,Uu[t]),o=this.ignoreCase?new RegExp(r,"i"):new RegExp(r);return ht(this,n,o)}},Wu=({pattern:e,mark:t},n)=>{let r=!1,o=e;o.indexOf("!")===0&&(r=!0,o=o.substr(1)),o=o.replace(Au,"!").replace(Pu,"#");let s=Fu(o);return new yr(e,t,o,n,r,s)},_r=class{constructor(t){this._ignoreCase=t,this._rules=[]}_add(t){if(t&&t[Ss]){this._rules=this._rules.concat(t._rules._rules),this._added=!0;return}if(gn(t)&&(t={pattern:t}),Hu(t.pattern)){let n=Wu(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,ys(gn(t)?Bu(t):t).forEach(this._add,this),this._added}test(t,n,r){let o=!1,s=!1,i;this._rules.forEach(a=>{let{negative:l}=a;s===l&&o!==s||l&&!o&&!s&&!n||!a[r].test(t)||(o=!l,s=l,i=l?xu:a)});let c={ignored:o,unignored:s};return i&&(c.rule=i),c}},ju=(e,t)=>{throw new t(e)},Ue=(e,t,n)=>gn(e)?e?Ue.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),Ts=e=>Ru.test(e);Ue.isNotRelative=Ts;Ue.convert=e=>e;var Sr=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:r=!1}={}){ht(this,Ss,!0),this._rules=new _r(n),this._strictPathCheck=!r,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,r,o){let s=t&&Ue.convert(t);return Ue(s,t,this._strictPathCheck?ju:vs),this._t(s,n,r,o)}checkIgnore(t){if(!Iu.test(t))return this.test(t);let n=t.split(gt).filter(Boolean);if(n.pop(),n.length){let r=this._t(n.join(gt)+gt,this._testCache,!0,n);if(r.ignored)return r}return this._rules.test(t,!1,fn)}_t(t,n,r,o){if(t in n)return n[t];if(o||(o=t.split(gt).filter(Boolean)),o.pop(),!o.length)return n[t]=this._rules.test(t,r,Ft);let s=this._t(o.join(gt)+gt,n,r,o);return n[t]=s.ignored?s:this._rules.test(t,r,Ft)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return ys(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},vr=e=>new Sr(e),zu=e=>Ue(e&&Ue.convert(e),e,vs),ws=()=>{let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");Ue.convert=e;let t=/^[a-z]:\//i;Ue.isNotRelative=n=>t.test(n)||Ts(n)};typeof process<"u"&&process.platform==="win32"&&ws();hn.exports=vr;vr.default=vr;hn.exports.isPathValid=zu;ht(hn.exports,Symbol.for("setupWindows"),ws)});var xi=Jo((Wv,bi)=>{"use strict";function yi(e){return Array.isArray(e)?e:[e]}var qr="",_i=" ",Gr="\\",Hd=/^\s+$/,Bd=/(?:[^\\]|^)\\$/,Wd=/^\\!/,jd=/^\\#/,zd=/\r?\n/g,Gd=/^\.*\/|^\.+$/,Kr="/",Ti="node-ignore";typeof Symbol<"u"&&(Ti=Symbol.for("node-ignore"));var Si=Ti,Kd=(e,t,n)=>Object.defineProperty(e,t,{value:n}),qd=/([0-z])-([0-z])/g,wi=()=>!1,Vd=e=>e.replace(qd,(t,n,r)=>n.charCodeAt(0)<=r.charCodeAt(0)?t:qr),Xd=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Jd=[[/^\uFEFF/,()=>qr],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?_i:qr)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+_i}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let r=n.replace(/\\\*/g,"[^\\/]*");return t+r}],[/\\\\\\(?=[$.|*+(){^])/g,()=>Gr],[/\\\\/g,()=>Gr],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,r,o)=>t===Gr?`\\[${n}${Xd(r)}${o}`:o==="]"&&r.length%2===0?`[${Vd(n)}${r}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`]],vi=Object.create(null),Yd=(e,t)=>{let n=vi[e];return n||(n=Jd.reduce((r,[o,s])=>r.replace(o,s.bind(e)),e),vi[e]=n),t?new RegExp(n,"i"):new RegExp(n)},Jr=e=>typeof e=="string",Qd=e=>e&&Jr(e)&&!Hd.test(e)&&!Bd.test(e)&&e.indexOf("#")!==0,Zd=e=>e.split(zd),Vr=class{constructor(t,n,r,o){this.origin=t,this.pattern=n,this.negative=r,this.regex=o}},em=(e,t)=>{let n=e,r=!1;e.indexOf("!")===0&&(r=!0,e=e.substr(1)),e=e.replace(Wd,"!").replace(jd,"#");let o=Yd(e,t);return new Vr(n,e,r,o)},tm=(e,t)=>{throw new t(e)},We=(e,t,n)=>Jr(e)?e?We.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),Ci=e=>Gd.test(e);We.isNotRelative=Ci;We.convert=e=>e;var Xr=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:r=!1}={}){Kd(this,Si,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=r,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(t){if(t&&t[Si]){this._rules=this._rules.concat(t._rules),this._added=!0;return}if(Qd(t)){let n=em(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,yi(Jr(t)?Zd(t):t).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(t){return this.add(t)}_testOne(t,n){let r=!1,o=!1;return this._rules.forEach(s=>{let{negative:i}=s;if(o===i&&r!==o||i&&!r&&!o&&!n)return;s.regex.test(t)&&(r=!i,o=i)}),{ignored:r,unignored:o}}_test(t,n,r,o){let s=t&&We.convert(t);return We(s,t,this._allowRelativePaths?wi:tm),this._t(s,n,r,o)}_t(t,n,r,o){if(t in n)return n[t];if(o||(o=t.split(Kr)),o.pop(),!o.length)return n[t]=this._testOne(t,r);let s=this._t(o.join(Kr)+Kr,n,r,o);return n[t]=s.ignored?s:this._testOne(t,r)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return yi(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},bn=e=>new Xr(e),nm=e=>We(e&&We.convert(e),e,wi);bn.isPathValid=nm;bn.default=bn;bi.exports=bn;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,"/");We.convert=e;let t=/^[a-z]:\//i;We.isNotRelative=n=>t.test(n)||Ci(n)}});function S_(e){let t=Number.parseInt(e,10);return!Number.isInteger(t)||t<=0||t>65535?null:t}function Zc(e){let t={open:!0};for(let n=0;n<e.length;n++){let r=e[n];if(r){if(r==="--open"){t.open=!0;continue}if(r==="--no-open"){t.open=!1;continue}if(r==="--host"){let o=e[n+1];o&&!o.startsWith("-")&&(t.host=o,n+=1);continue}if(r==="--port"){let o=e[n+1];if(o&&!o.startsWith("-")){let s=S_(o);s!==null&&(t.port=s,n+=1)}continue}if(r==="--static-dir"){let o=e[n+1];o&&!o.startsWith("-")&&(t.staticDir=o,n+=1);continue}}}return t}var el=Xo(()=>{"use strict"});var sl={};vl(sl,{runWebCommand:()=>R_});import{spawn as tl}from"child_process";import{existsSync as nl,readFileSync as v_}from"fs";import{createServer as T_}from"net";import{dirname as ir,join as _e,resolve as Ot}from"path";import{fileURLToPath as Vo}from"url";function sr(e){let t=Ot(e);for(;;){let n=_e(t,"package.json");if(nl(n))try{if(JSON.parse(v_(n,"utf8")).name==="@memo-code/memo")return t}catch{}let r=ir(t);if(r===t)break;t=r}return null}function rl(e){return nl(e)}function b_(e){let t=[];e&&t.push(Ot(e)),process.env.MEMO_WEB_SERVER_ENTRY&&t.push(Ot(process.env.MEMO_WEB_SERVER_ENTRY));let n=ir(Vo(import.meta.url)),r=sr(n)??sr(process.cwd());r&&(t.push(_e(r,"dist/web/server/main.cjs")),t.push(_e(r,"dist/web/server/main.js")),t.push(_e(r,"packages/web-server/dist/main.cjs")),t.push(_e(r,"packages/web-server/dist/main.js"))),t.push(_e(process.cwd(),"dist/web/server/main.cjs")),t.push(_e(process.cwd(),"dist/web/server/main.js")),t.push(_e(process.cwd(),"packages/web-server/dist/main.cjs")),t.push(_e(process.cwd(),"packages/web-server/dist/main.js"));for(let o of t)if(rl(o))return o;return null}function x_(e){let t=[];e&&t.push(Ot(e)),process.env.MEMO_WEB_STATIC_DIR&&t.push(Ot(process.env.MEMO_WEB_STATIC_DIR));let n=ir(Vo(import.meta.url)),r=sr(n)??sr(process.cwd());r&&(t.push(_e(r,"dist/web/ui")),t.push(_e(r,"packages/web-ui/dist"))),t.push(_e(process.cwd(),"dist/web/ui")),t.push(_e(process.cwd(),"packages/web-ui/dist"));for(let o of t)if(rl(_e(o,"index.html")))return o;return null}async function ol(e,t){return new Promise(n=>{let r=T_();r.unref(),r.once("error",()=>n(!1)),r.listen({host:e,port:t},()=>{r.close(()=>n(!0))})})}async function M_(e,t){for(let n=0;n<30;n++){let r=t+n;if(r>65535)break;if(await ol(e,r))return r}throw new Error(`No available port found from ${t} to ${t+29}`)}function k_(e,t){return t==="darwin"?{command:"open",args:[e]}:t==="win32"?{command:"cmd",args:["/c","start","",e]}:t==="linux"?{command:"xdg-open",args:[e]}:null}function A_(e){let t=k_(e,process.platform);if(!t)return!1;try{return tl(t.command,t.args,{stdio:"ignore",detached:!0}).unref(),!0}catch{return!1}}function P_(e,t){return`http://${e.includes(":")?`[${e}]`:e}:${t}`}async function E_(e,t,n=8e3){let r=Date.now();for(;Date.now()-r<n;){if(!await ol(e,t))return!0;await new Promise(o=>setTimeout(o,120))}return!1}async function R_(e){let t=Zc(e),n=t.host??w_,r=t.port??C_,o=await M_(n,r),s=b_();if(!s){console.error("web-server entry not found (main.js missing)."),console.error("Please run `pnpm run web:server:build` or `pnpm run build` first."),process.exitCode=1;return}let i=x_(t.staticDir);if(!i){console.error("web-ui static assets not found (index.html missing)."),console.error("Please run `pnpm run web:ui:build` or `pnpm run build` first."),process.exitCode=1;return}o!==r&&console.log(`[memo web] Port ${r} is busy, using ${o}`);let c=P_(n,o);console.log(`[memo web] Server: ${c}`),console.log(`[memo web] Entry: ${s}`),console.log(`[memo web] Static: ${i}`);let a=tl(process.execPath,[s],{stdio:"inherit",env:{...process.env,MEMO_WEB_HOST:n,MEMO_WEB_PORT:String(o),MEMO_WEB_STATIC_DIR:i,MEMO_CLI_ENTRY:process.argv[1],MEMO_TASK_PROMPTS_DIR:Ot(ir(Vo(import.meta.url)),"../task-prompts")}});t.open&&(!await E_(n,o)||!A_(c))&&console.warn(`[memo web] Failed to auto-open browser. Open manually: ${c}`);let l=p=>{a.killed||a.kill(p)};process.once("SIGINT",()=>{l("SIGINT")}),process.once("SIGTERM",()=>{l("SIGTERM")}),await new Promise(p=>{a.once("exit",(u,d)=>{if(d){process.exitCode=0,p();return}process.exitCode=u??0,p()})})}var w_,C_,il=Xo(()=>{"use strict";el();w_="127.0.0.1",C_=5494});import{randomUUID as al}from"crypto";import{readFile as I_}from"fs/promises";import{createInterface as O_}from"readline/promises";import{stdin as L_,stdout as N_}from"process";import{render as $_}from"ink";import Kl from"os";import{readFile as ss}from"fs/promises";import{join as is,dirname as ql,resolve as Vl}from"path";import{fileURLToPath as Xl}from"url";import{access as wl,readFile as Cl,readdir as bl,stat as xl}from"fs/promises";import{constants as Ml}from"fs";import{homedir as Zo}from"os";import{dirname as kl,isAbsolute as Al,join as ft,resolve as cn}from"path";import Pl from"fast-glob";var El="SKILL.md",Rl=6,Il=200,Ol=64,Ll=1024,Nl="- Discovery: The list above is the skills available in this session (name + description + file path). Skill bodies live on disk at the listed paths.\n- Trigger rules: If the user names a skill (with `$SkillName` or plain text) OR the task clearly matches a skill's description shown above, you must use that skill for that turn. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned.\n- Missing/blocked: If a named skill isn't in the list or the path can't be read, say so briefly and continue with the best fallback.\n- How to use a skill (progressive disclosure):\n 1) After deciding to use a skill, open its `SKILL.md`. Read only enough to follow the workflow.\n 2) When `SKILL.md` references relative paths (e.g., `scripts/foo.py`), resolve them relative to the skill directory listed above first, and only consider other paths if needed.\n 3) If `SKILL.md` points to extra folders such as `references/`, load only the specific files needed for the request; don't bulk-load everything.\n 4) If `scripts/` exist, prefer running or patching them instead of retyping large code blocks.\n 5) If `assets/` or templates exist, reuse them instead of recreating from scratch.\n- Coordination and sequencing:\n - If multiple skills apply, choose the minimal set that covers the request and state the order you'll use them.\n - Announce which skill(s) you're using and why (one short line). If you skip an obvious skill, say why.\n- Context hygiene:\n - Keep context small: summarize long sections instead of pasting them; only load extra files when needed.\n - Avoid deep reference-chasing: prefer opening only files directly linked from `SKILL.md` unless you're blocked.\n - When variants exist (frameworks, providers, domains), pick only the relevant reference file(s) and note that choice.\n- Safety and fallback: If a skill can't be applied cleanly (missing files, unclear instructions), state the issue, pick the next-best approach, and continue.";function es(e){return e.trim().split(/\s+/).join(" ")}function $l(e){let t=e.trim();return t.length>=2&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Dl(e){let t=e.split(/\r?\n/);if(t[0]?.trim()!=="---")return null;let n=[],r=!1;for(let o of t.slice(1)){if(o.trim()==="---"){r=!0;break}n.push(o)}return!r||n.length===0?null:n.join(`
|
|
3
|
-
`)}function
|
|
4
|
-
`)}var
|
|
2
|
+
var hl=Object.create;var mr=Object.defineProperty;var yl=Object.getOwnPropertyDescriptor;var _l=Object.getOwnPropertyNames;var Sl=Object.getPrototypeOf,vl=Object.prototype.hasOwnProperty;var Yo=(e,t)=>()=>(e&&(t=e(e=0)),t);var Qo=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Tl=(e,t)=>{for(var n in t)mr(e,n,{get:t[n],enumerable:!0})},wl=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of _l(t))!vl.call(e,o)&&o!==n&&mr(e,o,{get:()=>t[o],enumerable:!(r=yl(t,o))||r.enumerable});return e};var Zo=(e,t,n)=>(n=e!=null?hl(Sl(e)):{},wl(t||!e||!e.__esModule?mr(n,"default",{value:e,enumerable:!0}):n,e));var xs=Qo((wS,Sn)=>{"use strict";function Ss(e){return Array.isArray(e)?e:[e]}var ku=void 0,Sr="",ys=" ",_r="\\",Au=/^\s+$/,Pu=/(?:[^\\]|^)\\$/,Eu=/^\\!/,Ru=/^\\#/,Iu=/\r?\n/g,Ou=/^\.{0,2}\/|^\.{1,2}$/,Lu=/\/$/,yt="/",vs="node-ignore";typeof Symbol<"u"&&(vs=Symbol.for("node-ignore"));var Ts=vs,_t=(e,t,n)=>(Object.defineProperty(e,t,{value:n}),n),Nu=/([0-z])-([0-z])/g,ws=()=>!1,$u=e=>e.replace(Nu,(t,n,r)=>n.charCodeAt(0)<=r.charCodeAt(0)?t:Sr),Du=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Uu=[[/^\uFEFF/,()=>Sr],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?ys:Sr)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+ys}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let r=n.replace(/\\\*/g,"[^\\/]*");return t+r}],[/\\\\\\(?=[$.|*+(){^])/g,()=>_r],[/\\\\/g,()=>_r],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,r,o)=>t===_r?`\\[${n}${Du(r)}${o}`:o==="]"&&r.length%2===0?`[${$u(n)}${r}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`]],Fu=/(^|\\\/)?\\\*$/,Bt="regex",yn="checkRegex",_s="_",Hu={[Bt](e,t){return`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`},[yn](e,t){return`${t?`${t}[^/]*`:"[^/]*"}(?=$|\\/$)`}},Bu=e=>Uu.reduce((t,[n,r])=>t.replace(n,r.bind(e)),e),_n=e=>typeof e=="string",Wu=e=>e&&_n(e)&&!Au.test(e)&&!Pu.test(e)&&e.indexOf("#")!==0,ju=e=>e.split(Iu).filter(Boolean),vr=class{constructor(t,n,r,o,s,i){this.pattern=t,this.mark=n,this.negative=s,_t(this,"body",r),_t(this,"ignoreCase",o),_t(this,"regexPrefix",i)}get regex(){let t=_s+Bt;return this[t]?this[t]:this._make(Bt,t)}get checkRegex(){let t=_s+yn;return this[t]?this[t]:this._make(yn,t)}_make(t,n){let r=this.regexPrefix.replace(Fu,Hu[t]),o=this.ignoreCase?new RegExp(r,"i"):new RegExp(r);return _t(this,n,o)}},zu=({pattern:e,mark:t},n)=>{let r=!1,o=e;o.indexOf("!")===0&&(r=!0,o=o.substr(1)),o=o.replace(Eu,"!").replace(Ru,"#");let s=Bu(o);return new vr(e,t,o,n,r,s)},Tr=class{constructor(t){this._ignoreCase=t,this._rules=[]}_add(t){if(t&&t[Ts]){this._rules=this._rules.concat(t._rules._rules),this._added=!0;return}if(_n(t)&&(t={pattern:t}),Wu(t.pattern)){let n=zu(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,Ss(_n(t)?ju(t):t).forEach(this._add,this),this._added}test(t,n,r){let o=!1,s=!1,i;this._rules.forEach(a=>{let{negative:l}=a;s===l&&o!==s||l&&!o&&!s&&!n||!a[r].test(t)||(o=!l,s=l,i=l?ku:a)});let c={ignored:o,unignored:s};return i&&(c.rule=i),c}},Gu=(e,t)=>{throw new t(e)},Fe=(e,t,n)=>_n(e)?e?Fe.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),Cs=e=>Ou.test(e);Fe.isNotRelative=Cs;Fe.convert=e=>e;var wr=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:r=!1}={}){_t(this,Ts,!0),this._rules=new Tr(n),this._strictPathCheck=!r,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,r,o){let s=t&&Fe.convert(t);return Fe(s,t,this._strictPathCheck?Gu:ws),this._t(s,n,r,o)}checkIgnore(t){if(!Lu.test(t))return this.test(t);let n=t.split(yt).filter(Boolean);if(n.pop(),n.length){let r=this._t(n.join(yt)+yt,this._testCache,!0,n);if(r.ignored)return r}return this._rules.test(t,!1,yn)}_t(t,n,r,o){if(t in n)return n[t];if(o||(o=t.split(yt).filter(Boolean)),o.pop(),!o.length)return n[t]=this._rules.test(t,r,Bt);let s=this._t(o.join(yt)+yt,n,r,o);return n[t]=s.ignored?s:this._rules.test(t,r,Bt)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return Ss(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},Cr=e=>new wr(e),Ku=e=>Fe(e&&Fe.convert(e),e,ws),bs=()=>{let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");Fe.convert=e;let t=/^[a-z]:\//i;Fe.isNotRelative=n=>t.test(n)||Cs(n)};typeof process<"u"&&process.platform==="win32"&&bs();Sn.exports=Cr;Cr.default=Cr;Sn.exports.isPathValid=Ku;_t(Sn.exports,Symbol.for("setupWindows"),bs)});var ki=Qo((qv,Mi)=>{"use strict";function Si(e){return Array.isArray(e)?e:[e]}var Jr="",vi=" ",Vr="\\",Wd=/^\s+$/,jd=/(?:[^\\]|^)\\$/,zd=/^\\!/,Gd=/^\\#/,Kd=/\r?\n/g,qd=/^\.*\/|^\.+$/,Xr="/",Ci="node-ignore";typeof Symbol<"u"&&(Ci=Symbol.for("node-ignore"));var Ti=Ci,Vd=(e,t,n)=>Object.defineProperty(e,t,{value:n}),Xd=/([0-z])-([0-z])/g,bi=()=>!1,Jd=e=>e.replace(Xd,(t,n,r)=>n.charCodeAt(0)<=r.charCodeAt(0)?t:Jr),Yd=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Qd=[[/^\uFEFF/,()=>Jr],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?vi:Jr)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+vi}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let r=n.replace(/\\\*/g,"[^\\/]*");return t+r}],[/\\\\\\(?=[$.|*+(){^])/g,()=>Vr],[/\\\\/g,()=>Vr],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,r,o)=>t===Vr?`\\[${n}${Yd(r)}${o}`:o==="]"&&r.length%2===0?`[${Jd(n)}${r}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`]],wi=Object.create(null),Zd=(e,t)=>{let n=wi[e];return n||(n=Qd.reduce((r,[o,s])=>r.replace(o,s.bind(e)),e),wi[e]=n),t?new RegExp(n,"i"):new RegExp(n)},Zr=e=>typeof e=="string",em=e=>e&&Zr(e)&&!Wd.test(e)&&!jd.test(e)&&e.indexOf("#")!==0,tm=e=>e.split(Kd),Yr=class{constructor(t,n,r,o){this.origin=t,this.pattern=n,this.negative=r,this.regex=o}},nm=(e,t)=>{let n=e,r=!1;e.indexOf("!")===0&&(r=!0,e=e.substr(1)),e=e.replace(zd,"!").replace(Gd,"#");let o=Zd(e,t);return new Yr(n,e,r,o)},rm=(e,t)=>{throw new t(e)},je=(e,t,n)=>Zr(e)?e?je.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),xi=e=>qd.test(e);je.isNotRelative=xi;je.convert=e=>e;var Qr=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:r=!1}={}){Vd(this,Ti,!0),this._rules=[],this._ignoreCase=n,this._allowRelativePaths=r,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(t){if(t&&t[Ti]){this._rules=this._rules.concat(t._rules),this._added=!0;return}if(em(t)){let n=nm(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,Si(Zr(t)?tm(t):t).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(t){return this.add(t)}_testOne(t,n){let r=!1,o=!1;return this._rules.forEach(s=>{let{negative:i}=s;if(o===i&&r!==o||i&&!r&&!o&&!n)return;s.regex.test(t)&&(r=!i,o=i)}),{ignored:r,unignored:o}}_test(t,n,r,o){let s=t&&je.convert(t);return je(s,t,this._allowRelativePaths?bi:rm),this._t(s,n,r,o)}_t(t,n,r,o){if(t in n)return n[t];if(o||(o=t.split(Xr)),o.pop(),!o.length)return n[t]=this._testOne(t,r);let s=this._t(o.join(Xr)+Xr,n,r,o);return n[t]=s.ignored?s:this._testOne(t,r)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return Si(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},kn=e=>new Qr(e),om=e=>je(e&&je.convert(e),e,bi);kn.isPathValid=om;kn.default=kn;Mi.exports=kn;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,"/");je.convert=e;let t=/^[a-z]:\//i;je.isNotRelative=n=>t.test(n)||xi(n)}});function T_(e){let t=Number.parseInt(e,10);return!Number.isInteger(t)||t<=0||t>65535?null:t}function tl(e){let t={open:!0};for(let n=0;n<e.length;n++){let r=e[n];if(r){if(r==="--open"){t.open=!0;continue}if(r==="--no-open"){t.open=!1;continue}if(r==="--host"){let o=e[n+1];o&&!o.startsWith("-")&&(t.host=o,n+=1);continue}if(r==="--port"){let o=e[n+1];if(o&&!o.startsWith("-")){let s=T_(o);s!==null&&(t.port=s,n+=1)}continue}if(r==="--static-dir"){let o=e[n+1];o&&!o.startsWith("-")&&(t.staticDir=o,n+=1);continue}}}return t}var nl=Yo(()=>{"use strict"});var il={};Tl(il,{runWebCommand:()=>N_});import{spawn as rl}from"child_process";import{existsSync as ol,readFileSync as w_}from"fs";import{createServer as C_}from"net";import{dirname as sn,join as Y,resolve as Ne}from"path";import{fileURLToPath as cr}from"url";function nt(e){let t=Ne(e);for(;;){let n=Y(t,"package.json");if(ol(n))try{if(JSON.parse(w_(n,"utf8")).name==="@memo-code/memo")return t}catch{}let r=sn(t);if(r===t)break;t=r}return null}function lr(e){return ol(e)}function M_(e){let t=[];e&&t.push(Ne(e)),process.env.MEMO_WEB_SERVER_ENTRY&&t.push(Ne(process.env.MEMO_WEB_SERVER_ENTRY));let n=sn(cr(import.meta.url)),r=nt(n)??nt(process.cwd());r&&(t.push(Y(r,"dist/web/server/main.cjs")),t.push(Y(r,"dist/web/server/main.js")),t.push(Y(r,"packages/web-server/dist/main.cjs")),t.push(Y(r,"packages/web-server/dist/main.js"))),t.push(Y(process.cwd(),"dist/web/server/main.cjs")),t.push(Y(process.cwd(),"dist/web/server/main.js")),t.push(Y(process.cwd(),"packages/web-server/dist/main.cjs")),t.push(Y(process.cwd(),"packages/web-server/dist/main.js"));for(let o of t)if(lr(o))return o;return null}function k_(e){let t=[];e&&t.push(Ne(e)),process.env.MEMO_WEB_STATIC_DIR&&t.push(Ne(process.env.MEMO_WEB_STATIC_DIR));let n=sn(cr(import.meta.url)),r=nt(n)??nt(process.cwd());r&&(t.push(Y(r,"dist/web/ui")),t.push(Y(r,"packages/web-ui/dist"))),t.push(Y(process.cwd(),"dist/web/ui")),t.push(Y(process.cwd(),"packages/web-ui/dist"));for(let o of t)if(lr(Y(o,"index.html")))return o;return null}function A_(){let e=sn(cr(import.meta.url)),t=nt(e)??nt(process.cwd()),n=[];t&&(n.push(Y(t,"dist/task-prompts")),n.push(Y(t,"packages/tui/src/task-prompts"))),n.push(Ne(e,"../task-prompts")),n.push(Ne(e,"task-prompts"));for(let r of n)if(lr(Y(r,"init_agents.md")))return r;return n[0]??Ne(e,"../task-prompts")}function P_(){let e=sn(cr(import.meta.url)),t=nt(e)??nt(process.cwd()),n=[];process.env.MEMO_SYSTEM_PROMPT_PATH&&n.push(Ne(process.env.MEMO_SYSTEM_PROMPT_PATH)),t&&(n.push(Y(t,"dist/prompt.md")),n.push(Y(t,"packages/core/src/runtime/prompt.md"))),n.push(Ne(e,"../prompt.md")),n.push(Ne(e,"../../core/src/runtime/prompt.md"));for(let r of n)if(lr(r))return r;return null}async function sl(e,t){return new Promise(n=>{let r=C_();r.unref(),r.once("error",()=>n(!1)),r.listen({host:e,port:t},()=>{r.close(()=>n(!0))})})}async function E_(e,t){for(let n=0;n<30;n++){let r=t+n;if(r>65535)break;if(await sl(e,r))return r}throw new Error(`No available port found from ${t} to ${t+29}`)}function R_(e,t){return t==="darwin"?{command:"open",args:[e]}:t==="win32"?{command:"cmd",args:["/c","start","",e]}:t==="linux"?{command:"xdg-open",args:[e]}:null}function I_(e){let t=R_(e,process.platform);if(!t)return!1;try{return rl(t.command,t.args,{stdio:"ignore",detached:!0}).unref(),!0}catch{return!1}}function O_(e,t){return`http://${e.includes(":")?`[${e}]`:e}:${t}`}async function L_(e,t,n=8e3){let r=Date.now();for(;Date.now()-r<n;){if(!await sl(e,t))return!0;await new Promise(o=>setTimeout(o,120))}return!1}async function N_(e){let t=tl(e),n=t.host??b_,r=t.port??x_,o=await E_(n,r),s=M_();if(!s){console.error("web-server entry not found (main.js missing)."),console.error("Please run `pnpm run web:server:build` or `pnpm run build` first."),process.exitCode=1;return}let i=k_(t.staticDir);if(!i){console.error("web-ui static assets not found (index.html missing)."),console.error("Please run `pnpm run web:ui:build` or `pnpm run build` first."),process.exitCode=1;return}o!==r&&console.log(`[memo web] Port ${r} is busy, using ${o}`);let c=O_(n,o);console.log(`[memo web] Server: ${c}`),console.log(`[memo web] Entry: ${s}`),console.log(`[memo web] Static: ${i}`);let a=A_(),l=P_(),p=rl(process.execPath,[s],{stdio:"inherit",env:{...process.env,MEMO_WEB_HOST:n,MEMO_WEB_PORT:String(o),MEMO_WEB_STATIC_DIR:i,MEMO_CLI_ENTRY:process.argv[1],MEMO_TASK_PROMPTS_DIR:a,...l?{MEMO_SYSTEM_PROMPT_PATH:l}:{}}});t.open&&(!await L_(n,o)||!I_(c))&&console.warn(`[memo web] Failed to auto-open browser. Open manually: ${c}`);let u=d=>{p.killed||p.kill(d)};process.once("SIGINT",()=>{u("SIGINT")}),process.once("SIGTERM",()=>{u("SIGTERM")}),await new Promise(d=>{p.once("exit",(m,g)=>{if(g){process.exitCode=0,d();return}process.exitCode=m??0,d()})})}var b_,x_,al=Yo(()=>{"use strict";nl();b_="127.0.0.1",x_=5494});import{randomUUID as cl}from"crypto";import{readFile as $_}from"fs/promises";import{createInterface as D_}from"readline/promises";import{stdin as U_,stdout as F_}from"process";import{render as H_}from"ink";import ql from"os";import{readFile as as}from"fs/promises";import{existsSync as Vl}from"fs";import{join as Ut,dirname as Xl,resolve as cs}from"path";import{fileURLToPath as Jl}from"url";import{access as Cl,readFile as bl,readdir as xl,stat as Ml}from"fs/promises";import{constants as kl}from"fs";import{homedir as ts}from"os";import{dirname as Al,isAbsolute as Pl,join as ht,resolve as pn}from"path";import El from"fast-glob";var Rl="SKILL.md",Il=6,Ol=200,Ll=64,Nl=1024,$l="- Discovery: The list above is the skills available in this session (name + description + file path). Skill bodies live on disk at the listed paths.\n- Trigger rules: If the user names a skill (with `$SkillName` or plain text) OR the task clearly matches a skill's description shown above, you must use that skill for that turn. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned.\n- Missing/blocked: If a named skill isn't in the list or the path can't be read, say so briefly and continue with the best fallback.\n- How to use a skill (progressive disclosure):\n 1) After deciding to use a skill, open its `SKILL.md`. Read only enough to follow the workflow.\n 2) When `SKILL.md` references relative paths (e.g., `scripts/foo.py`), resolve them relative to the skill directory listed above first, and only consider other paths if needed.\n 3) If `SKILL.md` points to extra folders such as `references/`, load only the specific files needed for the request; don't bulk-load everything.\n 4) If `scripts/` exist, prefer running or patching them instead of retyping large code blocks.\n 5) If `assets/` or templates exist, reuse them instead of recreating from scratch.\n- Coordination and sequencing:\n - If multiple skills apply, choose the minimal set that covers the request and state the order you'll use them.\n - Announce which skill(s) you're using and why (one short line). If you skip an obvious skill, say why.\n- Context hygiene:\n - Keep context small: summarize long sections instead of pasting them; only load extra files when needed.\n - Avoid deep reference-chasing: prefer opening only files directly linked from `SKILL.md` unless you're blocked.\n - When variants exist (frameworks, providers, domains), pick only the relevant reference file(s) and note that choice.\n- Safety and fallback: If a skill can't be applied cleanly (missing files, unclear instructions), state the issue, pick the next-best approach, and continue.";function ns(e){return e.trim().split(/\s+/).join(" ")}function Dl(e){let t=e.trim();return t.length>=2&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Ul(e){let t=e.split(/\r?\n/);if(t[0]?.trim()!=="---")return null;let n=[],r=!1;for(let o of t.slice(1)){if(o.trim()==="---"){r=!0;break}n.push(o)}return!r||n.length===0?null:n.join(`
|
|
3
|
+
`)}function Fl(e,t){let n=e.split(/\r?\n/),r=!1,o=[];for(let s of n){if(!r){s.match(new RegExp(`^${t}\\s*:\\s*[|>]\\s*$`))&&(r=!0);continue}if(!/^\s+/.test(s))break;o.push(s.replace(/^\s+/,""))}return o.length===0?null:ns(o.join(" "))}function es(e,t){let n=Fl(e,t);if(n)return n;let r=new RegExp(`^${t}\\s*:\\s*(.+?)\\s*$`,"m"),o=e.match(r);return o?.[1]?ns(Dl(o[1])):null}function Hl(e,t){let n=Ul(e);if(!n)return null;let r=es(n,"name"),o=es(n,"description");return!r||!o||r.length>Ll||o.length>Nl?null:{name:r,description:o,path:t}}function rs(e,t){return e==="~"?t:e.startsWith("~/")?ht(t,e.slice(2)):e}async function Bl(e){try{return(await Ml(e)).isDirectory()}catch{return!1}}async function Wl(e){try{return await Cl(ht(e,".git"),kl.F_OK),!0}catch{return!1}}async function jl(e){let t=pn(e),n=t;for(;;){if(await Wl(n))return n;let r=Al(n);if(r===n)break;n=r}return t}async function zl(e){let t=[ht(e,".agents","skills")];try{let r=(await xl(e,{withFileTypes:!0})).filter(o=>o.isDirectory()&&o.name.startsWith(".")).map(o=>o.name).filter(o=>o!==".git").sort((o,s)=>o.localeCompare(s));for(let o of r)t.push(ht(e,o,"skills"))}catch{return un(t)}return un(t)}function un(e){let t=[],n=new Set;for(let r of e){let o=pn(r);n.has(o)||(n.add(o),t.push(o))}return t}async function Gl(e){let t=e.cwd??process.cwd(),n=e.homeDir??ts(),r=rs(e.memoHome??process.env.MEMO_HOME??ht(n,".memo"),n),o=await jl(t),s=await zl(o);return s.push(ht(r,"skills")),un(s)}async function Kl(e){if(e.skillRoots&&e.skillRoots.length>0){let t=e.homeDir??ts(),n=e.skillRoots.map(r=>{let o=rs(r,t);return Pl(o)?o:pn(o)});return un(n)}return Gl(e)}async function os(e={}){let t=await Kl(e),n=Math.max(1,e.maxSkills??Ol),r=[],o=new Set;for(let s of t){if(!await Bl(s))continue;let i=await El(`**/${Rl}`,{cwd:s,absolute:!0,onlyFiles:!0,deep:Il,caseSensitiveMatch:!1,followSymbolicLinks:!0,suppressErrors:!0,unique:!0,ignore:["**/.git/**","**/node_modules/**"]});i.sort((c,a)=>c.localeCompare(a));for(let c of i){let a=pn(c);if(o.has(a))continue;let l;try{l=await bl(a,"utf-8")}catch{continue}let p=Hl(l,a);if(p&&(r.push(p),o.add(a),r.length>=n))return r}}return r}function ss(e){if(e.length===0)return null;let t=[];t.push("## Skills"),t.push("A skill is a set of local instructions to follow that is stored in a `SKILL.md` file. Below is the list of skills that can be used. Each entry includes a name, description, and file path so you can open the source for full instructions when using a specific skill."),t.push("### Available skills");for(let n of e)t.push(`- ${n.name}: ${n.description} (file: ${n.path})`);return t.push("### How to use skills"),t.push($l),t.join(`
|
|
4
|
+
`)}var Yl=/{{\s*([\w.-]+)\s*}}/g;function Ql(e,t){return e.replace(Yl,(n,r)=>t[r]??"")}function Zl(){try{return ql.userInfo().username}catch{return process.env.USER??process.env.USERNAME??"unknown"}}function is(e){return cs(e)}function eu(e,t){if(!Array.isArray(t))return e;let n=new Set(t.map(r=>is(r)));return e.filter(r=>n.has(is(r.path)))}async function tu(e){let t=Ut(e,"AGENTS.md");try{let n=await as(t,"utf-8");return n.trim()?{path:t,content:n}:null}catch{return null}}function nu(e,t){return`${e}
|
|
5
5
|
|
|
6
6
|
## Project AGENTS.md (Startup Root)
|
|
7
7
|
Loaded from: ${t.path}
|
|
8
8
|
|
|
9
|
-
${t.content}`}function
|
|
9
|
+
${t.content}`}function ru(e,t){return`${e}
|
|
10
10
|
|
|
11
|
-
${t}`}function
|
|
12
|
-
`,"utf8")}),this.writeQueue}async flush(){await this.writeQueue}async close(){this.closed||(this.closed=!0,await this.flush())}};function
|
|
13
|
-
`),n=[];for(let r=0;r<t.length;r+=1){let o=
|
|
14
|
-
`),turns:i,events:n}}import{readdir as
|
|
15
|
-
`).toLowerCase().includes(c))}var
|
|
16
|
-
`)}function
|
|
11
|
+
${t}`}function ou(){return typeof __dirname=="string"?__dirname:Xl(Jl(import.meta.url))}function su(e){let t=ou(),n=[e,process.env.MEMO_SYSTEM_PROMPT_PATH,Ut(t,"prompt.md"),Ut(t,"../prompt.md"),Ut(t,"../../prompt.md")].filter(r=>!!r).map(r=>cs(r));for(let r of n)if(Vl(r))return r;return Ut(t,"prompt.md")}async function ls(e={}){let t=e.cwd??process.cwd(),n=su(e.promptPath),r=await as(n,"utf-8"),o={date:new Date().toISOString(),user:Zl(),pwd:t},s=Ql(r,o),i=await tu(t);if(i&&(s=nu(s,i)),e.includeSkills!==!1){let c=await os({cwd:t,skillRoots:e.skillRoots,homeDir:e.homeDir,memoHome:e.memoHome}),a=eu(c,e.activeSkillPaths),l=ss(a);l&&(s=ru(s,l))}return s}import{appendFile as iu,mkdir as au}from"fs/promises";import{dirname as cu}from"path";var dn=class{constructor(t){this.filePath=t}ensureDirPromise=null;writeQueue=Promise.resolve();closed=!1;ensureDirectory(){return this.ensureDirPromise||(this.ensureDirPromise=au(cu(this.filePath),{recursive:!0}).then(()=>{})),this.ensureDirPromise}async append(t){if(this.closed)throw new Error("History sink is closed");return this.writeQueue=this.writeQueue.then(async()=>{await this.ensureDirectory(),await iu(this.filePath,`${JSON.stringify(t)}
|
|
12
|
+
`,"utf8")}),this.writeQueue}async flush(){await this.writeQueue}async close(){this.closed||(this.closed=!0,await this.flush())}};function us(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{basename as fs}from"path";import{createHash as lu}from"crypto";import{basename as dS,resolve as uu}from"path";function pu(e){return e==="/"?e:e.replace(/\/+$/g,"")}function mn(e){let n=uu(e.trim()).replace(/\\/g,"/");return n==="/"?n:pu(n)}function ps(e){let t=mn(e);return lu("sha256").update(t).digest("hex").slice(0,16)}function ds(e,t){let n=mn(e),r=mn(t);return n===r?!0:n.startsWith(`${r}/`)}function fr(){return{prompt:0,completion:0,total:0}}function du(){return{total:0,success:0,failed:0,denied:0,cancelled:0}}function de(e){return typeof e!="string"?"":e.trim()}function gr(e){let t=de(e);return t?t.replace(/<\s*(think|thinking)\b[^>]*>[\s\S]*?<\s*\/\s*\1\s*>/gi," ").replace(/<\s*\/?\s*(think|thinking)\b[^>]*>/gi," ").replace(/\s+/g," ").trim():""}function Ht(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let t=Number.parseFloat(e);if(Number.isFinite(t))return t}return null}function at(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function mu(e,t){for(let s of t){let i=s.meta?.sessionId;if(typeof i=="string"&&i.trim())return i.trim()}let n=t.find(s=>{if(!s.meta)return!1;let i=s.meta.sessionId;return typeof i=="string"&&i.trim().length>0});if(n?.meta&&typeof n.meta.sessionId=="string")return n.meta.sessionId;let r=fs(e,".jsonl"),o=r.lastIndexOf("-");return o<=0||o>=r.length-1?r:r.slice(o+1)}function fu(e,t){if(e){let r=e.replace(/\\/g,"/").split("/").filter(Boolean),o=r[r.length-1];if(o)return o}return fs(t,".jsonl")}function Ft(e,t){let n=e.turnsById.get(t);if(n)return n;let r={turn:t,steps:[],byStep:new Map};return e.turnsById.set(t,r),r}function hr(e,t){let n=e.byStep.get(t);if(n)return n;let r={step:t};return e.byStep.set(t,r),e.steps=Array.from(e.byStep.values()).sort((o,s)=>o.step-s.step),r}function gu(e,t){if(!e.trim())return null;let n;try{n=JSON.parse(e)}catch{return null}if(!at(n))return null;let r=de(n.ts),o=de(n.type);if(!r||!o)return null;let s={index:t,ts:r,type:o},i=Ht(n.turn),c=Ht(n.step);i!==null&&(s.turn=Math.floor(i)),c!==null&&(s.step=Math.floor(c));let a=de(n.role);return a&&(s.role=a),typeof n.content=="string"&&(s.content=n.content),at(n.meta)&&(s.meta=n.meta),s}function fn(e,t){if(!t)return;let n=Ht(t.prompt),r=Ht(t.completion),o=Ht(t.total);n!==null&&(e.prompt+=Math.floor(n)),r!==null&&(e.completion+=Math.floor(r)),o!==null&&(e.total+=Math.floor(o))}function ms(e){if(!e)return"idle";let t=e.trim().toLowerCase();return t?t==="cancelled"?"cancelled":t==="error"||t==="prompt_limit"?"error":t==="running"?"running":"idle":"idle"}function hu(e){if(!e)return[];let t=[],n=de(e.tool);n&&t.push(n);let r=e.tools;if(Array.isArray(r))for(let s of r){let i=de(s);i&&t.push(i)}let o=e.toolBlocks;if(Array.isArray(o))for(let s of o){if(!at(s))continue;let i=de(s.name);i&&t.push(i)}return Array.from(new Set(t))}function yu(e,t){if(!t)return;let n=t.trim().toLowerCase();if(n){if(n==="success"){e.toolUsage.success+=1;return}if(n==="approval_denied"){e.toolUsage.denied+=1,e.toolUsage.failed+=1,e.hasCancelled=!0;return}if(n==="cancelled"){e.toolUsage.cancelled+=1,e.hasCancelled=!0;return}e.toolUsage.failed+=1,e.hasError=!0}}function _u(e){let t=e.split(`
|
|
13
|
+
`),n=[];for(let r=0;r<t.length;r+=1){let o=gu(t[r]??"",r);o&&n.push(o)}return n}function gn(e,t){let n=_u(e),r=new Date().toISOString(),o={sessionId:"",title:"",project:"",cwd:"",startedAt:n[0]?.ts??r,updatedAt:n[n.length-1]?.ts??n[0]?.ts??r,status:"idle",turnCount:0,tokenUsage:fr(),toolUsage:du(),turnsById:new Map,summaryParts:[],hasError:!1,hasCancelled:!1};for(let a of n){if(a.ts>o.updatedAt&&(o.updatedAt=a.ts),a.type==="session_start"&&a.meta){let l=de(a.meta.cwd);l&&(o.cwd=l)}if(a.type==="session_title"){let l=gr(a.content);l&&(o.title=l)}if(a.type==="turn_start"){let l=a.turn??o.turnCount+1,p=Ft(o,l);p.input=a.content,p.startedAt=a.ts,o.turnCount=Math.max(o.turnCount,l),a.content&&a.content.trim()&&(o.title||(o.title=gr(a.content)),o.summaryParts.push(`User: ${a.content.trim()}`))}if(a.type==="assistant"&&typeof a.turn=="number"){let l=Ft(o,a.turn),p=hr(l,a.step??l.steps.length),u=p.assistantText??"";p.assistantText=`${u}${a.content??""}`,a.content?.trim()&&o.summaryParts.push(`Assistant: ${a.content.trim()}`)}if(a.type==="action"&&typeof a.turn=="number"){let l=Ft(o,a.turn),p=hr(l,a.step??l.steps.length),u=hu(a.meta);for(let g of u)o.toolUsage.total+=1;let d=de(a.meta?.tool);d&&(p.action={tool:d,input:a.meta?.input});let m=de(a.meta?.thinking);if(m&&(p.thinking=m),Array.isArray(a.meta?.toolBlocks)){let g=a.meta.toolBlocks.filter(at).map(y=>{let b=de(y.name);return b?{tool:b,input:y.input}:null}).filter(y=>!!y);g.length>1&&(p.parallelActions=g)}}if(a.type==="observation"&&typeof a.turn=="number"){let l=Ft(o,a.turn),p=hr(l,a.step??l.steps.length);p.observation=a.content;let u=de(a.meta?.status);u&&(p.resultStatus=u),yu(o,u)}if(a.type==="final"&&typeof a.turn=="number"){let l=Ft(o,a.turn);l.finalText=a.content;let p=de(a.meta?.status);if(p){l.status=p;let d=ms(p);d==="error"&&(o.hasError=!0),d==="cancelled"&&(o.hasCancelled=!0)}let u=de(a.meta?.errorMessage);if(u&&(l.errorMessage=u),at(a.meta?.tokens)){let d=fr();fn(d,a.meta.tokens),l.tokenUsage=d,fn(o.tokenUsage,a.meta.tokens)}}if(a.type==="turn_end"){let l=de(a.meta?.status);if(l){let p=ms(l);p==="error"&&(o.hasError=!0),p==="cancelled"&&(o.hasCancelled=!0)}at(a.meta?.tokens)&&fn(o.tokenUsage,a.meta.tokens)}a.type==="session_end"&&at(a.meta?.tokens)&&(o.tokenUsage=fr(),fn(o.tokenUsage,a.meta.tokens))}o.sessionId=mu(t,n),o.project=fu(o.cwd,t),o.title=gr(o.title),o.title||(o.title=o.project||o.sessionId),o.hasError?o.status="error":o.hasCancelled?o.status="cancelled":o.status="idle";let s=o.startedAt.slice(0,10),i=Array.from(o.turnsById.values()).sort((a,l)=>a.turn-l.turn).map(a=>({turn:a.turn,input:a.input,startedAt:a.startedAt,finalText:a.finalText,status:a.status,errorMessage:a.errorMessage,tokenUsage:a.tokenUsage,steps:a.steps}));return{...{id:o.sessionId,sessionId:o.sessionId,filePath:t,title:o.title,project:o.project,workspaceId:o.cwd?ps(o.cwd):"",cwd:o.cwd,date:{day:/^\d{4}-\d{2}-\d{2}$/.test(s)?s:r.slice(0,10),startedAt:o.startedAt,updatedAt:o.updatedAt},status:o.status,turnCount:o.turnCount,tokenUsage:o.tokenUsage,toolUsage:o.toolUsage},summary:o.summaryParts.join(`
|
|
14
|
+
`),turns:i,events:n}}import{readdir as Su,readFile as vu,stat as Tu}from"fs/promises";import{join as wu,resolve as yr}from"path";function Cu(e,t){if(typeof e!="number"||!Number.isFinite(e))return t;let n=Math.floor(e);return n>0?n:t}function gs(e,t){if(typeof e!="number"||!Number.isFinite(e))return t;let n=Math.floor(e);return n<=0?t:Math.min(n,100)}function hs(e){if(!e)return null;let t=e.trim();return t&&/^\d{4}-\d{2}-\d{2}$/.test(t)?t:null}async function bu(e){let t=[],n=async r=>{let o;try{o=await Su(r,{withFileTypes:!0})}catch{return}await Promise.all(o.map(async s=>{if(s.isSymbolicLink())return;let i=wu(r,s.name);if(s.isDirectory()){await n(i);return}if(!(!s.isFile()||!s.name.endsWith(".jsonl")))try{let c=await Tu(i);t.push({filePath:yr(i),mtimeMs:c.mtimeMs,size:c.size})}catch{}}))};return await n(yr(e)),t}function xu(e,t,n,r){let o=r==="asc"?1:-1;if(n==="project"){let s=e.project.localeCompare(t.project);return s===0?e.date.updatedAt.localeCompare(t.date.updatedAt)*o:s*o}if(n==="title"){let s=e.title.localeCompare(t.title);return s===0?e.date.updatedAt.localeCompare(t.date.updatedAt)*o:s*o}return n==="startedAt"?e.date.startedAt.localeCompare(t.date.startedAt)*o:e.date.updatedAt.localeCompare(t.date.updatedAt)*o}function Mu(e,t){let n=e.project.trim(),r=e.cwd.trim(),o=/^\d{4}-\d{2}-\d{2}T\d{2}[-:]\d{2}[-:]\d{2}(?:\.\d+)?(?:Z)?-[A-Za-z0-9._-]+$/i.test(n)||/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(n)||n===e.sessionId;if(!n||!r||o||t.workspaceCwd&&!ds(r,t.workspaceCwd))return!1;if(t.project){let a=t.project.trim().toLowerCase();if(a&&n.toLowerCase()!==a)return!1}let s=hs(t.dateFrom),i=hs(t.dateTo);if(s&&e.date.day<s||i&&e.date.day>i)return!1;let c=t.q?.trim().toLowerCase();return!(c&&![e.title,n,r,e.sessionId,e.filePath].join(`
|
|
15
|
+
`).toLowerCase().includes(c))}var hn=class{sessionsDir;cache=new Map;sessionIdToPath=new Map;refreshInFlight=null;constructor(t){this.sessionsDir=yr(t.sessionsDir)}async refresh(){if(this.refreshInFlight){await this.refreshInFlight;return}let t=this.refreshInternal();this.refreshInFlight=t;try{await t}finally{this.refreshInFlight=null}}async list(t={}){await this.refresh();let n=Cu(t.page,1),r=gs(t.pageSize,20),o=t.sortBy??"updatedAt",s=t.order??"desc",i=Array.from(this.cache.values()).map(u=>u.summary).filter(u=>Mu(u,t)).sort((u,d)=>xu(u,d,o,s)),c=i.length,a=c===0?0:Math.ceil(c/r),l=(n-1)*r;return{items:i.slice(l,l+r),page:n,pageSize:r,total:c,totalPages:a}}async getSessionDetail(t){await this.refresh();let n=this.sessionIdToPath.get(t);return n?this.cache.get(n)?.detail??null:null}async getSessionEvents(t,n,r){let o=await this.getSessionDetail(t);if(!o)return null;let s=Number.parseInt(n??"0",10),i=Number.isFinite(s)&&s>=0?s:0,c=gs(r,100),a=o.events.slice(i,i+c),l=i+a.length;return{items:a,nextCursor:l>=o.events.length?null:String(l)}}async getAllSummaries(){return await this.refresh(),Array.from(this.cache.values()).map(t=>t.summary)}async refreshInternal(){let t=await bu(this.sessionsDir),n=new Set(t.map(r=>r.filePath));for(let r of Array.from(this.cache.keys()))if(!n.has(r)){let o=this.cache.get(r);o&&this.sessionIdToPath.delete(o.summary.sessionId),this.cache.delete(r)}for(let r of t){let o=this.cache.get(r.filePath);if(!(o&&o.mtimeMs===r.mtimeMs&&o.size===r.size))try{let s=await vu(r.filePath,"utf8"),i=gn(s,r.filePath),c=i,a={filePath:r.filePath,mtimeMs:r.mtimeMs,size:r.size,summary:c,detail:i};o&&this.sessionIdToPath.delete(o.summary.sessionId),this.cache.set(r.filePath,a),this.sessionIdToPath.set(c.sessionId,r.filePath)}catch{}}}};var Ps=Zo(xs(),1);import{existsSync as Ms,statSync as qu}from"fs";import{readFile as Vu,readdir as Xu}from"fs/promises";import{dirname as ks,join as wn,relative as As,resolve as Ju,sep as Yu}from"path";var Qu=6,Zu=2500,Es=25,ep=new Set([".git",".svn",".hg","node_modules","dist","build",".next",".turbo",".cache",".output","coverage","tmp","temp","logs"]),vn=new Map,br=new Map,St=new Map,tp=256;function Tn(e,t){if(St.size>=tp&&!St.has(e)){let n=St.keys().next().value;typeof n=="string"&&St.delete(n)}St.set(e,t)}function Rs(e){return e.split(Yu).join("/")}function np(e){return{maxDepth:typeof e.maxDepth=="number"?Math.max(1,e.maxDepth):Qu,maxEntries:typeof e.maxEntries=="number"?Math.max(100,e.maxEntries):Zu,limit:typeof e.limit=="number"?Math.max(1,e.limit):Es,respectGitIgnore:e.respectGitIgnore??!0,ignoreGlobs:e.ignoreGlobs?.length?e.ignoreGlobs:[]}}function rp(e,t){let n=e.split("/").filter(Boolean),r=n[n.length-1]??"";return n.some(o=>ep.has(o))||r.endsWith(".log")?!0:t.ignoreGlobs.length?t.ignoreGlobs.some(o=>{let s=o.replace(/\\/g,"/").trim();if(!s)return!1;if(s.endsWith("/**")){let i=s.slice(0,-3);return e.startsWith(i)}if(s.startsWith("*")){let i=s.slice(1);return e.endsWith(i)}return e.includes(s)}):!1}function op(e){return e.replace(/\\/g,"/")}function sp(e){let t=Ju(e),n=St.get(t);if(n)return n;let r=t;try{qu(r).isFile()&&(r=ks(r))}catch{r=process.cwd()}let o=r,s=[];for(;;){if(s.push(r),Ms(wn(r,".gitignore"))||Ms(wn(r,".git"))){for(let c of s)Tn(c,r);return Tn(t,r),r}let i=ks(r);if(i===r){for(let c of s)Tn(c,o);return Tn(t,o),o}r=i}}async function ip(e){let t=wn(e,".gitignore");try{return(await Vu(t,"utf8")).split(/\r?\n/).map(r=>r.trim()).filter(r=>r.length>0&&!r.startsWith("#"))}catch{return[]}}function ap(e){let t=(0,Ps.default)();return e.length>0&&t.add(e),t}async function cp(e){let t=ap(await ip(e));return{root:e,ignores:n=>{let r=As(e,n);return!r||r.startsWith("..")?!1:t.ignores(op(r))}}}async function lp(e){let t=sp(e),n=br.get(t);if(n)return n;let r=cp(t).catch(o=>{throw br.delete(t),o});return br.set(t,r),r}function up(e){return JSON.stringify({maxDepth:e.maxDepth,maxEntries:e.maxEntries,respectGitIgnore:e.respectGitIgnore,ignoreGlobs:e.ignoreGlobs})}async function pp(e,t){let n=[],r=t.respectGitIgnore?await lp(e):null,o=async(s,i)=>{if(n.length>=t.maxEntries)return;let c;try{c=await Xu(s,{withFileTypes:!0})}catch{return}for(let a of c){if(n.length>=t.maxEntries)break;if(a.isSymbolicLink())continue;let l=wn(s,a.name);if(r?.ignores(l))continue;let p=As(e,l);if(!p)continue;let u=Rs(p);if(rp(u,t))continue;let d=u.split("/").filter(Boolean),m=a.isDirectory();n.push({path:u,pathLower:u.toLowerCase(),segments:d,segmentsLower:d.map(g=>g.toLowerCase()),depth:i,isDir:m}),m&&i<t.maxDepth&&await o(l,i+1)}};return await o(e,0),n.sort((s,i)=>s.path.localeCompare(i.path)),n}async function dp(e,t){let n=np(t),r=up(n),o=vn.get(e);if(o&&o.signature===r)return o.pending?o.pending:o.entries;let s=pp(e,n).then(i=>(vn.set(e,{entries:i,signature:r}),i)).catch(i=>{throw vn.delete(e),i});return vn.set(e,{entries:[],signature:r,pending:s}),s}function mp(e,t){if(!t.length)return e.depth+(e.isDir?-.2:.2);let n=e.depth,r=0;for(let o of t){let s=-1;for(let i=r;i<e.segmentsLower.length;i++){let c=e.segmentsLower[i];if(c.startsWith(o)){s=i,n+=(i-r)*1.2,n+=c.length-o.length;break}let a=c.indexOf(o);if(a!==-1){s=i,n+=(i-r)*2+a+2;break}}if(s===-1)return null;r=s+1}return e.isDir&&(n-=.5),n}function fp(e,t,n){let o=t.trim().replace(/\\/g,"/").split("/").filter(Boolean).map(i=>i.toLowerCase()),s=[];for(let i of e){let c=mp(i,o);c!==null&&s.push({entry:i,score:c})}return s.sort((i,c)=>{let a=i.score-c.score;return a!==0?a:i.entry.path.localeCompare(c.entry.path)}),s.slice(0,n).map(({entry:i})=>({id:i.path,path:i.path,name:i.segments[i.segments.length-1]??i.path,parent:i.segments.length>1?i.segments.slice(0,-1).join("/"):void 0,isDir:i.isDir}))}async function Is(e){let t=await dp(e.cwd,e),n=typeof e.limit=="number"?Math.max(1,e.limit):Es;return fp(t,e.query,n)}var W={HELP:"help",EXIT:"exit",NEW:"new",RESUME:"resume",REVIEW:"review",MODELS:"models",TOOLS:"tools",COMPACT:"compact",MCP:"mcp",INIT:"init"},me={NONE:"none",ONCE:"once",FULL:"full"};function Wt(e){return`/${e}`}var jt=[{name:W.HELP,description:"Show command and shortcut help"},{name:W.EXIT,description:"Exit current session"},{name:W.NEW,description:"Start a fresh session"},{name:W.RESUME,description:"List and load session history"},{name:W.REVIEW,description:"Review a GitHub pull request and post comments"},{name:W.MODELS,description:"List or switch configured models"},{name:W.TOOLS,description:"Set tool permission mode (none/once/full)"},{name:W.COMPACT,description:"Compact conversation context now"},{name:W.MCP,description:"Show configured MCP servers"},{name:W.INIT,description:"Generate AGENTS.md with agent instructions"}],gp={none:me.NONE,off:me.NONE,disabled:me.NONE,"no-tools":me.NONE,once:me.ONCE,ask:me.ONCE,single:me.ONCE,strict:me.ONCE,full:me.FULL,all:me.FULL,dangerous:me.FULL,"full-access":me.FULL};function hp(e){if(!e)return null;let t=e.trim().toLowerCase();return t?gp[t]??null:null}function Os(e){return e===me.NONE?"none (no tools)":e===me.ONCE?"once (approval required)":"full (no approval)"}function Ls(){let e=jt.reduce((n,r)=>Math.max(n,r.name.length),0);return["Available commands:",...jt.map(n=>` ${Wt(n.name).padEnd(e+3)} ${n.description}`)," exit Exit session (without slash)","","Shortcuts:"," Enter Send message"," Shift+Enter New line"," Up/Down Browse local input history"," Tab Accept active suggestion"," Ctrl+L Clear screen and start new session"," Esc Esc Interrupt running turn / clear input"].join(`
|
|
16
|
+
`)}function yp(e){if(!e)return null;let t=e.trim();if(!t)return null;let n=t.match(/^#?(\d+)$/);if(n){let o=Number(n[1]);return Number.isInteger(o)&&o>0?o:null}let r=t.match(/\/pull\/(\d+)(?:[/?#].*)?$/i);if(r){let o=Number(r[1]);return Number.isInteger(o)&&o>0?o:null}return null}function xr(e,t){let[n,...r]=e.trim().slice(1).split(/\s+/);switch((n??"").toLowerCase()){case W.HELP:return{kind:"message",title:"Help",content:Ls()};case W.EXIT:return{kind:"exit"};case W.NEW:return{kind:"new"};case W.RESUME:return{kind:"message",title:"Resume",content:'Type "resume" followed by keywords to load local session history.'};case W.REVIEW:{let s=r.join(" ").trim(),i=yp(s);return i?{kind:"review_pr",prNumber:i}:{kind:"message",title:"Review",content:`Usage: ${Wt(W.REVIEW)} <prNumber>
|
|
17
17
|
Examples: /review 999, /review #999`}}case W.MODELS:{if(!t.providers.length)return{kind:"message",title:"Models",content:`No providers configured. Check ${t.configPath}`};let s=r.join(" ").trim(),i=t.providers.find(l=>l.name===s)??t.providers.find(l=>l.model===s);if(i)return{kind:"switch_model",provider:i};let c=t.providers.map(l=>{let p=l.name===t.providerName&&l.model===t.model?" (current)":"",u=l.base_url?` @ ${l.base_url}`:"";return`- ${l.name}: ${l.model}${u}${p}`});return{kind:"message",title:"Models",content:`${s?`Not found: ${s}
|
|
18
18
|
|
|
19
19
|
`:""}${c.join(`
|
|
20
|
-
`)}`}}case W.TOOLS:{let s=r.join(" ").trim(),i=
|
|
21
|
-
Choose one of: ${c}`}:{kind:"message",title:"Tools",content:`Current: ${
|
|
22
|
-
Usage: ${
|
|
20
|
+
`)}`}}case W.TOOLS:{let s=r.join(" ").trim(),i=hp(s),c=["none","once","full"].join(", ");return s?i?i===t.toolPermissionMode?{kind:"message",title:"Tools",content:`Already using ${Os(i)}.`}:{kind:"set_tool_permission",mode:i}:{kind:"message",title:"Tools",content:`Unsupported mode: ${s}
|
|
21
|
+
Choose one of: ${c}`}:{kind:"message",title:"Tools",content:`Current: ${Os(t.toolPermissionMode)}
|
|
22
|
+
Usage: ${Wt(W.TOOLS)} <mode>
|
|
23
23
|
Modes: ${c}`}}case W.COMPACT:return{kind:"compact"};case W.MCP:{let s=Object.keys(t.mcpServers);if(!s.length)return{kind:"message",title:"MCP Servers",content:"No MCP servers configured in current config."};let i=[];i.push(`Total: ${s.length}`),i.push("");for(let[c,a]of Object.entries(t.mcpServers))i.push(`- ${c}`),"url"in a?(i.push(` type: ${a.type??"streamable_http"}`),i.push(` url: ${a.url}`),a.bearer_token_env_var&&i.push(` bearer: ${a.bearer_token_env_var}`)):(i.push(` type: ${a.type??"stdio"}`),i.push(` command: ${a.command}`),a.args?.length&&i.push(` args: ${a.args.join(" ")}`)),i.push("");return{kind:"message",title:"MCP Servers",content:i.join(`
|
|
24
24
|
`)}}case W.INIT:return{kind:"init_agents_md"};default:return{kind:"message",title:"Unknown",content:`Unknown command: ${e}
|
|
25
|
-
Type ${
|
|
25
|
+
Type ${Wt(W.HELP)} for available commands.`}}}import{mkdir as _p,writeFile as Sp,readFile as vp,access as Tp}from"fs/promises";import{homedir as Us}from"os";import{dirname as wp,join as ct,parse as Cp,resolve as bp}from"path";import{randomUUID as DS}from"crypto";import{parse as xp}from"toml";var Mp=ct(Us(),".memo"),kp="sessions",Ns=12e4,Fs=80,zt={current_provider:"deepseek",mcp_oauth_credentials_store_mode:"auto",auto_compact_threshold_percent:Fs,providers:[{name:"deepseek",env_api_key:"DEEPSEEK_API_KEY",model:"deepseek-chat",base_url:"https://api.deepseek.com"}],mcp_servers:{}};function Hs(e){return typeof e=="number"&&Number.isInteger(e)&&Number.isFinite(e)&&e>=1&&e<=100?e:Fs}function Mr(e){return e.trim().toLowerCase()}function $s(e){if(typeof e?.context_window=="number"&&Number.isFinite(e.context_window)&&e.context_window>0)return Math.floor(e.context_window)}function vt(e,t){let n=e.model_profiles;if(!n)return Ns;let r=new Map;for(let[c,a]of Object.entries(n))r.set(Mr(c),a);let o=Mr(t.name),s=Mr(t.model),i=`${o}:${s}`;return $s(r.get(i))??$s(r.get(s))??Ns}function Ds(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:JSON.stringify(e)}function Ap(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=[];for(let[n,r]of Object.entries(e)){if(!r)continue;let o=Array.isArray(r)?r:[r];for(let s of o){if(!s||typeof s!="object")continue;let i={...s};(typeof i.name!="string"||i.name.length===0)&&n&&(i.name=n),t.push(i)}}return t}function Pp(e){if(!Array.isArray(e))return;let t=e.filter(n=>typeof n=="string").map(n=>n.trim()).filter(Boolean);return Array.from(new Set(t))}function Ep(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e)){if(!r||typeof r!="object"||Array.isArray(r))continue;let o=r,s={};typeof o.supports_parallel_tool_calls=="boolean"&&(s.supports_parallel_tool_calls=o.supports_parallel_tool_calls),typeof o.supports_reasoning_content=="boolean"&&(s.supports_reasoning_content=o.supports_reasoning_content),typeof o.context_window=="number"&&Number.isFinite(o.context_window)&&o.context_window>0&&(s.context_window=Math.floor(o.context_window)),Object.keys(s).length>0&&(t[n]=s)}return Object.keys(t).length>0?t:void 0}function Bs(e){return e.startsWith("~")?ct(Us(),e.slice(1)):e}function Rp(e){let t=e.providers.map(c=>{let a=typeof c?.name=="string"?c.name:"";if(!a)return"";let p=[`[[providers.${Ds(a)}]]`,`name = ${JSON.stringify(a)}`,`env_api_key = ${JSON.stringify(String(c.env_api_key??""))}`,`model = ${JSON.stringify(String(c.model??""))}`];return c.base_url&&p.push(`base_url = ${JSON.stringify(String(c.base_url))}`),p.join(`
|
|
26
26
|
`)}).filter(Boolean).join(`
|
|
27
27
|
|
|
28
|
-
`),n=e.model_profiles?Object.entries(e.model_profiles).map(([c,a])=>{let l=[],p=
|
|
28
|
+
`),n=e.model_profiles?Object.entries(e.model_profiles).map(([c,a])=>{let l=[],p=Ds(c);return l.push(`[model_profiles.${p}]`),typeof a.supports_parallel_tool_calls=="boolean"&&l.push(`supports_parallel_tool_calls = ${a.supports_parallel_tool_calls}`),typeof a.supports_reasoning_content=="boolean"&&l.push(`supports_reasoning_content = ${a.supports_reasoning_content}`),typeof a.context_window=="number"&&Number.isFinite(a.context_window)&&a.context_window>0&&l.push(`context_window = ${Math.floor(a.context_window)}`),l.length>1?l.join(`
|
|
29
29
|
`):""}).filter(Boolean).join(`
|
|
30
30
|
|
|
31
31
|
`):"",r="";e.mcp_servers&&Object.keys(e.mcp_servers).length>0&&(r=Object.entries(e.mcp_servers).map(([c,a])=>{if("url"in a){let y=[`[mcp_servers.${c}]`];y.push(`type = "${a.type??"streamable_http"}"`),y.push(`url = "${a.url}"`),a.bearer_token_env_var&&y.push(`bearer_token_env_var = ${JSON.stringify(a.bearer_token_env_var)}`);let b=a.http_headers??a.headers;if(b&&Object.keys(b).length>0){let U=Object.entries(b).map(([H,R])=>`${JSON.stringify(H)} = ${JSON.stringify(R)}`).join(", "),T=a.http_headers?"http_headers":"headers";y.push(`${T} = { ${U} }`)}return y.join(`
|
|
@@ -39,46 +39,46 @@ ${u}${l}`.trimEnd(),m=a.env?Object.entries(a.env):[];if(m.length===0)return d;le
|
|
|
39
39
|
[mcp_servers.${c}.env]
|
|
40
40
|
${g}`}).join(`
|
|
41
41
|
|
|
42
|
-
`));let o=[`current_provider = "${e.current_provider}"`];Array.isArray(e.active_mcp_servers)&&o.push(`active_mcp_servers = ${JSON.stringify(e.active_mcp_servers)}`),Array.isArray(e.active_skills)&&o.push(`active_skills = ${JSON.stringify(e.active_skills)}`);let s=e.mcp_oauth_credentials_store_mode;return(s==="auto"||s==="keyring"||s==="file")&&o.push(`mcp_oauth_credentials_store_mode = ${JSON.stringify(s)}`),typeof e.mcp_oauth_callback_port=="number"&&Number.isInteger(e.mcp_oauth_callback_port)&&e.mcp_oauth_callback_port>0&&e.mcp_oauth_callback_port<=65535&&o.push(`mcp_oauth_callback_port = ${e.mcp_oauth_callback_port}`),o.push(`auto_compact_threshold_percent = ${
|
|
42
|
+
`));let o=[`current_provider = "${e.current_provider}"`];Array.isArray(e.active_mcp_servers)&&o.push(`active_mcp_servers = ${JSON.stringify(e.active_mcp_servers)}`),Array.isArray(e.active_skills)&&o.push(`active_skills = ${JSON.stringify(e.active_skills)}`);let s=e.mcp_oauth_credentials_store_mode;return(s==="auto"||s==="keyring"||s==="file")&&o.push(`mcp_oauth_credentials_store_mode = ${JSON.stringify(s)}`),typeof e.mcp_oauth_callback_port=="number"&&Number.isInteger(e.mcp_oauth_callback_port)&&e.mcp_oauth_callback_port>0&&e.mcp_oauth_callback_port<=65535&&o.push(`mcp_oauth_callback_port = ${e.mcp_oauth_callback_port}`),o.push(`auto_compact_threshold_percent = ${Hs(e.auto_compact_threshold_percent)}`),[o.join(`
|
|
43
43
|
`),t,n,r].filter(Boolean).join(`
|
|
44
44
|
|
|
45
|
-
`)}async function we(e,t){await hp(vp(e),{recursive:!0}),await yp(e,Pp(t),"utf-8")}async function ee(){let e=process.env.MEMO_HOME?Fs(process.env.MEMO_HOME):bp,t=it(e,"config.toml");try{await Sp(t);let n=await _p(t,"utf-8"),r=Cp(n),o=Mp(r.providers),s=Array.isArray(r.active_mcp_servers)?r.active_mcp_servers.filter(m=>typeof m=="string"&&m.trim().length>0):void 0,i=kp(r.active_skills),c=r.mcp_oauth_credentials_store_mode==="auto"||r.mcp_oauth_credentials_store_mode==="keyring"||r.mcp_oauth_credentials_store_mode==="file"?r.mcp_oauth_credentials_store_mode:Wt.mcp_oauth_credentials_store_mode,a=typeof r.mcp_oauth_callback_port=="number"&&Number.isInteger(r.mcp_oauth_callback_port)&&r.mcp_oauth_callback_port>0&&r.mcp_oauth_callback_port<=65535?r.mcp_oauth_callback_port:void 0,l=Us(r.auto_compact_threshold_percent),p=Ap(r.model_profiles),u={current_provider:r.current_provider??Wt.current_provider,mcp_oauth_credentials_store_mode:c,mcp_oauth_callback_port:a,auto_compact_threshold_percent:l,providers:o,model_profiles:p,mcp_servers:r.mcp_servers??{},active_mcp_servers:s,active_skills:i},d=!u.providers.length;return{config:d?Wt:u,home:e,configPath:t,needsSetup:d}}catch{return{config:Wt,home:e,configPath:t,needsSetup:!0}}}function at(e,t){let n=t||e.current_provider,r=e.providers.find(o=>o.name===n);return r||(e.providers?.[0]??Wt.providers[0])}function jt(e,t){let n=t.historyDir??it(e.home,xp),r=Fs(n),o=wp(t.cwd??process.cwd()),s=Tp(o).root,c=o.slice(s.length).split(/[\\/]+/).filter(Boolean);if(process.platform==="win32"){let l=/^([A-Za-z]):/.exec(s)?.[1];l&&c.unshift(l.toUpperCase())}if(c.length===0)return it(r,"-root");let a=`-${c.map(l=>l.replace(/[^A-Za-z0-9._-]/g,"_")).join("-")}`;return it(r,a)}function Hs(e,t){let n=new Date,r=String(n.getFullYear()),o=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),c=String(n.getMinutes()).padStart(2,"0"),a=String(n.getSeconds()).padStart(2,"0"),l=`${r}-${o}-${s}T${i}-${c}-${a}`,p=t.replace(/[^A-Za-z0-9._-]/g,"_"),u=`${l}-${p}.jsonl`;return it(e,u)}import{createHash as Ep}from"crypto";import{spawn as Rp}from"child_process";import{createServer as Ip}from"http";import{mkdir as Op,readFile as Lp,rename as Np,writeFile as $p}from"fs/promises";import{homedir as Mr}from"os";import{dirname as Dp,join as Pr}from"path";import{auth as Bs}from"@modelcontextprotocol/sdk/client/auth.js";var kr=1,Up="mcp-oauth.json",Fp=3e5,Hp=5e3,Ws="MCP-Protocol-Version",Bp="2024-11-05",Er="memo-code.mcp.oauth",Wp=33333;function jp(e){return{client_name:"Memo Code CLI",redirect_uris:[e],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"}}function js(e){return e instanceof Error?e.message:String(e)}function Rr(e){return new URL(e).toString()}function Ir(e){return e==="file"||e==="keyring"||e==="auto"?e:"auto"}function zs(e){return e==="~"?Mr():e.startsWith("~/")?Pr(Mr(),e.slice(2)):e}function zp(e){return e?.memoHome?.trim()?zs(e.memoHome.trim()):process.env.MEMO_HOME?.trim()?zs(process.env.MEMO_HOME.trim()):Pr(Mr(),".memo")}function Xs(e){return Pr(zp(e),"auth",Up)}function St(e){return Ep("sha256").update(Rr(e)).digest("hex")}function Gs(){return{version:kr,credentials:{}}}async function Or(e){let t=Xs(e);try{let n=await Lp(t,"utf8"),r=JSON.parse(n);return r.version!==kr||!r.credentials?Gs():{version:kr,credentials:r.credentials}}catch{return Gs()}}async function Js(e,t){let n=Xs(e),r=`${n}.tmp`;await Op(Dp(n),{recursive:!0}),await $p(r,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),await Np(r,n)}var vn=null;async function Lr(){return vn||(vn=(async()=>{try{let t=await new Function("specifier","return import(specifier)")("keytar"),n=t.default??t;return n&&typeof n.getPassword=="function"&&typeof n.setPassword=="function"&&typeof n.deletePassword=="function"?n:null}catch{return null}})(),vn)}async function br(e,t){let n=St(e);return(await Or(t)).credentials[n]?.credential}async function xr(e,t,n){let r=St(e),o=await Or(n);o.credentials[r]={url:Rr(e),updatedAt:Date.now(),credential:t},await Js(n,o)}async function Ar(e,t){let n=St(e),r=await Or(t);return r.credentials[n]?(delete r.credentials[n],await Js(t,r),!0):!1}async function Ks(e,t){let n=St(t),r=await e.getPassword(Er,n);return r?JSON.parse(r).credential:void 0}async function qs(e,t,n){let r=St(t),o={url:Rr(t),updatedAt:Date.now(),credential:n};await e.setPassword(Er,r,JSON.stringify(o))}async function Vs(e,t){let n=St(t);return e.deletePassword(Er,n)}function Gp(e,t){return new URL(e).origin===t.origin}function Ys(e){return{...e.http_headers??e.headers??{}}}function Kp(e){let t=e.replace(/^\/+|\/+$/g,"");if(!t)return["/.well-known/oauth-authorization-server"];let n=[],r=o=>{n.includes(o)||n.push(o)};return r(`/.well-known/oauth-authorization-server/${t}`),r(`/${t}/.well-known/oauth-authorization-server`),r("/.well-known/oauth-authorization-server"),n}function qp(e){if(!e||e.length===0)return;let t=e.flatMap(n=>n.split(/[,\s]+/g)).map(n=>n.trim()).filter(Boolean);if(t.length!==0)return t.join(" ")}function Qs(e){if(e!==void 0){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error(`Invalid MCP OAuth callback port "${e}". Use an integer between 1 and 65535.`);return e}}function Vp(e){return process.platform==="darwin"?{command:"open",args:[e]}:process.platform==="win32"?{command:"cmd",args:["/c","start","",e]}:{command:"xdg-open",args:[e]}}async function Xp(e){let{command:t,args:n}=Vp(e);await new Promise((r,o)=>{let s=Rp(t,n,{detached:!0,stdio:"ignore"}),i=!1,c=p=>{if(!i){if(i=!0,s.off("error",a),s.off("spawn",l),p){o(p);return}r()}},a=p=>{c(p)},l=()=>{c()};s.on("error",a),s.on("spawn",l),s.unref()})}function Zs(e,t){return async(n,r)=>{let o=typeof n=="string"||n instanceof URL?new URL(String(n),e):new URL(n.url),s=new Headers(r?.headers??{});if(Gp(e,o)){for(let[i,c]of Object.entries(t))s.has(i)||s.set(i,c);s.has(Ws)||s.set(Ws,Bp)}return fetch(o,{...r,headers:s})}}async function ei(e,t){let n=new URL(e),r=Zs(e,t),o=Kp(n.pathname);for(let s of o){let i=new URL(n.toString());i.pathname=s,i.search="",i.hash="";let c=new AbortController,a=setTimeout(()=>c.abort(),Hp);try{let l=await r(i,{method:"GET",signal:c.signal});if(!l.ok)continue;let p=await l.json();if(typeof p.authorization_endpoint=="string"&&typeof p.token_endpoint=="string")return!0}catch{continue}finally{clearTimeout(a)}}return!1}var Tn=class{constructor(t,n,r,o,s){this.serverUrl=t;this.settings=n;this.redirectUrlValue=r;this.handleRedirect=o;this.clientMetadata=jp(r),s&&(this.credential=s,this.loaded=!0)}loaded=!1;credential={};verifier=null;clientMetadata;get redirectUrl(){return this.redirectUrlValue}async ensureLoaded(){if(this.loaded)return;let t=await wn(this.serverUrl,this.settings);this.credential=t.credential??{},this.loaded=!0}async persist(){await Jp(this.serverUrl,this.credential,this.settings)}async clientInformation(){return await this.ensureLoaded(),this.credential.clientInformation}async saveClientInformation(t){await this.ensureLoaded(),this.credential={...this.credential,clientInformation:t},await this.persist()}async tokens(){return await this.ensureLoaded(),this.credential.tokens}async saveTokens(t){await this.ensureLoaded(),this.credential={...this.credential,tokens:t},await this.persist()}async redirectToAuthorization(t){await this.handleRedirect(t)}saveCodeVerifier(t){this.verifier=t}codeVerifier(){if(!this.verifier)throw new Error("OAuth code verifier is missing.");return this.verifier}async invalidateCredentials(t){if(await this.ensureLoaded(),t==="all")this.credential={};else if(t==="client")this.credential={...this.credential,clientInformation:void 0};else if(t==="tokens")this.credential={...this.credential,tokens:void 0};else if(t==="verifier"){this.verifier=null;return}await this.persist()}};async function wn(e,t){let n=Ir(t?.storeMode);if(n==="file")return{backend:"file",credential:await br(e,t)};let r=await Lr();if(n==="keyring"){if(!r)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return{backend:"keyring",credential:await Ks(r,e)}}if(!r)return{backend:"file",credential:await br(e,t)};try{let o=await Ks(r,e);if(o)return{backend:"keyring",credential:o}}catch{}return{backend:"file",credential:await br(e,t)}}async function Jp(e,t,n){let r=Ir(n?.storeMode);if(r==="file")return await xr(e,t,n),{backend:"file"};let o=await Lr();if(r==="keyring"){if(!o)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return await qs(o,e,t),{backend:"keyring"}}if(!o)return await xr(e,t,n),{backend:"file"};try{return await qs(o,e,t),await Ar(e,n).catch(()=>{}),{backend:"keyring"}}catch{return await xr(e,t,n),{backend:"file"}}}async function Yp(e,t){let n=Ir(t?.storeMode);if(n==="file")return{backend:"file",removed:await Ar(e,t)};let r=await Lr();if(n==="keyring"){if(!r)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return{backend:"keyring",removed:await Vs(r,e)}}let o=!1;if(r)try{o=await Vs(r,e)}catch{o=!1}let s=await Ar(e,t);return{backend:o?"keyring":"file",removed:o||s}}async function Nr(e,t){return"url"in e?e.bearer_token_env_var?"bearer_token":(await wn(e.url,t)).credential?.tokens?.access_token?"oauth":await ei(e.url,Ys(e))?"not_logged_in":"unsupported":"unsupported"}async function Qp(e,t){let n=Qs(e),r="127.0.0.1",o=!1,s=null,i=null,c=null,a=new Promise((d,m)=>{i=d,c=m}),l=Ip((d,m)=>{let g=new URL(d.url??"/",`http://${r}`);if(g.pathname!=="/callback"){m.writeHead(404,{"Content-Type":"text/plain"}),m.end("Not found");return}let y=g.searchParams.get("code"),b=g.searchParams.get("error"),U=g.searchParams.get("error_description");if(y){m.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),m.end("<html><body><h1>Authentication complete.</h1><p>You can close this window.</p></body></html>"),i?.(y);return}let T=U??b??"OAuth callback missing code.";m.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),m.end(`<html><body><h1>Authentication failed.</h1><p>${T}</p></body></html>`),c?.(new Error(T))});await new Promise((d,m)=>{l.once("error",m),l.listen(n??0,r,()=>{l.off("error",m),d()})});let p=l.address();if(!p||typeof p=="string")throw await new Promise(d=>l.close(()=>d())),new Error("Failed to resolve OAuth callback listener address.");s=setTimeout(()=>{c?.(new Error("Timed out waiting for OAuth callback."))},t),s.unref?.();let u=async()=>{o||(o=!0,s&&(clearTimeout(s),s=null),await new Promise(d=>l.close(()=>d())))};return{redirectUrl:`http://${r}:${p.port}/callback`,waitForCode:async()=>{try{return await a}finally{await u()}},close:u}}async function $r(e){if(e.config.bearer_token_env_var)throw new Error(`Server "${e.serverName}" is configured with bearer_token_env_var. Remove it to use OAuth login.`);let t=Ys(e.config);if(!await ei(e.config.url,t))throw new Error(`Server "${e.serverName}" does not advertise OAuth support. Configure --bearer-token-env-var instead.`);let r=await Qp(e.settings?.callbackPort,e.timeoutMs??Fp),o=Zs(e.config.url,t),s=new Tn(e.config.url,e.settings,r.redirectUrl,async i=>{let c=i.toString();e.onAuthorizationUrl?.(c);try{await Xp(c)}catch(a){e.onBrowserOpenFailure?.(new Error(js(a)),i.toString())}});try{let i=qp(e.scopes);if(await Bs(s,{serverUrl:e.config.url,scope:i,fetchFn:o})==="REDIRECT"){let l=await r.waitForCode();if(await Bs(s,{serverUrl:e.config.url,authorizationCode:l,scope:i,fetchFn:o})!=="AUTHORIZED")throw new Error("OAuth authorization did not complete.")}let a=await wn(e.config.url,e.settings);if(!a.credential?.tokens?.access_token)throw new Error("OAuth login completed but no access token was stored.");return{backend:a.backend}}catch(i){throw new Error(`OAuth login failed: ${js(i)}`)}finally{await r.close()}}async function Dr(e){return Yp(e.config.url,e.settings)}async function ti(e){if(e.config.bearer_token_env_var)return null;let t=await wn(e.config.url,e.settings);if(!t.credential?.tokens?.access_token)return null;let r=`http://127.0.0.1:${Qs(e.settings?.callbackPort)??Wp}/callback`;return new Tn(e.config.url,e.settings,r,async()=>{throw new Error(`MCP server "${e.serverName}" requires OAuth login. Run: memo mcp login ${e.serverName}`)},t.credential)}import{access as qS,mkdir as VS,readFile as XS,readdir as JS,rm as YS,writeFile as QS}from"fs/promises";import{homedir as ev}from"os";import{basename as nv,dirname as rv,join as ov,resolve as sv}from"path";import{z as He}from"zod";function D(e){let{inputSchema:t,execute:n,...r}=e,o=t.toJSONSchema?.(),{$schema:s,...i}=o??{};return{...r,source:"native",inputSchema:i,validateInput:c=>{let a=t.safeParse(c);if(!a.success){let l=a.error.issues[0]?.message??"invalid input";return{ok:!1,error:`${e.name} invalid input: ${l}`}}return{ok:!0,data:a.data}},execute:n}}function h(e,t=!1){return{content:[{type:"text",text:e}],isError:t}}import{spawn as wd}from"child_process";import{EventEmitter as Cd}from"events";import{resolve as bd}from"path";import{posix as Zp}from"path";var ni=220,ri=4096,ed=/^\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)$/i,td=/(?:^|[\s(])(?:\d?>>?|>>|>\||&>)\s*\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)(?:\s|$)/i,nd=new Set(["-u","--user","-g","--group","-h","--host","-p","--prompt","-C","-T","-r","--role","-t","--type","-D","--chdir"]),rd=new Set(["fdisk","sfdisk","cfdisk","parted","sgdisk","gdisk","wipefs","blkdiscard","shred"]);function Ur(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function od(e){let t=e.replace(/\s+/g," ").trim();return t.length>ni?`${t.slice(0,ni)}\u2026`:t}function oi(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return(t.split(/[\\/]/).at(-1)??t).toLowerCase()}function sd(e){let t=null,n=!1;for(let r=0;r<e.length;r+=1){let o=e[r];if(n){n=!1;continue}if(o==="\\"&&t!=="'"){n=!0;continue}if(t){o===t&&(t=null);continue}if(o==='"'||o==="'"){t=o;continue}if(o==="#")return e.slice(0,r)}return e}function id(e){let t=[],n="",r=null,o=!1,s=()=>{let i=sd(n).trim();i&&t.push(i),n=""};for(let i=0;i<e.length;i+=1){let c=e[i];if(o){n+=c,o=!1;continue}if(c==="\\"&&r!=="'"){n+=c,o=!0;continue}if(r){n+=c,c===r&&(r=null);continue}if(c==='"'||c==="'"){r=c,n+=c;continue}if(c===";"||c===`
|
|
46
|
-
`){s();continue}if(c==="&"){e[i+1]==="&"&&(i+=1),s();continue}if(c==="|"){e[i+1]==="|"&&(i+=1),s();continue}n+=c}return s(),t}function
|
|
45
|
+
`)}async function we(e,t){await _p(wp(e),{recursive:!0}),await Sp(e,Rp(t),"utf-8")}async function te(){let e=process.env.MEMO_HOME?Bs(process.env.MEMO_HOME):Mp,t=ct(e,"config.toml");try{await Tp(t);let n=await vp(t,"utf-8"),r=xp(n),o=Ap(r.providers),s=Array.isArray(r.active_mcp_servers)?r.active_mcp_servers.filter(m=>typeof m=="string"&&m.trim().length>0):void 0,i=Pp(r.active_skills),c=r.mcp_oauth_credentials_store_mode==="auto"||r.mcp_oauth_credentials_store_mode==="keyring"||r.mcp_oauth_credentials_store_mode==="file"?r.mcp_oauth_credentials_store_mode:zt.mcp_oauth_credentials_store_mode,a=typeof r.mcp_oauth_callback_port=="number"&&Number.isInteger(r.mcp_oauth_callback_port)&&r.mcp_oauth_callback_port>0&&r.mcp_oauth_callback_port<=65535?r.mcp_oauth_callback_port:void 0,l=Hs(r.auto_compact_threshold_percent),p=Ep(r.model_profiles),u={current_provider:r.current_provider??zt.current_provider,mcp_oauth_credentials_store_mode:c,mcp_oauth_callback_port:a,auto_compact_threshold_percent:l,providers:o,model_profiles:p,mcp_servers:r.mcp_servers??{},active_mcp_servers:s,active_skills:i},d=!u.providers.length;return{config:d?zt:u,home:e,configPath:t,needsSetup:d}}catch{return{config:zt,home:e,configPath:t,needsSetup:!0}}}function lt(e,t){let n=t||e.current_provider,r=e.providers.find(o=>o.name===n);return r||(e.providers?.[0]??zt.providers[0])}function Gt(e,t){let n=t.historyDir??ct(e.home,kp),r=Bs(n),o=bp(t.cwd??process.cwd()),s=Cp(o).root,c=o.slice(s.length).split(/[\\/]+/).filter(Boolean);if(process.platform==="win32"){let l=/^([A-Za-z]):/.exec(s)?.[1];l&&c.unshift(l.toUpperCase())}if(c.length===0)return ct(r,"-root");let a=`-${c.map(l=>l.replace(/[^A-Za-z0-9._-]/g,"_")).join("-")}`;return ct(r,a)}function Ws(e,t){let n=new Date,r=String(n.getFullYear()),o=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),c=String(n.getMinutes()).padStart(2,"0"),a=String(n.getSeconds()).padStart(2,"0"),l=`${r}-${o}-${s}T${i}-${c}-${a}`,p=t.replace(/[^A-Za-z0-9._-]/g,"_"),u=`${l}-${p}.jsonl`;return ct(e,u)}import{createHash as Ip}from"crypto";import{spawn as Op}from"child_process";import{createServer as Lp}from"http";import{mkdir as Np,readFile as $p,rename as Dp,writeFile as Up}from"fs/promises";import{homedir as Pr}from"os";import{dirname as Fp,join as Ir}from"path";import{auth as js}from"@modelcontextprotocol/sdk/client/auth.js";var Er=1,Hp="mcp-oauth.json",Bp=3e5,Wp=5e3,zs="MCP-Protocol-Version",jp="2024-11-05",Or="memo-code.mcp.oauth",zp=33333;function Gp(e){return{client_name:"Memo Code CLI",redirect_uris:[e],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"}}function Gs(e){return e instanceof Error?e.message:String(e)}function Lr(e){return new URL(e).toString()}function Nr(e){return e==="file"||e==="keyring"||e==="auto"?e:"auto"}function Ks(e){return e==="~"?Pr():e.startsWith("~/")?Ir(Pr(),e.slice(2)):e}function Kp(e){return e?.memoHome?.trim()?Ks(e.memoHome.trim()):process.env.MEMO_HOME?.trim()?Ks(process.env.MEMO_HOME.trim()):Ir(Pr(),".memo")}function Ys(e){return Ir(Kp(e),"auth",Hp)}function Tt(e){return Ip("sha256").update(Lr(e)).digest("hex")}function qs(){return{version:Er,credentials:{}}}async function $r(e){let t=Ys(e);try{let n=await $p(t,"utf8"),r=JSON.parse(n);return r.version!==Er||!r.credentials?qs():{version:Er,credentials:r.credentials}}catch{return qs()}}async function Qs(e,t){let n=Ys(e),r=`${n}.tmp`;await Np(Fp(n),{recursive:!0}),await Up(r,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),await Dp(r,n)}var Cn=null;async function Dr(){return Cn||(Cn=(async()=>{try{let t=await new Function("specifier","return import(specifier)")("keytar"),n=t.default??t;return n&&typeof n.getPassword=="function"&&typeof n.setPassword=="function"&&typeof n.deletePassword=="function"?n:null}catch{return null}})(),Cn)}async function kr(e,t){let n=Tt(e);return(await $r(t)).credentials[n]?.credential}async function Ar(e,t,n){let r=Tt(e),o=await $r(n);o.credentials[r]={url:Lr(e),updatedAt:Date.now(),credential:t},await Qs(n,o)}async function Rr(e,t){let n=Tt(e),r=await $r(t);return r.credentials[n]?(delete r.credentials[n],await Qs(t,r),!0):!1}async function Vs(e,t){let n=Tt(t),r=await e.getPassword(Or,n);return r?JSON.parse(r).credential:void 0}async function Xs(e,t,n){let r=Tt(t),o={url:Lr(t),updatedAt:Date.now(),credential:n};await e.setPassword(Or,r,JSON.stringify(o))}async function Js(e,t){let n=Tt(t);return e.deletePassword(Or,n)}function qp(e,t){return new URL(e).origin===t.origin}function Zs(e){return{...e.http_headers??e.headers??{}}}function Vp(e){let t=e.replace(/^\/+|\/+$/g,"");if(!t)return["/.well-known/oauth-authorization-server"];let n=[],r=o=>{n.includes(o)||n.push(o)};return r(`/.well-known/oauth-authorization-server/${t}`),r(`/${t}/.well-known/oauth-authorization-server`),r("/.well-known/oauth-authorization-server"),n}function Xp(e){if(!e||e.length===0)return;let t=e.flatMap(n=>n.split(/[,\s]+/g)).map(n=>n.trim()).filter(Boolean);if(t.length!==0)return t.join(" ")}function ei(e){if(e!==void 0){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error(`Invalid MCP OAuth callback port "${e}". Use an integer between 1 and 65535.`);return e}}function Jp(e){return process.platform==="darwin"?{command:"open",args:[e]}:process.platform==="win32"?{command:"cmd",args:["/c","start","",e]}:{command:"xdg-open",args:[e]}}async function Yp(e){let{command:t,args:n}=Jp(e);await new Promise((r,o)=>{let s=Op(t,n,{detached:!0,stdio:"ignore"}),i=!1,c=p=>{if(!i){if(i=!0,s.off("error",a),s.off("spawn",l),p){o(p);return}r()}},a=p=>{c(p)},l=()=>{c()};s.on("error",a),s.on("spawn",l),s.unref()})}function ti(e,t){return async(n,r)=>{let o=typeof n=="string"||n instanceof URL?new URL(String(n),e):new URL(n.url),s=new Headers(r?.headers??{});if(qp(e,o)){for(let[i,c]of Object.entries(t))s.has(i)||s.set(i,c);s.has(zs)||s.set(zs,jp)}return fetch(o,{...r,headers:s})}}async function ni(e,t){let n=new URL(e),r=ti(e,t),o=Vp(n.pathname);for(let s of o){let i=new URL(n.toString());i.pathname=s,i.search="",i.hash="";let c=new AbortController,a=setTimeout(()=>c.abort(),Wp);try{let l=await r(i,{method:"GET",signal:c.signal});if(!l.ok)continue;let p=await l.json();if(typeof p.authorization_endpoint=="string"&&typeof p.token_endpoint=="string")return!0}catch{continue}finally{clearTimeout(a)}}return!1}var bn=class{constructor(t,n,r,o,s){this.serverUrl=t;this.settings=n;this.redirectUrlValue=r;this.handleRedirect=o;this.clientMetadata=Gp(r),s&&(this.credential=s,this.loaded=!0)}loaded=!1;credential={};verifier=null;clientMetadata;get redirectUrl(){return this.redirectUrlValue}async ensureLoaded(){if(this.loaded)return;let t=await xn(this.serverUrl,this.settings);this.credential=t.credential??{},this.loaded=!0}async persist(){await Qp(this.serverUrl,this.credential,this.settings)}async clientInformation(){return await this.ensureLoaded(),this.credential.clientInformation}async saveClientInformation(t){await this.ensureLoaded(),this.credential={...this.credential,clientInformation:t},await this.persist()}async tokens(){return await this.ensureLoaded(),this.credential.tokens}async saveTokens(t){await this.ensureLoaded(),this.credential={...this.credential,tokens:t},await this.persist()}async redirectToAuthorization(t){await this.handleRedirect(t)}saveCodeVerifier(t){this.verifier=t}codeVerifier(){if(!this.verifier)throw new Error("OAuth code verifier is missing.");return this.verifier}async invalidateCredentials(t){if(await this.ensureLoaded(),t==="all")this.credential={};else if(t==="client")this.credential={...this.credential,clientInformation:void 0};else if(t==="tokens")this.credential={...this.credential,tokens:void 0};else if(t==="verifier"){this.verifier=null;return}await this.persist()}};async function xn(e,t){let n=Nr(t?.storeMode);if(n==="file")return{backend:"file",credential:await kr(e,t)};let r=await Dr();if(n==="keyring"){if(!r)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return{backend:"keyring",credential:await Vs(r,e)}}if(!r)return{backend:"file",credential:await kr(e,t)};try{let o=await Vs(r,e);if(o)return{backend:"keyring",credential:o}}catch{}return{backend:"file",credential:await kr(e,t)}}async function Qp(e,t,n){let r=Nr(n?.storeMode);if(r==="file")return await Ar(e,t,n),{backend:"file"};let o=await Dr();if(r==="keyring"){if(!o)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return await Xs(o,e,t),{backend:"keyring"}}if(!o)return await Ar(e,t,n),{backend:"file"};try{return await Xs(o,e,t),await Rr(e,n).catch(()=>{}),{backend:"keyring"}}catch{return await Ar(e,t,n),{backend:"file"}}}async function Zp(e,t){let n=Nr(t?.storeMode);if(n==="file")return{backend:"file",removed:await Rr(e,t)};let r=await Dr();if(n==="keyring"){if(!r)throw new Error('Keyring storage is not available. Set mcp_oauth_credentials_store_mode = "file".');return{backend:"keyring",removed:await Js(r,e)}}let o=!1;if(r)try{o=await Js(r,e)}catch{o=!1}let s=await Rr(e,t);return{backend:o?"keyring":"file",removed:o||s}}async function Ur(e,t){return"url"in e?e.bearer_token_env_var?"bearer_token":(await xn(e.url,t)).credential?.tokens?.access_token?"oauth":await ni(e.url,Zs(e))?"not_logged_in":"unsupported":"unsupported"}async function ed(e,t){let n=ei(e),r="127.0.0.1",o=!1,s=null,i=null,c=null,a=new Promise((d,m)=>{i=d,c=m}),l=Lp((d,m)=>{let g=new URL(d.url??"/",`http://${r}`);if(g.pathname!=="/callback"){m.writeHead(404,{"Content-Type":"text/plain"}),m.end("Not found");return}let y=g.searchParams.get("code"),b=g.searchParams.get("error"),U=g.searchParams.get("error_description");if(y){m.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),m.end("<html><body><h1>Authentication complete.</h1><p>You can close this window.</p></body></html>"),i?.(y);return}let T=U??b??"OAuth callback missing code.";m.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),m.end(`<html><body><h1>Authentication failed.</h1><p>${T}</p></body></html>`),c?.(new Error(T))});await new Promise((d,m)=>{l.once("error",m),l.listen(n??0,r,()=>{l.off("error",m),d()})});let p=l.address();if(!p||typeof p=="string")throw await new Promise(d=>l.close(()=>d())),new Error("Failed to resolve OAuth callback listener address.");s=setTimeout(()=>{c?.(new Error("Timed out waiting for OAuth callback."))},t),s.unref?.();let u=async()=>{o||(o=!0,s&&(clearTimeout(s),s=null),await new Promise(d=>l.close(()=>d())))};return{redirectUrl:`http://${r}:${p.port}/callback`,waitForCode:async()=>{try{return await a}finally{await u()}},close:u}}async function Fr(e){if(e.config.bearer_token_env_var)throw new Error(`Server "${e.serverName}" is configured with bearer_token_env_var. Remove it to use OAuth login.`);let t=Zs(e.config);if(!await ni(e.config.url,t))throw new Error(`Server "${e.serverName}" does not advertise OAuth support. Configure --bearer-token-env-var instead.`);let r=await ed(e.settings?.callbackPort,e.timeoutMs??Bp),o=ti(e.config.url,t),s=new bn(e.config.url,e.settings,r.redirectUrl,async i=>{let c=i.toString();e.onAuthorizationUrl?.(c);try{await Yp(c)}catch(a){e.onBrowserOpenFailure?.(new Error(Gs(a)),i.toString())}});try{let i=Xp(e.scopes);if(await js(s,{serverUrl:e.config.url,scope:i,fetchFn:o})==="REDIRECT"){let l=await r.waitForCode();if(await js(s,{serverUrl:e.config.url,authorizationCode:l,scope:i,fetchFn:o})!=="AUTHORIZED")throw new Error("OAuth authorization did not complete.")}let a=await xn(e.config.url,e.settings);if(!a.credential?.tokens?.access_token)throw new Error("OAuth login completed but no access token was stored.");return{backend:a.backend}}catch(i){throw new Error(`OAuth login failed: ${Gs(i)}`)}finally{await r.close()}}async function Hr(e){return Zp(e.config.url,e.settings)}async function ri(e){if(e.config.bearer_token_env_var)return null;let t=await xn(e.config.url,e.settings);if(!t.credential?.tokens?.access_token)return null;let r=`http://127.0.0.1:${ei(e.settings?.callbackPort)??zp}/callback`;return new bn(e.config.url,e.settings,r,async()=>{throw new Error(`MCP server "${e.serverName}" requires OAuth login. Run: memo mcp login ${e.serverName}`)},t.credential)}import{access as QS,mkdir as ZS,readFile as ev,readdir as tv,rm as nv,writeFile as rv}from"fs/promises";import{homedir as sv}from"os";import{basename as av,dirname as cv,join as lv,resolve as uv}from"path";import{z as Be}from"zod";function D(e){let{inputSchema:t,execute:n,...r}=e,o=t.toJSONSchema?.(),{$schema:s,...i}=o??{};return{...r,source:"native",inputSchema:i,validateInput:c=>{let a=t.safeParse(c);if(!a.success){let l=a.error.issues[0]?.message??"invalid input";return{ok:!1,error:`${e.name} invalid input: ${l}`}}return{ok:!0,data:a.data}},execute:n}}function h(e,t=!1){return{content:[{type:"text",text:e}],isError:t}}import{spawn as bd}from"child_process";import{EventEmitter as xd}from"events";import{resolve as Md}from"path";import{posix as td}from"path";var oi=220,si=4096,nd=/^\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)$/i,rd=/(?:^|[\s(])(?:\d?>>?|>>|>\||&>)\s*\/dev\/(?:sd[a-z]\d*|vd[a-z]\d*|xvd[a-z]\d*|hd[a-z]\d*|nvme\d+n\d+(?:p\d+)?|mmcblk\d+(?:p\d+)?|disk\d+|rdisk\d+)(?:\s|$)/i,od=new Set(["-u","--user","-g","--group","-h","--host","-p","--prompt","-C","-T","-r","--role","-t","--type","-D","--chdir"]),sd=new Set(["fdisk","sfdisk","cfdisk","parted","sgdisk","gdisk","wipefs","blkdiscard","shred"]);function Br(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function id(e){let t=e.replace(/\s+/g," ").trim();return t.length>oi?`${t.slice(0,oi)}\u2026`:t}function ii(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return(t.split(/[\\/]/).at(-1)??t).toLowerCase()}function ad(e){let t=null,n=!1;for(let r=0;r<e.length;r+=1){let o=e[r];if(n){n=!1;continue}if(o==="\\"&&t!=="'"){n=!0;continue}if(t){o===t&&(t=null);continue}if(o==='"'||o==="'"){t=o;continue}if(o==="#")return e.slice(0,r)}return e}function cd(e){let t=[],n="",r=null,o=!1,s=()=>{let i=ad(n).trim();i&&t.push(i),n=""};for(let i=0;i<e.length;i+=1){let c=e[i];if(o){n+=c,o=!1;continue}if(c==="\\"&&r!=="'"){n+=c,o=!0;continue}if(r){n+=c,c===r&&(r=null);continue}if(c==='"'||c==="'"){r=c,n+=c;continue}if(c===";"||c===`
|
|
46
|
+
`){s();continue}if(c==="&"){e[i+1]==="&"&&(i+=1),s();continue}if(c==="|"){e[i+1]==="|"&&(i+=1),s();continue}n+=c}return s(),t}function ld(e){let t=[],n="",r=null,o=!1,s=()=>{n&&t.push(n),n=""};for(let i=0;i<e.length;i+=1){let c=e[i];if(o){n+=c,o=!1;continue}if(c==="\\"&&r!=="'"){o=!0;continue}if(r){c===r?r=null:n+=c;continue}if(c==='"'||c==="'"){r=c;continue}if(/\s/.test(c)){s();continue}n+=c}return s(),t}function ai(e){return/^[A-Za-z_][A-Za-z0-9_]*=.*/.test(e)}function ud(e,t){let n=t;for(;n<e.length;){let r=ii(e[n]??"");if(r==="sudo"){for(n+=1;n<e.length;){let o=e[n]??"";if(!o.startsWith("-"))break;n+=1,od.has(o)&&n<e.length&&(n+=1)}continue}if(r==="env"){for(n+=1;n<e.length;){let o=e[n]??"";if(o.startsWith("-")||ai(o)){n+=1;continue}break}continue}if(r==="command"||r==="nohup"||r==="time"){n+=1;continue}break}return n}function pd(e){let t=ld(e);if(t.length===0)return null;let n=0;for(;n<t.length&&ai(t[n]??"");)n+=1;if(n=ud(t,n),n>=t.length)return null;let r=ii(t[n]??"");return r?{raw:e,commandName:r,args:t.slice(n+1)}:null}function Wr(e){let t=e.trim().replace(/^['"]|['"]$/g,"");return nd.test(t)}function dd(e){let t=e.trim().replace(/^['"]|['"]$/g,""),n=t.toLowerCase();return n==="/"||n==="/*"||n==="/.*"||n==="~"||n==="~/"||n==="~/*"||n==="$home"||n==="$home/"||n==="$home/*"||n==="${home}"||n==="${home}/"||n==="${home}/*"?!0:t.startsWith("/")&&!/[*?[\]{}$]/.test(t)?td.normalize(t)==="/":!1}function md(e){return e.startsWith("-")&&e!=="-"}function fd(e){if(e.commandName!=="rm")return null;let t=!1,n=0;for(;n<e.args.length;){let o=e.args[n]??"";if(o==="--"){n+=1;break}if(!md(o))break;if(o==="--recursive"){t=!0,n+=1;continue}if(o.startsWith("--")){n+=1;continue}let s=o.slice(1);(s.includes("r")||s.includes("R"))&&(t=!0),n+=1}if(!t)return null;let r=e.args.slice(n);for(let o of r)if(dd(o))return{ruleId:"rm_recursive_critical_target",matchedSegment:e.raw};return null}function gd(e){return e.commandName==="mkfs"||e.commandName.startsWith("mkfs.")?{ruleId:"mkfs_filesystem_create",matchedSegment:e.raw}:null}function hd(e){if(e.commandName!=="dd")return null;for(let t=0;t<e.args.length;t+=1){let n=e.args[t]??"",r=n.indexOf("=");if(r<=0)continue;let o=n.slice(0,r).toLowerCase(),s=n.slice(r+1);if(o==="of"&&Wr(s))return{ruleId:"dd_write_block_device",matchedSegment:e.raw}}for(let t=0;t<e.args.length-1;t+=1){let n=(e.args[t]??"").toLowerCase(),r=e.args[t+1]??"";if(n==="of"&&Wr(r))return{ruleId:"dd_write_block_device",matchedSegment:e.raw}}return null}function yd(e){return!sd.has(e.commandName)||!e.args.some(t=>Wr(t))?null:{ruleId:"disk_mutation_block_device",matchedSegment:e.raw}}function _d(e){return rd.test(e)?{ruleId:"redirect_block_device",matchedSegment:e}:null}function Sd(e){for(let t of cd(e)){let n=pd(t);if(n){let o=fd(n);if(o)return o;let s=gd(n);if(s)return s;let i=hd(n);if(i)return i;let c=yd(n);if(c)return c}let r=_d(t);if(r)return r}return null}function vd(e,t){let n=id(e.command),r=typeof e.sessionId=="number"?` session_id="${e.sessionId}"`:"";return`<system_hint type="tool_call_denied" tool="${Br(e.toolName)}" reason="dangerous_command" policy="blacklist" rule="${Br(t.ruleId)}"${r} command="${Br(n)}">Blocked a high-risk shell command to prevent irreversible data loss. Use a safer and scoped alternative.</system_hint>`}function jr(e){let t=Sd(e.command);return t?{blocked:!0,xml:vd(e,t),match:t}:{blocked:!1}}function ci(e){let n=e.replace(/\r\n/g,`
|
|
47
47
|
`).replace(/\r/g,`
|
|
48
48
|
`).split(`
|
|
49
|
-
`),r=n.pop()??"";return{completedLines:n,remainder:r}}function
|
|
50
|
-
`)}function
|
|
51
|
-
[exec error] ${y.message}`,p.eventBus.emit("output")}),l.on("close",y=>{p.exited=!0,p.exitCode=typeof y=="number"?y:-1,p.eventBus.emit("exit")}),this.sessions.set(o,p),this.cleanupSessions();let d=typeof t.execution_timeout_ms=="number"&&t.execution_timeout_ms>0?Math.floor(t.execution_timeout_ms):null,m=
|
|
49
|
+
`),r=n.pop()??"";return{completedLines:n,remainder:r}}function zr(e){return e.length<=si?e:e.slice(-si)}import{AsyncLocalStorage as Td}from"async_hooks";import{resolve as wd}from"path";var li=new Td;function ui(e){if(!(!e||!e.trim()))return wd(e)}function Cd(){return li.getStore()??{}}function He(e=process.cwd()){return ui(Cd().cwd)??e}async function pi(e,t){let n={cwd:ui(e.cwd)};return new Promise((r,o)=>{li.run(n,()=>{Promise.resolve(t()).then(r,o)})})}var kd=1e4,Ad=250,Pd=2e3,Mn=64;function Ed(e){return Math.ceil(e.length/4)}function Rd(){return Math.random().toString(16).slice(2)||String(Date.now())}function Id(e){let t=e.login,n=e.shell?.trim();if(process.platform==="win32"){let o=n||"powershell.exe";return o.toLowerCase().includes("powershell")?{file:o,args:["-NoProfile","-Command",e.cmd]}:{file:o,args:[t?"-lc":"-c",e.cmd]}}return{file:n||process.env.SHELL||"/bin/bash",args:[t?"-lc":"-c",e.cmd]}}function Od(e,t){let r=(typeof t=="number"&&t>0?Math.floor(t):Pd)*4,o=Ed(e);return e.length<=r?{output:e,originalTokenCount:o,deliveredChars:e.length}:{output:e.slice(0,r),originalTokenCount:o,deliveredChars:r}}function Ld(e){let t=[];return t.push(`Chunk ID: ${e.chunkId}`),t.push(`Wall time: ${e.wallTimeSeconds.toFixed(4)} seconds`),e.exitCode!==null?t.push(`Process exited with code ${e.exitCode}`):t.push(`Process running with session ID ${e.sessionId}`),t.push(`Original token count: ${e.originalTokenCount}`),t.push("Output:"),t.push(e.output),t.join(`
|
|
50
|
+
`)}function di(e,t){return typeof e!="number"||Number.isNaN(e)?t:e<0?0:Math.floor(e)}async function mi(e,t){t<=0||e.exited||await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(c),i(),n())},s=()=>{o()},i=()=>{e.eventBus.off("exit",s)},c=setTimeout(()=>{o()},t);c.unref?.(),e.eventBus.on("exit",s)})}async function fi(e,t){e.exited||t<=0||await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(c),i(),n())},s=()=>{o()},i=()=>{e.eventBus.off("exit",s)},c=setTimeout(()=>{o()},t);c.unref?.(),e.eventBus.on("exit",s)})}var Gr=class{sessions=new Map;nextId=1;cleanupSessions(){if(this.sessions.size<=Mn)return;let t=Array.from(this.sessions.values()).filter(n=>n.exited).sort((n,r)=>n.startedAtMs-r.startedAtMs);for(let n of t){if(this.sessions.size<=Mn)break;this.sessions.delete(n.id)}}activeSessionCount(){let t=0;for(let n of this.sessions.values())n.exited||(t+=1);return t}async terminateForTimeout(t){if(!t.exited){try{t.proc.kill("SIGTERM")}catch{}if(await fi(t,200),!t.exited){try{t.proc.kill("SIGKILL")}catch{}await fi(t,200)}}}async start(t){let n=t.cmd.trim();if(!n)throw new Error("cmd must not be empty");if(this.cleanupSessions(),this.activeSessionCount()>=Mn)throw new Error(`too many active sessions (max ${Mn})`);let r=jr({toolName:t.source_tool??"exec_command",command:n});if(r.blocked)return r.xml;let o=this.nextId++,s=Date.now(),i=Id({cmd:n,shell:t.shell,login:t.login!==!1}),c=He(),a=t.workdir?.trim()?Md(c,t.workdir.trim()):c,l=bd(i.file,i.args,{cwd:a,env:process.env,stdio:["pipe","pipe","pipe"],shell:!1}),p={id:o,output:"",readOffset:0,pendingStdinInput:"",startedAtMs:s,exited:!1,exitCode:null,eventBus:new xd,proc:l},u=(y,b)=>{let U=typeof b=="string"?b:b.toString("utf8");p.output+=y?`${y}${U}`:U,p.eventBus.emit("output")};l.stdout?.on("data",y=>u("",y)),l.stderr?.on("data",y=>u("",y)),l.on("error",y=>{p.output+=`
|
|
51
|
+
[exec error] ${y.message}`,p.eventBus.emit("output")}),l.on("close",y=>{p.exited=!0,p.exitCode=typeof y=="number"?y:-1,p.eventBus.emit("exit")}),this.sessions.set(o,p),this.cleanupSessions();let d=typeof t.execution_timeout_ms=="number"&&t.execution_timeout_ms>0?Math.floor(t.execution_timeout_ms):null,m=di(t.yield_time_ms,kd),g=d!==null?Math.min(m,Math.max(0,d)):m;if(await mi(p,g),d!==null&&!p.exited&&Date.now()-s>=d)throw await this.terminateForTimeout(p),this.cleanupSessions(),new Error(`command timed out after ${d}ms`);return this.buildResponseText(p,t.max_output_tokens)}async write(t){let n=this.sessions.get(t.session_id);if(!n)throw new Error(`session_id ${t.session_id} not found`);if(!n.exited&&t.chars&&t.chars.length>0){let o=zr(`${n.pendingStdinInput}${t.chars}`),{completedLines:s,remainder:i}=ci(o);for(let c of s){if(!c.trim())continue;let a=jr({toolName:t.source_tool??"write_stdin",command:c,sessionId:n.id});if(a.blocked)return n.pendingStdinInput="",a.xml}n.pendingStdinInput=zr(i);try{let c=n.proc.stdin;c&&!c.destroyed&&!c.writableEnded&&c.write(t.chars)}catch{}}let r=di(t.yield_time_ms,Ad);return await mi(n,r),this.buildResponseText(n,t.max_output_tokens)}buildResponseText(t,n){let r=t.output.slice(t.readOffset),o=Od(r,n);t.readOffset+=o.deliveredChars;let s={sessionId:t.id,chunkId:Rd(),wallTimeSeconds:(Date.now()-t.startedAtMs)/1e3,exitCode:t.exited?t.exitCode:null,output:o.output,originalTokenCount:o.originalTokenCount};return Ld(s)}},gi=new Gr;async function wt(e){return gi.start(e)}async function hi(e){return gi.write(e)}var Nd=Be.object({command:Be.array(Be.string().min(1)).min(1,"command cannot be empty"),workdir:Be.string().optional(),timeout_ms:Be.number().int().positive().optional(),sandbox_permissions:Be.enum(["use_default","require_escalated"]).optional(),justification:Be.string().optional(),prefix_rule:Be.array(Be.string().min(1)).optional()}).strict(),$d=/^[A-Za-z0-9_./:@%+-]+$/;function Dd(e){return e.length===0?"''":$d.test(e)?e:`'${e.replace(/'/g,`'"'"'`)}'`}function Ud(e){return e.map(t=>Dd(t)).join(" ")}var yi=D({name:"shell",description:"Runs a shell command (argv form) and returns output.",inputSchema:Nd,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,timeout_ms:n})=>{try{let r=await wt({cmd:Ud(e),workdir:t,login:!1,yield_time_ms:n,execution_timeout_ms:n,source_tool:"shell"});return h(r)}catch(r){return h(`shell failed: ${r.message}`,!0)}}});import{z as We}from"zod";var Fd=We.object({command:We.string().min(1,"command cannot be empty"),workdir:We.string().optional(),login:We.boolean().optional(),timeout_ms:We.number().int().positive().optional(),sandbox_permissions:We.enum(["use_default","require_escalated"]).optional(),justification:We.string().optional(),prefix_rule:We.array(We.string().min(1)).optional()}).strict(),_i=D({name:"shell_command",description:"Runs a shell command and returns its output. Always set workdir when possible.",inputSchema:Fd,supportsParallelToolCalls:!0,isMutating:!0,execute:async({command:e,workdir:t,login:n,timeout_ms:r})=>{try{let o=await wt({cmd:e,workdir:t,login:n,yield_time_ms:r,execution_timeout_ms:r,source_tool:"shell_command"});return h(o)}catch(o){return h(`shell_command failed: ${o.message}`,!0)}}});import{z as Me}from"zod";var Hd=Me.object({cmd:Me.string().min(1,"cmd cannot be empty"),workdir:Me.string().optional(),shell:Me.string().optional(),login:Me.boolean().optional(),tty:Me.boolean().optional(),yield_time_ms:Me.number().int().nonnegative().optional(),max_output_tokens:Me.number().int().positive().optional(),sandbox_permissions:Me.enum(["use_default","require_escalated"]).optional(),justification:Me.string().optional(),prefix_rule:Me.array(Me.string().min(1)).optional()}).strict(),Kr=D({name:"exec_command",description:"Runs a command in a PTY-like managed session, returning output or a session ID for ongoing interaction.",inputSchema:Hd,supportsParallelToolCalls:!0,isMutating:!0,execute:async e=>{try{let t=await wt({...e,source_tool:"exec_command"});return h(t)}catch(t){return h(`exec_command failed: ${t.message}`,!0)}}});import{z as Kt}from"zod";var Bd=Kt.object({session_id:Kt.number().int().positive(),chars:Kt.string().optional(),yield_time_ms:Kt.number().int().nonnegative().optional(),max_output_tokens:Kt.number().int().positive().optional()}).strict(),qr=D({name:"write_stdin",description:"Writes characters to an existing unified exec session and returns recent output.",inputSchema:Bd,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{try{let t=await hi({...e,source_tool:"write_stdin"});return h(t)}catch(t){return h(`write_stdin failed: ${t.message}`,!0)}}});import{access as ym,readFile as _m,realpath as Sm,writeFile as vm}from"fs/promises";import{z as he}from"zod";var mm=Zo(ki(),1);import{normalize as im,resolve as am,dirname as Yv,join as cm,relative as lm,isAbsolute as um}from"path";import{homedir as pm}from"os";import{existsSync as eT,statSync as tT,realpathSync as dm}from"fs";import{readFile as rT}from"fs/promises";function sm(e){let t=e?.trim();if(!t)return null;let n=Number(t);return!Number.isFinite(n)||n<=0?null:Math.floor(n)}function An(){return sm(process.env.MEMO_TOOL_RESULT_MAX_CHARS)??2e4}function Ai(){let e=An(),t=Math.max(16,Math.floor(e*.25)),n=Math.max(32,e-t),r=Math.max(32,Math.floor(e*.6));return Math.min(12e3,r,n)}function ze(e){return im(am(e))}function Pn(e){let t=ze(e);try{return ze(dm(t))}catch{return t}}function fm(e,t){let n=lm(t,e);return n===""||!n.startsWith("..")&&!um(n)}function gm(){let e=process.env.MEMO_SANDBOX_WRITABLE_ROOTS?.trim();return e?e.split(",").map(t=>t.trim()).filter(Boolean).map(t=>Pn(t)):[]}function Pi(){let e=new Set;e.add(Pn(He()));let t=process.env.MEMO_HOME?.trim()||cm(pm(),".memo");e.add(Pn(t));for(let n of gm())e.add(n);return Array.from(e)}function hm(e){let t=Pn(e);return Pi().some(r=>fm(t,r))}function Ei(e){if(hm(e))return null;let t=Pi();return`sandbox write denied: ${e} is not within allowed directories (${t.join(", ")})`}var Tm=he.object({old_string:he.string().min(1,"old_string cannot be empty"),new_string:he.string(),replace_all:he.boolean().optional()}).strict(),Ri=he.object({file_path:he.string().min(1),old_string:he.string().optional(),new_string:he.string().optional(),replace_all:he.boolean().optional(),edits:he.array(Tm).min(1).optional()}).superRefine((e,t)=>{let n=!!(e.edits&&e.edits.length>0),r=e.old_string!==void 0||e.new_string!==void 0||e.replace_all!==void 0;if(n&&r){t.addIssue({code:he.ZodIssueCode.custom,message:"Use either edits or old_string/new_string fields, not both."});return}if(!n){if(typeof e.old_string!="string"||typeof e.new_string!="string"){t.addIssue({code:he.ZodIssueCode.custom,message:"Provide old_string/new_string, or use edits."});return}e.old_string.trim()||t.addIssue({code:he.ZodIssueCode.custom,message:"old_string cannot be empty",path:["old_string"]});return}for(let o=0;o<(e.edits?.length??0);o+=1){let s=e.edits?.[o];s&&(s.old_string.trim()||t.addIssue({code:he.ZodIssueCode.custom,message:"old_string cannot be empty",path:["edits",o,"old_string"]}))}}).strict();function wm(e){let t=Ei(e);if(t)throw new Error(t)}function Cm(e){return e.edits&&e.edits.length>0?e.edits:[{old_string:e.old_string??"",new_string:e.new_string??"",replace_all:e.replace_all}]}var Ii=D({name:"apply_patch",description:"Edit a local file by direct string replacement. Supports single replacement fields or batch edits.",inputSchema:Ri,supportsParallelToolCalls:!1,isMutating:!0,execute:async e=>{let t=Ri.safeParse(e);if(!t.success){let o=t.error.issues[0]?.message??"invalid input";return h(`apply_patch invalid input: ${o}`,!0)}let n=t.data,r=ze(n.file_path);try{await ym(r);let o=ze(await Sm(r));wm(o);let s=await _m(o,"utf8"),i=Cm(e),c=s,a=0;for(let l=0;l<i.length;l+=1){let p=i[l];if(!p)continue;let u=p.old_string,d=p.replace_all??!1;if(!c.includes(u))return i.length===1?h("apply_patch failed: target text not found.",!0):h(`apply_patch failed: target text not found at edit ${l+1}.`,!0);if(d){let m=c.split(u),g=m.length-1;c=m.join(p.new_string),a+=g}else c=c.replace(u,p.new_string),a+=1}return c===s?h("No changes made."):(await vm(o,c,"utf8"),h(`Success. Updated file: ${o}
|
|
52
52
|
Edits: ${i.length}
|
|
53
|
-
Replacements: ${a}`))}catch(o){return o.code==="ENOENT"?h(`apply_patch failed: file does not exist: ${r}`,!0):h(`apply_patch failed: ${o.message}`,!0)}}});import{readFile as
|
|
54
|
-
`)}function
|
|
55
|
-
`))}catch(i){return h(`list_dir failed: ${i.message}`,!0)}}});import{spawn as
|
|
56
|
-
`))}catch(s){return h(`grep_files failed: ${s.message}`,!0)}}});import{z as ze}from"zod";import{createHash as Gm}from"crypto";import{mkdir as Km,readFile as qm,rename as Vm,writeFile as Xm}from"fs/promises";import{homedir as Zr}from"os";import{dirname as Jm,join as no}from"path";var Ym="mcp.json",An=2,Qm=120,Zm=600*1e3,$i=1440*60*1e3;function Yr(){return process.env.MEMO_FORCE_MCP_DISK_CACHE==="1"?!0:!(process.env.MEMO_FORCE_MCP_DISK_CACHE==="0"||process.env.NODE_ENV==="test"||typeof process.env.VITEST<"u"||typeof process.env.VITEST_WORKER_ID<"u")}function ef(e){return e==="~"?Zr():e.startsWith("~/")?no(Zr(),e.slice(2)):e}function tf(){let e=process.env.MEMO_HOME?.trim();return e?ef(e):no(Zr(),".memo")}function Di(){return no(tf(),"cache",Ym)}function eo(e){if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(r=>eo(r)).join(",")}]`;let t=e;return`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${eo(t[r])}`).join(",")}}`}function Ui(e){return Gm("sha256").update(eo(e)).digest("hex")}function nf(e){return e instanceof Error?e.message:String(e)}function kn(){return{version:An,toolsByServer:{},responses:{}}}var to=class{data=kn();loaded=!1;loadPromise=null;persistTimer=null;persistRunning=!1;persistRequested=!1;responseInflight=new Map;pruneExpiredResponses(t=Date.now()){for(let[n,r]of Object.entries(this.data.responses))r.expiresAt<=t&&delete this.data.responses[n]}pruneExpiredTools(t=Date.now()){for(let[n,r]of Object.entries(this.data.toolsByServer))t-r.fetchedAt>$i&&delete this.data.toolsByServer[n]}async ensureLoaded(){if(!Yr()){this.loaded=!0;return}if(!this.loaded){if(this.loadPromise){await this.loadPromise;return}this.loadPromise=(async()=>{let t=Di();try{let n=await qm(t,"utf8"),r=JSON.parse(n);if(r.version===An){let o=r;this.data={version:An,toolsByServer:o.toolsByServer??{},responses:o.responses??{}}}else r.version===1&&r.entries?this.data={version:An,toolsByServer:{},responses:r.entries}:this.data=kn()}catch{this.data=kn()}finally{this.pruneExpiredResponses(),this.pruneExpiredTools(),this.loaded=!0}})(),await this.loadPromise}}async persistToDisk(){if(!Yr())return;this.pruneExpiredResponses(),this.pruneExpiredTools();let t=Di(),n=`${t}.tmp`,r=Jm(t);await Km(r,{recursive:!0}),await Xm(n,JSON.stringify(this.data,null,2),"utf8"),await Vm(n,t)}async flushPersistQueue(){if(!(!this.persistRequested||this.persistRunning)){this.persistRequested=!1,this.persistRunning=!0;try{await this.persistToDisk()}catch{}finally{this.persistRunning=!1,this.persistRequested&&this.flushPersistQueue()}}}schedulePersist(){Yr()&&(this.persistRequested=!0,!this.persistTimer&&(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.flushPersistQueue()},Qm),this.persistTimer.unref?.()))}async getServerTools(t,n){await this.ensureLoaded();let r=this.data.toolsByServer[t];if(!r)return null;if(r.configHash!==Ui(n))return delete this.data.toolsByServer[t],this.schedulePersist(),null;let o=Date.now()-r.fetchedAt;return o>$i?(delete this.data.toolsByServer[t],this.schedulePersist(),null):{tools:r.tools,stale:o>Zm,ageMs:o}}async setServerTools(t,n,r){await this.ensureLoaded(),this.data.toolsByServer[t]={fetchedAt:Date.now(),configHash:Ui(n),tools:r},this.schedulePersist()}async withResponseCache(t,n,r){await this.ensureLoaded();let o=this.data.responses[t];if(o&&o.expiresAt>Date.now())return o.value;o&&o.expiresAt<=Date.now()&&delete this.data.responses[t];let s=this.responseInflight.get(t);if(s)return await s;let i=(async()=>{let c=await r();return this.data.responses[t]={expiresAt:Date.now()+n,value:c},this.schedulePersist(),c})();this.responseInflight.set(t,i);try{return await i}catch(c){throw new Error(nf(c))}finally{this.responseInflight.delete(t)}}async flushForTests(){this.persistTimer&&(clearTimeout(this.persistTimer),this.persistTimer=null),this.persistRequested=!0,await this.flushPersistQueue()}resetForTests(){this.data=kn(),this.loaded=!1,this.loadPromise=null,this.responseInflight.clear(),this.persistRequested=!1,this.persistRunning=!1,this.persistTimer&&(clearTimeout(this.persistTimer),this.persistTimer=null)}},Qr=null;function Pn(){return Qr||(Qr=new to),Qr}var Fi=null,Hi=null;function ro(e){Fi=e}function Bi(){return Fi}function oo(e){Hi=e}function Wi(){return Hi}var rf=ze.object({server:ze.string().optional(),cursor:ze.string().optional()}).strict(),of=ze.object({server:ze.string().optional(),cursor:ze.string().optional()}).strict(),sf=ze.object({server:ze.string().min(1),uri:ze.string().min(1)}).strict(),En=15e3,af=6e4;function so(){let e=Bi();if(!e)throw new Error("MCP pool is not initialized");return e}function io(){return Wi()??Pn()}function Gi(e){return e instanceof Error?e.message:String(e)}function ji(e,t){return`list_resources:${e}:${t??""}`}function zi(e,t){return`list_resource_templates:${e}:${t??""}`}function cf(e,t){return`read_resource:${e}:${t}`}function ao(e,t){return typeof e.hasServer=="function"?e.hasServer(t):typeof e.get=="function"?!!e.get(t):!1}async function co(e,t){if(typeof e.get=="function"){let n=e.get(t);if(n)return n}if(typeof e.connect=="function")return e.connect(t)}async function Ki(e){if(typeof e.getKnownServerNames=="function"&&typeof e.connect=="function"){let n=e.getKnownServerNames().sort((s,i)=>s.localeCompare(i)),r=await Promise.allSettled(n.map(s=>e.connect(s))),o=[];return r.forEach((s,i)=>{if(s.status==="fulfilled"){o.push(s.value);return}let c=n[i];c&&o.push({name:c,client:null,__error:s.reason})}),o.sort((s,i)=>s.name.localeCompare(i.name))}return(typeof e.getAll=="function"?e.getAll():[]).sort((n,r)=>n.name.localeCompare(r.name))}var qi=D({name:"list_mcp_resources",description:"Lists resources provided by MCP servers. Prefer resources over web search when possible.",inputSchema:rf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=so(),r=io(),o=e?.trim();if(o){if(!ao(n,o))return h(`MCP server not found: ${e}`,!0);let a=await co(n,o);if(!a)return h(`MCP server not found: ${e}`,!0);let l=await r.withResponseCache(ji(a.name,t),En,async()=>{let p=await a.client.listResources(t?{cursor:t}:void 0);return{server:a.name,resources:p.resources,nextCursor:p.nextCursor}});return h(JSON.stringify(l,null,2))}if(t)return h("cursor is only supported when server is specified",!0);let s=await Ki(n),i=`all:${s.map(a=>a.name).join(",")}`,c=await r.withResponseCache(ji(i),En,async()=>{let a=await Promise.allSettled(s.map(async u=>{if(!u.client)throw new Error(`MCP server '${u.name}' is not connected`);return{server:u.name,result:await u.client.listResources()}})),l=[],p=[];return a.forEach((u,d)=>{let m=s[d]?.name??"unknown";if(u.status==="rejected"){p.push({server:m,error:Gi(u.reason)});return}for(let g of u.value.result.resources)l.push({server:u.value.server,...g})}),{resources:l,...p.length>0?{errors:p}:{}}});return h(JSON.stringify(c,null,2))}catch(n){return h(`list_mcp_resources failed: ${n.message}`,!0)}}}),Vi=D({name:"list_mcp_resource_templates",description:"Lists resource templates provided by MCP servers. Prefer resource templates over web search when possible.",inputSchema:of,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=so(),r=io(),o=e?.trim();if(o){if(!ao(n,o))return h(`MCP server not found: ${e}`,!0);let a=await co(n,o);if(!a)return h(`MCP server not found: ${e}`,!0);let l=await r.withResponseCache(zi(a.name,t),En,async()=>{let p=await a.client.listResourceTemplates(t?{cursor:t}:void 0);return{server:a.name,resourceTemplates:p.resourceTemplates,nextCursor:p.nextCursor}});return h(JSON.stringify(l,null,2))}if(t)return h("cursor is only supported when server is specified",!0);let s=await Ki(n),i=`all:${s.map(a=>a.name).join(",")}`,c=await r.withResponseCache(zi(i),En,async()=>{let a=await Promise.allSettled(s.map(async u=>{if(!u.client)throw new Error(`MCP server '${u.name}' is not connected`);return{server:u.name,result:await u.client.listResourceTemplates()}})),l=[],p=[];return a.forEach((u,d)=>{let m=s[d]?.name??"unknown";if(u.status==="rejected"){p.push({server:m,error:Gi(u.reason)});return}for(let g of u.value.result.resourceTemplates)l.push({server:u.value.server,...g})}),{resourceTemplates:l,...p.length>0?{errors:p}:{}}});return h(JSON.stringify(c,null,2))}catch(n){return h(`list_mcp_resource_templates failed: ${n.message}`,!0)}}}),Xi=D({name:"read_mcp_resource",description:"Read a specific resource from an MCP server given the server name and resource URI.",inputSchema:sf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,uri:t})=>{try{let n=so(),r=io(),o=e.trim();if(!ao(n,o))return h(`MCP server not found: ${e}`,!0);let s=await co(n,o);if(!s)return h(`MCP server not found: ${e}`,!0);let i=await r.withResponseCache(cf(o,t),af,async()=>{let c=await s.client.readResource({uri:t});return{server:o,uri:t,...c}});return h(JSON.stringify(i,null,2))}catch(n){return h(`read_mcp_resource failed: ${n.message}`,!0)}}});import{z as Tt}from"zod";var lf=Tt.object({step:Tt.string().min(1),status:Tt.enum(["pending","in_progress","completed"])}).strict(),uf=Tt.object({explanation:Tt.string().optional(),plan:Tt.array(lf).min(1)}).strict(),Ji=[],Yi=D({name:"update_plan",description:"Updates the task plan. At most one step can be in_progress at a time.",inputSchema:uf,supportsParallelToolCalls:!1,isMutating:!1,execute:async({explanation:e,plan:t})=>{if(t.filter(r=>r.status==="in_progress").length>1)return h("At most one step can be in_progress at a time",!0);if(t.length<4){let r=t[0]?.step??"";return h(`<system_hint tool="update_plan" reason="simple_task">Task "${r}" is simple (${t.length} step${t.length>1?"s":""}) - execute directly without update_plan.</system_hint>`)}return Ji=t,h(JSON.stringify({message:"Plan updated",explanation:e,plan:Ji},null,2))}});import{readFile as pf}from"fs/promises";import{homedir as df}from"os";import{join as Qi}from"path";import{z as Zi}from"zod";var mf=Zi.object({memory_id:Zi.string().min(1)}).strict();function ff(){let e=process.env.MEMO_HOME?.trim()||Qi(df(),".memo");return Qi(e,"Agents.md")}var ea=D({name:"get_memory",description:"Loads the stored memory payload for a memory_id.",inputSchema:mf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({memory_id:e})=>{try{let t=ff(),n=await pf(t,"utf8");return h(JSON.stringify({memory_id:e,memory_summary:n},null,2))}catch{return h(`memory not found for memory_id=${e}`,!0)}}});import{z as ta}from"zod";var gf=ta.object({url:ta.string().min(1)}).strict(),na=1e4,qt=512e3,hf=new Set(["http:","https:"]),yf=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,_f=/<\s*(br|hr)\s*\/?>/gi,Sf=/<\s*li[^>]*>/gi,vf=/<[^>]+>/g,Tf=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,wf=e=>e.replace(/ /gi," ").replace(/</gi,"<").replace(/>/gi,">").replace(/&/gi,"&").replace(/"/gi,'"').replace(/'/g,"'").replace(/&#(x?[0-9a-fA-F]+);/g,(r,o)=>{try{let s=o.startsWith("x")||o.startsWith("X")?parseInt(o.slice(1),16):parseInt(o,10);return Number.isFinite(s)?String.fromCharCode(s):""}catch{return""}}),Cf=e=>{let r=e.replace(Tf," ").replace(Sf,"- ").replace(_f,`
|
|
57
|
-
`).replace(
|
|
58
|
-
`).replace(
|
|
53
|
+
Replacements: ${a}`))}catch(o){return o.code==="ENOENT"?h(`apply_patch failed: file does not exist: ${r}`,!0):h(`apply_patch failed: ${o.message}`,!0)}}});import{readFile as bm}from"fs/promises";import{z as Oe}from"zod";var Oi=500,Li=200,xm=Oe.object({file_path:Oe.string().min(1),offset:Oe.number().int().positive().optional(),limit:Oe.number().int().positive().optional(),mode:Oe.enum(["slice","indentation"]).optional(),indentation:Oe.object({anchor_line:Oe.number().int().positive().optional(),max_levels:Oe.number().int().nonnegative().optional(),include_siblings:Oe.boolean().optional(),include_header:Oe.boolean().optional(),max_lines:Oe.number().int().positive().optional()}).strict().optional()}).strict();function Mm(e){return e.length<=Oi?e:e.slice(0,Oi)}function km(e){let t=0;for(let n of e)if(n===" ")t+=1;else if(n===" ")t+=4;else break;return t}function Am(e){return e.split(/\r?\n/).map((n,r)=>({line:r+1,text:Mm(n),indent:km(n)}))}function Pm(e){return e.map(t=>`L${t.line}: ${t.text}`).join(`
|
|
54
|
+
`)}function Em(e,t,n){let r=t-1;if(r>=e.length)throw new Error("offset exceeds file length");return e.slice(r,r+n)}function Rm(e,t){let n=t.offset??1,r=t.limit??Li,o=t.indentation,s=o?.anchor_line??n;if(s<=0||s>e.length)throw new Error("anchor_line exceeds file length");let i=e[s-1];if(!i)throw new Error("anchor_line exceeds file length");let c=o?.max_levels??0,a=o?.include_siblings??!0,l=o?.include_header??!0,p=o?.max_lines??r,u=Math.max(1,Math.min(r,p)),d=c===0?0:Math.max(0,i.indent-c*4),m=s-1,g=s-1;for(;m-1>=0;){let y=e[m-1];if(!y)break;let b=/^\s*(#|\/\/|--)/.test(y.text),U=y.text.trim().length===0;if(y.indent<d||!a&&y.indent===d&&!b&&!U||!l&&(b||U)&&y.indent<i.indent||(m-=1,g-m+1>=u))break}for(;g+1<e.length&&g-m+1<u;){let y=e[g+1];if(!y||y.indent<d||!a&&y.indent===d)break;g+=1}return e.slice(m,g+1)}var Ni=D({name:"read_file",description:"Reads a local file with 1-indexed line numbers, supporting slice and indentation-aware block modes.",inputSchema:xm,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??1,n=e.limit??Li;if(t<=0)return h("offset must be a 1-indexed line number",!0);if(n<=0)return h("limit must be greater than zero",!0);let r=e.file_path.trim();if(!r.startsWith("/"))return h("file_path must be an absolute path",!0);let o=ze(r);try{let s=await bm(o,"utf8"),i=Am(s);if(i.length===0)return h("");let a=(e.mode??"slice")==="indentation"?Rm(i,e):Em(i,t,n);return h(Pm(a))}catch(s){return h(`read_file failed: ${s.message}`,!0)}}});import{readdir as Im,lstat as Om}from"fs/promises";import{join as Lm}from"path";import{z as qt}from"zod";var Nm=1,$m=25,Dm=2,Um=qt.object({dir_path:qt.string().min(1),offset:qt.number().int().positive().optional(),limit:qt.number().int().positive().optional(),depth:qt.number().int().positive().optional()}).strict();function Fm(e){let t=" ".repeat(e.displayDepth*2),n="";e.kind==="dir"&&(n="/"),e.kind==="symlink"&&(n="@"),e.kind==="other"&&(n="?");let r=e.path.split("/"),o=r[r.length-1]??e.path;return`${t}${o}${n}`}var $i=D({name:"list_dir",description:"Lists entries in a local directory with 1-indexed entry numbers and simple type labels.",inputSchema:Um,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.offset??Nm,n=e.limit??$m,r=e.depth??Dm;if(t<=0)return h("offset must be a 1-indexed entry number",!0);if(n<=0)return h("limit must be greater than zero",!0);if(r<=0)return h("depth must be greater than zero",!0);let o=e.dir_path.trim();if(!o.startsWith("/"))return h("dir_path must be an absolute path",!0);let s=ze(o);try{let i=[{absPath:s,depth:r,displayDepth:0}],c=[];for(;i.length>0;){let u=i.shift();if(!u)continue;let d=await Im(u.absPath);d.sort((m,g)=>m.localeCompare(g));for(let m of d){let g=Lm(u.absPath,m),y=await Om(g),b=y.isSymbolicLink()?"symlink":y.isDirectory()?"dir":y.isFile()?"file":"other";c.push({path:g,displayDepth:u.displayDepth,kind:b}),b==="dir"&&u.depth>1&&i.push({absPath:g,depth:u.depth-1,displayDepth:u.displayDepth+1})}}if(c.length===0)return h(`Absolute path: ${s}`);let a=t-1;if(a>=c.length)return h("offset exceeds directory entry count",!0);let l=c.slice(a,a+n),p=[`Absolute path: ${s}`,...l.map(Fm)];return a+n<c.length&&p.push(`More than ${n} entries found`),h(p.join(`
|
|
55
|
+
`))}catch(i){return h(`list_dir failed: ${i.message}`,!0)}}});import{spawn as Hm}from"child_process";import{resolve as Bm}from"path";import{z as Vt}from"zod";var Wm=100,jm=2e3,zm=3e4,Gm=Vt.object({pattern:Vt.string().min(1),include:Vt.string().optional(),path:Vt.string().optional(),limit:Vt.number().int().positive().optional()}).strict();function Km(e){return new Promise((t,n)=>{let r=["--files-with-matches","--sortr=modified","--regexp",e.pattern,"--max-count","1","--no-messages"];e.include?.trim()&&r.push("--glob",e.include.trim()),r.push("--",e.searchPath);let o=Hm("rg",r,{cwd:e.cwd,stdio:["ignore","pipe","pipe"]}),s=[],i=[];o.stdout?.setEncoding("utf8"),o.stderr?.setEncoding("utf8"),o.stdout?.on("data",g=>s.push(g)),o.stderr?.on("data",g=>i.push(g));let c=!1,a=null,l=!1,p=()=>{clearTimeout(m),a&&(clearTimeout(a),a=null)},u=g=>{l||(l=!0,p(),n(g))},d=g=>{l||(l=!0,p(),t(g))},m=setTimeout(()=>{c=!0;try{o.kill("SIGTERM")}catch{}a=setTimeout(()=>{if(o.exitCode===null)try{o.kill("SIGKILL")}catch{}},500),a.unref?.()},zm);m.unref?.(),o.on("error",g=>{u(g)}),o.on("close",g=>{if(c){u(new Error("rg timed out after 30 seconds"));return}d({exitCode:typeof g=="number"?g:-1,stdout:s.join(""),stderr:i.join("")})})})}var Di=D({name:"grep_files",description:"Finds files whose contents match the pattern and lists them by modification time.",inputSchema:Gm,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t=e.pattern.trim();if(!t)return h("pattern must not be empty",!0);let n=Math.min(e.limit??Wm,jm),r=He(),o=e.path?.trim()?Bm(r,e.path.trim()):r;try{let s=await Km({pattern:t,include:e.include,searchPath:o,cwd:r,limit:n});if(s.exitCode===1)return h("No matches found.");if(s.exitCode!==0)return h(`rg failed: ${s.stderr||s.stdout}`,!0);let i=s.stdout.split(/\r?\n/).map(c=>c.trim()).filter(Boolean).slice(0,n);return i.length===0?h("No matches found."):h(i.join(`
|
|
56
|
+
`))}catch(s){return h(`grep_files failed: ${s.message}`,!0)}}});import{z as Ge}from"zod";import{createHash as qm}from"crypto";import{mkdir as Vm,readFile as Xm,rename as Jm,writeFile as Ym}from"fs/promises";import{homedir as no}from"os";import{dirname as Qm,join as so}from"path";var Zm="mcp.json",Rn=2,ef=120,tf=600*1e3,Ui=1440*60*1e3;function eo(){return process.env.MEMO_FORCE_MCP_DISK_CACHE==="1"?!0:!(process.env.MEMO_FORCE_MCP_DISK_CACHE==="0"||process.env.NODE_ENV==="test"||typeof process.env.VITEST<"u"||typeof process.env.VITEST_WORKER_ID<"u")}function nf(e){return e==="~"?no():e.startsWith("~/")?so(no(),e.slice(2)):e}function rf(){let e=process.env.MEMO_HOME?.trim();return e?nf(e):so(no(),".memo")}function Fi(){return so(rf(),"cache",Zm)}function ro(e){if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(r=>ro(r)).join(",")}]`;let t=e;return`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${ro(t[r])}`).join(",")}}`}function Hi(e){return qm("sha256").update(ro(e)).digest("hex")}function of(e){return e instanceof Error?e.message:String(e)}function En(){return{version:Rn,toolsByServer:{},responses:{}}}var oo=class{data=En();loaded=!1;loadPromise=null;persistTimer=null;persistRunning=!1;persistRequested=!1;responseInflight=new Map;pruneExpiredResponses(t=Date.now()){for(let[n,r]of Object.entries(this.data.responses))r.expiresAt<=t&&delete this.data.responses[n]}pruneExpiredTools(t=Date.now()){for(let[n,r]of Object.entries(this.data.toolsByServer))t-r.fetchedAt>Ui&&delete this.data.toolsByServer[n]}async ensureLoaded(){if(!eo()){this.loaded=!0;return}if(!this.loaded){if(this.loadPromise){await this.loadPromise;return}this.loadPromise=(async()=>{let t=Fi();try{let n=await Xm(t,"utf8"),r=JSON.parse(n);if(r.version===Rn){let o=r;this.data={version:Rn,toolsByServer:o.toolsByServer??{},responses:o.responses??{}}}else r.version===1&&r.entries?this.data={version:Rn,toolsByServer:{},responses:r.entries}:this.data=En()}catch{this.data=En()}finally{this.pruneExpiredResponses(),this.pruneExpiredTools(),this.loaded=!0}})(),await this.loadPromise}}async persistToDisk(){if(!eo())return;this.pruneExpiredResponses(),this.pruneExpiredTools();let t=Fi(),n=`${t}.tmp`,r=Qm(t);await Vm(r,{recursive:!0}),await Ym(n,JSON.stringify(this.data,null,2),"utf8"),await Jm(n,t)}async flushPersistQueue(){if(!(!this.persistRequested||this.persistRunning)){this.persistRequested=!1,this.persistRunning=!0;try{await this.persistToDisk()}catch{}finally{this.persistRunning=!1,this.persistRequested&&this.flushPersistQueue()}}}schedulePersist(){eo()&&(this.persistRequested=!0,!this.persistTimer&&(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.flushPersistQueue()},ef),this.persistTimer.unref?.()))}async getServerTools(t,n){await this.ensureLoaded();let r=this.data.toolsByServer[t];if(!r)return null;if(r.configHash!==Hi(n))return delete this.data.toolsByServer[t],this.schedulePersist(),null;let o=Date.now()-r.fetchedAt;return o>Ui?(delete this.data.toolsByServer[t],this.schedulePersist(),null):{tools:r.tools,stale:o>tf,ageMs:o}}async setServerTools(t,n,r){await this.ensureLoaded(),this.data.toolsByServer[t]={fetchedAt:Date.now(),configHash:Hi(n),tools:r},this.schedulePersist()}async withResponseCache(t,n,r){await this.ensureLoaded();let o=this.data.responses[t];if(o&&o.expiresAt>Date.now())return o.value;o&&o.expiresAt<=Date.now()&&delete this.data.responses[t];let s=this.responseInflight.get(t);if(s)return await s;let i=(async()=>{let c=await r();return this.data.responses[t]={expiresAt:Date.now()+n,value:c},this.schedulePersist(),c})();this.responseInflight.set(t,i);try{return await i}catch(c){throw new Error(of(c))}finally{this.responseInflight.delete(t)}}async flushForTests(){this.persistTimer&&(clearTimeout(this.persistTimer),this.persistTimer=null),this.persistRequested=!0,await this.flushPersistQueue()}resetForTests(){this.data=En(),this.loaded=!1,this.loadPromise=null,this.responseInflight.clear(),this.persistRequested=!1,this.persistRunning=!1,this.persistTimer&&(clearTimeout(this.persistTimer),this.persistTimer=null)}},to=null;function In(){return to||(to=new oo),to}var Bi=null,Wi=null;function io(e){Bi=e}function ji(){return Bi}function ao(e){Wi=e}function zi(){return Wi}var sf=Ge.object({server:Ge.string().optional(),cursor:Ge.string().optional()}).strict(),af=Ge.object({server:Ge.string().optional(),cursor:Ge.string().optional()}).strict(),cf=Ge.object({server:Ge.string().min(1),uri:Ge.string().min(1)}).strict(),On=15e3,lf=6e4;function co(){let e=ji();if(!e)throw new Error("MCP pool is not initialized");return e}function lo(){return zi()??In()}function qi(e){return e instanceof Error?e.message:String(e)}function Gi(e,t){return`list_resources:${e}:${t??""}`}function Ki(e,t){return`list_resource_templates:${e}:${t??""}`}function uf(e,t){return`read_resource:${e}:${t}`}function uo(e,t){return typeof e.hasServer=="function"?e.hasServer(t):typeof e.get=="function"?!!e.get(t):!1}async function po(e,t){if(typeof e.get=="function"){let n=e.get(t);if(n)return n}if(typeof e.connect=="function")return e.connect(t)}async function Vi(e){if(typeof e.getKnownServerNames=="function"&&typeof e.connect=="function"){let n=e.getKnownServerNames().sort((s,i)=>s.localeCompare(i)),r=await Promise.allSettled(n.map(s=>e.connect(s))),o=[];return r.forEach((s,i)=>{if(s.status==="fulfilled"){o.push(s.value);return}let c=n[i];c&&o.push({name:c,client:null,__error:s.reason})}),o.sort((s,i)=>s.name.localeCompare(i.name))}return(typeof e.getAll=="function"?e.getAll():[]).sort((n,r)=>n.name.localeCompare(r.name))}var Xi=D({name:"list_mcp_resources",description:"Lists resources provided by MCP servers. Prefer resources over web search when possible.",inputSchema:sf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=co(),r=lo(),o=e?.trim();if(o){if(!uo(n,o))return h(`MCP server not found: ${e}`,!0);let a=await po(n,o);if(!a)return h(`MCP server not found: ${e}`,!0);let l=await r.withResponseCache(Gi(a.name,t),On,async()=>{let p=await a.client.listResources(t?{cursor:t}:void 0);return{server:a.name,resources:p.resources,nextCursor:p.nextCursor}});return h(JSON.stringify(l,null,2))}if(t)return h("cursor is only supported when server is specified",!0);let s=await Vi(n),i=`all:${s.map(a=>a.name).join(",")}`,c=await r.withResponseCache(Gi(i),On,async()=>{let a=await Promise.allSettled(s.map(async u=>{if(!u.client)throw new Error(`MCP server '${u.name}' is not connected`);return{server:u.name,result:await u.client.listResources()}})),l=[],p=[];return a.forEach((u,d)=>{let m=s[d]?.name??"unknown";if(u.status==="rejected"){p.push({server:m,error:qi(u.reason)});return}for(let g of u.value.result.resources)l.push({server:u.value.server,...g})}),{resources:l,...p.length>0?{errors:p}:{}}});return h(JSON.stringify(c,null,2))}catch(n){return h(`list_mcp_resources failed: ${n.message}`,!0)}}}),Ji=D({name:"list_mcp_resource_templates",description:"Lists resource templates provided by MCP servers. Prefer resource templates over web search when possible.",inputSchema:af,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,cursor:t})=>{try{let n=co(),r=lo(),o=e?.trim();if(o){if(!uo(n,o))return h(`MCP server not found: ${e}`,!0);let a=await po(n,o);if(!a)return h(`MCP server not found: ${e}`,!0);let l=await r.withResponseCache(Ki(a.name,t),On,async()=>{let p=await a.client.listResourceTemplates(t?{cursor:t}:void 0);return{server:a.name,resourceTemplates:p.resourceTemplates,nextCursor:p.nextCursor}});return h(JSON.stringify(l,null,2))}if(t)return h("cursor is only supported when server is specified",!0);let s=await Vi(n),i=`all:${s.map(a=>a.name).join(",")}`,c=await r.withResponseCache(Ki(i),On,async()=>{let a=await Promise.allSettled(s.map(async u=>{if(!u.client)throw new Error(`MCP server '${u.name}' is not connected`);return{server:u.name,result:await u.client.listResourceTemplates()}})),l=[],p=[];return a.forEach((u,d)=>{let m=s[d]?.name??"unknown";if(u.status==="rejected"){p.push({server:m,error:qi(u.reason)});return}for(let g of u.value.result.resourceTemplates)l.push({server:u.value.server,...g})}),{resourceTemplates:l,...p.length>0?{errors:p}:{}}});return h(JSON.stringify(c,null,2))}catch(n){return h(`list_mcp_resource_templates failed: ${n.message}`,!0)}}}),Yi=D({name:"read_mcp_resource",description:"Read a specific resource from an MCP server given the server name and resource URI.",inputSchema:cf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({server:e,uri:t})=>{try{let n=co(),r=lo(),o=e.trim();if(!uo(n,o))return h(`MCP server not found: ${e}`,!0);let s=await po(n,o);if(!s)return h(`MCP server not found: ${e}`,!0);let i=await r.withResponseCache(uf(o,t),lf,async()=>{let c=await s.client.readResource({uri:t});return{server:o,uri:t,...c}});return h(JSON.stringify(i,null,2))}catch(n){return h(`read_mcp_resource failed: ${n.message}`,!0)}}});import{z as Ct}from"zod";var pf=Ct.object({step:Ct.string().min(1),status:Ct.enum(["pending","in_progress","completed"])}).strict(),df=Ct.object({explanation:Ct.string().optional(),plan:Ct.array(pf).min(1)}).strict(),Qi=[],Zi=D({name:"update_plan",description:"Updates the task plan. At most one step can be in_progress at a time.",inputSchema:df,supportsParallelToolCalls:!1,isMutating:!1,execute:async({explanation:e,plan:t})=>{if(t.filter(r=>r.status==="in_progress").length>1)return h("At most one step can be in_progress at a time",!0);if(t.length<4){let r=t[0]?.step??"";return h(`<system_hint tool="update_plan" reason="simple_task">Task "${r}" is simple (${t.length} step${t.length>1?"s":""}) - execute directly without update_plan.</system_hint>`)}return Qi=t,h(JSON.stringify({message:"Plan updated",explanation:e,plan:Qi},null,2))}});import{readFile as mf}from"fs/promises";import{homedir as ff}from"os";import{join as ea}from"path";import{z as ta}from"zod";var gf=ta.object({memory_id:ta.string().min(1)}).strict();function hf(){let e=process.env.MEMO_HOME?.trim()||ea(ff(),".memo");return ea(e,"Agents.md")}var na=D({name:"get_memory",description:"Loads the stored memory payload for a memory_id.",inputSchema:gf,supportsParallelToolCalls:!0,isMutating:!1,execute:async({memory_id:e})=>{try{let t=hf(),n=await mf(t,"utf8");return h(JSON.stringify({memory_id:e,memory_summary:n},null,2))}catch{return h(`memory not found for memory_id=${e}`,!0)}}});import{z as ra}from"zod";var yf=ra.object({url:ra.string().min(1)}).strict(),oa=1e4,Xt=512e3,_f=new Set(["http:","https:"]),Sf=/<\/\s*(p|div|section|article|header|footer|aside|main|h[1-6]|li|tr|table|blockquote)\s*>/gi,vf=/<\s*(br|hr)\s*\/?>/gi,Tf=/<\s*li[^>]*>/gi,wf=/<[^>]+>/g,Cf=/<(script|style)[^>]*>[\s\S]*?<\/\s*\1>/gi,bf=e=>e.replace(/ /gi," ").replace(/</gi,"<").replace(/>/gi,">").replace(/&/gi,"&").replace(/"/gi,'"').replace(/'/g,"'").replace(/&#(x?[0-9a-fA-F]+);/g,(r,o)=>{try{let s=o.startsWith("x")||o.startsWith("X")?parseInt(o.slice(1),16):parseInt(o,10);return Number.isFinite(s)?String.fromCharCode(s):""}catch{return""}}),xf=e=>{let r=e.replace(Cf," ").replace(Tf,"- ").replace(vf,`
|
|
57
|
+
`).replace(Sf,`
|
|
58
|
+
`).replace(wf," "),s=bf(r).replace(/\r/g,"").split(`
|
|
59
59
|
`).map(c=>c.trim().replace(/[ \t]{2,}/g," "));return s.filter((c,a)=>c.length>0||a>0&&(s[a-1]?.length??0)>0).join(`
|
|
60
|
-
`).trim()},
|
|
61
|
-
...[truncated]`}function
|
|
62
|
-
${o}`),
|
|
60
|
+
`).trim()},Mf=e=>e.replace(/\s+/g," ").trim(),sa=D({name:"webfetch",description:"HTTP GET request, returns processed plain text body (automatically strips HTML tags)",inputSchema:yf,supportsParallelToolCalls:!0,isMutating:!1,execute:async e=>{let t;try{t=new URL(e.url)}catch{return h(`Invalid URL: ${e.url}`,!0)}if(!_f.has(t.protocol))return h(`Unsupported protocol: ${t.protocol}`,!0);let n=new AbortController,r=setTimeout(()=>n.abort(),oa);try{let o=await globalThis.fetch(t,{signal:n.signal}),s=o.headers.get("content-length"),i=s?Number(s):void 0;if(i&&i>Xt)return h(`Request rejected: response body too large (${i} bytes)`,!0);let c=0,a="";if(o.body&&o.body.getReader){let U=o.body.getReader(),T=[];for(;;){let{done:I,value:G}=await U.read();if(I)break;if(G){if(c+=G.byteLength,c>Xt)return n.abort(),h(`Request aborted: response body exceeds ${Xt} bytes`,!0);T.push(G)}}let H=new Uint8Array(c),R=0;for(let I of T)H.set(I,R),R+=I.byteLength;a=new TextDecoder().decode(H)}else if(a=await o.text(),c=new TextEncoder().encode(a).byteLength,c>Xt)return h(`Request rejected: response body exceeds ${Xt} bytes`,!0);let l=o.headers.get("content-type")||"",p=/text\/html/i.test(l)||/^\s*<!doctype html/i.test(a)||/^\s*<html[\s>]/i.test(a),u=p?xf(a):a.trim(),d=Mf(u),m=Ai(),g=d.length>m?`${d.slice(0,m)}...`:d,y=d.length>m?" text_truncated=true":"",b=p?" source=html_stripped":"";return h(`status=${o.status} bytes=${c} text_chars=${d.length} text="${g}"${y}${b}`)}catch(o){return o.name==="AbortError"?h(`Request timeout or aborted (${oa}ms)`,!0):h(`Request failed: ${o.message}`,!0)}finally{clearTimeout(r)}}});import{spawn as kf}from"child_process";import{existsSync as Af}from"fs";import{resolve as Pf}from"path";import{z as fe}from"zod";var Ef=3e4,Rf=1e4,If=3e5,ia=4,Of=1500,aa=2e3,Je=new Map,Lf=fe.object({message:fe.string().min(1),agent_type:fe.string().optional()}).strict(),Nf=fe.object({id:fe.string().min(1),message:fe.string().min(1),interrupt:fe.boolean().optional()}).strict(),$f=fe.object({id:fe.string().min(1)}).strict(),Df=fe.object({ids:fe.array(fe.string().min(1)).min(1),timeout_ms:fe.number().int().positive().optional()}).strict(),Uf=fe.object({id:fe.string().min(1)}).strict();function bt(){return new Date().toISOString()}function mo(e){return h(`agent not found: ${e}`,!0)}function Ff(){let e=process.env.MEMO_SUBAGENT_MAX_AGENTS?.trim();if(!e)return ia;let t=Number(e);return!Number.isFinite(t)||t<=0?ia:Math.floor(t)}function Hf(){let e=0;for(let t of Je.values())t.running&&(e+=1);return e}function Bf(){let e=process.env.MEMO_SUBAGENT_COMMAND?.trim();if(e)return e;let t=Pf(He(),"dist/index.js");return Af(t)?`node ${JSON.stringify(t)} --dangerous`:"memo --dangerous"}function Wf(e){return e!=="running"}function jf(e){return new Promise(t=>{setTimeout(t,e)})}function zf(e){return e===void 0?Ef:e<=0?null:Math.max(Rf,Math.min(If,e))}function Gf(e){return e.length<=aa?e:`${e.slice(0,aa)}
|
|
61
|
+
...[truncated]`}function Kf(e,t){let n=[],r=e.trim(),o=t.trim();return r&&n.push(r),o&&n.push(`stderr:
|
|
62
|
+
${o}`),Gf(n.join(`
|
|
63
63
|
|
|
64
|
-
`))}async function
|
|
65
|
-
`)}catch{}try{s.stdin?.end()}catch{}return r}var
|
|
66
|
-
`)}function
|
|
64
|
+
`))}async function ca(e){let t=e.running;if(!t)return;t.interrupted=!0;let n=t.process;n.exitCode!==null||n.killed||await new Promise(r=>{let o=!1,s=()=>{o||(o=!0,clearTimeout(i),n.off("close",s),r())},i=setTimeout(()=>{if(n.exitCode===null)try{n.kill("SIGKILL")}catch{s()}},Of);n.on("close",s);try{n.kill("SIGTERM")}catch{s()}})}function qf(e){let t=Je.get(e);return t?t.status:"not_found"}function Vf(e){let t=Je.get(e);return t?{status:t.status,last_message:t.lastMessage,last_output:t.lastOutput,last_error:t.lastError,last_submission_id:t.lastSubmissionId,updated_at:t.updatedAt}:{status:"not_found",last_message:null,last_output:null,last_error:null,last_submission_id:null,updated_at:null}}function Xf(e){return{agent_id:e.id,status:e.status,created_at:e.createdAt,updated_at:e.updatedAt,last_message:e.lastMessage,last_submission_id:e.lastSubmissionId,has_last_output:!!e.lastOutput,has_last_error:!!e.lastError}}function Jf(e){let{record:t,submissionId:n,stdout:r,stderr:o,exitCode:s,interrupted:i}=e;if(!(!t.running||t.running.id!==n)&&(t.running=null,t.updatedAt=bt(),t.lastOutput=Kf(r,o)||null,t.lastError=null,t.status!=="closed")){if(i){t.status="errored",t.lastError="interrupted",t.statusBeforeClose="errored";return}if(s===0){t.status="completed",t.statusBeforeClose="completed";return}t.status="errored",t.lastError=`submission failed with exit code ${s}`,t.statusBeforeClose="errored"}}async function la(e,t){let n=Ff();if(Hf()>=n)throw new Error(`subagent concurrency limit reached (${n})`);let r=crypto.randomUUID(),o=Bf(),s=kf(o,{cwd:He(),env:{...process.env},shell:!0,stdio:["pipe","pipe","pipe"]}),i=[],c=[];s.stdout?.setEncoding("utf8"),s.stderr?.setEncoding("utf8"),s.stdout?.on("data",a=>i.push(a)),s.stderr?.on("data",a=>c.push(a)),s.on("error",a=>{c.push(`[spawn error] ${a.message}`)}),e.running={id:r,message:t,process:s,startedAt:bt(),interrupted:!1},e.status="running",e.lastMessage=t,e.lastSubmissionId=r,e.updatedAt=bt(),s.on("close",a=>{let l=typeof a=="number"?a:-1,p=!!(e.running?.id===r&&e.running.interrupted);Jf({record:e,submissionId:r,stdout:i.join(""),stderr:c.join(""),exitCode:l,interrupted:p})});try{s.stdin?.write(`${t.trim()}
|
|
65
|
+
`)}catch{}try{s.stdin?.end()}catch{}return r}var ua=D({name:"spawn_agent",description:"Spawn a sub-agent for a well-scoped task and return the agent id.",inputSchema:Lf,supportsParallelToolCalls:!1,isMutating:!0,execute:async({message:e})=>{let t=e.trim();if(!t)return h("spawn_agent failed: message must not be empty",!0);let n=crypto.randomUUID(),r=bt(),o={id:n,createdAt:r,updatedAt:r,status:"running",statusBeforeClose:"completed",lastMessage:t,lastSubmissionId:null,lastOutput:null,lastError:null,running:null};Je.set(n,o);try{let s=await la(o,t);return h(JSON.stringify({...Xf(o),submission_id:s},null,2))}catch(s){return Je.delete(n),h(`spawn_agent failed: ${s.message}`,!0)}}}),pa=D({name:"send_input",description:"Send a message to an existing agent.",inputSchema:Nf,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e,message:t,interrupt:n})=>{let r=Je.get(e);if(!r)return mo(e);let o=t.trim();if(!o)return h("send_input failed: message must not be empty",!0);if(r.status==="closed")return h(`send_input failed: agent ${e} is closed; run resume_agent first`,!0);if(r.running){if(!n)return h(`send_input failed: agent ${e} is busy; set interrupt=true to cancel current submission`,!0);await ca(r)}try{let s=await la(r,o);return h(JSON.stringify({agent_id:r.id,status:r.status,submission_id:s},null,2))}catch(s){return h(`send_input failed: ${s.message}`,!0)}}}),da=D({name:"resume_agent",description:"Resume a previously closed agent by id.",inputSchema:$f,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=Je.get(e);return t?(t.status==="closed"&&(t.status=t.statusBeforeClose,t.updatedAt=bt()),h(JSON.stringify({agent_id:e,status:t.status},null,2))):mo(e)}}),ma=D({name:"wait",description:"Wait for agent statuses and return current snapshots.",inputSchema:Df,supportsParallelToolCalls:!1,isMutating:!1,execute:async({ids:e,timeout_ms:t})=>{let n=zf(t);if(n===null)return h("wait failed: timeout_ms must be greater than zero",!0);let r=()=>{let i={},c={};for(let a of e){let l=qf(a);Wf(l)&&(i[a]=l,c[a]=Vf(a))}return{status:i,details:c}},o=r();if(Object.keys(o.status).length>0)return h(JSON.stringify({status:o.status,details:o.details,timed_out:!1},null,2));let s=Date.now()+n;for(;Date.now()<s;)if(await jf(100),o=r(),Object.keys(o.status).length>0)return h(JSON.stringify({status:o.status,details:o.details,timed_out:!1},null,2));return h(JSON.stringify({status:{},details:{},timed_out:!0},null,2))}}),fa=D({name:"close_agent",description:"Close an agent and return its last known status.",inputSchema:Uf,supportsParallelToolCalls:!1,isMutating:!0,execute:async({id:e})=>{let t=Je.get(e);return t?t.status==="closed"?h(JSON.stringify({agent_id:e,status:"closed"},null,2)):(t.statusBeforeClose=t.running?"completed":t.status,t.status="closed",t.updatedAt=bt(),await ca(t),h(JSON.stringify({agent_id:e,status:"closed"},null,2))):mo(e)}});var fo={list_mcp_resources:"read",list_mcp_resource_templates:"read",read_mcp_resource:"read",update_plan:"read",get_memory:"read",webfetch:"read",read_file:"read",list_dir:"read",grep_files:"read",wait:"read",spawn_agent:"read",send_input:"read",resume_agent:"read",close_agent:"read",apply_patch:"write",shell:"execute",shell_command:"execute",exec_command:"execute",write_stdin:"execute"},ga=new Set(["spawn_agent","send_input","resume_agent","wait","close_agent"]),Ln={read:0,write:1,execute:2},ha=["exec","run","shell","command","stdin"],ya=["write","patch","create","delete","modify","update"],_a=["read","get","fetch","search","list","find"],Sa=new Set(["write","execute"]);function ho(e){let t={...fo,...e?.customLevels};return{getRiskLevel(n){if(n in t)return t[n];let r=n.toLowerCase();return go(r,ha)?"execute":go(r,ya)?"write":go(r,_a)?"read":"write"},compareRisk(n,r){return Ln[n]-Ln[r]},needsApproval(n,r){return r==="strict"?!0:Sa.has(n)}}}function go(e,t){return t.some(n=>e.includes(n))}import{createHash as Yf}from"crypto";function Nn(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map(n=>Nn(n)).join(",")+"]":`{${Object.entries(e).sort(([n],[r])=>n.localeCompare(r)).map(([n,r])=>`${JSON.stringify(n)}:${Nn(r)}`).join(",")}}`}function yo(e,t){let n=Nn(t),r=`${e}:${n}`;return Yf("sha256").update(r).digest("hex").slice(0,16)}function Qf(e){return`Tool "${e}" requires approval.`}function _o(e){let{mode:t="auto",dangerous:n=!1,toolRiskLevels:r}=e||{},o=t==="strict"?"strict":"auto";if(n)return{isDangerousMode:!0,getRiskLevel:()=>"read",check:()=>({needApproval:!1,decision:"auto-execute"}),recordDecision:()=>{},isGranted:()=>!0,clearOnceApprovals:()=>{},dispose:()=>{}};let s=ho({customLevels:r}),i={sessionTools:new Set,onceTools:new Set,deniedTools:new Set,toolByFingerprint:new Map};return{get isDangerousMode(){return!1},getRiskLevel(c){return s.getRiskLevel(c)},check(c,a){if(ga.has(c))return{needApproval:!1,decision:"auto-execute"};let l=s.getRiskLevel(c);if(!s.needsApproval(l,o))return{needApproval:!1,decision:"auto-execute"};let p=yo(c,a);return i.toolByFingerprint.set(p,c),i.sessionTools.has(c)||i.onceTools.has(c)?{needApproval:!1,decision:"auto-execute"}:i.deniedTools.has(c)?{needApproval:!0,fingerprint:p,riskLevel:l,reason:"This request was previously denied.",toolName:c,params:a}:{needApproval:!0,fingerprint:p,riskLevel:l,reason:Qf(c),toolName:c,params:a}},recordDecision(c,a){let l=i.toolByFingerprint.get(c);if(l)switch(i.sessionTools.delete(l),i.onceTools.delete(l),i.deniedTools.delete(l),a){case"session":i.sessionTools.add(l);break;case"once":i.onceTools.add(l);break;case"deny":i.deniedTools.add(l);break}},isGranted(c){let a=i.toolByFingerprint.get(c);return a?i.sessionTools.has(a)||i.onceTools.has(a):!1},clearOnceApprovals(){i.onceTools.clear()},dispose(){i.sessionTools.clear(),i.onceTools.clear(),i.deniedTools.clear(),i.toolByFingerprint.clear()}}}var va=1e5;function Zf(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function eg(e){let t=0;for(let n of e.content??[]){if(n.type==="text"){t+=n.text.length;continue}try{t+=JSON.stringify(n).length}catch{t+=100}}return t}function tg(e,t,n){return`<system_hint type="tool_output_omitted" tool="${Zf(e)}" reason="too_long" actual_chars="${t}" max_chars="${n}">Tool output too long, automatically omitted. Please narrow the scope or add limit parameters and try again.</system_hint>`}function ng(e,t){let n=An(),r=eg(t);return r<=n?t:{content:[{type:"text",text:tg(e,r,n)}],isError:!1}}function rg(e){return(e.content?.flatMap(n=>n.type==="text"?[n.text]:[])??[]).join(`
|
|
66
|
+
`)}function Ta(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function og(e,t){let n=t;if(typeof t=="string"){if(t.length>va)return{ok:!1,error:`${e.name} invalid input: input string too large (max ${va} chars)`};let r=t.trim();if(r)try{n=JSON.parse(r)}catch{n=r}else n={}}if(!Ta(n))return{ok:!1,error:`${e.name} invalid input: expected object`};if(typeof e.validateInput=="function"){let r=e.validateInput(n);return r.ok?Ta(r.data)?{ok:!0,data:r.data}:{ok:!1,error:`${e.name} invalid input: expected object`}:r}return{ok:!0,data:n}}function sg(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("sandbox")||t.includes("permission denied")||t.includes("operation not permitted")||t.includes("eacces")?"sandbox_denied":"execution_failed"}var So=class{constructor(t){this.config=t;this.approvalManager=_o(t.approval)}approvalManager;async executeAction(t,n){let r=Date.now(),o=t.id??`${t.name}:${r}`,s=this.approvalManager.check(t.name,t.input);if(s.needApproval){let c={toolName:s.toolName,params:s.params,fingerprint:s.fingerprint,riskLevel:s.riskLevel,reason:s.reason};await n?.onApprovalRequest?.(c);let a=n?.requestApproval?await n.requestApproval(c):"deny";if(this.approvalManager.recordDecision(s.fingerprint,a),await n?.onApprovalResponse?.({fingerprint:s.fingerprint,decision:a}),a==="deny")return{actionId:o,tool:t.name,status:"approval_denied",errorType:"approval_denied",success:!1,observation:`User denied tool execution: ${t.name}`,durationMs:Date.now()-r,rejected:!0}}let i=this.config.tools[t.name];if(!i)return{actionId:o,tool:t.name,status:"tool_not_found",errorType:"tool_not_found",success:!1,observation:`Unknown tool: ${t.name}`,durationMs:Date.now()-r};try{let c=og(i,t.input);if(!c.ok)return{actionId:o,tool:t.name,status:"input_invalid",errorType:"input_invalid",success:!1,observation:c.error,durationMs:Date.now()-r};let a=await i.execute(c.data),l=ng(t.name,a);return{actionId:o,tool:t.name,status:"success",success:!0,observation:rg(l)||"(no tool output)",durationMs:Date.now()-r}}catch(c){let a=sg(c);return{actionId:o,tool:t.name,status:a,errorType:a,success:!1,observation:`Tool execution failed: ${c.message}`,durationMs:Date.now()-r}}}async executeActions(t,n={}){let r=n.executionMode??"sequential",o=n.failurePolicy??(n.stopOnRejection===!1?"collect_all":"fail_fast"),s=[];if(r==="parallel"){let a=await Promise.all(t.map(l=>this.executeAction(l,n)));if(o==="fail_fast"){let l=a.findIndex(p=>p.rejected);s=l>=0?a.slice(0,l+1):a}else s=a}else for(let a of t){let l=await this.executeAction(a,n);if(s.push(l),l.rejected&&o==="fail_fast")break}let i=s.some(a=>a.rejected),c=s.map(a=>`[${a.tool}]: ${a.observation}`).join(`
|
|
67
67
|
|
|
68
|
-
`);return{results:s,combinedObservation:c,hasRejection:i,executionMode:r,failurePolicy:o}}clearOnceApprovals(){this.approvalManager.clearOnceApprovals()}dispose(){this.approvalManager.dispose()}};function
|
|
68
|
+
`);return{results:s,combinedObservation:c,hasRejection:i,executionMode:r,failurePolicy:o}}clearOnceApprovals(){this.approvalManager.clearOnceApprovals()}dispose(){this.approvalManager.dispose()}};function wa(e){return new So(e)}var $n=class{tools=new Map;register(t){this.tools.set(t.name,t)}registerMany(t){for(let n of t)this.register(n)}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,r]of this.tools)t[n]=r;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}};import{Client as ig}from"@modelcontextprotocol/sdk/client/index.js";import{StreamableHTTPClientTransport as ag}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{StdioClientTransport as cg}from"@modelcontextprotocol/sdk/client/stdio.js";import{UnauthorizedError as lg}from"@modelcontextprotocol/sdk/client/auth.js";import{StreamableHTTPError as ug}from"@modelcontextprotocol/sdk/client/streamableHttp.js";function pg(e){if(!e)return;let t={...process.env,...e},n=Object.entries(t).filter(r=>typeof r[1]=="string");return Object.fromEntries(n)}function Ca(){return new ig({name:"memo-code-cli-client",version:"1.0.0"},{capabilities:{}})}function dg(e){if(!(!e||Object.keys(e).length===0))return{headers:e}}function mg(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 fg(e,t,n){let r=new URL(t.url),o=dg(mg(t)),s=await ri({serverName:e,config:t,settings:n});try{let i=Ca(),c=new ag(r,{requestInit:o,...s?{authProvider:s}:{}});return await i.connect(c),{client:i,transport:c}}catch(i){let c=hg(i)?` Run "memo mcp login ${e}".`:"",a=`Failed to connect via streamable_http (${i.message}).${c}`,l=new Error(a);throw l.cause=i,l}}async function gg(e,t,n){if("url"in t)return fg(e,t,n);let r={command:t.command,args:t.args,env:pg(t.env),stderr:t.stderr??(process.stdout.isTTY&&process.stdin.isTTY?"ignore":void 0)},o=new cg(r),s=Ca();return await s.connect(o),{client:s,transport:o}}var Dn=class{connections=new Map;pendingConnections=new Map;serverConfigs=new Map;oauthSettings;setServerConfigs(t,n){this.serverConfigs=new Map(Object.entries(t)),this.oauthSettings=n}hasServer(t){return this.connections.has(t)||this.serverConfigs.has(t)}async connect(t,n){n&&this.serverConfigs.set(t,n);let r=this.connections.get(t);if(r)return r;let o=this.pendingConnections.get(t);if(o)return o;let s=n??this.serverConfigs.get(t);if(!s)throw new Error(`MCP server config not found: ${t}`);let i=(async()=>{let{client:c,transport:a}=await gg(t,s,this.oauthSettings);try{let l=await c.listTools(),p={name:t,client:c,transport:a,tools:(l.tools||[]).map(u=>({name:`${t}_${u.name}`,description:u.description||`Tool from ${t}: ${u.name}`,source:"mcp",serverName:t,originalName:u.name,inputSchema:u.inputSchema,execute:async()=>({content:[]})}))};return this.connections.set(t,p),p}catch(l){try{await c.close()}catch{}throw l}})();this.pendingConnections.set(t,i);try{return await i}finally{this.pendingConnections.delete(t)}}get(t){return this.connections.get(t)}getAll(){return Array.from(this.connections.values())}getKnownServerNames(){let t=new Set([...Array.from(this.serverConfigs.keys()),...Array.from(this.connections.keys())]);return Array.from(t.values())}getAllTools(){let t=[];for(let n of this.connections.values())for(let r of n.tools)t.push({name:r.name,description:r.description,serverName:r.serverName,originalName:r.originalName,inputSchema:r.inputSchema,client:n.client});return t}async closeAll(){let t=Array.from(this.connections.values()).map(async n=>{try{await n.client.close()}catch(r){console.error(`[MCP] Error closing client ${n.name}:`,r)}});await Promise.all(t),this.connections.clear(),this.pendingConnections.clear()}get size(){return this.connections.size}};function hg(e){if(e instanceof lg)return!0;if(e instanceof ug)return e.code===401||e.code===403;let t=e?.message?.toLowerCase()??"";return t.includes("unauthorized")||t.includes("401")||t.includes("403")||t.includes("oauth")}var Un=class{pool;serverToolNames=new Map;refreshPromises=new Map;tools=new Map;cacheStore=In();shouldLog;constructor(){this.pool=new Dn,io(this.pool),ao(this.cacheStore),this.shouldLog=!(process.stdout.isTTY&&process.stdin.isTTY)}buildTool(t,n,r){return{name:`${t}_${r.originalName}`,description:r.description||`Tool from ${t}: ${r.originalName}`,source:"mcp",serverName:t,originalName:r.originalName,inputSchema:r.inputSchema??{},execute:async o=>(await this.pool.connect(t,n)).client.callTool({name:r.originalName,arguments:o})}}replaceServerTools(t,n){let r=this.serverToolNames.get(t);if(r)for(let s of r)this.tools.delete(s);let o=new Set;for(let s of n)this.tools.set(s.name,s),o.add(s.name);this.serverToolNames.set(t,o)}connectionToDescriptors(t,n){return n.tools.map(r=>({originalName:r.originalName,description:r.description||`Tool from ${t}: ${r.originalName}`,inputSchema:r.inputSchema}))}async refreshServer(t,n,r){let o=this.refreshPromises.get(t);if(o){r==="sync"&&await o;return}let s=(async()=>{try{let i=await this.pool.connect(t,n),c=this.connectionToDescriptors(t,i);await this.cacheStore.setServerTools(t,n,c);let a=c.map(l=>this.buildTool(t,n,l));this.replaceServerTools(t,a),this.shouldLog&&r==="background"&&console.log(`[MCP] Refreshed '${t}' tools in background (${a.length})`)}catch(i){this.shouldLog&&console.error(`[MCP] Failed to refresh server '${t}':`,i)}})();this.refreshPromises.set(t,s),s.finally(()=>{this.refreshPromises.delete(t)}),r==="sync"&&await s}removeToolsForMissingServers(t){for(let[n,r]of this.serverToolNames.entries())if(!t.has(n)){for(let o of r)this.tools.delete(o);this.serverToolNames.delete(n)}}async loadServers(t){return this.loadServersWithOptions(t)}async loadServersWithOptions(t,n){if(!t||Object.keys(t).length===0)return 0;let r=Object.entries(t);this.pool.setServerConfigs(t,n),this.removeToolsForMissingServers(new Set(r.map(([s])=>s)));let o=[];for(let[s,i]of r){let c=await this.cacheStore.getServerTools(s,i);if(c){let a=c.tools.map(l=>this.buildTool(s,i,l));this.replaceServerTools(s,a),this.shouldLog&&console.log(`[MCP] Loaded ${a.length} cached tools for '${s}' (${c.stale?"stale":"fresh"})`),c.stale&&this.refreshServer(s,i,"background");continue}o.push(this.refreshServer(s,i,"sync"))}return await Promise.all(o),this.tools.size}get(t){return this.tools.get(t)}getAll(){return Array.from(this.tools.values())}toRegistry(){let t={};for(let[n,r]of this.tools)t[n]=r;return t}has(t){return this.tools.has(t)}get size(){return this.tools.size}async dispose(){await this.pool.closeAll(),this.tools.clear(),this.serverToolNames.clear(),this.refreshPromises.clear(),io(null),ao(null)}getPool(){return this.pool}};var Fn=class{nativeRegistry;mcpRegistry;constructor(){this.nativeRegistry=new $n,this.mcpRegistry=new Un}registerNativeTool(t){this.nativeRegistry.register(t)}registerNativeTools(t){for(let n of t)this.registerNativeTool(n)}async loadMcpServers(t,n){return this.mcpRegistry.loadServersWithOptions(t,n)}getTool(t){return this.nativeRegistry.get(t)??this.mcpRegistry.get(t)}getAllTools(){return[...this.nativeRegistry.getAll(),...this.mcpRegistry.getAll()]}toRegistry(){return{...this.nativeRegistry.toRegistry(),...this.mcpRegistry.toRegistry()}}hasTool(t){return this.nativeRegistry.has(t)||this.mcpRegistry.has(t)}getToolCount(){let t=this.nativeRegistry.size,n=this.mcpRegistry.size;return{native:t,mcp:n,total:t+n}}async execute(t,n){let r=this.getTool(t);if(!r)throw new Error(`Tool '${t}' not found`);return r.execute(n)}generateToolDefinitions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema||{type:"object",properties:{}}}))}generateToolDescriptions(){let t=this.getAllTools();if(t.length===0)return"";let n=[];n.push("## Available Tools"),n.push("");let r=t.filter(s=>s.source==="native"),o=t.filter(s=>s.source==="mcp");if(r.length>0){n.push("### Built-in Tools"),n.push("");for(let s of r)n.push(this.formatToolDescription(s));n.push("")}if(o.length>0){n.push("### External MCP Tools"),n.push("");let s=this.groupByServer(o);for(let[i,c]of Object.entries(s)){n.push(`**Server: ${i}**`),n.push("");for(let a of c)n.push(this.formatToolDescription(a));n.push("")}}return n.join(`
|
|
69
69
|
`)}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(`
|
|
70
|
-
`)}groupByServer(t){let n={};for(let r of t)if(r.source==="mcp"){let o=r.serverName;n[o]||(n[o]=[]),n[o].push(r)}return n}getToolDescriptions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,source:t.source,serverName:t.source==="mcp"?t.serverName:void 0,inputSchema:t.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};function
|
|
70
|
+
`)}groupByServer(t){let n={};for(let r of t)if(r.source==="mcp"){let o=r.serverName;n[o]||(n[o]=[]),n[o].push(r)}return n}getToolDescriptions(){return this.getAllTools().map(t=>({name:t.name,description:t.description,source:t.source,serverName:t.source==="mcp"?t.serverName:void 0,inputSchema:t.inputSchema}))}async dispose(){await this.mcpRegistry.dispose()}};function yg(e){let t=process.env[e]?.trim();return t?new Set(t.split(",").map(n=>n.trim()).filter(Boolean)):new Set}function _g(){let e=[],t=process.env.MEMO_SHELL_TOOL_TYPE?.trim()||"unified_exec",n=yg("MEMO_EXPERIMENTAL_TOOLS"),r=n.size===0,o=process.env.MEMO_ENABLE_COLLAB_TOOLS!=="0",s=process.env.MEMO_ENABLE_MEMORY_TOOL!=="0";return t==="shell"?e.push(yi):t==="shell_command"?e.push(_i):t==="unified_exec"?e.push(Kr,qr):t!=="disabled"&&e.push(Kr,qr),e.push(Xi,Ji,Yi),e.push(Zi),e.push(Ii),(r||n.has("grep_files"))&&e.push(Di),(r||n.has("read_file"))&&e.push(Ni),(r||n.has("list_dir"))&&e.push($i),s&&e.push(na),e.push(sa),o&&e.push(ua,pa,da,ma,fa),e}function Sg(e){let t={};for(let n of e)t[n.name]=n;return t}var vg=Sg(_g()),Tg=Object.values(vg),ba=Tg;import Eg from"openai";import{encoding_for_model as wg,get_encoding as Cg}from"@dqbd/tiktoken";var xa="cl100k_base";function bg(e){let t=e?.trim()||xa;try{let n=()=>wg(t);return n().free(),{model:t,factory:n}}catch{let n=xa,r=()=>Cg(n);return r().free(),{model:n,factory:r}}}function xg(e){if(e.role==="assistant"){let t=e.reasoning_content?`
|
|
71
71
|
${e.reasoning_content}`:"";return e.tool_calls?.length?`${e.content}${t}
|
|
72
72
|
${JSON.stringify(e.tool_calls)}`:`${e.content}${t}`}return e.role==="tool"?`${e.content}
|
|
73
73
|
${e.tool_call_id}
|
|
74
|
-
${e.name??""}`:e.content}function
|
|
74
|
+
${e.name??""}`:e.content}function Ma(e){let{model:t,factory:n}=bg(e),r=n(),o=4,s=2,i=1,c=l=>l?r.encode(l).length:0;return{model:t,countText:c,countMessages:l=>{if(!l.length)return 0;let p=0;for(let u of l)p+=o,p+=c(xg(u)),u.name&&(p+=i);return p+=s,p},dispose:()=>r.free()}}import"openai";var Mg={supportsParallelToolCalls:!1,supportsReasoningContent:!1};function vo(e){return e.trim().toLowerCase()}function kg(e,t,n){if(!n)return;let r=new Map;for(let[s,i]of Object.entries(n))r.set(vo(s),i);let o=r.get(`${e}:${t}`);return o||r.get(t)}function Ag(e,t){if(!t)return{capabilities:e,usedOverride:!1};let n={...e},r=!1;return typeof t.supports_parallel_tool_calls=="boolean"&&(n.supportsParallelToolCalls=t.supports_parallel_tool_calls,r=!0),typeof t.supports_reasoning_content=="boolean"&&(n.supportsReasoningContent=t.supports_reasoning_content,r=!0),typeof t.context_window=="number"&&Number.isFinite(t.context_window)&&t.context_window>0&&(n.contextWindow=Math.floor(t.context_window),r=!0),{capabilities:n,usedOverride:r}}function ka(e,t){let n=vo(e.name),r=vo(e.model),{capabilities:o,usedOverride:s}=Ag(Mg,kg(n,r,t));return{profile:{wireApi:"chat_completions",...o,isFallback:!s}}}function Pg(e){if(e.length!==0)return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.input_schema}}))}function Aa(e){let t=Pg(e.toolDefinitions),n={model:e.model,messages:e.messages,tools:t,tool_choice:t?"auto":void 0};return t&&e.profile.supportsParallelToolCalls&&(n.parallel_tool_calls=!0),n}function Rg(e,t){if(!e||!t)return e;let n=new Set(t.map(o=>o.trim()).filter(Boolean));if(n.size===0)return{};let r={};for(let[o,s]of Object.entries(e))n.has(o)&&(r[o]=s);return r}function Ig(e){try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,raw:e,error:t.message}}}function Og(e){if(e.role==="assistant"){let t={role:"assistant",content:e.content,tool_calls:e.tool_calls?.map(n=>({id:n.id,type:n.type,function:{name:n.function.name,arguments:n.function.arguments}}))};return e.reasoning_content&&(t.reasoning_content=e.reasoning_content),t}return e.role==="tool"?{role:"tool",content:e.content,tool_call_id:e.tool_call_id}:{role:e.role,content:e.content}}function Lg(e){let t=e?.reasoning_content;if(typeof t!="string")return;let n=t.trim();return n.length>0?n:void 0}function Ng(e){return!e||typeof e!="object"?!1:Array.isArray(e.choices)}async function Pa(e,t,n){let r=await te(),o=r.config,s=new Fn;if(s.registerNativeTools(ba),await s.loadMcpServers(Rg(o.mcp_servers,t.activeMcpServers),{memoHome:r.home,storeMode:o.mcp_oauth_credentials_store_mode,callbackPort:o.mcp_oauth_callback_port}),e.tools)for(let[d,m]of Object.entries(e.tools))s.registerNativeTool({name:d,description:m.description,source:"native",inputSchema:{type:"object"},execute:m.execute});let i=s.toRegistry(),c=async()=>{let d=e.loadPrompt?await e.loadPrompt():await ls({cwd:t.cwd,memoHome:r.home,activeSkillPaths:o.active_skills}),m=s.generateToolDescriptions();return m&&(d+=`
|
|
75
75
|
|
|
76
|
-
${m}`),d},a=s.generateToolDefinitions(),l=
|
|
77
|
-
`),{thinkingParts:n,cleaned:r}
|
|
76
|
+
${m}`),d},a=s.generateToolDefinitions(),l=Gt(r,t),p=Ws(l,n),u=new dn(p);return{tools:i,dispose:async()=>{e.dispose&&await e.dispose(),await s.dispose()},callLLM:e.callLLM??(async(d,m,g)=>{let y=lt(o,t.providerName),b=process.env[y.env_api_key]??process.env.OPENAI_API_KEY??process.env.DEEPSEEK_API_KEY;if(!b)throw new Error(`Missing env var ${y.env_api_key} (or OPENAI_API_KEY/DEEPSEEK_API_KEY)`);let U=new Eg({apiKey:b,baseURL:y.base_url}),T=d.map(Og),{profile:H}=ka(y,o.model_profiles),R=g?.tools??a,I=Aa({model:y.model,messages:T,toolDefinitions:R,profile:H}),G=await U.chat.completions.create(I,{signal:g?.signal});if(!Ng(G))throw new Error("Streaming response is not supported in core callLLM");let ie=G.choices?.[0]?.message,Re=Lg(ie);if(ie?.tool_calls&&ie.tool_calls.length>0){let z=[];ie.content&&z.push({type:"text",text:ie.content});for(let P of ie.tool_calls)if(P.type==="function"){let ne=Ig(P.function.arguments);ne.ok?z.push({type:"tool_use",id:P.id,name:P.function.name,input:ne.data}):z.push({type:"text",text:`[tool_use parse error] ${ne.error}; raw: ${ne.raw}`})}let M=z.some(P=>P.type==="tool_use");return{content:z,reasoning_content:Re,stop_reason:M?"tool_use":"end_turn",usage:{prompt:G.usage?.prompt_tokens??void 0,completion:G.usage?.completion_tokens??void 0,total:G.usage?.total_tokens??void 0}}}let ae=ie?.content;if(typeof ae!="string")throw new Error("OpenAI-compatible API returned empty content");return{content:[{type:"text",text:ae}],reasoning_content:Re,stop_reason:"end_turn",usage:{prompt:G.usage?.prompt_tokens??void 0,completion:G.usage?.completion_tokens??void 0,total:G.usage?.total_tokens??void 0}}}),loadPrompt:c,historySinks:e.historySinks??[u],tokenCounter:e.tokenCounter??Ma(t.tokenizerModel),historyFilePath:p}}function $g(e){let t=[],n=/<\s*(think|thinking)\s*>([\s\S]*?)<\/\s*\1\s*>/gi,r=e.replace(n,(o,s,i)=>{let c=(i??"").trim();return c&&t.push(c),c});return{thinkingParts:t,cleaned:r.trim()}}function Ea(e){if(e.length===0)return;let t=e.join(`
|
|
77
|
+
`),{thinkingParts:n,cleaned:r}=$g(t);return n.length>0?n.join(`
|
|
78
78
|
|
|
79
|
-
`):r||void 0}import{randomUUID as
|
|
80
|
-
`)}function
|
|
81
|
-
`),toolUseBlocks:n.map(r=>({id:r.id,name:r.name,input:r.input})),reasoningContent:typeof e.reasoning_content=="string"&&e.reasoning_content.trim().length>0?e.reasoning_content:void 0,stopReason:e.stop_reason,usage:e.usage}}async function
|
|
79
|
+
`):r||void 0}import{randomUUID as qg}from"crypto";var Hn="interactive";var wo="success",xt="Tool usage is disabled in the current permission mode. Switch to /tools once or /tools full to enable tools.";var Dg="Skipped tool execution after previous rejection.",Ra="Tool execution skipped: tools are disabled in current permission mode.";function Ug(e){process.stderr.write(`${JSON.stringify(e)}
|
|
80
|
+
`)}function Ia(e){if(e.toolPermissionMode==="none")return{mode:"none",toolsDisabled:!0,dangerous:!1,approvalMode:"auto"};if(e.toolPermissionMode==="once")return{mode:"once",toolsDisabled:!1,dangerous:!1,approvalMode:"auto"};if(e.toolPermissionMode==="full")return{mode:"full",toolsDisabled:!1,dangerous:!0,approvalMode:"auto"};let t=e.dangerous??!1;return{mode:t?"full":"auto",toolsDisabled:!1,dangerous:t,approvalMode:"auto"}}function Co(){return{prompt:0,completion:0,total:0}}function bo(e,t){if(!t)return;let n=t.prompt??0,r=t.completion??0,o=t.total??n+r;e.prompt+=n,e.completion+=r,e.total+=o}function xo(e){let t=e.content.filter(r=>r.type==="text"),n=e.content.filter(r=>r.type==="tool_use");return{textContent:t.map(r=>r.text).join(`
|
|
81
|
+
`),toolUseBlocks:n.map(r=>({id:r.id,name:r.name,input:r.input})),reasoningContent:typeof e.reasoning_content=="string"&&e.reasoning_content.trim().length>0?e.reasoning_content:void 0,stopReason:e.stop_reason,usage:e.usage}}async function Oa(e,t){for(let n of t)try{await n.append(e)}catch(r){Ug({level:"error",event:"history_sink_append_failed",sink:n.constructor?.name||"anonymous_sink",message:r.message})}}function La(e){if(!(e instanceof Error))return!1;if(e.name==="AbortError")return!0;let t=e.message?.toLowerCase?.()??"";return t.includes("request was aborted")||t.includes("operation was aborted")||t.includes("aborted")}function Bn(e){return To(e,new WeakSet,0)}var Fg=100;function To(e,t,n){if(n>Fg)return JSON.stringify("[MaxDepthExceeded]");if(typeof e=="bigint")return JSON.stringify(e.toString());if(e===null||typeof e!="object")return JSON.stringify(e)??"null";if(t.has(e))return JSON.stringify("[Circular]");if(t.add(e),Array.isArray(e)){let s=`[${e.map(i=>To(i,t,n+1)).join(",")}]`;return t.delete(e),s}let o=`{${Object.entries(e).sort(([s],[i])=>s.localeCompare(i)).map(([s,i])=>`${JSON.stringify(s)}:${To(i,t,n+1)}`).join(",")}}`;return t.delete(e),o}function Na(e){return e.map(t=>({id:t.id,type:"function",function:{name:t.name,arguments:Bn(t.input)}}))}function $a(e,t){let n=e.trim();if(!n)return null;let r=[n],o=n.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);o?.[1]&&r.push(o[1].trim());for(let s of r)if(!(!s.startsWith("{")||!s.endsWith("}")))try{let i=JSON.parse(s);if(!i||typeof i!="object"||Array.isArray(i))continue;let c=i,a=typeof c.tool=="string"?c.tool.trim():"";if(!a||!Object.prototype.hasOwnProperty.call(t,a))continue;return{tool:a,input:c.input??{}}}catch{}return null}function Hg(e){return e.length<=60?e:`${e.slice(0,57).trimEnd()}...`}function Da(e){let t=e.replace(/\s+/g," ").trim();if(!t)return"New Session";if(!t.includes(" "))return t.length<=20?t:`${t.slice(0,20).trimEnd()}...`;let r=t.split(" ").filter(Boolean).slice(0,8).join(" ");return Hg(r||t)}function Mo(e){return{role:"tool",content:e.observation,tool_call_id:e.actionId,name:e.tool}}function Ua(e,t,n){let r=new Map(t.map(o=>[o.actionId,o]));return e.map(o=>{let s=r.get(o.id);return s||{actionId:o.id,tool:o.name,status:n?"approval_denied":"execution_failed",errorType:n?"approval_denied":"execution_failed",success:!1,observation:n?`${Dg} ${o.name}`:`Tool result missing for ${o.name}; execution aborted before producing output.`,durationMs:0,rejected:n?!0:void 0}})}import{randomUUID as zg}from"crypto";var Fa=`You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary for another LLM that will resume the task.
|
|
82
82
|
|
|
83
83
|
Include:
|
|
84
84
|
- Current progress and key decisions made
|
|
@@ -86,38 +86,38 @@ Include:
|
|
|
86
86
|
- What remains to be done (clear next steps)
|
|
87
87
|
- Any critical data, examples, or references needed to continue
|
|
88
88
|
|
|
89
|
-
Be concise, structured, and focused on helping the next LLM seamlessly continue the work.`,
|
|
90
|
-
`).trim();return t.length<=4e3?t:`${t.slice(0,4e3)}...`}function
|
|
91
|
-
${
|
|
92
|
-
${
|
|
93
|
-
${
|
|
94
|
-
`)}function
|
|
89
|
+
Be concise, structured, and focused on helping the next LLM seamlessly continue the work.`,Ao="Another language model started to solve this problem and produced a summary of its thinking process. Use this summary to continue the task without redoing completed work.";function ko(e){let t=e.replace(/\r\n/g,`
|
|
90
|
+
`).trim();return t.length<=4e3?t:`${t.slice(0,4e3)}...`}function Bg(e,t){let n=e.role.toUpperCase();if(e.role==="assistant"&&e.tool_calls?.length){let r=e.tool_calls.map(o=>o.function.name).join(", ");return`[${t}] ${n} (tool_calls: ${r})
|
|
91
|
+
${ko(e.content)}`}if(e.role==="tool"){let r=e.name?` (${e.name})`:"";return`[${t}] ${n}${r}
|
|
92
|
+
${ko(e.content)}`}return`[${t}] ${n}
|
|
93
|
+
${ko(e.content)}`}function Ha(e){return e.role!=="user"?!1:e.content.startsWith(`${Ao}
|
|
94
|
+
`)}function Ba(e){return["Conversation history to summarize:",e.length?e.map((n,r)=>Bg(n,r)).join(`
|
|
95
95
|
|
|
96
96
|
`):"(empty)","","Return only the summary body in plain text. Do not add markdown fences."].join(`
|
|
97
|
-
`)}function
|
|
98
|
-
${t}`};return n?[n,...s,i]:[...s,i]}selectCompactionUserMessages(t){if(!t.length)return[];let n=[],r=
|
|
97
|
+
`)}function Wg(){return{onTurnStart:[],onContextUsage:[],onContextCompacted:[],onAction:[],onObservation:[],onFinal:[],onApprovalRequest:[],onApprovalResponse:[],onTitleGenerated:[]}}function Wa(e,t){t&&(t.onTurnStart&&e.onTurnStart.push(t.onTurnStart),t.onContextUsage&&e.onContextUsage.push(t.onContextUsage),t.onContextCompacted&&e.onContextCompacted.push(t.onContextCompacted),t.onAction&&e.onAction.push(t.onAction),t.onObservation&&e.onObservation.push(t.onObservation),t.onFinal&&e.onFinal.push(t.onFinal),t.onApprovalRequest&&e.onApprovalRequest.push(t.onApprovalRequest),t.onApprovalResponse&&e.onApprovalResponse.push(t.onApprovalResponse),t.onTitleGenerated&&e.onTitleGenerated.push(t.onTitleGenerated))}function ja(e){let t=Wg();if(Wa(t,e.hooks),Array.isArray(e.middlewares))for(let n of e.middlewares)Wa(t,n);return t}async function V(e,t,n){let r=e[t];if(r.length)for(let o of r)try{await o(n)}catch(s){console.warn(`Hook ${t} failed: ${s.message}`)}}function Mt(e){return e.map(t=>t.role==="assistant"&&t.tool_calls?.length?{...t,tool_calls:t.tool_calls.map(n=>({...n,function:{...n.function}}))}:{...t})}var Gg=80,Kg=2e4,Wn=class{constructor(t,n,r,o,s){this.deps=t;this.options=n;this.id=n.sessionId||zg(),this.mode=n.mode||Hn,this.history=[{role:"system",content:r}],this.tokenCounter=o,this.sinks=t.historySinks??[],this.hooks=ja(t),this.historyFilePath=s;let i=Ia(n);this.toolsDisabled=i.toolsDisabled,this.toolPermissionMode=i.mode,this.toolOrchestrator=wa({tools:t.tools,approval:{dangerous:i.dangerous,mode:i.approvalMode}})}title;id;mode;history;historyFilePath;turnIndex=0;tokenCounter;sinks;sessionUsage=Co();startedAt=Date.now();hooks;closed=!1;sessionStartEmitted=!1;currentAbortController=null;cancelling=!1;lastActionSignature=null;repeatedActionCount=0;toolOrchestrator;toolsDisabled=!1;toolPermissionMode="auto";async init(){}resetActionRepetition(){this.lastActionSignature=null,this.repeatedActionCount=0}maybeWarnRepeatedAction(t,n){let r=`${t}:${Bn(n)}`;if(this.lastActionSignature===r?this.repeatedActionCount+=1:(this.lastActionSignature=r,this.repeatedActionCount=1),this.repeatedActionCount===3){let o=Bn(n).slice(0,200),s=`\u7CFB\u7EDF\u63D0\u9192\uFF1A\u4F60\u5DF2\u8FDE\u7EED3\u6B21\u8C03\u7528\u540C\u4E00\u5DE5\u5177\u300C${t}\u300D\u4E14\u53C2\u6570\u76F8\u540C\uFF08${o}${o.length>=200?"\u2026":""}\uFF09\u3002\u8BF7\u786E\u8BA4\u662F\u5426\u9677\u5165\u5FAA\u73AF\uFF0C\u5FC5\u8981\u65F6\u76F4\u63A5\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\u6216\u8C03\u6574\u53C2\u6570\u3002`;this.history.push({role:"system",content:s})}}resolveContextWindow(){let t=this.options.contextWindow;return typeof t=="number"&&Number.isFinite(t)&&t>0?Math.floor(t):12e4}resolveSessionCwd(){let t=this.options.cwd?.trim();return t||process.cwd()}resolveAutoCompactThresholdPercent(){let t=this.options.autoCompactThresholdPercent;return typeof t=="number"&&Number.isInteger(t)&&Number.isFinite(t)&&t>=1&&t<=100?t:Gg}resolveThresholdTokens(t){let n=Math.floor(t*this.resolveAutoCompactThresholdPercent()/100);return Math.max(1,n)}calculateUsagePercent(t,n){return t<=0||n<=0?0:Math.round(t/n*1e4)/100}async emitContextUsage(t,n,r,o,s,i){let c=this.calculateUsagePercent(r,o);await this.emitEvent("context_usage",{turn:t,step:n,meta:{phase:i,prompt_tokens:r,context_window:o,threshold_tokens:s,usage_percent:c}}),await V(this.hooks,"onContextUsage",{sessionId:this.id,turn:t,step:n,promptTokens:r,contextWindow:o,thresholdTokens:s,usagePercent:c,phase:i})}async emitContextCompacted(t,n,r){await this.emitEvent("context_compact",{turn:t,step:n,content:r.summary,meta:{reason:r.reason,status:r.status,before_tokens:r.beforeTokens,after_tokens:r.afterTokens,threshold_tokens:r.thresholdTokens,reduction_percent:r.reductionPercent,error_message:r.errorMessage}}),await V(this.hooks,"onContextCompacted",{sessionId:this.id,turn:t,step:n,reason:r.reason,status:r.status,beforeTokens:r.beforeTokens,afterTokens:r.afterTokens,thresholdTokens:r.thresholdTokens,reductionPercent:r.reductionPercent,summary:r.summary,errorMessage:r.errorMessage})}buildCompactedHistory(t){let n=this.history[0]?.role==="system"?this.history[0]:void 0,o=(n?this.history.slice(1):this.history).filter(c=>c.role==="user"&&!Ha(c)).map(c=>c.content),s=this.selectCompactionUserMessages(o).map(c=>({role:"user",content:c})),i={role:"user",content:`${Ao}
|
|
98
|
+
${t}`};return n?[n,...s,i]:[...s,i]}selectCompactionUserMessages(t){if(!t.length)return[];let n=[],r=Kg;for(let o=t.length-1;o>=0;o-=1){let s=t[o];if(!s)continue;let i=this.tokenCounter.countText(s);if(i<=r){if(n.push(s),r=Math.max(0,r-i),r===0)break;continue}r>0&&n.push(s.slice(0,r));break}return n.reverse(),n}normalizeCompactionSummary(t){return(t.replace(/<think>[\s\S]*?<\/think>/gi,"").trim()||t).replace(/\n{3,}/g,`
|
|
99
99
|
|
|
100
|
-
`).trim()}async compactHistoryInternal(t,n,r){let o=this.resolveContextWindow(),s=this.resolveThresholdTokens(o),i=this.tokenCounter.countMessages(this.history),a=(this.history[0]?.role==="system"?this.history[0]:void 0)?this.history.slice(1):this.history.slice();if(!a.length){let l={reason:t,status:"skipped",beforeTokens:i,afterTokens:i,thresholdTokens:s,reductionPercent:0};return await this.emitContextCompacted(n,r,l),l}try{let l=await this.deps.callLLM([{role:"system",content:
|
|
100
|
+
`).trim()}async compactHistoryInternal(t,n,r){let o=this.resolveContextWindow(),s=this.resolveThresholdTokens(o),i=this.tokenCounter.countMessages(this.history),a=(this.history[0]?.role==="system"?this.history[0]:void 0)?this.history.slice(1):this.history.slice();if(!a.length){let l={reason:t,status:"skipped",beforeTokens:i,afterTokens:i,thresholdTokens:s,reductionPercent:0};return await this.emitContextCompacted(n,r,l),l}try{let l=await this.deps.callLLM([{role:"system",content:Fa},{role:"user",content:Ba(a)}],void 0,{tools:[]}),p=xo(l),u=this.normalizeCompactionSummary(p.textContent);if(!u)throw new Error("Compaction model returned an empty summary.");let d=this.buildCompactedHistory(u),m=this.tokenCounter.countMessages(d);this.history.splice(0,this.history.length,...d);let g=i>0?Math.max(0,Math.round((i-m)/i*1e4)/100):0,y={reason:t,status:"success",beforeTokens:i,afterTokens:m,thresholdTokens:s,reductionPercent:g,summary:u};return await this.emitContextCompacted(n,r,y),y}catch(l){let p={reason:t,status:"failed",beforeTokens:i,afterTokens:i,thresholdTokens:s,reductionPercent:0,errorMessage:l.message};return await this.emitContextCompacted(n,r,p),p}}buildToolApprovalHooks(t,n){return{onApprovalRequest:async r=>{await V(this.hooks,"onApprovalRequest",{sessionId:this.id,turn:t,step:n,request:r})},requestApproval:async r=>this.deps.requestApproval?this.deps.requestApproval(r):"deny",onApprovalResponse:async({fingerprint:r,decision:o})=>{await V(this.hooks,"onApprovalResponse",{sessionId:this.id,turn:t,step:n,fingerprint:r,decision:o})}}}async executeToolAction(t,n,r,o,s){return this.toolOrchestrator.executeAction({id:t,name:n,input:r},this.buildToolApprovalHooks(o,s))}async maybeGenerateSessionTitle(t,n){if(t!==1||this.title)return;let r=Da(n);this.title=r,await this.emitEvent("session_title",{turn:t,content:r,meta:{source:"first_prompt",original_prompt:n}}),await V(this.hooks,"onTitleGenerated",{sessionId:this.id,turn:t,title:r,originalPrompt:n})}async runTurn(t){return pi({cwd:this.resolveSessionCwd()},async()=>{let n=new AbortController;this.currentAbortController=n,this.cancelling=!1,this.turnIndex+=1;let r=this.turnIndex,o=[],s=Co(),i=Date.now(),c=this.resolveContextWindow(),a=this.resolveThresholdTokens(c),l=this.resolveAutoCompactThresholdPercent(),p=!1;if(!this.sessionStartEmitted){let u=this.history[0]?.role==="system"?this.history[0].content:void 0;await this.emitEvent("session_start",{content:u,role:u?"system":void 0,meta:{mode:this.mode,cwd:this.resolveSessionCwd(),tokenizer:this.tokenCounter.model,warnPromptTokens:this.options.warnPromptTokens,contextWindow:c,autoCompactThresholdPercent:l,toolPermissionMode:this.toolPermissionMode}}),this.sessionStartEmitted=!0}this.history.push({role:"user",content:t});try{let u=this.tokenCounter.countMessages(this.history);await this.emitEvent("turn_start",{turn:r,content:t,meta:{tokens:{prompt:u}}}),await V(this.hooks,"onTurnStart",{sessionId:this.id,turn:r,input:t,promptTokens:u,history:Mt(this.history)}),await this.emitContextUsage(r,0,u,c,a,"turn_start"),await this.maybeGenerateSessionTitle(r,t);let d="",m="ok",g,y=0,b=null,U=-1;for(let T=0;;T++){let H=this.tokenCounter.countMessages(this.history);if(await this.emitContextUsage(r,T,H,c,a,"step_start"),!p&&H>=a&&(p=!0,await this.compactHistoryInternal("auto",r,T),H=this.tokenCounter.countMessages(this.history),await this.emitContextUsage(r,T,H,c,a,"post_compact")),H>c){let A=`Context tokens (${H}) exceed the limit. Please shorten the input or restart the session.`;this.history.push({role:"assistant",content:A}),m="prompt_limit",d=A,g=A,await this.emitEvent("final",{turn:r,step:T,content:A,role:"assistant",meta:{tokens:{prompt:H}}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:A,status:m,errorMessage:g,turnUsage:{...s},steps:o});break}this.options.warnPromptTokens&&H>this.options.warnPromptTokens&&console.warn(`Prompt tokens are near the limit: ${H}`);let R="",I=[],G,ie,Re,ae=!1;try{let A=await this.deps.callLLM(this.history,re=>{re&&(ae=!0),this.deps.onAssistantStep?.(re,T)},{signal:n.signal}),O=xo(A);R=O.textContent,I=O.toolUseBlocks,ie=O.stopReason,G=O.usage,Re=O.reasoningContent,R.trim().length>0&&(b=R,U=T)}catch(A){if(this.cancelling&&La(A)){m="cancelled",d="",g="Turn cancelled",await this.emitEvent("final",{turn:r,step:T,content:"",role:"assistant",meta:{cancelled:!0}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,errorMessage:g,turnUsage:{...s},steps:o});break}let O=`LLM call failed: ${A.message}`;this.history.push({role:"assistant",content:O}),m="error",d=O,g=O,await this.emitEvent("final",{turn:r,content:O,role:"assistant"}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,errorMessage:g,turnUsage:{...s},steps:o});break}!ae&&R&&this.deps.onAssistantStep?.(R,T);let z=I.length===0&&R?$a(R,this.deps.tools):null,M,P=null;if(I.length>0){let A=I[0];if(A){let O=R?Ea([R]):void 0;M={action:{tool:A.name,input:A.input},thinking:O},P={role:"assistant",content:R,reasoning_content:Re,tool_calls:Na(I)}}else M={}}else R?(M={final:R},P={role:"assistant",content:R,reasoning_content:Re}):M={};let ne=this.tokenCounter.countText(R),ce=G?.prompt??H,F=G?.completion??ne,le=G?.total??ce+F,J={prompt:ce,completion:F,total:le};if(bo(s,J),bo(this.sessionUsage,J),o.push({index:T,assistantText:R,parsed:M,tokenUsage:J}),await this.emitEvent("assistant",{turn:r,step:T,content:R,role:"assistant",meta:{tokens:J,protocol_violation:!!z,protocol_violation_count:z?y+1:y||void 0}}),z){y+=1;let A=`Model protocol error: returned plain-text tool JSON for "${z.tool}" ${y} times. Structured tool calls are required.`;m="error",d=A,g=A,this.history.push({role:"assistant",content:A}),await this.emitEvent("final",{turn:r,step:T,content:A,role:"assistant",meta:{error_type:"model_protocol_error",tool:z.tool,protocol_violation:!0,protocol_violation_count:y,tokens:J}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,errorMessage:g,tokenUsage:J,turnUsage:{...s},steps:o});break}if(P&&this.history.push(P),I.length>0&&this.toolsDisabled){for(let A of I)this.history.push({role:"tool",content:Ra,tool_call_id:A.id,name:A.name});m="error",d=xt,g=xt,this.history.push({role:"assistant",content:xt}),await this.emitEvent("final",{turn:r,step:T,content:xt,role:"assistant",meta:{error_type:"tool_disabled",tool_count:I.length,tools:I.map(A=>A.name).join(","),tokens:J}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:xt,status:m,errorMessage:g,tokenUsage:J,turnUsage:{...s},steps:o});break}if(I.length>1){for(let k of I)this.maybeWarnRepeatedAction(k.name,k.input);await this.emitEvent("action",{turn:r,step:T,meta:{tools:I.map(k=>k.name),action_ids:I.map(k=>k.id),action_id:I[0]?.id,parallel:!0,phase:"dispatch",thinking:M.thinking,toolBlocks:I.map(k=>({id:k.id,name:k.name,input:k.input}))}});let A=I[0];A&&await V(this.hooks,"onAction",{sessionId:this.id,turn:r,step:T,action:{tool:A.name,input:A.input},parallelActions:I.map(k=>({tool:k.name,input:k.input})),thinking:M.thinking,history:Mt(this.history)});let O=I.every(k=>!!this.deps.tools[k.name]?.supportsParallelToolCalls),re=I.some(k=>!!this.deps.tools[k.name]?.isMutating),Se=O&&!re?"parallel":"sequential",ge=await this.toolOrchestrator.executeActions(I.map(k=>({id:k.id,name:k.name,input:k.input})),{...this.buildToolApprovalHooks(r,T),executionMode:Se,failurePolicy:"fail_fast"}),qe=Ua(I,ge.results,ge.hasRejection);for(let[k,L]of qe.entries())this.history.push(Mo(L)),await this.emitEvent("observation",{turn:r,step:T,content:L.observation,meta:{tool:L.tool,index:k,action_id:L.actionId,phase:"result",status:L.status,error_type:L.errorType,duration_ms:L.durationMs,execution_mode:Se}});let De=qe.map(k=>`[${k.tool}]: ${k.observation}`).join(`
|
|
101
101
|
|
|
102
|
-
`),
|
|
103
|
-
`):""}).join("")}function
|
|
102
|
+
`),rt=qe.map(k=>k.status),ve=rt.find(k=>k!==wo)??wo,be=o[o.length-1];if(be&&(be.observation=De),await V(this.hooks,"onObservation",{sessionId:this.id,turn:r,step:T,tool:I.map(k=>k.name).join(", "),observation:De,resultStatus:ve,parallelResultStatuses:rt,history:Mt(this.history)}),ge.hasRejection){let k=qe.find(L=>L.rejected);m="cancelled",d="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:r,step:T,content:d,role:"assistant",meta:{rejected:!0,phase:"result",action_id:k?.actionId,error_type:k?.errorType??"approval_denied",duration_ms:k?.durationMs}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,tokenUsage:J,turnUsage:{...s},steps:o});break}continue}else if(M.action){this.maybeWarnRepeatedAction(M.action.tool,M.action.input);let A=I[0]?.id??`${r}:${T}:single:${M.action.tool}`;await this.emitEvent("action",{turn:r,step:T,meta:{tool:M.action.tool,input:M.action.input,action_id:A,phase:"dispatch",thinking:M.thinking}}),await V(this.hooks,"onAction",{sessionId:this.id,turn:r,step:T,action:M.action,thinking:M.thinking,history:Mt(this.history)});let O=await this.executeToolAction(A,M.action.tool,M.action.input,r,T);if(O.rejected){this.history.push(Mo({...O,observation:O.observation||`User denied tool execution: ${M.action.tool}`})),m="cancelled",d="\u7528\u6237\u62D2\u7EDD\u4E86\u5DE5\u5177\u6267\u884C\uFF0C\u5DF2\u505C\u6B62\u5F53\u524D\u64CD\u4F5C\u3002",await this.emitEvent("final",{turn:r,step:T,content:d,role:"assistant",meta:{rejected:!0,phase:"result",action_id:O.actionId,error_type:O.errorType??"approval_denied",duration_ms:O.durationMs}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,tokenUsage:J,turnUsage:{...s},steps:o});break}let re=O.observation;this.history.push({role:"tool",content:re,tool_call_id:O.actionId,name:M.action.tool});let Se=o[o.length-1];Se&&(Se.observation=re),await this.emitEvent("observation",{turn:r,step:T,content:re,meta:{tool:M.action.tool,action_id:O.actionId,phase:"result",status:O.status,error_type:O.errorType,duration_ms:O.durationMs}}),await V(this.hooks,"onObservation",{sessionId:this.id,turn:r,step:T,tool:M.action.tool,observation:re,resultStatus:O.status,history:Mt(this.history)});continue}if(ie==="end_turn"||M.final){this.resetActionRepetition();let A=ie==="end_turn"&&!M.final&&R.trim().length===0&&!!b&&U===T-1;d=A?b??"":M.final||R,M.final&&(M.final=d),await this.emitEvent("final",{turn:r,step:T,content:d,role:"assistant",meta:{tokens:J,fallback_from_previous_text:A||void 0}}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,step:T,finalText:d,status:m,tokenUsage:J,turnUsage:{...s},steps:o});break}this.resetActionRepetition();break}return!d&&m!=="cancelled"&&(m==="ok"&&(m="error"),d="Unable to produce a final answer. Please retry or adjust the request.",g=d,this.history.push({role:"assistant",content:d}),await this.emitEvent("final",{turn:r,content:d,role:"assistant"}),await V(this.hooks,"onFinal",{sessionId:this.id,turn:r,finalText:d,status:m,errorMessage:g,turnUsage:{...s},steps:o})),await this.emitEvent("turn_end",{turn:r,meta:{status:m,stepCount:o.length,durationMs:Date.now()-i,tokens:s,protocol_violation_count:y||void 0}}),{finalText:d,steps:o,status:m,errorMessage:g,tokenUsage:s}}finally{this.currentAbortController=null,this.cancelling=!1,this.toolOrchestrator.clearOnceApprovals()}})}cancelCurrentTurn(){this.currentAbortController&&(this.cancelling=!0,this.currentAbortController.abort())}async compactHistory(t="manual"){return this.compactHistoryInternal(t,this.turnIndex,0)}listToolNames(){return Object.keys(this.deps.tools)}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)try{n.close?await n.close():n.flush&&await n.flush()}catch(r){console.error(`History flush failed: ${r.message}`)}}this.tokenCounter.dispose(),this.toolOrchestrator.dispose(),this.deps.dispose&&await this.deps.dispose()}async emitEvent(t,n){if(!this.sinks.length)return;let r=us({sessionId:this.id,type:t,turn:n.turn,step:n.step,content:n.content,role:n.role,meta:n.meta});await Oa(r,this.sinks)}};async function jn(e,t={}){let n=t.sessionId||qg(),r=await Pa(e,{...t,sessionId:n},n),o=await r.loadPrompt(),s=new Wn({...e,...r},{...t,sessionId:n,mode:t.mode??Hn},o,r.tokenCounter,r.historyFilePath);return await s.init(),s}import{randomUUID as Ot}from"crypto";import{readFile as o_}from"fs/promises";import{useCallback as X,useEffect as Lt,useMemo as on,useReducer as s_,useRef as ir,useState as ee}from"react";import{Box as Vc,Text as i_,useApp as a_}from"ink";import{memo as dh,useMemo as rc,useRef as oc,useEffect as mh}from"react";import{Box as tc,Static as fh,Text as zn}from"ink";import{memo as Io}from"react";import{Box as Ye,Text as se}from"ink";var ke={PENDING:"pending",EXECUTING:"executing",SUCCESS:"success",ERROR:"error"};import kt from"path";var Vg="success",Jt=".";function Po(e){return e?e===Vg?ke.SUCCESS:ke.ERROR:ke.SUCCESS}function za(e){if(e?.length)return e.map(t=>Po(t))}function Ga(e,t){return!t||t<=0||!e||e<=0?0:Math.min(100,e/t*100)}function Yt(e,t=80){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function Ka(e){if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Eo(e,t){let n=e.trim();if(!n)return e;if(n===Jt)return Jt;if(kt.isAbsolute(n)){let r=kt.relative(kt.resolve(t),n);return r?kt.normalize(r):Jt}if(n.startsWith("./")||n.startsWith("../")){let r=kt.normalize(n);return!r||r==="."||r==="./"?Jt:r}return n}function qa(e){return e?e===Jt||kt.isAbsolute(e)?!0:e.startsWith("./")||e.startsWith("../"):!1}import{memo as th,useMemo as nh}from"react";import{Box as Le,Text as Ce}from"ink";import{marked as Xg}from"marked";var Jg=/(`[^`\n]+`|\[[^\]]+\]\((?:\\.|[^)])+\)|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/g;function Qt(e){return e.map(t=>{let n=t;return typeof n.text=="string"?n.text:typeof n.raw=="string"?n.raw:Array.isArray(n.tokens)?Qt(n.tokens):Array.isArray(n.items)?n.items.map(r=>typeof r.text=="string"?r.text:Array.isArray(r.tokens)?Qt(r.tokens):"").filter(Boolean).join(`
|
|
103
|
+
`):""}).join("")}function Yg(e){let t=[],n=e.replace(/<think>([\s\S]*?)<\/think>/gi,(r,o)=>{let s=o.trim();return s&&t.push(s),""});return{think:t,cleaned:n}}function Qg(e){if(e.startsWith("`")&&e.endsWith("`"))return{type:"inlineCode",content:e.slice(1,-1)};if(e.startsWith("**")&&e.endsWith("**")||e.startsWith("__")&&e.endsWith("__"))return{type:"bold",content:e.slice(2,-2)};if(e.startsWith("*")&&e.endsWith("*")||e.startsWith("_")&&e.endsWith("_"))return{type:"italic",content:e.slice(1,-1)};let t=e.match(/^\[([^\]]+)\]\((.+)\)$/);return t?{type:"link",label:t[1]??"",href:t[2]??""}:{type:"text",content:e}}function Xa(e){if(!e)return[];let t=[],n=0;for(let r of e.matchAll(Jg)){let o=r[0];if(!o)continue;let s=r.index??0;s>n&&t.push({type:"text",content:e.slice(n,s)}),t.push(Qg(o)),n=s+o.length}return n<e.length&&t.push({type:"text",content:e.slice(n)}),t.filter(r=>r.type==="link"?r.label.length>0||r.href.length>0:r.content.length>0)}function Zg(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.tokens)?Qt(e.tokens):""}function eh(e){return typeof e.text=="string"&&e.text.length>0?e.text:Array.isArray(e.tokens)?Qt(e.tokens):typeof e.raw=="string"?e.raw.split(`
|
|
104
104
|
`).map(t=>t.replace(/^>\s?/,"")).join(`
|
|
105
|
-
`).trim():""}function
|
|
106
|
-
|
|
107
|
-
`)});let o=
|
|
108
|
-
`);if(t.length===0)return["Think:"];let n=t.findIndex(r=>r.trim().length>0);return n<0&&(n=0),t.map((r,o)=>o===n?`Think: ${r}`:r)}function
|
|
109
|
-
`)}function
|
|
110
|
-
`).map((n,r)=>
|
|
111
|
-
`,Math.max(0,n-1));return r===-1?0:r+1}function
|
|
112
|
-
`,n);return r===-1?e.length:r}function
|
|
113
|
-
`);return o?{value:`${e.slice(0,r)}${o}${e.slice(r)}`,cursor:r+o.length}:{value:e,cursor:r}}function
|
|
114
|
-
`){c=y,p(),i=u,c=u,a="",l=0;continue}let b=Math.max(0,
|
|
115
|
-
`,this.extendWindow(t),!0):!1}newlineShouldInsertInsteadOfSubmit(t){let n=this.burstWindowUntilMs!==null&&t<=this.burstWindowUntilMs;return this.isActiveInternal()||n}extendWindow(t){this.burstWindowUntilMs=t+this.enterSuppressWindowMs}beginWithRetroGrabbed(t,n){t&&(this.buffer+=t),this.active=!0,this.extendWindow(n)}appendCharToBuffer(t,n){t&&(this.buffer+=t,this.extendWindow(n))}decideBeginBuffer(t,n,r){let o=
|
|
116
|
-
`)&&K(!1)},[$,K]),
|
|
117
|
-
`)){let B
|
|
118
|
-
`)){let B
|
|
119
|
-
`,!0),L.current.extendWindow(_);return}}if(
|
|
120
|
-
`,!0);return}let ue=M.current.value.trim();if(!ue)return;if(ue.startsWith("/")){let B=wr(ue,rn);switch(B.kind){case"message":se(B.title,B.content);break;case"new":b();break;case"exit":g();break;case"switch_model":R(B.provider);break;case"set_tool_permission":I(B.mode);break;case"compact":T();break;case"review_pr":G(B.prNumber);break;case"init_agents_md":m(Dh);break;default:{let xe=B}}P.current=null,$({value:"",cursor:0},!0),K(!1);return}m(ue),P.current=null,$({value:"",cursor:0},!0),K(!1);return}if(De!=="none"){let x=M.current,E=De==="backspace"?mc(x.value,x.cursor):Io(x.value,x.cursor);P.current=null,$(E,!0);return}if(w&&Nt){let x=Array.from(w);if(x.length!==1){le(!1),N(w,!0),L.current.clearAfterExplicitPaste();return}let E=x[0]??"";if(!E)return;let ue=ot=>{let mt=M.current,on=mt.value.slice(0,mt.cursor),sn=mt.value.slice(mt.cursor),$t=L.current.decideBeginBuffer(_,on,ot);return $t?(P.current=null,$({value:`${on.slice(0,$t.start)}${sn}`,cursor:$t.start},!0),L.current.appendCharToBuffer(E,_),!0):!1};if(!((E.codePointAt(0)??0)<=127)){let ot=L.current.onPlainCharNoHold(_);if(ot?.type==="buffer_append"){L.current.appendCharToBuffer(E,_);return}if(ot?.type==="begin_buffer"&&ue(ot.retroChars))return;le(!1),N(E,!0);return}let xe=L.current.onPlainChar(E,_);if(xe.type==="retain_first_char")return;if(xe.type==="buffer_append"||xe.type==="begin_buffer_from_pending"){L.current.appendCharToBuffer(E,_);return}if(xe.type==="begin_buffer"&&ue(xe.retroChars))return;le(!1),N(E,!0);return}w&&(N(w,!0),L.current.clearWindowAfterNonChar())});let dt=Re?.columns??process.stdout?.columns??80,Y=Math.max(1,dt-3),Ve=Tc(ie.value,ie.cursor,Y),rt=Ve.lines;return Mc(Lo,{flexDirection:"column",gap:1,children:[kt(Lo,{flexDirection:"column",paddingY:1,children:rt.map((w,S)=>{let _=w.text,Q=!t&&S===Ve.row,re=Q?_.slice(0,Ve.cursorInRow):_,De=Q?_.slice(Ve.cursorInRow):"";return Mc(Lo,{children:[kt(Xn,{color:"gray",children:S===0?"\u203A ":" "}),kt(Xn,{children:re}),Q?kt(Xn,{color:"cyan",children:"\u258A"}):null,Q?kt(Xn,{children:De}):null]},`line-${S}`)})}),J!=="none"?kt(cc,{items:O.map(({value:w,meta:S,..._})=>_),activeIndex:Se,loading:Ke}):null]})});import{memo as Jh}from"react";import{Box as Ac,Text as Do}from"ink";import{jsx as Uo,jsxs as Pc}from"react/jsx-runtime";var Ec=Jh(function({busy:t,pendingApproval:n=!1,contextPercent:r}){let o=`${r.toFixed(1)}%`;return Pc(Ac,{justifyContent:"space-between",children:[Uo(Ac,{children:t?Uo(Do,{color:"yellow",children:"Working..."}):Uo(Do,{color:"gray",children:n?"Approval pending \u2022 Enter confirm \u2022 Esc deny":"Enter send \u2022 Shift+Enter newline \u2022 /help"})}),Pc(Do,{color:"gray",children:["context: ",o]})]})});import{memo as Yh}from"react";import{Box as Jn,Text as Fo,useInput as Qh}from"ink";import{Select as Zh,StatusMessage as ey}from"@inkjs/ui";import{jsx as pt,jsxs as Rc}from"react/jsx-runtime";var ty=[{label:"Allow once",decision:"once"},{label:"Allow for this session",decision:"session"},{label:"Deny",decision:"deny"}];function ny(e){if(!e)return"";if(typeof e!="object")return String(e);let t=Object.entries(e);if(!t.length)return"";let[n,r]=t[0]??[];if(!n)return"";let o=typeof r=="string"?r:JSON.stringify(r);return`${n}=${o?.slice(0,60)??""}${o&&o.length>60?"...":""}`}var Ic=Yh(function({request:t,onDecision:n}){Qh((o,s)=>{(s.escape||s.ctrl&&o==="c")&&n("deny")});let r=ny(t.params);return Rc(Jn,{flexDirection:"column",borderStyle:"single",borderColor:"yellow",paddingX:1,children:[pt(Fo,{bold:!0,color:"yellow",children:"Tool Approval Required"}),Rc(Fo,{children:[t.toolName,r?` (${r})`:""]}),pt(Jn,{marginTop:1,children:pt(ey,{variant:"warning",children:t.reason})}),pt(Jn,{marginTop:1,flexDirection:"column",children:pt(Zh,{options:ty.map(o=>({label:o.label,value:o.decision})),onChange:o=>{n(o)}})}),pt(Jn,{marginTop:1,children:pt(Fo,{color:"gray",children:"Enter confirm \u2022 Esc deny"})})]})});import{memo as ry,useMemo as oy,useState as sy}from"react";import{Box as Ho,Text as Yn,useInput as iy}from"ink";import{MultiSelect as ay}from"@inkjs/ui";import{jsx as tn,jsxs as Bo}from"react/jsx-runtime";function cy(e,t){let n=new Set(e);return t.filter(r=>n.has(r))}var Oc=ry(function({serverNames:t,defaultSelected:n,onConfirm:r,onExit:o}){let s=oy(()=>{let l=cy(t,n);return n.length===0?[]:l.length>0?l:[...t]},[n,t]),[i,c]=sy(s),a=i.length===t.length;return iy((l,p)=>{if(p.ctrl&&l==="c"){o();return}p.escape&&r(i,!1)}),Bo(Ho,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[tn(Yn,{bold:!0,color:"cyan",children:"Activate MCP Servers"}),tn(Yn,{color:"gray",children:"Select servers to load for this run."}),tn(Ho,{marginTop:1,flexDirection:"column",children:tn(ay,{options:t.map(l=>({label:l,value:l})),defaultValue:s,onChange:c,onSubmit:l=>{r(l,!0)}})}),Bo(Ho,{marginTop:1,flexDirection:"column",children:[Bo(Yn,{color:"gray",children:["Selected: ",i.length,"/",t.length,a?" (all)":""]}),tn(Yn,{color:"gray",children:"Controls: \u2191/\u2193 move, Space toggle, Enter confirm"})]})]})});import{spawn as ly}from"child_process";var Wo="\x07",uy="Memo: Approval required",py="Memo CLI",dy=2e3;function my(e){return e.replace(/\s+/g," ").trim()}function fy(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function gy(e){let t=my(e.reason),n=`Tool ${e.toolName} is waiting for your approval.`;return t?fy(`${n} ${t}`,220):n}function Lc(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function hy(e,t=process.platform){let n=uy,r=gy(e);return t==="darwin"?{command:"osascript",args:["-e",`display notification "${Lc(r)}" with title "${Lc(n)}"`]}:t==="linux"?{command:"notify-send",args:["--app-name",py,n,r]}:null}async function yy(e,t){await new Promise((n,r)=>{let o=ly(e,t,{stdio:"ignore"}),s=!1,i=a=>{if(!s){if(s=!0,a){r(a);return}n()}},c=setTimeout(()=>{try{o.kill()}catch{}i()},dy);o.once("error",a=>{clearTimeout(c),i(a)}),o.once("exit",a=>{if(clearTimeout(c),a===0||a===null){i();return}i(new Error(`${e} exited with code ${a}`))})})}function _y(e){if(e){e(Wo);return}try{if(process.stdout?.isTTY){process.stdout.write(Wo);return}process.stderr?.isTTY&&process.stderr.write(Wo)}catch{}}async function Nc(e,t={}){_y(t.writeBell);let n=hy(e,t.platform??process.platform);if(!n)return;let r=t.runCommand??yy;try{await r(n.command,n.args)}catch{}}import{Box as At,Text as Ge,useInput as Sy}from"ink";import{Spinner as vy,StatusMessage as Ty,TextInput as wy}from"@inkjs/ui";import{memo as Cy,useCallback as $c,useMemo as by,useState as Qn}from"react";import{jsx as Ee,jsxs as Pt}from"react/jsx-runtime";var Ze=[{key:"name",label:"Provider name",hint:"Used for /models switching",defaultValue:"deepseek"},{key:"envKey",label:"API key env var",hint:"Read at runtime from environment variables",defaultValue:"DEEPSEEK_API_KEY"},{key:"model",label:"Model name",defaultValue:"deepseek-chat"},{key:"baseUrl",label:"Base URL",defaultValue:"https://api.deepseek.com"}],Dc=Cy(function({configPath:t,onComplete:n,onExit:r}){let[o,s]=Qn(0),[i,c]=Qn({}),[a,l]=Qn(!1),[p,u]=Qn(null),d=Ze[o]??Ze[0],m=$c(async b=>{l(!0),u(null);try{let U={current_provider:b.name,providers:[{name:b.name,env_api_key:b.envKey,model:b.model,base_url:b.baseUrl||void 0}]};await we(t,U),n()}catch(U){u(U.message),l(!1)}},[t,n]),g=$c(async b=>{if(!d)return;let U=b.trim()||d.defaultValue,T={...i,[d.key]:U};if(c(T),o<Ze.length-1){s(o+1);return}let H={name:T.name||Ze[0].defaultValue,envKey:T.envKey||Ze[1].defaultValue,model:T.model||Ze[2].defaultValue,baseUrl:T.baseUrl||Ze[3].defaultValue};await m(H)},[m,d,o,i]);Sy((b,U)=>{U.ctrl&&b==="c"&&r()});let y=by(()=>`Step ${o+1}/${Ze.length}`,[o]);return d?Pt(At,{flexDirection:"column",children:[Ee(Ge,{bold:!0,children:"Memo setup"}),Ee(Ge,{color:"gray",children:"No provider config found. Complete setup to continue."}),Pt(Ge,{color:"gray",children:["Config path: ",t]}),Pt(At,{marginTop:1,flexDirection:"column",children:[Ee(Ge,{color:"cyan",children:y}),Ee(Ge,{children:d.label}),Pt(Ge,{color:"gray",children:["Default: ",d.defaultValue]}),d.hint?Ee(Ge,{color:"gray",children:d.hint}):null]}),Pt(At,{marginTop:1,children:[Ee(Ge,{color:"gray",children:"> "}),Ee(wy,{isDisabled:a,defaultValue:i[d.key]??"",placeholder:d.defaultValue,onSubmit:b=>{g(b)}},d.key)]}),Ee(At,{marginTop:1,children:Ee(Ge,{color:"gray",children:"Enter to continue, Ctrl+C to exit"})}),a?Ee(At,{marginTop:1,children:Ee(vy,{label:"Saving config..."})}):null,p?Ee(At,{marginTop:1,children:Pt(Ty,{variant:"error",children:["Failed to save config: ",p]})}):null]}):null});function Uc(e){let t=e.finalText?.trim();return t||e.steps.map(n=>n.assistantText??"").join("").trim()}function xy(e){return e==="ok"||e==="error"||e==="cancelled"?e:void 0}function My(e){if(e.resultStatus)return e.resultStatus==="success"?ke.SUCCESS:ke.ERROR}function ky(e,t,n){return{index:-(n+1),userInput:e.input??"",steps:(e.steps??[]).map(r=>({index:r.step,assistantText:r.assistantText??"",thinking:r.thinking,action:r.action,parallelActions:r.parallelActions,observation:r.observation,toolStatus:My(r)})),status:xy(e.status),errorMessage:e.errorMessage,tokenUsage:e.tokenUsage,finalText:Uc(e),sequence:t}}function Zn(e){let t=dn(e,"history.log"),n=[...t.turns].sort((i,c)=>i.turn-c.turn),r=[];for(let i of n){let c=(i.input??"").trim();c&&r.push({role:"user",content:c});let a=Uc(i);a&&r.push({role:"assistant",content:a})}let o=0,s=n.map((i,c)=>(o+=1,ky(i,o,c)));return{summary:t.summary,messages:r,turns:s,maxSequence:o}}function jo(){return{turns:[],historicalTurns:[],systemMessages:[],sequence:0}}function Ay(e,t){return{index:e,userInput:"",steps:[],sequence:t}}function er(e,t){if(e.length>t)return e;let n=e.slice();for(;n.length<=t;)n.push({index:n.length,assistantText:""});return n}function Et(e,t,n){let r=e.turns.slice(),o=r.findIndex(i=>i.index===t);if(o===-1){let i=e.sequence+1;return r.push(n(Ay(t,i))),{turns:r,sequence:i}}let s=r[o];return s?(r[o]=n(s),{turns:r,sequence:e.sequence}):{turns:r,sequence:e.sequence}}function Py(e){return{id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,title:e.title,content:e.content,tone:e.tone??"info",sequence:e.sequence}}function Fc(e,t){switch(t.type){case"append_system_message":{let n=e.sequence+1;return{...e,sequence:n,systemMessages:[...e.systemMessages,Py({title:t.title,content:t.content,tone:t.tone,sequence:n})]}}case"turn_start":{let n=Et(e,t.turn,r=>({...r,index:t.turn,userInput:t.input,steps:[],finalText:void 0,status:void 0,errorMessage:void 0,tokenUsage:void 0,startedAt:Date.now(),durationMs:void 0,contextPromptTokens:t.promptTokens??r.contextPromptTokens}));return{...e,turns:n.turns,sequence:n.sequence}}case"context_usage":{let n=Et(e,t.turn,r=>{let o=er(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,contextPromptTokens:t.promptTokens},{...r,contextPromptTokens:t.promptTokens,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"assistant_chunk":{let n=Et(e,t.turn,r=>{let o=er(r.steps,t.step),s=o[t.step];if(!s)return r;let i=`${s.assistantText}${t.chunk}`;return i===s.assistantText?r:(o[t.step]={...s,assistantText:i},{...r,steps:o})});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_action":{let n=Et(e,t.turn,r=>{let o=er(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,action:t.action,thinking:t.thinking,parallelActions:t.parallelActions&&t.parallelActions.length>1?t.parallelActions:void 0,toolStatus:ke.EXECUTING},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_observation":{let n=Et(e,t.turn,r=>{let o=er(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,observation:t.observation,toolStatus:t.toolStatus,parallelToolStatuses:t.parallelToolStatuses},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"turn_final":{let n=Et(e,t.turn,r=>{let o=r.startedAt??Date.now(),s=Math.max(0,Date.now()-o),i=t.tokenUsage?.prompt??r.contextPromptTokens;return{...r,finalText:t.finalText,status:t.status,errorMessage:t.errorMessage,tokenUsage:t.turnUsage,contextPromptTokens:i,startedAt:o,durationMs:s}});return{...e,turns:n.turns,sequence:n.sequence}}case"replace_history":return{...e,historicalTurns:t.turns,sequence:Math.max(e.sequence,t.maxSequence)};case"clear_current_timeline":return{...e,turns:[],systemMessages:[]};case"reset_all":return jo();default:return e}}import{dirname as tr,join as Bc,resolve as Ey}from"path";import{statSync as Ry,existsSync as Wc,readFileSync as Iy}from"fs";import{readFile as Oy}from"fs/promises";import{get as Ly}from"https";import{fileURLToPath as Ny}from"url";function Hc(e){let t=e.trim().replace(/^v/i,""),[n="",r]=t.split("-",2),o=n.split(".").map(s=>Number(s));return o.length<3||o.some(s=>!Number.isFinite(s))?null:{major:o[0]??0,minor:o[1]??0,patch:o[2]??0,prerelease:r??null}}function $y(e,t){let n=Hc(e),r=Hc(t);return!n||!r?!1:n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch!==r.patch?n.patch>r.patch:n.prerelease&&!r.prerelease?!1:!n.prerelease&&r.prerelease?!0:n.prerelease&&r.prerelease?n.prerelease>r.prerelease:!1}function jc(){try{let t=Ny(import.meta.url);return tr(t)}catch{}let e=Ey(process.argv[1]??process.cwd());try{return Ry(e).isFile()?tr(e):e}catch{return process.cwd()}}async function Dy(e){let t=Bc(e,"package.json");if(!Wc(t))return null;let n=await Oy(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}function Uy(e){let t=Bc(e,"package.json");if(!Wc(t))return null;try{let n=Iy(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}catch{return null}}async function Fy(){let e=jc();for(;;){let t=await Dy(e);if(t&&t.name==="@memo-code/memo")return t;let n=tr(e);if(n===e)break;e=n}return null}function nr(){let e=jc();for(;;){let t=Uy(e);if(t&&t.name==="@memo-code/memo")return t;let n=tr(e);if(n===e)break;e=n}return null}async function Hy(e,t=1500){let r=`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`;return new Promise(o=>{let s=Ly(r,{timeout:t},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),o(null);return}let c=[];i.on("data",a=>c.push(a)),i.on("end",()=>{try{let a=JSON.parse(Buffer.concat(c).toString("utf8"));o(a.version??null)}catch{o(null)}})});s.on("timeout",()=>{s.destroy(),o(null)}),s.on("error",()=>o(null))})}async function zc(){let e=await Fy();if(!e)return null;let t=await Hy(e.name);return!t||!$y(t,e.version)?null:{current:e.version,latest:t}}import{readFile as By}from"fs/promises";import{dirname as Wy,join as jy}from"path";import{fileURLToPath as zy}from"url";var Gy=/{{\s*([\w.-]+)\s*}}/g;function Ky(e,t){return e.replace(Gy,(n,r)=>t[r]??"")}async function zo(e,t={}){let n=Wy(zy(import.meta.url)),r=jy(n,"task-prompts",`${e}.md`),o=await By(r,"utf-8");return Ky(o,t)}import{spawn as qy}from"child_process";var Vy=12e3,Xy=new Set(["WRITE","MAINTAIN","ADMIN"]),Jy=["pull_request_read","list_pull_requests","search_pull_requests","add_issue_comment","add_comment_to_pending_review","issue_read","get_me"];function Yy(e){return e.replace(/\\/g,"/").toLowerCase()}function Qy(e,t){if(e.toLowerCase().includes("github"))return!0;if("command"in t){let o=Yy(t.command),s=(t.args??[]).join(" ").toLowerCase();return!!(o.includes("github")||o.includes("gh-")||s.includes("github")||s.includes("gh-"))}let r=t.url.toLowerCase();return r.includes("github")||r.includes("api.github.com")}function Zy(e,t){let n=new Set(t),r=Object.entries(e).filter(([i,c])=>Qy(i,c)).map(([i])=>i),o=r.find(i=>n.has(i))??null,s=r.filter(i=>!n.has(i));return{active:o,inactiveCandidates:s}}function e_(e){let t=new Map;for(let n of e)for(let r of Jy){let o=`_${r}`;if(!n.endsWith(o))continue;let s=n.slice(0,-o.length);s&&t.set(s,(t.get(s)??0)+1)}return Array.from(t.entries()).filter(([,n])=>n>=2).sort((n,r)=>r[1]-n[1]).map(([n])=>n)}async function Go(e,t,n,r=Vy){return new Promise(o=>{let s=qy(e,t,{cwd:n,env:process.env,stdio:["ignore","pipe","pipe"]}),i="",c="",a=!1,l=u=>{a||(a=!0,clearTimeout(p),o(u))},p=setTimeout(()=>{s.kill("SIGTERM"),l({ok:!1,stdout:i,stderr:c,code:null,errorMessage:`${e} ${t.join(" ")} timed out after ${r}ms`})},r);s.stdout.on("data",u=>{i+=u.toString()}),s.stderr.on("data",u=>{c+=u.toString()}),s.on("error",u=>{l({ok:!1,stdout:i,stderr:c,code:null,errorMessage:u.message})}),s.on("close",u=>{l({ok:u===0,stdout:i,stderr:c,code:u})})})}async function t_(e){if(!(await Go("gh",["--version"],e)).ok)return{ok:!1,reason:"GitHub MCP not available, and GitHub CLI (gh) is not installed or not executable. Install gh: https://cli.github.com/"};let n=await Go("gh",["auth","status","-h","github.com"],e);if(!n.ok)return{ok:!1,reason:`GitHub CLI is installed but not authenticated for github.com. Run: gh auth login -h github.com (detail: ${n.stderr.trim()||n.stdout.trim()||n.errorMessage||"unknown error"})`};let r=await Go("gh",["repo","view","--json","nameWithOwner,viewerPermission"],e);if(!r.ok)return{ok:!1,reason:`GitHub CLI authentication works, but this directory is not a readable GitHub repo for gh (detail: ${r.stderr.trim()||r.stdout.trim()||r.errorMessage||"unknown error"})`};let o;try{o=JSON.parse(r.stdout)}catch{return{ok:!1,reason:"Failed to parse `gh repo view` output. Try upgrading gh and retry."}}let s=o.nameWithOwner?.trim(),i=o.viewerPermission?.trim().toUpperCase();return!s||!i?{ok:!1,reason:"GitHub CLI did not return repository or permission info from `gh repo view`."}:Xy.has(i)?{ok:!0,repository:s,viewerPermission:i}:{ok:!1,reason:`GitHub CLI connected to ${s}, but permission is ${i}. PR review comments require WRITE/MAINTAIN/ADMIN permission.`}}async function Gc(e){let t=e_(e.availableToolNames??[]),n=e.activeMcpServerNames.find(l=>t.includes(l))??null,r=l=>{let p=e.availableToolNames;if(!p||p.length===0)return!0;let u=`${l}_`;return p.some(d=>d.startsWith(u))};if(n&&r(n))return{kind:"github_mcp",strategy:"github_mcp",details:`Using active GitHub MCP server \`${n}\` (detected from loaded MCP tool signatures).`,mcpServerPrefix:n};let{active:o,inactiveCandidates:s}=Zy(e.mcpServers,e.activeMcpServerNames);if(o&&r(o))return{kind:"github_mcp",strategy:"github_mcp",details:`Using active GitHub MCP server \`${o}\`.`,mcpServerPrefix:o};let i=await t_(e.cwd);if(i.ok){let l=s.length?` GitHub MCP server(s) configured but inactive in this session: ${s.join(", ")}.`:"";return{kind:"gh_cli",strategy:"gh_cli",details:`Using gh CLI on repo \`${i.repository}\` with permission \`${i.viewerPermission}\`.${l}`,repository:i.repository,viewerPermission:i.viewerPermission}}let c=s.length?` Also found configured but inactive GitHub MCP server(s): ${s.join(", ")}. Start a new session and activate one of them, or fix gh CLI access.`:"",a=o&&!r(o)?` Active MCP server \`${o}\` is configured, but no tools with prefix \`${o}_\` are currently loaded in this session.`:"";return{kind:"unavailable",reason:`${i.reason}${a}${c}`}}import{jsx as et,jsxs as l_}from"react/jsx-runtime";function i_(e,t){if(e.length===0)return[];if(t===void 0)return[...e];if(t.length===0)return[];let n=new Set(e),r=t.filter(o=>n.has(o));return r.length>0?r:[...e]}function a_(e,t){if(e.length===0)return[];if(t.length===0)return[];let n=new Set(e);return t.filter(r=>n.has(r))}function c_(){try{process.stdout?.isTTY&&process.stdout.write("\x1Bc")}catch{}}function qc({sessionOptions:e,providerName:t,model:n,configPath:r,mcpServers:o,cwd:s,sessionsDir:i,providers:c,modelProfiles:a,dangerous:l=!1,needsSetup:p=!1,initialHistory:u}){let{exit:d}=s_(),m=nn(()=>Object.keys(o??{}).sort(),[o]),g=nn(()=>i_(m,e.activeMcpServers),[m,e.activeMcpServers]),y=e.toolPermissionMode??(l?ye.FULL:ye.ONCE),[b,U]=r_(Fc,void 0,jo),[T,H]=Z(t),[R,I]=Z(n),[G,se]=Z(c),[Re,ie]=Z(a),[z,M]=Z(y),P=X(f=>_t({model_profiles:Re},f),[Re]),[te,ae]=Z({...e,providerName:t,contextWindow:P({name:t,model:n}),dangerous:y===ye.FULL,toolPermissionMode:y}),[F,ce]=Z(!1),[J,A]=Z([]),[O,ne]=Z(null),[Se,fe]=Z(null),[Ke,$e]=Z(P({name:t,model:n})),[tt,ve]=Z(0),[be,k]=Z(p),[L,rn]=Z(!p&&m.length>0),[Te,K]=Z(g),[$,Lt]=Z(null),[N,nt]=Z(null),le=rr(null),qe=rr(null),dt=rr(null),[Y,Ve]=Z(null),rt=rr(null),w=nn(()=>nr(),[]),S=X(f=>{U(f)},[]);It(()=>{u&&(S({type:"clear_current_timeline"}),S({type:"replace_history",turns:u.turns,maxSequence:u.maxSequence}),fe(u.messages),u.summary.trim()&&S({type:"append_system_message",title:"History",content:u.summary,tone:"info"}))},[S,u]),It(()=>{be||(K(g),rn(m.length>0))},[be,g,m.length]);let _=X((f,v,C="info")=>{S({type:"append_system_message",title:f,content:v,tone:C})},[S]),Q=nn(()=>({onAssistantStep:(f,v)=>{let C=qe.current;C&&S({type:"assistant_chunk",turn:C,step:v,chunk:f})},requestApproval:z===ye.FULL||z===ye.NONE?void 0:f=>new Promise(v=>{Nc(f),Ve(f),rt.current=v}),hooks:{onTurnStart:({turn:f,input:v,promptTokens:C})=>{qe.current=f;let q=dt.current;q&&(dt.current=null);let Ie=q??v;C&&C>0&&ve(C),S({type:"turn_start",turn:f,input:Ie,promptTokens:C})},onContextUsage:({turn:f,step:v,promptTokens:C,phase:q})=>{ve(C),S({type:"context_usage",turn:f,step:v,promptTokens:C,phase:q})},onContextCompacted:({reason:f,status:v,beforeTokens:C,afterTokens:q,reductionPercent:Ie,errorMessage:cr})=>{v==="success"&&ve(q);let lr=f==="manual"?"manual command":"auto trigger";if(v==="success"){_("Context compacted",`Compacted by ${lr}: ${C} -> ${q} tokens (${Ie.toFixed(2)}% reduced).`);return}if(v==="skipped"){_("Context compacted",`Skipped (${lr}): nothing to compact.`,"warning");return}_("Context compacted",`Failed (${lr}): ${cr??"unknown error"}`,"warning")},onAction:({turn:f,step:v,action:C,thinking:q,parallelActions:Ie})=>{S({type:"tool_action",turn:f,step:v,action:C,thinking:q,parallelActions:Ie})},onObservation:({turn:f,step:v,observation:C,resultStatus:q,parallelResultStatuses:Ie})=>{S({type:"tool_observation",turn:f,step:v,observation:C,toolStatus:Mo(q),parallelToolStatuses:Wa(Ie)})},onFinal:({turn:f,finalText:v,status:C,errorMessage:q,turnUsage:Ie,tokenUsage:cr})=>{S({type:"turn_final",turn:f,finalText:v,status:C,errorMessage:q,turnUsage:Ie,tokenUsage:cr}),ce(!1)}}}),[_,S,z]);It(()=>{let f=!1;return(async()=>{if(!(be||L))try{let v=le.current;v&&await v.close();let C=await Hn(Q,te);if(f){await C.close();return}le.current=C,nt(C),ne(C.historyFilePath??null)}catch(v){if(f)return;le.current=null,nt(null),ne(null),ce(!1),_("Session",`Failed to create session: ${v.message}`,"error")}})(),()=>{f=!0}},[_,Q,L,te,be]),It(()=>{let f=!1;return(async()=>{let v=await zc();f||!v||_("Update",`Update available: v${v.latest}. Run: npm install -g @memo-code/memo@latest`)})(),()=>{f=!0}},[_]),It(()=>()=>{le.current&&le.current.close()},[]);let re=X(async()=>{let f=rt.current;f&&(f("deny"),rt.current=null),Y&&Ve(null),le.current&&await le.current.close(),Lt("Bye!"),setTimeout(()=>d(),250)},[d,Y]),De=X(()=>{if(F){_("Clear","Cancel current run before clearing timeline.","warning");return}if(Y){_("Clear","Resolve current approval request before clearing timeline.","warning");return}S({type:"clear_current_timeline"}),fe(null),ve(0),c_()},[_,F,S,Y]),ar=X(()=>{if(F){_("New Session","Cancel current run before starting a new session.","warning");return}if(Y){_("New Session","Resolve current approval request before starting a new session.","warning");return}S({type:"reset_all"}),fe(null),ve(0),qe.current=null,ae(f=>({...f,sessionId:Rt()})),_("New Session","Started a fresh session.")},[_,F,S,Y]),Nt=X(async f=>{try{let v=await ee();await we(v.configPath,{...v.config,current_provider:f})}catch(v){_("Config",`Failed to persist provider: ${v.message}`,"warning")}},[_]),x=X(async f=>{if(F){_("Model switch","Cancel current run before switching models.","warning");return}if(f.name===T&&f.model===R){_("Model switch",`Already using ${f.name} (${f.model}).`);return}S({type:"reset_all"}),ve(0),qe.current=null;let v=P(f);H(f.name),I(f.model),$e(v),ae(C=>({...C,sessionId:Rt(),providerName:f.name,contextWindow:v})),await Nt(f.name),_("Model switch",`Switched to ${f.name} (${f.model}).`)},[_,F,R,T,S,Nt,P]),E=X(f=>f===ye.NONE?"none (no tools)":f===ye.ONCE?"once (approval required)":"full (no approval)",[]),ue=X(f=>{if(F){_("Tools","Cancel current run before changing tool permission mode.","warning");return}if(Y){_("Tools","Resolve current approval request before changing tool permission mode.","warning");return}if(f===z){_("Tools",`Already using ${E(f)}.`);return}M(f),ae(v=>({...v,sessionId:Rt(),dangerous:f===ye.FULL,toolPermissionMode:f})),_("Tools",`Tool permission set to ${E(f)}.`)},[_,F,Y,E,z]),B=X(async f=>{try{let v=await ee();await we(v.configPath,{...v.config,active_mcp_servers:f})}catch(v){_("MCP",`Failed to persist active MCP servers: ${v.message}`,"warning")}},[_]),xe=X((f,v)=>{let C=a_(m,f);K(C),rn(!1),ae(q=>({...q,sessionId:Rt(),activeMcpServers:C})),v&&B(C)},[m,B]),ot=X(async f=>{if(F){_("History","Cancel current run before loading session history.","warning");return}if(Y){_("History","Resolve current approval request before loading session history.","warning");return}try{let v=await n_(f.sessionFile,"utf8"),C=Zn(v);S({type:"clear_current_timeline"}),S({type:"replace_history",turns:C.turns,maxSequence:C.maxSequence}),fe(C.messages),ce(!1),nt(null),ne(null),ve(0),qe.current=null,ae(q=>({...q,sessionId:Rt()})),_("History",C.summary||f.input)}catch(v){_("History",`Failed to load ${f.sessionFile}: ${v.message}`,"error")}},[_,F,S,Y]),mt=X(()=>{F&&N?.cancelCurrentTurn?.()},[F,N]),on=X(async()=>{if(F){_("Compact","Cancel current run before compacting context.","warning");return}if(Y){_("Compact","Resolve current approval request before compacting context.","warning");return}if(N)try{let f=await N.compactHistory("manual");ve(f.afterTokens)}catch(f){_("Compact",`Failed to compact context: ${f.message}`,"error")}},[_,F,Y,N]),sn=X(async()=>{if(!N||F)return;let f=Ye(Ne.INIT);try{let v=await zo("init_agents");A(C=>[...C,f]),ce(!0),dt.current=f,await N.runTurn(v)}catch(v){ce(!1),_("Init",`Failed to run init task: ${v.message}`,"error")}},[_,F,N]),$t=X(async f=>{if(!N||F)return;if(z===ye.NONE){_("Review",'Tool permission mode is "none". Set `/tools once` or `/tools full` before running `/review`.',"warning");return}let v=`${Ye(Ne.REVIEW)} ${f}`;try{let C=await Gc({cwd:s,mcpServers:o,activeMcpServerNames:Te,availableToolNames:N.listToolNames?.()??[]});if(C.kind==="unavailable"){_("Review",C.reason,"error");return}let q=await zo("review_pull_request",{pr_number:String(f),backend_strategy:C.strategy,backend_details:C.details,mcp_server_prefix:C.kind==="github_mcp"?C.mcpServerPrefix:"github"});A(Ie=>[...Ie,v]),_("Review",C.details),ce(!0),dt.current=v,await N.runTurn(q)}catch(C){ce(!1),_("Review",`Failed to run review task for PR #${f}: ${C.message}`,"error")}},[Te,_,F,s,o,N,z]),ul=X(async f=>{let v=f.trim();if(v){if(v.toLowerCase()===bc){await re();return}if(v===Ye(Ne.INIT)){await sn();return}if(!(!N||F)){A(C=>[...C,v]),ce(!0);try{await N.runTurn(v)}catch(C){ce(!1),_("Run",`Turn failed: ${C.message}`,"error")}}}},[_,F,re,sn,N]),pl=X(async()=>{try{let f=await ee(),v=at(f.config),C=_t(f.config,v);se(f.config.providers),ie(f.config.model_profiles),H(v.name),I(v.model),$e(C),ae(q=>({...q,sessionId:Rt(),providerName:v.name,contextWindow:C,autoCompactThresholdPercent:f.config.auto_compact_threshold_percent})),k(!1),_("Setup",`Config saved to ${f.configPath}`)}catch(f){_("Setup",`Failed to reload config: ${f.message}`,"error")}},[_]);It(()=>{if(!N||!Se?.length)return;let f=N.history[0];f&&(N.history.splice(0,N.history.length,f,...Se),fe(null))},[Se,N]);let dl=X(f=>{let v=rt.current;v&&(v(f),rt.current=null),Ve(null)},[]),ml=ja(tt,Ke),fl=nn(()=>({providerName:T,model:R,cwd:s,sessionId:te.sessionId??"unknown",mcpNames:Te,version:w?.version??"unknown"}),[Te,R,T,s,w?.version,te.sessionId]);return $?et(Kc,{children:et(o_,{color:"green",children:$})}):be?et(Dc,{configPath:r,onComplete:pl,onExit:re}):L?et(Oc,{serverNames:m,defaultSelected:g,onConfirm:xe,onExit:()=>{re()}}):l_(Kc,{flexDirection:"column",children:[et(rc,{header:fl,systemMessages:b.systemMessages,turns:b.turns,historicalTurns:b.historicalTurns}),et(kc,{disabled:!N||!!Y,busy:F,history:J,cwd:s,sessionsDir:i,currentSessionFile:O??void 0,providers:G,configPath:r,providerName:T,model:R,toolPermissionMode:z,mcpServers:o,onSubmit:f=>{ul(f)},onExit:()=>{re()},onClear:De,onNewSession:ar,onCancelRun:mt,onCompact:()=>{on()},onHistorySelect:f=>{ot(f)},onModelSelect:f=>{x(f)},onSetToolPermission:ue,onReviewPullRequest:f=>{$t(f)},onSystemMessage:_}),Y?et(Ic,{request:Y,onDecision:dl}):null,et(Ec,{busy:F,pendingApproval:!!Y,contextPercent:ml})]})}var u_=`
|
|
105
|
+
`).trim():""}function Va(e){return typeof e.text=="string"?e.text:Array.isArray(e.tokens)?Qt(e.tokens):typeof e.raw=="string"?e.raw:""}function Ja(e){let{think:t,cleaned:n}=Yg(e),r=[];t.length>0&&r.push({type:"think",content:t.join(`
|
|
106
|
+
|
|
107
|
+
`)});let o=Xg.lexer(n);for(let s of o)switch(s.type){case"html":{r.push({type:"html",content:s.text??s.raw??""});break}case"hr":{r.push({type:"hr"});break}case"heading":{r.push({type:"heading",level:typeof s.depth=="number"?s.depth:1,content:s.text??Va(s)});break}case"paragraph":case"text":{let i=Va(s);i.trim().length>0&&r.push({type:"paragraph",content:i});break}case"code":{r.push({type:"code",language:s.lang,content:s.text??""});break}case"blockquote":{let i=eh(s);i.trim().length>0&&r.push({type:"blockquote",content:i});break}case"list":{let i=Array.isArray(s.items)?s.items.map(c=>Zg(c)).filter(c=>c.trim().length>0):[];i.length>0&&r.push({type:"list",items:i,ordered:!!s.ordered});break}default:break}return r}import{Fragment as uh,jsx as j,jsxs as At}from"react/jsx-runtime";var rh="\u2014\u2014\u2014";function oh(e,t){return e.repeat(Math.max(0,t))}function sh(e){let t=e.split(`
|
|
108
|
+
`);if(t.length===0)return["Think:"];let n=t.findIndex(r=>r.trim().length>0);return n<0&&(n=0),t.map((r,o)=>o===n?`Think: ${r}`:r)}function ih(e){return e.split(`
|
|
109
|
+
`)}function ah({content:e}){let t=ih(e);return j(Le,{flexDirection:"column",marginY:1,children:t.map((n,r)=>j(Ce,{children:n},r))})}function ch({node:e}){switch(e.type){case"bold":return j(Ce,{bold:!0,children:e.content});case"italic":return j(Ce,{italic:!0,children:e.content});case"inlineCode":return j(Ce,{color:"cyan",children:e.content});case"link":return At(uh,{children:[j(Ce,{color:"blue",underline:!0,children:e.label}),At(Ce,{color:"gray",children:[" (",e.href,")"]})]});case"text":return j(Ce,{children:e.content});default:return null}}function Ro({content:e}){let t=Xa(e);return j(Le,{flexWrap:"wrap",children:t.map((n,r)=>j(ch,{node:n},r))})}function lh(e,t){switch(e.type){case"html":return j(Le,{children:j(Ce,{color:"gray",dimColor:!0,children:e.content})},t);case"hr":return j(Le,{marginY:1,children:j(Ce,{color:"gray",dimColor:!0,children:rh})},t);case"think":return j(Le,{flexDirection:"column",marginY:1,children:sh(e.content).map((n,r)=>j(Ce,{color:"gray",dimColor:!0,children:n},r))},t);case"heading":return j(Le,{children:At(Ce,{bold:!0,color:"cyan",children:[oh("#",e.level)," ",e.content]})},t);case"paragraph":return j(Ro,{content:e.content},t);case"code":return j(ah,{content:e.content},t);case"blockquote":return j(Le,{flexDirection:"column",children:e.content.split(`
|
|
110
|
+
`).map((n,r)=>At(Le,{children:[j(Ce,{color:"gray",dimColor:!0,children:"> "}),j(Ro,{content:n})]},r))},t);case"list":return j(Le,{flexDirection:"column",children:e.items.map((n,r)=>At(Le,{children:[At(Ce,{color:"gray",children:[e.ordered?`${r+1}.`:"\u2022"," "]}),j(Ro,{content:n})]},r))},t);default:return null}}var Ya=th(function({content:t}){let n=nh(()=>Ja(t),[t]);return j(Le,{flexDirection:"column",children:n.map((r,o)=>lh(r,`${r.type}-${o}`))})});import{jsx as ye,jsxs as Ae}from"react/jsx-runtime";function Qa(e){return e===ke.ERROR?"red":e===ke.EXECUTING?"yellow":"green"}function Za(e,t){if(e==null)return null;if(typeof e=="string"){let s=qa(e)?Eo(e,t):e;return Yt(s,70)}if(typeof e!="object"||Array.isArray(e))return Yt(String(e),70);let n=e,r=["cmd","path","file_path","dir_path","query","pattern","url","content"],o=new Set(["path","file_path","dir_path"]);for(let s of r){let i=n[s];if(i==null||i==="")continue;let c=String(i),a=o.has(s)?Eo(c,t):c;return Yt(a,70)}return Yt(Ka(n),70)}var ec=Io(function({message:t}){let n=t.tone==="error"?"red":t.tone==="warning"?"yellow":"cyan";return Ae(Ye,{flexDirection:"column",children:[Ae(se,{color:n,children:["\u25CF ",t.title]}),ye(se,{color:"gray",children:t.content})]})}),ph=Io(function({step:t,cwd:n}){let r=!!(t.parallelActions&&t.parallelActions.length>1),o=!r&&t.action?Za(t.action.input,n):null;return Ae(Ye,{flexDirection:"column",children:[t.thinking?Ae(Ye,{children:[ye(se,{color:"gray",children:"\u25CF "}),ye(se,{color:"gray",children:t.thinking})]}):null,r?t.parallelActions?.map((s,i)=>{let c=Za(s.input,n);return Ae(Ye,{children:[Ae(se,{color:Qa(t.parallelToolStatuses?.[i]??t.toolStatus),children:["\u25CF"," "]}),ye(se,{color:"gray",children:"Used "}),ye(se,{color:"cyan",children:s.tool}),c?Ae(se,{color:"gray",children:[" (",c,")"]}):null]},`${s.tool}-${i}`)}):null,!r&&t.action?Ae(Ye,{children:[ye(se,{color:Qa(t.toolStatus),children:"\u25CF "}),ye(se,{color:"gray",children:"Used "}),ye(se,{color:"cyan",children:t.action.tool}),o?Ae(se,{color:"gray",children:[" (",o,")"]}):null]}):null]})}),Oo=Io(function({turn:t,cwd:n}){return Ae(Ye,{flexDirection:"column",children:[Ae(Ye,{marginY:.5,children:[ye(se,{color:"gray",children:"\u203A "}),ye(se,{children:t.userInput})]}),t.steps.map(r=>ye(ph,{step:r,cwd:n},`${t.index}-${r.index}`)),t.finalText?ye(Ye,{marginTop:0,children:ye(Ya,{content:t.finalText})}):null,t.status&&t.status!=="ok"?Ae(se,{color:"red",children:["Status: ",t.status]}):null,t.errorMessage?ye(se,{color:"red",children:t.errorMessage}):null]})});import{jsx as Zt,jsxs as en}from"react/jsx-runtime";function nc(e){return e.sequence??0}function gh(e){return e.type==="header"}function hh(e){return e.id!==void 0}function yh(e){let t=oc("");return rc(()=>{let n=`${e.sessionId}-${e.providerName}-${e.model}-${e.version}`;return n!==t.current&&(t.current=n),t.current},[e.sessionId,e.providerName,e.model,e.version])}var sc=dh(function({header:t,systemMessages:n,turns:r,historicalTurns:o}){let s=yh(t),i=oc(t.cwd);mh(()=>{i.current=t.cwd},[t.cwd]);let{completedTurns:c,inProgressTurn:a,staticItems:l}=rc(()=>{let u=[...o,...r],d=u.length>0?u[u.length-1]:void 0,m=d&&!!(d.finalText||d.status&&d.status!=="ok"),g=m?u:u.slice(0,-1),y=m?void 0:d,b={type:"header",data:t},U=[...n,...g];U.sort((H,R)=>nc(H)-nc(R));let T=[b,...U];return{completedTurns:g,inProgressTurn:y,staticItems:T}},[t,o,r,n]),p=i.current;return en(tc,{flexDirection:"column",children:[Zt(fh,{items:l,children:u=>gh(u)?en(tc,{borderStyle:"round",borderColor:"blue",paddingX:1,flexDirection:"column",children:[Zt(zn,{bold:!0,children:"Memo Code CLI"}),en(zn,{color:"gray",children:[u.data.providerName," / ",u.data.model," \u2022 v",u.data.version]}),en(zn,{color:"gray",children:["cwd: ",u.data.cwd]}),en(zn,{color:"gray",children:["mcp: ",u.data.mcpNames.join(", ")||"none"]})]},`header-${s}`):hh(u)?Zt(ec,{message:u},u.id):Zt(Oo,{turn:u,cwd:p},`turn-${u.sequence??u.index}`)}),a?Zt(Oo,{turn:a,cwd:p}):null]})});import{memo as Nh,useCallback as dt,useEffect as Yn,useMemo as kc,useRef as nn,useState as Ze}from"react";import{Box as Do,Text as Qn,useInput as $h,useStdout as Dh}from"ink";async function ic(e){return Is(e)}import{basename as _h,resolve as Lo}from"path";var ac=new Map;function cc(e){let t=Lo(e);return process.platform==="win32"?t.toLowerCase():t}function lc(e){return Lo(e)}function Sh(e){let t=Lo(e),n=ac.get(t);if(n)return n;let r=new hn({sessionsDir:t});return ac.set(t,r),r}function vh(e){let t=Date.parse(e);return Number.isFinite(t)?t:0}function Th(e){let t=e.title?.trim();return t||_h(e.filePath).replace(/\.jsonl$/i,"")}async function Gn(e){let t=e.limit??10;if(t<=0)return[];let r=await Sh(e.sessionsDir).getAllSummaries(),o=cc(e.cwd),s=e.activeSessionFile?lc(e.activeSessionFile):null,i=e.keyword?.trim().toLowerCase(),c=new Set,a=[],l=[...r].sort((p,u)=>u.date.updatedAt.localeCompare(p.date.updatedAt));for(let p of l){if(a.length>=t)break;if(cc(p.cwd)!==o)continue;let u=lc(p.filePath);if(s&&u===s||c.has(u))continue;let d=Th(p);i&&!d.toLowerCase().includes(i)||(c.add(u),a.push({id:u,cwd:e.cwd,input:d,ts:vh(p.date.updatedAt),sessionFile:u}))}return a}import{memo as wh}from"react";import{Box as Kn,Text as qn}from"ink";import{jsx as ut,jsxs as bh}from"react/jsx-runtime";var Ch="#3a3a3a",Vn="#262626",uc=wh(function({items:t,activeIndex:n,loading:r}){return r?ut(Kn,{paddingX:1,backgroundColor:Vn,children:ut(qn,{color:"gray",children:"Loading..."})}):t.length?ut(Kn,{flexDirection:"column",backgroundColor:Vn,children:t.map((o,s)=>{let i=s===n;return bh(Kn,{paddingX:1,gap:2,backgroundColor:i?Ch:Vn,children:[ut(qn,{color:i?"cyan":"white",bold:i,children:o.title}),o.subtitle?ut(qn,{color:"gray",children:o.subtitle}):null]},o.id)})}):ut(Kn,{paddingX:1,backgroundColor:Vn,children:ut(qn,{color:"gray",children:"No matches"})})});import xh from"string-width";var Mh=55296,kh=56319,Ah=56320,Ph=57343;function pc(e){return e>=Mh&&e<=kh}function dc(e){return e>=Ah&&e<=Ph}function Pe(e,t){if(!Number.isFinite(t)||t<=0)return 0;if(t>=e.length)return e.length;if(e.length===0)return 0;let n=Math.floor(t);if(n<=0)return 0;if(n>=e.length)return e.length;let r=e.charCodeAt(n),o=e.charCodeAt(n-1);return dc(r)&&pc(o)?n-1:n}function mc(e,t){let n=Pe(e,t);if(n>=e.length)return e.length;let r=e.codePointAt(n);return r===void 0?Math.min(e.length,n+1):Math.min(e.length,n+(r>65535?2:1))}function pt(e,t){let n=Pe(e,t);if(n<=0)return 0;let r=n-1;if(r<=0)return r;let o=e.charCodeAt(r),s=e.charCodeAt(r-1);return dc(o)&&pc(s)?r-1:r}function Xn(e,t){let n=Pe(e,t),r=e.lastIndexOf(`
|
|
111
|
+
`,Math.max(0,n-1));return r===-1?0:r+1}function Jn(e,t){let n=Pe(e,t),r=e.indexOf(`
|
|
112
|
+
`,n);return r===-1?e.length:r}function Eh(e){return/[\p{L}\p{N}_]/u.test(e)}function fc(e,t,n){let r=Pe(e,t);if(!n)return{value:e,cursor:r};let o=n.replace(/\r\n?/g,`
|
|
113
|
+
`);return o?{value:`${e.slice(0,r)}${o}${e.slice(r)}`,cursor:r+o.length}:{value:e,cursor:r}}function gc(e,t){let n=Pe(e,t);if(n<=0)return{value:e,cursor:n};let r=pt(e,n);return{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function No(e,t){let n=Pe(e,t);if(n>=e.length)return{value:e,cursor:n};let r=mc(e,n);return{value:`${e.slice(0,n)}${e.slice(r)}`,cursor:n}}function hc(e,t){let n=Pe(e,t);if(n<=0)return{value:e,cursor:n};let r=n;for(;r>0;){let s=pt(e,r);if(e.slice(s,r).trim().length>0)break;r=s}for(;r>0;){let s=pt(e,r),i=e.slice(s,r);if(!Eh(i))break;r=s}return r===n&&(r=pt(e,n)),{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function yc(e,t){let n=Pe(e,t),r=Xn(e,n);return r>=n?{value:e,cursor:n}:{value:`${e.slice(0,r)}${e.slice(n)}`,cursor:r}}function _c(e,t){let n=Pe(e,t),r=Jn(e,n);return r<=n?{value:e,cursor:n}:{value:`${e.slice(0,n)}${e.slice(r)}`,cursor:n}}function Sc(e,t){return pt(e,t)}function vc(e,t){return mc(e,t)}function Tc(e,t){return Xn(e,t)}function wc(e,t){return Jn(e,t)}function $o(e,t,n,r){let o=Pe(e,t),s=Xn(e,o),i=Jn(e,o),c=o-s,a=r??c;if(n==="up"){if(s===0)return{cursor:o,preferredColumn:a,changed:!1};let d=s-1,m=Xn(e,d),g=Math.min(m+a,d);return{cursor:g,preferredColumn:a,changed:g!==o}}if(i>=e.length)return{cursor:o,preferredColumn:a,changed:!1};let l=i+1,p=Jn(e,l),u=Math.min(l+a,p);return{cursor:u,preferredColumn:a,changed:u!==o}}function Cc(e,t,n){let r=Pe(e,t),o=Number.isFinite(n)?Math.max(1,Math.floor(n)):1,s=[],i=0,c=0,a="",l=0,p=()=>{s.push({text:a,start:i,end:c})},u=0;for(let g of e){let y=u;if(u+=g.length,g===`
|
|
114
|
+
`){c=y,p(),i=u,c=u,a="",l=0;continue}let b=Math.max(0,xh(g));a.length>0&&l+b>o&&(p(),i=y,c=y,a="",l=0),a+=g,c=u,l+=b}if(p(),s.length===0)return{lines:[{text:"",start:0,end:0}],row:0,cursorInRow:0};let d=Math.max(0,s.length-1),m=(s[d]?.text??"").length;for(let g=0;g<s.length;g+=1){let y=s[g];if(y&&!(r<y.start)&&r<=y.end){d=g,m=r-y.start;break}}return{lines:s,row:d,cursorInRow:m}}function bc(e,t){let n=e==="\b"||e==="\x7F",r=!!t.ctrl&&e.toLowerCase()==="h";return t.backspace||n||r||t.delete&&!(t.ctrl||t.meta)?"backspace":t.delete?"delete":"none"}var Rh=3,xc=8,Ih=120,Oh=process.platform==="win32"?60:8,tn=class{lastPlainCharAtMs=null;consecutivePlainChars=0;burstWindowUntilMs=null;buffer="";active=!1;pendingFirstChar=null;minChars;charIntervalMs;enterSuppressWindowMs;activeIdleTimeoutMs;constructor(t={}){this.minChars=t.minChars??Rh,this.charIntervalMs=t.charIntervalMs??xc,this.enterSuppressWindowMs=t.enterSuppressWindowMs??Ih,this.activeIdleTimeoutMs=t.activeIdleTimeoutMs??Oh}static recommendedFlushDelayMs(){return xc+1}recommendedActiveFlushDelayMs(){return this.activeIdleTimeoutMs+1}onPlainChar(t,n){let r=Array.from(t)[0]??"";return this.notePlainChar(n),this.active?(this.extendWindow(n),{type:"buffer_append"}):this.pendingFirstChar&&n-this.pendingFirstChar.atMs<=this.charIntervalMs?(this.active=!0,this.buffer+=this.pendingFirstChar.ch,this.pendingFirstChar=null,this.extendWindow(n),{type:"begin_buffer_from_pending"}):this.consecutivePlainChars>=this.minChars?{type:"begin_buffer",retroChars:Math.max(0,this.consecutivePlainChars-1)}:r?(this.pendingFirstChar={ch:r,atMs:n},{type:"retain_first_char"}):{type:"retain_first_char"}}onPlainCharNoHold(t){return this.notePlainChar(t),this.active?(this.extendWindow(t),{type:"buffer_append"}):this.consecutivePlainChars>=this.minChars?{type:"begin_buffer",retroChars:Math.max(0,this.consecutivePlainChars-1)}:null}flushIfDue(t){let n=this.isActiveInternal()?this.activeIdleTimeoutMs:this.charIntervalMs;if(!(this.lastPlainCharAtMs!==null&&t-this.lastPlainCharAtMs>n))return{type:"none"};if(this.isActiveInternal()){this.active=!1;let o=this.buffer;return this.buffer="",{type:"paste",text:o}}if(this.pendingFirstChar){let o=this.pendingFirstChar.ch;return this.pendingFirstChar=null,{type:"typed",text:o}}return{type:"none"}}appendNewlineIfActive(t){return this.isActiveInternal()?(this.buffer+=`
|
|
115
|
+
`,this.extendWindow(t),!0):!1}newlineShouldInsertInsteadOfSubmit(t){let n=this.burstWindowUntilMs!==null&&t<=this.burstWindowUntilMs;return this.isActiveInternal()||n}extendWindow(t){this.burstWindowUntilMs=t+this.enterSuppressWindowMs}beginWithRetroGrabbed(t,n){t&&(this.buffer+=t),this.active=!0,this.extendWindow(n)}appendCharToBuffer(t,n){t&&(this.buffer+=t,this.extendWindow(n))}decideBeginBuffer(t,n,r){let o=Lh(n,r),s=n.slice(o);return/\s/u.test(s)||Array.from(s).length>=16?(this.beginWithRetroGrabbed(s,t),{start:o,grabbed:s}):null}flushBeforeModifiedInput(){if(!this.isActive())return null;this.active=!1;let t=this.buffer;return this.buffer="",this.pendingFirstChar&&(t+=this.pendingFirstChar.ch,this.pendingFirstChar=null),t}clearWindowAfterNonChar(){this.consecutivePlainChars=0,this.lastPlainCharAtMs=null,this.burstWindowUntilMs=null,this.active=!1,this.pendingFirstChar=null}isActive(){return this.isActiveInternal()||this.pendingFirstChar!==null}isBuffering(){return this.isActiveInternal()}hasPendingFirstChar(){return this.pendingFirstChar!==null}clearAfterExplicitPaste(){this.lastPlainCharAtMs=null,this.consecutivePlainChars=0,this.burstWindowUntilMs=null,this.active=!1,this.buffer="",this.pendingFirstChar=null}notePlainChar(t){this.lastPlainCharAtMs!==null&&t-this.lastPlainCharAtMs<=this.charIntervalMs?this.consecutivePlainChars+=1:this.consecutivePlainChars=1,this.lastPlainCharAtMs=t}isActiveInternal(){return this.active||this.buffer.length>0}};function Lh(e,t){if(t<=0)return e.length;let n=e.length,r=t;for(;r>0&&n>0;)n=pt(e,n),r-=1;return n}var $e={HELP:"help",EXIT:"exit",NEW:"new",RESUME:"resume",REVIEW:"review",MODELS:"models",TOOLS:"tools",COMPACT:"compact",MCP:"mcp",INIT:"init"},_e={NONE:"none",ONCE:"once",FULL:"full"};function Qe(e){return`/${e}`}var Mc="exit";import{jsx as Pt,jsxs as Ac}from"react/jsx-runtime";var Uh=400,Uo=Qe($e.MODELS),Fo=Qe($e.TOOLS),Fh=Qe($e.INIT),Hh=[{mode:_e.NONE,description:"Disable all tool calls"},{mode:_e.ONCE,description:"Require approval when needed"},{mode:_e.FULL,description:"Run tools without approval"}];function Bh(e){let t=e.lastIndexOf("@");if(t===-1)return null;if(t>0){let r=e[t-1];if(r&&!/\s/.test(r))return null}let n=e.slice(t+1);return/\s/.test(n)?null:{type:"file",query:n,tokenStart:t+1}}function Wh(e){let t=e.trimStart(),n=e.length-t.length;if(!t.length)return null;let r=t;if(r.startsWith("/")&&(r=r.slice(1)),!r.toLowerCase().startsWith($e.RESUME)||e.slice(0,n).trim().length>0)return null;let s=r.slice($e.RESUME.length);return s&&!s.startsWith(" ")?null:{type:"history",keyword:s.trim()}}function jh(e){let t=e.trimStart();if(!t.startsWith("/"))return null;let n=t.slice(1);return n.includes(" ")?null:n.length?/^[a-zA-Z-]+$/.test(n)?{type:"slash",keyword:n.toLowerCase()}:null:{type:"slash",keyword:""}}function zh(e){let t=e.trimStart();if(!t.startsWith(Uo))return null;let n=t.slice(Uo.length);return n&&!n.startsWith(" ")?null:{type:"models",keyword:n.trim().toLowerCase()}}function Gh(e){let t=e.trimStart();if(!t.startsWith(Fo))return null;let n=t.slice(Fo.length);return n&&!n.startsWith(" ")?null:{type:"tools"}}function Kh(e){return Gh(e)??zh(e)??jh(e)??Bh(e)??Wh(e)}function qh(e){let t=new Date(e);if(Number.isNaN(t.getTime()))return"";let n=String(t.getFullYear()),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${n}-${r}-${o} ${s}:${i}`}function Vh(e,t){return{mode:"model",items:e.filter(r=>{if(!t)return!0;let o=r.name.toLowerCase(),s=r.model.toLowerCase();return o.includes(t)||s.includes(t)}).map(r=>({id:r.name,title:`${r.name}: ${r.model}`,subtitle:r.base_url,kind:"model",value:`${Uo} ${r.name}`,meta:{type:"model",provider:r}}))}}function Xh(e){return{mode:"tools",items:Hh.map(n=>({id:n.mode,title:n.mode,subtitle:n.mode===e?`Current \xB7 ${n.description}`:n.description,kind:"tools",value:`${Fo} ${n.mode}`,meta:{type:"tools",mode:n.mode}}))}}function Jh(e){return{mode:"slash",items:jt.filter(n=>n.name.startsWith(e)).map(n=>({id:n.name,title:`/${n.name}`,subtitle:n.description,kind:"slash",value:`/${n.name}`,meta:{type:"slash"}}))}}async function Yh({trigger:e,cwd:t,sessionsDir:n,currentSessionFile:r,providers:o,toolPermissionMode:s}){switch(e.type){case"file":return{mode:"file",items:(await ic({cwd:t,query:e.query,limit:8,respectGitIgnore:!0})).map(a=>({id:a.id,title:a.isDir?`${a.path}/`:a.path,kind:"file",value:a.isDir?`${a.path}/`:a.path,meta:{type:"file",isDir:a.isDir}}))};case"history":return{mode:"history",items:(await Gn({sessionsDir:n,cwd:t,keyword:e.keyword,activeSessionFile:r})).map(a=>({id:a.id,title:a.input,subtitle:qh(a.ts),kind:"history",value:a.input,meta:{type:"history",entry:a}}))};case"models":return Vh(o,e.keyword);case"tools":return Xh(s);case"slash":return Jh(e.keyword)}}var Pc=Nh(function({disabled:t,busy:n,history:r,cwd:o,sessionsDir:s,currentSessionFile:i,providers:c,configPath:a,providerName:l,model:p,toolPermissionMode:u,mcpServers:d,onSubmit:m,onExit:g,onClear:y,onNewSession:b,onCancelRun:U,onCompact:T,onHistorySelect:H,onModelSelect:R,onSetToolPermission:I,onReviewPullRequest:G,onSystemMessage:ie}){let{stdout:Re}=Dh(),[ae,z]=Ze({value:"",cursor:0}),M=nn(ae),P=nn(null),[ne,ce]=Ze(null),[F,le]=Ze(""),[J,A]=Ze("none"),[O,re]=Ze([]),[Se,ge]=Ze(0),[qe,De]=Ze(!1),[rt,ve]=Ze(!1),be=nn(0),k=nn(0),L=nn(new tn);Yn(()=>{M.current=ae,ve(!1)},[ae]);let an=kc(()=>({configPath:a,providerName:l,model:p,mcpServers:d,providers:c,toolPermissionMode:u}),[a,l,p,d,c,u]),Te=kc(()=>t||rt?null:Kh(ae.value),[t,ae.value,rt]),K=dt((w=!0)=>{w&&ve(!0),A("none"),re([]),ge(0),De(!1)},[]),$=dt((w,S=!1)=>{M.current=w,z(w),S&&(ce(null),le(""))},[]),Nt=dt(()=>{$({value:"",cursor:0},!0)},[$]),N=dt((w,S=!0)=>{if(!w)return;let _=M.current;P.current=null;let Z=fc(_.value,_.cursor,w);$(Z,S),w.includes(`
|
|
116
|
+
`)&&K(!1)},[$,K]),ot=dt(w=>w.type==="none"?!1:w.type==="paste"?(w.text&&N(w.text,!0),!0):(N(w.text,!0),!0),[N]),ue=dt((w=!0)=>{let S=L.current.flushBeforeModifiedInput();return S&&N(S,!0),w&&L.current.clearWindowAfterNonChar(),!!S},[N]);Yn(()=>{let w=setInterval(()=>{let S=L.current.flushIfDue(Date.now());ot(S)},tn.recommendedFlushDelayMs());return()=>{clearInterval(w)}},[ot]),Yn(()=>{t&&K(!1)},[t,K]),Yn(()=>{if(!Te){K(!1);return}let w=!1,S=++be.current;return De(!0),(async()=>{try{let{mode:_,items:Z}=await Yh({trigger:Te,cwd:o,sessionsDir:s,currentSessionFile:i,providers:c,toolPermissionMode:u});if(w||S!==be.current)return;A(_),re(Z),ge(oe=>Z.length?Math.min(oe,Z.length-1):0)}finally{!w&&S===be.current&&De(!1)}})(),()=>{w=!0}},[Te,o,s,i,c,u,K]);let Ve=dt(w=>{if(w){if(J==="file"&&Te?.type==="file"){let S=M.current.value,_=S.slice(0,Te.tokenStart),Z=S.slice(Te.tokenStart+Te.query.length),oe=`${_}${w.value}${Z}`,Ue=_.length+w.value.length;$({value:oe,cursor:Ue},!0),w.meta?.type==="file"&&w.meta.isDir||K();return}switch(w.meta?.type){case"history":H(w.meta.entry),$({value:w.value,cursor:w.value.length},!1),K();return;case"model":R(w.meta.provider),Nt(),K();return;case"tools":I(w.meta.mode),Nt(),K();return;case"slash":$({value:`${w.value} `,cursor:`${w.value} `.length},!0),K(!1);return;default:$({value:w.value,cursor:w.value.length},!0),K()}}},[$,J,Te,K,Nt,H,R,I]);$h((w,S)=>{if(S.ctrl&&w==="c"){g();return}if(t)return;let _=Date.now();ot(L.current.flushIfDue(_));let Z=J!=="none",oe=Z&&O.length>0,Ue=bc(w,S),ur=!!(S.ctrl||S.meta),$t=!!w&&!ur&&!S.return&&!S.tab&&Ue==="none"&&!S.escape&&!S.upArrow&&!S.downArrow&&!S.leftArrow&&!S.rightArrow;if(!$t&&!S.return&&ue(!0),S.ctrl&&w==="a"){let x=M.current,E=Tc(x.value,x.cursor);P.current=null,$({value:x.value,cursor:E},!1);return}if(S.ctrl&&w==="e"){let x=M.current,E=wc(x.value,x.cursor);P.current=null,$({value:x.value,cursor:E},!1);return}if(S.ctrl&&w==="u"){let x=M.current,E=yc(x.value,x.cursor);P.current=null,$(E,!0);return}if(S.ctrl&&w==="k"){let x=M.current,E=_c(x.value,x.cursor);P.current=null,$(E,!0);return}if(S.ctrl&&w==="w"){let x=M.current,E=hc(x.value,x.cursor);P.current=null,$(E,!0);return}if(S.ctrl&&w==="d"){let x=M.current;if(!x.value){g();return}let E=No(x.value,x.cursor);P.current=null,$(E,!0);return}if(S.ctrl&&w==="l"){$({value:"",cursor:0},!0),K(),y(),b();return}if(S.escape){if(_-k.current<=Uh){k.current=0,n?U():(P.current=null,$({value:"",cursor:0},!0),K());return}k.current=_,Z&&K();return}if(S.upArrow){if(oe){ge(B=>B<=0?O.length-1:B-1);return}let x=M.current;if(x.value.includes(`
|
|
117
|
+
`)){let B=$o(x.value,x.cursor,"up",P.current??void 0);if(B.changed){P.current=B.preferredColumn,$({value:x.value,cursor:B.cursor},!1);return}}if(!r.length)return;if(ne===null){le(x.value);let B=r.length-1;ce(B);let xe=r[B]??"";P.current=null,$({value:xe,cursor:xe.length},!1);return}let E=Math.max(0,ne-1);ce(E);let pe=r[E]??"";P.current=null,$({value:pe,cursor:pe.length},!1);return}if(S.downArrow){if(oe){ge(B=>(B+1)%O.length);return}let x=M.current;if(x.value.includes(`
|
|
118
|
+
`)){let B=$o(x.value,x.cursor,"down",P.current??void 0);if(B.changed){P.current=B.preferredColumn,$({value:x.value,cursor:B.cursor},!1);return}}if(ne===null)return;let E=ne+1;if(E>=r.length){ce(null),P.current=null,$({value:F,cursor:F.length},!1),le("");return}ce(E);let pe=r[E]??"";P.current=null,$({value:pe,cursor:pe.length},!1);return}if(S.leftArrow){let x=M.current,E=Sc(x.value,x.cursor);P.current=null,$({value:x.value,cursor:E},!1);return}if(S.rightArrow){let x=M.current,E=vc(x.value,x.cursor);P.current=null,$({value:x.value,cursor:E},!1);return}if(S.tab&&oe){Ve(O[Se]);return}if(S.return){if(oe){Ve(O[Se]);return}L.current.hasPendingFirstChar()&&!L.current.isBuffering()&&ue(!1);let x=M.current.value.trimStart().startsWith("/");if(!S.shift&&!x){if(L.current.appendNewlineIfActive(_))return;if(L.current.newlineShouldInsertInsteadOfSubmit(_)){ue(!1),N(`
|
|
119
|
+
`,!0),L.current.extendWindow(_);return}}if(ue(!0),S.shift){N(`
|
|
120
|
+
`,!0);return}let pe=M.current.value.trim();if(!pe)return;if(pe.startsWith("/")){let B=xr(pe,an);switch(B.kind){case"message":ie(B.title,B.content);break;case"new":b();break;case"exit":g();break;case"switch_model":R(B.provider);break;case"set_tool_permission":I(B.mode);break;case"compact":T();break;case"review_pr":G(B.prNumber);break;case"init_agents_md":m(Fh);break;default:{let xe=B}}P.current=null,$({value:"",cursor:0},!0),K(!1);return}m(pe),P.current=null,$({value:"",cursor:0},!0),K(!1);return}if(Ue!=="none"){let x=M.current,E=Ue==="backspace"?gc(x.value,x.cursor):No(x.value,x.cursor);P.current=null,$(E,!0);return}if(w&&$t){let x=Array.from(w);if(x.length!==1){ue(!1),N(w,!0),L.current.clearAfterExplicitPaste();return}let E=x[0]??"";if(!E)return;let pe=it=>{let gt=M.current,cn=gt.value.slice(0,gt.cursor),ln=gt.value.slice(gt.cursor),Dt=L.current.decideBeginBuffer(_,cn,it);return Dt?(P.current=null,$({value:`${cn.slice(0,Dt.start)}${ln}`,cursor:Dt.start},!0),L.current.appendCharToBuffer(E,_),!0):!1};if(!((E.codePointAt(0)??0)<=127)){let it=L.current.onPlainCharNoHold(_);if(it?.type==="buffer_append"){L.current.appendCharToBuffer(E,_);return}if(it?.type==="begin_buffer"&&pe(it.retroChars))return;ue(!1),N(E,!0);return}let xe=L.current.onPlainChar(E,_);if(xe.type==="retain_first_char")return;if(xe.type==="buffer_append"||xe.type==="begin_buffer_from_pending"){L.current.appendCharToBuffer(E,_);return}if(xe.type==="begin_buffer"&&pe(xe.retroChars))return;ue(!1),N(E,!0);return}w&&(N(w,!0),L.current.clearWindowAfterNonChar())});let ft=Re?.columns??process.stdout?.columns??80,Q=Math.max(1,ft-3),Xe=Cc(ae.value,ae.cursor,Q),st=Xe.lines;return Ac(Do,{flexDirection:"column",gap:1,children:[Pt(Do,{flexDirection:"column",paddingY:1,children:st.map((w,S)=>{let _=w.text,Z=!t&&S===Xe.row,oe=Z?_.slice(0,Xe.cursorInRow):_,Ue=Z?_.slice(Xe.cursorInRow):"";return Ac(Do,{children:[Pt(Qn,{color:"gray",children:S===0?"\u203A ":" "}),Pt(Qn,{children:oe}),Z?Pt(Qn,{color:"cyan",children:"\u258A"}):null,Z?Pt(Qn,{children:Ue}):null]},`line-${S}`)})}),J!=="none"?Pt(uc,{items:O.map(({value:w,meta:S,..._})=>_),activeIndex:Se,loading:qe}):null]})});import{memo as Qh}from"react";import{Box as Ec,Text as Ho}from"ink";import{jsx as Bo,jsxs as Rc}from"react/jsx-runtime";var Ic=Qh(function({busy:t,pendingApproval:n=!1,contextPercent:r}){let o=`${r.toFixed(1)}%`;return Rc(Ec,{justifyContent:"space-between",children:[Bo(Ec,{children:t?Bo(Ho,{color:"yellow",children:"Working..."}):Bo(Ho,{color:"gray",children:n?"Approval pending \u2022 Enter confirm \u2022 Esc deny":"Enter send \u2022 Shift+Enter newline \u2022 /help"})}),Rc(Ho,{color:"gray",children:["context: ",o]})]})});import{memo as Zh}from"react";import{Box as Zn,Text as Wo,useInput as ey}from"ink";import{Select as ty,StatusMessage as ny}from"@inkjs/ui";import{jsx as mt,jsxs as Oc}from"react/jsx-runtime";var ry=[{label:"Allow once",decision:"once"},{label:"Allow for this session",decision:"session"},{label:"Deny",decision:"deny"}];function oy(e){if(!e)return"";if(typeof e!="object")return String(e);let t=Object.entries(e);if(!t.length)return"";let[n,r]=t[0]??[];if(!n)return"";let o=typeof r=="string"?r:JSON.stringify(r);return`${n}=${o?.slice(0,60)??""}${o&&o.length>60?"...":""}`}var Lc=Zh(function({request:t,onDecision:n}){ey((o,s)=>{(s.escape||s.ctrl&&o==="c")&&n("deny")});let r=oy(t.params);return Oc(Zn,{flexDirection:"column",borderStyle:"single",borderColor:"yellow",paddingX:1,children:[mt(Wo,{bold:!0,color:"yellow",children:"Tool Approval Required"}),Oc(Wo,{children:[t.toolName,r?` (${r})`:""]}),mt(Zn,{marginTop:1,children:mt(ny,{variant:"warning",children:t.reason})}),mt(Zn,{marginTop:1,flexDirection:"column",children:mt(ty,{options:ry.map(o=>({label:o.label,value:o.decision})),onChange:o=>{n(o)}})}),mt(Zn,{marginTop:1,children:mt(Wo,{color:"gray",children:"Enter confirm \u2022 Esc deny"})})]})});import{memo as sy,useMemo as iy,useState as ay}from"react";import{Box as jo,Text as er,useInput as cy}from"ink";import{MultiSelect as ly}from"@inkjs/ui";import{jsx as rn,jsxs as zo}from"react/jsx-runtime";function uy(e,t){let n=new Set(e);return t.filter(r=>n.has(r))}var Nc=sy(function({serverNames:t,defaultSelected:n,onConfirm:r,onExit:o}){let s=iy(()=>{let l=uy(t,n);return n.length===0?[]:l.length>0?l:[...t]},[n,t]),[i,c]=ay(s),a=i.length===t.length;return cy((l,p)=>{if(p.ctrl&&l==="c"){o();return}p.escape&&r(i,!1)}),zo(jo,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[rn(er,{bold:!0,color:"cyan",children:"Activate MCP Servers"}),rn(er,{color:"gray",children:"Select servers to load for this run."}),rn(jo,{marginTop:1,flexDirection:"column",children:rn(ly,{options:t.map(l=>({label:l,value:l})),defaultValue:s,onChange:c,onSubmit:l=>{r(l,!0)}})}),zo(jo,{marginTop:1,flexDirection:"column",children:[zo(er,{color:"gray",children:["Selected: ",i.length,"/",t.length,a?" (all)":""]}),rn(er,{color:"gray",children:"Controls: \u2191/\u2193 move, Space toggle, Enter confirm"})]})]})});import{spawn as py}from"child_process";var Go="\x07",dy="Memo: Approval required",my="Memo CLI",fy=2e3;function gy(e){return e.replace(/\s+/g," ").trim()}function hy(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3))}...`}function yy(e){let t=gy(e.reason),n=`Tool ${e.toolName} is waiting for your approval.`;return t?hy(`${n} ${t}`,220):n}function $c(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function _y(e,t=process.platform){let n=dy,r=yy(e);return t==="darwin"?{command:"osascript",args:["-e",`display notification "${$c(r)}" with title "${$c(n)}"`]}:t==="linux"?{command:"notify-send",args:["--app-name",my,n,r]}:null}async function Sy(e,t){await new Promise((n,r)=>{let o=py(e,t,{stdio:"ignore"}),s=!1,i=a=>{if(!s){if(s=!0,a){r(a);return}n()}},c=setTimeout(()=>{try{o.kill()}catch{}i()},fy);o.once("error",a=>{clearTimeout(c),i(a)}),o.once("exit",a=>{if(clearTimeout(c),a===0||a===null){i();return}i(new Error(`${e} exited with code ${a}`))})})}function vy(e){if(e){e(Go);return}try{if(process.stdout?.isTTY){process.stdout.write(Go);return}process.stderr?.isTTY&&process.stderr.write(Go)}catch{}}async function Dc(e,t={}){vy(t.writeBell);let n=_y(e,t.platform??process.platform);if(!n)return;let r=t.runCommand??Sy;try{await r(n.command,n.args)}catch{}}import{Box as Et,Text as Ke,useInput as Ty}from"ink";import{Spinner as wy,StatusMessage as Cy,TextInput as by}from"@inkjs/ui";import{memo as xy,useCallback as Uc,useMemo as My,useState as tr}from"react";import{jsx as Ee,jsxs as Rt}from"react/jsx-runtime";var et=[{key:"name",label:"Provider name",hint:"Used for /models switching",defaultValue:"deepseek"},{key:"envKey",label:"API key env var",hint:"Read at runtime from environment variables",defaultValue:"DEEPSEEK_API_KEY"},{key:"model",label:"Model name",defaultValue:"deepseek-chat"},{key:"baseUrl",label:"Base URL",defaultValue:"https://api.deepseek.com"}],Fc=xy(function({configPath:t,onComplete:n,onExit:r}){let[o,s]=tr(0),[i,c]=tr({}),[a,l]=tr(!1),[p,u]=tr(null),d=et[o]??et[0],m=Uc(async b=>{l(!0),u(null);try{let U={current_provider:b.name,providers:[{name:b.name,env_api_key:b.envKey,model:b.model,base_url:b.baseUrl||void 0}]};await we(t,U),n()}catch(U){u(U.message),l(!1)}},[t,n]),g=Uc(async b=>{if(!d)return;let U=b.trim()||d.defaultValue,T={...i,[d.key]:U};if(c(T),o<et.length-1){s(o+1);return}let H={name:T.name||et[0].defaultValue,envKey:T.envKey||et[1].defaultValue,model:T.model||et[2].defaultValue,baseUrl:T.baseUrl||et[3].defaultValue};await m(H)},[m,d,o,i]);Ty((b,U)=>{U.ctrl&&b==="c"&&r()});let y=My(()=>`Step ${o+1}/${et.length}`,[o]);return d?Rt(Et,{flexDirection:"column",children:[Ee(Ke,{bold:!0,children:"Memo setup"}),Ee(Ke,{color:"gray",children:"No provider config found. Complete setup to continue."}),Rt(Ke,{color:"gray",children:["Config path: ",t]}),Rt(Et,{marginTop:1,flexDirection:"column",children:[Ee(Ke,{color:"cyan",children:y}),Ee(Ke,{children:d.label}),Rt(Ke,{color:"gray",children:["Default: ",d.defaultValue]}),d.hint?Ee(Ke,{color:"gray",children:d.hint}):null]}),Rt(Et,{marginTop:1,children:[Ee(Ke,{color:"gray",children:"> "}),Ee(by,{isDisabled:a,defaultValue:i[d.key]??"",placeholder:d.defaultValue,onSubmit:b=>{g(b)}},d.key)]}),Ee(Et,{marginTop:1,children:Ee(Ke,{color:"gray",children:"Enter to continue, Ctrl+C to exit"})}),a?Ee(Et,{marginTop:1,children:Ee(wy,{label:"Saving config..."})}):null,p?Ee(Et,{marginTop:1,children:Rt(Cy,{variant:"error",children:["Failed to save config: ",p]})}):null]}):null});function Hc(e){let t=e.finalText?.trim();return t||e.steps.map(n=>n.assistantText??"").join("").trim()}function ky(e){return e==="ok"||e==="error"||e==="cancelled"?e:void 0}function Ay(e){if(e.resultStatus)return e.resultStatus==="success"?ke.SUCCESS:ke.ERROR}function Py(e,t,n){return{index:-(n+1),userInput:e.input??"",steps:(e.steps??[]).map(r=>({index:r.step,assistantText:r.assistantText??"",thinking:r.thinking,action:r.action,parallelActions:r.parallelActions,observation:r.observation,toolStatus:Ay(r)})),status:ky(e.status),errorMessage:e.errorMessage,tokenUsage:e.tokenUsage,finalText:Hc(e),sequence:t}}function nr(e){let t=gn(e,"history.log"),n=[...t.turns].sort((i,c)=>i.turn-c.turn),r=[];for(let i of n){let c=(i.input??"").trim();c&&r.push({role:"user",content:c});let a=Hc(i);a&&r.push({role:"assistant",content:a})}let o=0,s=n.map((i,c)=>(o+=1,Py(i,o,c)));return{summary:t.summary,messages:r,turns:s,maxSequence:o}}function Ko(){return{turns:[],historicalTurns:[],systemMessages:[],sequence:0}}function Ey(e,t){return{index:e,userInput:"",steps:[],sequence:t}}function rr(e,t){if(e.length>t)return e;let n=e.slice();for(;n.length<=t;)n.push({index:n.length,assistantText:""});return n}function It(e,t,n){let r=e.turns.slice(),o=r.findIndex(i=>i.index===t);if(o===-1){let i=e.sequence+1;return r.push(n(Ey(t,i))),{turns:r,sequence:i}}let s=r[o];return s?(r[o]=n(s),{turns:r,sequence:e.sequence}):{turns:r,sequence:e.sequence}}function Ry(e){return{id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,title:e.title,content:e.content,tone:e.tone??"info",sequence:e.sequence}}function Bc(e,t){switch(t.type){case"append_system_message":{let n=e.sequence+1;return{...e,sequence:n,systemMessages:[...e.systemMessages,Ry({title:t.title,content:t.content,tone:t.tone,sequence:n})]}}case"turn_start":{let n=It(e,t.turn,r=>({...r,index:t.turn,userInput:t.input,steps:[],finalText:void 0,status:void 0,errorMessage:void 0,tokenUsage:void 0,startedAt:Date.now(),durationMs:void 0,contextPromptTokens:t.promptTokens??r.contextPromptTokens}));return{...e,turns:n.turns,sequence:n.sequence}}case"context_usage":{let n=It(e,t.turn,r=>{let o=rr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,contextPromptTokens:t.promptTokens},{...r,contextPromptTokens:t.promptTokens,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"assistant_chunk":{let n=It(e,t.turn,r=>{let o=rr(r.steps,t.step),s=o[t.step];if(!s)return r;let i=`${s.assistantText}${t.chunk}`;return i===s.assistantText?r:(o[t.step]={...s,assistantText:i},{...r,steps:o})});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_action":{let n=It(e,t.turn,r=>{let o=rr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,action:t.action,thinking:t.thinking,parallelActions:t.parallelActions&&t.parallelActions.length>1?t.parallelActions:void 0,toolStatus:ke.EXECUTING},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"tool_observation":{let n=It(e,t.turn,r=>{let o=rr(r.steps,t.step),s=o[t.step];return s?(o[t.step]={...s,observation:t.observation,toolStatus:t.toolStatus,parallelToolStatuses:t.parallelToolStatuses},{...r,steps:o}):r});return{...e,turns:n.turns,sequence:n.sequence}}case"turn_final":{let n=It(e,t.turn,r=>{let o=r.startedAt??Date.now(),s=Math.max(0,Date.now()-o),i=t.tokenUsage?.prompt??r.contextPromptTokens;return{...r,finalText:t.finalText,status:t.status,errorMessage:t.errorMessage,tokenUsage:t.turnUsage,contextPromptTokens:i,startedAt:o,durationMs:s}});return{...e,turns:n.turns,sequence:n.sequence}}case"replace_history":return{...e,historicalTurns:t.turns,sequence:Math.max(e.sequence,t.maxSequence)};case"clear_current_timeline":return{...e,turns:[],systemMessages:[]};case"reset_all":return Ko();default:return e}}import{dirname as or,join as jc,resolve as Iy}from"path";import{statSync as Oy,existsSync as zc,readFileSync as Ly}from"fs";import{readFile as Ny}from"fs/promises";import{get as $y}from"https";import{fileURLToPath as Dy}from"url";function Wc(e){let t=e.trim().replace(/^v/i,""),[n="",r]=t.split("-",2),o=n.split(".").map(s=>Number(s));return o.length<3||o.some(s=>!Number.isFinite(s))?null:{major:o[0]??0,minor:o[1]??0,patch:o[2]??0,prerelease:r??null}}function Uy(e,t){let n=Wc(e),r=Wc(t);return!n||!r?!1:n.major!==r.major?n.major>r.major:n.minor!==r.minor?n.minor>r.minor:n.patch!==r.patch?n.patch>r.patch:n.prerelease&&!r.prerelease?!1:!n.prerelease&&r.prerelease?!0:n.prerelease&&r.prerelease?n.prerelease>r.prerelease:!1}function Gc(){try{let t=Dy(import.meta.url);return or(t)}catch{}let e=Iy(process.argv[1]??process.cwd());try{return Oy(e).isFile()?or(e):e}catch{return process.cwd()}}async function Fy(e){let t=jc(e,"package.json");if(!zc(t))return null;let n=await Ny(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}function Hy(e){let t=jc(e,"package.json");if(!zc(t))return null;try{let n=Ly(t,"utf8"),r=JSON.parse(n);return!r.name||!r.version?null:{name:r.name,version:r.version}}catch{return null}}async function By(){let e=Gc();for(;;){let t=await Fy(e);if(t&&t.name==="@memo-code/memo")return t;let n=or(e);if(n===e)break;e=n}return null}function sr(){let e=Gc();for(;;){let t=Hy(e);if(t&&t.name==="@memo-code/memo")return t;let n=or(e);if(n===e)break;e=n}return null}async function Wy(e,t=1500){let r=`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`;return new Promise(o=>{let s=$y(r,{timeout:t},i=>{if(i.statusCode&&i.statusCode>=400){i.resume(),o(null);return}let c=[];i.on("data",a=>c.push(a)),i.on("end",()=>{try{let a=JSON.parse(Buffer.concat(c).toString("utf8"));o(a.version??null)}catch{o(null)}})});s.on("timeout",()=>{s.destroy(),o(null)}),s.on("error",()=>o(null))})}async function Kc(){let e=await By();if(!e)return null;let t=await Wy(e.name);return!t||!Uy(t,e.version)?null:{current:e.version,latest:t}}import{readFile as jy}from"fs/promises";import{dirname as zy,join as Gy}from"path";import{fileURLToPath as Ky}from"url";var qy=/{{\s*([\w.-]+)\s*}}/g;function Vy(e,t){return e.replace(qy,(n,r)=>t[r]??"")}async function qo(e,t={}){let n=zy(Ky(import.meta.url)),r=Gy(n,"task-prompts",`${e}.md`),o=await jy(r,"utf-8");return Vy(o,t)}import{spawn as Xy}from"child_process";var Jy=12e3,Yy=new Set(["WRITE","MAINTAIN","ADMIN"]),Qy=["pull_request_read","list_pull_requests","search_pull_requests","add_issue_comment","add_comment_to_pending_review","issue_read","get_me"];function Zy(e){return e.replace(/\\/g,"/").toLowerCase()}function e_(e,t){if(e.toLowerCase().includes("github"))return!0;if("command"in t){let o=Zy(t.command),s=(t.args??[]).join(" ").toLowerCase();return!!(o.includes("github")||o.includes("gh-")||s.includes("github")||s.includes("gh-"))}let r=t.url.toLowerCase();return r.includes("github")||r.includes("api.github.com")}function t_(e,t){let n=new Set(t),r=Object.entries(e).filter(([i,c])=>e_(i,c)).map(([i])=>i),o=r.find(i=>n.has(i))??null,s=r.filter(i=>!n.has(i));return{active:o,inactiveCandidates:s}}function n_(e){let t=new Map;for(let n of e)for(let r of Qy){let o=`_${r}`;if(!n.endsWith(o))continue;let s=n.slice(0,-o.length);s&&t.set(s,(t.get(s)??0)+1)}return Array.from(t.entries()).filter(([,n])=>n>=2).sort((n,r)=>r[1]-n[1]).map(([n])=>n)}async function Vo(e,t,n,r=Jy){return new Promise(o=>{let s=Xy(e,t,{cwd:n,env:process.env,stdio:["ignore","pipe","pipe"]}),i="",c="",a=!1,l=u=>{a||(a=!0,clearTimeout(p),o(u))},p=setTimeout(()=>{s.kill("SIGTERM"),l({ok:!1,stdout:i,stderr:c,code:null,errorMessage:`${e} ${t.join(" ")} timed out after ${r}ms`})},r);s.stdout.on("data",u=>{i+=u.toString()}),s.stderr.on("data",u=>{c+=u.toString()}),s.on("error",u=>{l({ok:!1,stdout:i,stderr:c,code:null,errorMessage:u.message})}),s.on("close",u=>{l({ok:u===0,stdout:i,stderr:c,code:u})})})}async function r_(e){if(!(await Vo("gh",["--version"],e)).ok)return{ok:!1,reason:"GitHub MCP not available, and GitHub CLI (gh) is not installed or not executable. Install gh: https://cli.github.com/"};let n=await Vo("gh",["auth","status","-h","github.com"],e);if(!n.ok)return{ok:!1,reason:`GitHub CLI is installed but not authenticated for github.com. Run: gh auth login -h github.com (detail: ${n.stderr.trim()||n.stdout.trim()||n.errorMessage||"unknown error"})`};let r=await Vo("gh",["repo","view","--json","nameWithOwner,viewerPermission"],e);if(!r.ok)return{ok:!1,reason:`GitHub CLI authentication works, but this directory is not a readable GitHub repo for gh (detail: ${r.stderr.trim()||r.stdout.trim()||r.errorMessage||"unknown error"})`};let o;try{o=JSON.parse(r.stdout)}catch{return{ok:!1,reason:"Failed to parse `gh repo view` output. Try upgrading gh and retry."}}let s=o.nameWithOwner?.trim(),i=o.viewerPermission?.trim().toUpperCase();return!s||!i?{ok:!1,reason:"GitHub CLI did not return repository or permission info from `gh repo view`."}:Yy.has(i)?{ok:!0,repository:s,viewerPermission:i}:{ok:!1,reason:`GitHub CLI connected to ${s}, but permission is ${i}. PR review comments require WRITE/MAINTAIN/ADMIN permission.`}}async function qc(e){let t=n_(e.availableToolNames??[]),n=e.activeMcpServerNames.find(l=>t.includes(l))??null,r=l=>{let p=e.availableToolNames;if(!p||p.length===0)return!0;let u=`${l}_`;return p.some(d=>d.startsWith(u))};if(n&&r(n))return{kind:"github_mcp",strategy:"github_mcp",details:`Using active GitHub MCP server \`${n}\` (detected from loaded MCP tool signatures).`,mcpServerPrefix:n};let{active:o,inactiveCandidates:s}=t_(e.mcpServers,e.activeMcpServerNames);if(o&&r(o))return{kind:"github_mcp",strategy:"github_mcp",details:`Using active GitHub MCP server \`${o}\`.`,mcpServerPrefix:o};let i=await r_(e.cwd);if(i.ok){let l=s.length?` GitHub MCP server(s) configured but inactive in this session: ${s.join(", ")}.`:"";return{kind:"gh_cli",strategy:"gh_cli",details:`Using gh CLI on repo \`${i.repository}\` with permission \`${i.viewerPermission}\`.${l}`,repository:i.repository,viewerPermission:i.viewerPermission}}let c=s.length?` Also found configured but inactive GitHub MCP server(s): ${s.join(", ")}. Start a new session and activate one of them, or fix gh CLI access.`:"",a=o&&!r(o)?` Active MCP server \`${o}\` is configured, but no tools with prefix \`${o}_\` are currently loaded in this session.`:"";return{kind:"unavailable",reason:`${i.reason}${a}${c}`}}import{jsx as tt,jsxs as p_}from"react/jsx-runtime";function c_(e,t){if(e.length===0)return[];if(t===void 0)return[...e];if(t.length===0)return[];let n=new Set(e),r=t.filter(o=>n.has(o));return r.length>0?r:[...e]}function l_(e,t){if(e.length===0)return[];if(t.length===0)return[];let n=new Set(e);return t.filter(r=>n.has(r))}function u_(){try{process.stdout?.isTTY&&process.stdout.write("\x1Bc")}catch{}}function Xc({sessionOptions:e,providerName:t,model:n,configPath:r,mcpServers:o,cwd:s,sessionsDir:i,providers:c,modelProfiles:a,dangerous:l=!1,needsSetup:p=!1,initialHistory:u}){let{exit:d}=a_(),m=on(()=>Object.keys(o??{}).sort(),[o]),g=on(()=>c_(m,e.activeMcpServers),[m,e.activeMcpServers]),y=e.toolPermissionMode??(l?_e.FULL:_e.ONCE),[b,U]=s_(Bc,void 0,Ko),[T,H]=ee(t),[R,I]=ee(n),[G,ie]=ee(c),[Re,ae]=ee(a),[z,M]=ee(y),P=X(f=>vt({model_profiles:Re},f),[Re]),[ne,ce]=ee({...e,providerName:t,contextWindow:P({name:t,model:n}),dangerous:y===_e.FULL,toolPermissionMode:y}),[F,le]=ee(!1),[J,A]=ee([]),[O,re]=ee(null),[Se,ge]=ee(null),[qe,De]=ee(P({name:t,model:n})),[rt,ve]=ee(0),[be,k]=ee(p),[L,an]=ee(!p&&m.length>0),[Te,K]=ee(g),[$,Nt]=ee(null),[N,ot]=ee(null),ue=ir(null),Ve=ir(null),ft=ir(null),[Q,Xe]=ee(null),st=ir(null),w=on(()=>sr(),[]),S=X(f=>{U(f)},[]);Lt(()=>{u&&(S({type:"clear_current_timeline"}),S({type:"replace_history",turns:u.turns,maxSequence:u.maxSequence}),ge(u.messages),u.summary.trim()&&S({type:"append_system_message",title:"History",content:u.summary,tone:"info"}))},[S,u]),Lt(()=>{be||(K(g),an(m.length>0))},[be,g,m.length]);let _=X((f,v,C="info")=>{S({type:"append_system_message",title:f,content:v,tone:C})},[S]),Z=on(()=>({onAssistantStep:(f,v)=>{let C=Ve.current;C&&S({type:"assistant_chunk",turn:C,step:v,chunk:f})},requestApproval:z===_e.FULL||z===_e.NONE?void 0:f=>new Promise(v=>{Dc(f),Xe(f),st.current=v}),hooks:{onTurnStart:({turn:f,input:v,promptTokens:C})=>{Ve.current=f;let q=ft.current;q&&(ft.current=null);let Ie=q??v;C&&C>0&&ve(C),S({type:"turn_start",turn:f,input:Ie,promptTokens:C})},onContextUsage:({turn:f,step:v,promptTokens:C,phase:q})=>{ve(C),S({type:"context_usage",turn:f,step:v,promptTokens:C,phase:q})},onContextCompacted:({reason:f,status:v,beforeTokens:C,afterTokens:q,reductionPercent:Ie,errorMessage:pr})=>{v==="success"&&ve(q);let dr=f==="manual"?"manual command":"auto trigger";if(v==="success"){_("Context compacted",`Compacted by ${dr}: ${C} -> ${q} tokens (${Ie.toFixed(2)}% reduced).`);return}if(v==="skipped"){_("Context compacted",`Skipped (${dr}): nothing to compact.`,"warning");return}_("Context compacted",`Failed (${dr}): ${pr??"unknown error"}`,"warning")},onAction:({turn:f,step:v,action:C,thinking:q,parallelActions:Ie})=>{S({type:"tool_action",turn:f,step:v,action:C,thinking:q,parallelActions:Ie})},onObservation:({turn:f,step:v,observation:C,resultStatus:q,parallelResultStatuses:Ie})=>{S({type:"tool_observation",turn:f,step:v,observation:C,toolStatus:Po(q),parallelToolStatuses:za(Ie)})},onFinal:({turn:f,finalText:v,status:C,errorMessage:q,turnUsage:Ie,tokenUsage:pr})=>{S({type:"turn_final",turn:f,finalText:v,status:C,errorMessage:q,turnUsage:Ie,tokenUsage:pr}),le(!1)}}}),[_,S,z]);Lt(()=>{let f=!1;return(async()=>{if(!(be||L))try{let v=ue.current;v&&await v.close();let C=await jn(Z,ne);if(f){await C.close();return}ue.current=C,ot(C),re(C.historyFilePath??null)}catch(v){if(f)return;ue.current=null,ot(null),re(null),le(!1),_("Session",`Failed to create session: ${v.message}`,"error")}})(),()=>{f=!0}},[_,Z,L,ne,be]),Lt(()=>{let f=!1;return(async()=>{let v=await Kc();f||!v||_("Update",`Update available: v${v.latest}. Run: npm install -g @memo-code/memo@latest`)})(),()=>{f=!0}},[_]),Lt(()=>()=>{ue.current&&ue.current.close()},[]);let oe=X(async()=>{let f=st.current;f&&(f("deny"),st.current=null),Q&&Xe(null),ue.current&&await ue.current.close(),Nt("Bye!"),setTimeout(()=>d(),250)},[d,Q]),Ue=X(()=>{if(F){_("Clear","Cancel current run before clearing timeline.","warning");return}if(Q){_("Clear","Resolve current approval request before clearing timeline.","warning");return}S({type:"clear_current_timeline"}),ge(null),ve(0),u_()},[_,F,S,Q]),ur=X(()=>{if(F){_("New Session","Cancel current run before starting a new session.","warning");return}if(Q){_("New Session","Resolve current approval request before starting a new session.","warning");return}S({type:"reset_all"}),ge(null),ve(0),Ve.current=null,ce(f=>({...f,sessionId:Ot()})),_("New Session","Started a fresh session.")},[_,F,S,Q]),$t=X(async f=>{try{let v=await te();await we(v.configPath,{...v.config,current_provider:f})}catch(v){_("Config",`Failed to persist provider: ${v.message}`,"warning")}},[_]),x=X(async f=>{if(F){_("Model switch","Cancel current run before switching models.","warning");return}if(f.name===T&&f.model===R){_("Model switch",`Already using ${f.name} (${f.model}).`);return}S({type:"reset_all"}),ve(0),Ve.current=null;let v=P(f);H(f.name),I(f.model),De(v),ce(C=>({...C,sessionId:Ot(),providerName:f.name,contextWindow:v})),await $t(f.name),_("Model switch",`Switched to ${f.name} (${f.model}).`)},[_,F,R,T,S,$t,P]),E=X(f=>f===_e.NONE?"none (no tools)":f===_e.ONCE?"once (approval required)":"full (no approval)",[]),pe=X(f=>{if(F){_("Tools","Cancel current run before changing tool permission mode.","warning");return}if(Q){_("Tools","Resolve current approval request before changing tool permission mode.","warning");return}if(f===z){_("Tools",`Already using ${E(f)}.`);return}M(f),ce(v=>({...v,sessionId:Ot(),dangerous:f===_e.FULL,toolPermissionMode:f})),_("Tools",`Tool permission set to ${E(f)}.`)},[_,F,Q,E,z]),B=X(async f=>{try{let v=await te();await we(v.configPath,{...v.config,active_mcp_servers:f})}catch(v){_("MCP",`Failed to persist active MCP servers: ${v.message}`,"warning")}},[_]),xe=X((f,v)=>{let C=l_(m,f);K(C),an(!1),ce(q=>({...q,sessionId:Ot(),activeMcpServers:C})),v&&B(C)},[m,B]),it=X(async f=>{if(F){_("History","Cancel current run before loading session history.","warning");return}if(Q){_("History","Resolve current approval request before loading session history.","warning");return}try{let v=await o_(f.sessionFile,"utf8"),C=nr(v);S({type:"clear_current_timeline"}),S({type:"replace_history",turns:C.turns,maxSequence:C.maxSequence}),ge(C.messages),le(!1),ot(null),re(null),ve(0),Ve.current=null,ce(q=>({...q,sessionId:Ot()})),_("History",C.summary||f.input)}catch(v){_("History",`Failed to load ${f.sessionFile}: ${v.message}`,"error")}},[_,F,S,Q]),gt=X(()=>{F&&N?.cancelCurrentTurn?.()},[F,N]),cn=X(async()=>{if(F){_("Compact","Cancel current run before compacting context.","warning");return}if(Q){_("Compact","Resolve current approval request before compacting context.","warning");return}if(N)try{let f=await N.compactHistory("manual");ve(f.afterTokens)}catch(f){_("Compact",`Failed to compact context: ${f.message}`,"error")}},[_,F,Q,N]),ln=X(async()=>{if(!N||F)return;let f=Qe($e.INIT);try{let v=await qo("init_agents");A(C=>[...C,f]),le(!0),ft.current=f,await N.runTurn(v)}catch(v){le(!1),_("Init",`Failed to run init task: ${v.message}`,"error")}},[_,F,N]),Dt=X(async f=>{if(!N||F)return;if(z===_e.NONE){_("Review",'Tool permission mode is "none". Set `/tools once` or `/tools full` before running `/review`.',"warning");return}let v=`${Qe($e.REVIEW)} ${f}`;try{let C=await qc({cwd:s,mcpServers:o,activeMcpServerNames:Te,availableToolNames:N.listToolNames?.()??[]});if(C.kind==="unavailable"){_("Review",C.reason,"error");return}let q=await qo("review_pull_request",{pr_number:String(f),backend_strategy:C.strategy,backend_details:C.details,mcp_server_prefix:C.kind==="github_mcp"?C.mcpServerPrefix:"github"});A(Ie=>[...Ie,v]),_("Review",C.details),le(!0),ft.current=v,await N.runTurn(q)}catch(C){le(!1),_("Review",`Failed to run review task for PR #${f}: ${C.message}`,"error")}},[Te,_,F,s,o,N,z]),pl=X(async f=>{let v=f.trim();if(v){if(v.toLowerCase()===Mc){await oe();return}if(v===Qe($e.INIT)){await ln();return}if(!(!N||F)){A(C=>[...C,v]),le(!0);try{await N.runTurn(v)}catch(C){le(!1),_("Run",`Turn failed: ${C.message}`,"error")}}}},[_,F,oe,ln,N]),dl=X(async()=>{try{let f=await te(),v=lt(f.config),C=vt(f.config,v);ie(f.config.providers),ae(f.config.model_profiles),H(v.name),I(v.model),De(C),ce(q=>({...q,sessionId:Ot(),providerName:v.name,contextWindow:C,autoCompactThresholdPercent:f.config.auto_compact_threshold_percent})),k(!1),_("Setup",`Config saved to ${f.configPath}`)}catch(f){_("Setup",`Failed to reload config: ${f.message}`,"error")}},[_]);Lt(()=>{if(!N||!Se?.length)return;let f=N.history[0];f&&(N.history.splice(0,N.history.length,f,...Se),ge(null))},[Se,N]);let ml=X(f=>{let v=st.current;v&&(v(f),st.current=null),Xe(null)},[]),fl=Ga(rt,qe),gl=on(()=>({providerName:T,model:R,cwd:s,sessionId:ne.sessionId??"unknown",mcpNames:Te,version:w?.version??"unknown"}),[Te,R,T,s,w?.version,ne.sessionId]);return $?tt(Vc,{children:tt(i_,{color:"green",children:$})}):be?tt(Fc,{configPath:r,onComplete:dl,onExit:oe}):L?tt(Nc,{serverNames:m,defaultSelected:g,onConfirm:xe,onExit:()=>{oe()}}):p_(Vc,{flexDirection:"column",children:[tt(sc,{header:gl,systemMessages:b.systemMessages,turns:b.turns,historicalTurns:b.historicalTurns}),tt(Pc,{disabled:!N||!!Q,busy:F,history:J,cwd:s,sessionsDir:i,currentSessionFile:O??void 0,providers:G,configPath:r,providerName:T,model:R,toolPermissionMode:z,mcpServers:o,onSubmit:f=>{pl(f)},onExit:()=>{oe()},onClear:Ue,onNewSession:ur,onCancelRun:gt,onCompact:()=>{cn()},onHistorySelect:f=>{it(f)},onModelSelect:f=>{x(f)},onSetToolPermission:pe,onReviewPullRequest:f=>{Dt(f)},onSystemMessage:_}),Q?tt(Lc,{request:Q,onDecision:ml}):null,tt(Ic,{busy:F,pendingApproval:!!Q,contextPercent:fl})]})}var d_=`
|
|
121
121
|
Usage:
|
|
122
122
|
memo mcp list [--json]
|
|
123
123
|
memo mcp get <name> [--json]
|
|
@@ -126,14 +126,14 @@ Usage:
|
|
|
126
126
|
memo mcp remove <name>
|
|
127
127
|
memo mcp login <name> [--scopes scope1,scope2]
|
|
128
128
|
memo mcp logout <name>
|
|
129
|
-
`;function
|
|
130
|
-
`)}function
|
|
131
|
-
${a}`)},onBrowserOpenFailure:()=>{console.log("Browser launch failed. Open the URL above manually.")}});console.log(`OAuth login completed for "${o}" (credentials stored in ${c.backend}).`)}catch(c){console.error(
|
|
132
|
-
`),{...t,config:u,needsSetup:!1}}finally{s.close()}}async function
|
|
129
|
+
`;function ar(){console.log(d_.trim())}function Jc(e){return e instanceof Error?e.message:String(e)}function m_(e){let t=e.indexOf("=");if(t<=0)return null;let n=e.slice(0,t).trim(),r=e.slice(t+1);return n?{key:n,value:r}:null}function Yc(e,t,n){let r=[];if(r.push(`${e}`),n&&r.push(` auth_status: ${n}`),"url"in t){r.push(` type: ${t.type??"streamable_http"}`),r.push(` url: ${t.url}`),t.bearer_token_env_var&&r.push(` bearer_token_env_var: ${t.bearer_token_env_var}`);let o=t.http_headers??t.headers;o&&Object.keys(o).length>0&&r.push(` headers: ${Object.entries(o).map(([s,i])=>`${s}=${i}`).join(", ")}`)}else r.push(` type: ${t.type??"stdio"}`),r.push(` command: ${t.command}`),t.args&&t.args.length>0&&r.push(` args: ${t.args.join(" ")}`),t.env&&Object.keys(t.env).length>0&&r.push(` env: ${Object.entries(t.env).map(([o,s])=>`${o}=${s}`).join(", ")}`);return r.join(`
|
|
130
|
+
`)}function f_(e){let t=e.shift();if(!t)return{error:"Missing server name."};let n,r,o={},s=[];for(let i=0;i<e.length;i+=1){let c=e[i];if(c){if(c==="--"){s=e.slice(i+1);break}if(c==="--url"){let a=e[i+1];if(!a)return{error:"Missing value for --url."};n=a,i+=1;continue}if(c==="--bearer-token-env-var"){let a=e[i+1];if(!a)return{error:"Missing value for --bearer-token-env-var."};r=a,i+=1;continue}if(c==="--env"){let a=e[i+1];if(!a)return{error:"Missing value for --env (KEY=VALUE)."};let l=m_(a);if(!l)return{error:"Invalid --env format. Use KEY=VALUE."};o[l.key]=l.value,i+=1;continue}return c==="--help"||c==="-h"?{error:""}:{error:`Unknown option: ${c}`}}}return n?s.length>0?{error:"Use either --url or a stdio command, not both."}:Object.keys(o).length>0?{error:"--env is only supported with stdio servers."}:{options:{name:t,url:n,bearerTokenEnvVar:r}}:r?{error:"--bearer-token-env-var is only supported with HTTP servers."}:s.length===0?{error:"Missing stdio command. Use `-- <command...>`."}:{options:{name:t,command:s[0],args:s.slice(1),env:Object.keys(o).length>0?o:void 0}}}function g_(e){let[t,...n]=e;return!t||t==="--help"||t==="-h"||t==="help"?{command:"help",rest:[]}:{command:t,rest:n}}function Xo(e,t=[]){let n=new Set(t);for(let r=0;r<e.length;r+=1){let o=e[r];if(o){if(o.startsWith("--")){n.has(o)&&(r+=1);continue}return o}}return null}function h_(e){return e.split(/[,\s]+/g).map(t=>t.trim()).filter(Boolean)}function y_(e){let t,n;for(let r=0;r<e.length;r+=1){let o=e[r];if(o){if(o==="--help"||o==="-h")return{showHelp:!0};if(o==="--scopes"){let s=e[r+1];if(!s)return{error:"Missing value for --scopes."};let i=h_(s);if(i.length===0)return{error:"Invalid --scopes value. Use comma-separated scopes."};n=i,r+=1;continue}if(o.startsWith("--"))return{error:`Unknown option: ${o}`};if(!t){t=o;continue}return{error:`Unexpected argument: ${o}`}}}return{name:t,scopes:n}}function Jo(e){return{memoHome:e.home,storeMode:e.config.mcp_oauth_credentials_store_mode,callbackPort:e.config.mcp_oauth_callback_port}}async function Qc(e){let{command:t,rest:n}=g_(e);if(t==="help"){ar();return}if(t==="list"){let r=n.includes("--json"),o=await te(),s=o.config.mcp_servers??{},i=Object.keys(s),c=Jo(o),a=new Map;if(await Promise.all(i.map(async l=>{let p=s[l];if(p)try{let u=await Ur(p,c);a.set(l,u)}catch{a.set(l,"unsupported")}})),r){let l={};for(let p of i){let u=s[p];u&&(l[p]={...u,auth_status:a.get(p)??"unsupported"})}console.log(JSON.stringify(l,null,2));return}if(i.length===0){console.log('No MCP servers configured. Add one with "memo mcp add".');return}console.log(`MCP servers (${i.length}):`);for(let l of i){let p=s[l];p&&console.log(Yc(l,p,a.get(l)??"unsupported"))}return}if(t==="get"){let r=n.includes("--json"),o=Xo(n);if(!o){console.error("Missing server name."),process.exitCode=1;return}let i=(await te()).config.mcp_servers?.[o];if(!i){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}if(r){console.log(JSON.stringify(i,null,2));return}console.log(Yc(o,i));return}if(t==="add"){let r=f_(n);if(r.error!==void 0){r.error&&(console.error(r.error),process.exitCode=1),ar();return}let o=r.options;if(!o)return;if(o.url)try{new URL(o.url)}catch{console.error("Invalid URL."),process.exitCode=1;return}let s=await te(),i={...s.config.mcp_servers??{}};if(i[o.name]){console.error(`MCP server "${o.name}" already exists.`),process.exitCode=1;return}let c;o.url?c={type:"streamable_http",url:o.url,...o.bearerTokenEnvVar?{bearer_token_env_var:o.bearerTokenEnvVar}:{}}:c={command:o.command,args:o.args&&o.args.length>0?o.args:void 0,env:o.env},i[o.name]=c,await we(s.configPath,{...s.config,mcp_servers:i}),console.log(`Added MCP server "${o.name}".`);return}if(t==="remove"){let r=Xo(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let o=await te(),s={...o.config.mcp_servers??{}};if(!s[r]){console.error(`Unknown MCP server "${r}".`),process.exitCode=1;return}delete s[r],await we(o.configPath,{...o.config,mcp_servers:s}),console.log(`Removed MCP server "${r}".`);return}if(t==="login"){let r=y_(n);if(r.showHelp){ar();return}if(r.error){console.error(r.error),process.exitCode=1;return}let o=r.name;if(!o){console.error("Missing server name."),process.exitCode=1;return}let s=await te(),i=s.config.mcp_servers?.[o];if(!i){console.error(`Unknown MCP server "${o}".`),process.exitCode=1;return}if(!("url"in i)){console.error("OAuth login only applies to streamable HTTP servers."),process.exitCode=1;return}console.log(`Starting OAuth login for "${o}"...`);try{let c=await Fr({serverName:o,config:i,scopes:r.scopes,settings:Jo(s),onAuthorizationUrl:a=>{console.log(`Open this URL to authorize:
|
|
131
|
+
${a}`)},onBrowserOpenFailure:()=>{console.log("Browser launch failed. Open the URL above manually.")}});console.log(`OAuth login completed for "${o}" (credentials stored in ${c.backend}).`)}catch(c){console.error(Jc(c)),process.exitCode=1}return}if(t==="logout"){let r=Xo(n);if(!r){console.error("Missing server name."),process.exitCode=1;return}let o=await te(),s=o.config.mcp_servers?.[r];if(!s){console.error(`Unknown MCP server "${r}".`),process.exitCode=1;return}if(!("url"in s)){console.error("OAuth logout only applies to streamable HTTP servers."),process.exitCode=1;return}try{(await Hr({config:s,settings:Jo(o)})).removed?console.log(`Removed OAuth credentials for "${r}".`):console.log(`No OAuth credentials stored for "${r}".`)}catch(i){console.error(Jc(i)),process.exitCode=1}return}console.error(`Unknown subcommand: ${t}`),ar(),process.exitCode=1}function Zc(e){let t={dangerous:!1,showVersion:!1,once:!1,prev:!1},n=[];for(let r=0;r<e.length;r++){let o=e[r];if(o!==void 0){if(o==="--version"||o==="-v"){t.showVersion=!0;continue}if(o==="--once"||o==="-once"){t.once=!0;continue}if(o==="--prev"||o==="-prev"){t.prev=!0;continue}if(o==="--dangerous"||o==="-d"){t.dangerous=!0;continue}n.push(o)}}return{question:n.join(" "),options:t}}var __=["mcp","web"];function S_(e){return e.length===0?{token:null,offset:0}:e[0]==="--"?{token:e[1]??null,offset:2}:{token:e[0]??null,offset:1}}function v_(e){return __.includes(e)}function el(e){let{token:t,offset:n}=S_(e);return t&&v_(t)?{kind:"subcommand",name:t,args:e.slice(n)}:{kind:"default",args:e}}import{jsx as K_}from"react/jsx-runtime";async function ll(e){let t=await te();if(!t.needsSetup)return t;let n=t.config.providers[0],o=[n?.env_api_key,"OPENAI_API_KEY","DEEPSEEK_API_KEY"].filter(Boolean).some(c=>!!process.env[c]);if(n&&o)return await we(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=D_({input:U_,output:F_}),i=async(c,a)=>(await s.question(c)).trim()||a;try{console.log("No provider config found. Please answer the prompts:");let c=await i("Provider name [deepseek]: ","deepseek"),a=await i("API key env var [DEEPSEEK_API_KEY]: ","DEEPSEEK_API_KEY"),l=await i("Model name [deepseek-chat]: ","deepseek-chat"),p=await i("Base URL [https://api.deepseek.com]: ","https://api.deepseek.com"),u={current_provider:c,providers:[{name:c,env_api_key:a,model:l,base_url:p||void 0}]};return await we(t.configPath,u),console.log(`Config written to ${t.configPath}
|
|
132
|
+
`),{...t,config:u,needsSetup:!1}}finally{s.close()}}async function ul(e,t){let r=(await Gn({sessionsDir:e,cwd:t,limit:1}))[0];if(!r)return null;let o=await $_(r.sessionFile,"utf8");return nr(o)}function B_(e,t){if(!t.length)return;let n=e.history[0];n&&e.history.splice(0,e.history.length,n,...t)}async function W_(e){let t=await ll("plain"),n=lt(t.config),r=vt(t.config,n),s={sessionId:cl(),mode:"interactive",contextWindow:r,autoCompactThresholdPercent:t.config.auto_compact_threshold_percent,activeMcpServers:t.config.active_mcp_servers,dangerous:e.options.dangerous},i=Gt(t,s),c=e.options.prev?await ul(i,process.cwd()):null;if(e.options.prev&&!c){console.error("No previous session found for current directory."),process.exitCode=1;return}e.options.dangerous&&console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!");let a={requestApproval:e.options.dangerous?void 0:u=>(console.log(`
|
|
133
133
|
[approval required] ${u.toolName}: ${u.reason}`),console.log("[approval] Run with --dangerous to bypass approval"),Promise.resolve("deny")),hooks:{onAction:({action:u})=>{console.log(`
|
|
134
|
-
[tool] ${u.tool}`),u.input!==void 0&&console.log(`[input] ${JSON.stringify(u.input)}`)},onObservation:()=>{}}},l=await
|
|
134
|
+
[tool] ${u.tool}`),u.input!==void 0&&console.log(`[input] ${JSON.stringify(u.input)}`)},onObservation:()=>{}}},l=await jn(a,s);c&&(B_(l,c.messages),console.log("[session] Continued from previous session context."));let p=e.question;if(!p&&!process.stdin.isTTY&&(p=await G_()),!p){console.error("No input provided. Pass a question or use stdin."),await l.close();return}try{console.log(`User: ${p}
|
|
135
135
|
`);let u=await l.runTurn(p);console.log(`
|
|
136
136
|
${u.finalText}`),console.log(`
|
|
137
137
|
[tokens] prompt=${u.tokenUsage.prompt} completion=${u.tokenUsage.completion} total=${u.tokenUsage.total}`),console.log(`
|
|
138
|
-
provider=${n.name} model=${n.model}`)}catch(u){console.error(`Run failed: ${u.message}`)}finally{await l.close()}}async function
|
|
139
|
-
`)),await
|
|
138
|
+
provider=${n.name} model=${n.model}`)}catch(u){console.error(`Run failed: ${u.message}`)}finally{await l.close()}}async function j_(e){let t=await ll("tui"),n=lt(t.config),r=vt(t.config,n),s={sessionId:cl(),mode:"interactive",contextWindow:r,autoCompactThresholdPercent:t.config.auto_compact_threshold_percent,activeMcpServers:t.config.active_mcp_servers,dangerous:e.options.dangerous},i=Gt(t,s),c=e.options.prev?await ul(i,process.cwd()):null;if(e.options.prev&&!c){console.error("No previous session found for current directory."),process.exitCode=1;return}e.options.dangerous&&(console.log("\u26A0\uFE0F DANGEROUS MODE: All tool approvals are bypassed!"),console.log(` Use with caution.
|
|
139
|
+
`)),await H_(K_(Xc,{sessionOptions:s,providerName:n.name,model:n.model,configPath:t.configPath,mcpServers:t.config.mcp_servers??{},cwd:process.cwd(),sessionsDir:i,providers:t.config.providers,modelProfiles:t.config.model_profiles,dangerous:e.options.dangerous,needsSetup:t.needsSetup,initialHistory:c??void 0}),{exitOnCtrlC:!1,patchConsole:!1}).waitUntilExit()}async function z_(){let e=process.argv.slice(2),t=el(e);if(t.kind==="subcommand"){if(t.name==="mcp"){await Qc(t.args);return}if(t.name==="web"){let{runWebCommand:o}=await Promise.resolve().then(()=>(al(),il));await o(t.args);return}}let n=Zc(t.args);if(n.options.showVersion){let s=sr()?.version??"unknown";console.log(s);return}let r=process.stdin.isTTY&&process.stdout.isTTY;if(n.options.once||!r){await W_(n);return}await j_(n)}z_();async function G_(){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()})}
|