agent-termo 1.0.3 → 1.0.4

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/cli.js CHANGED
@@ -1,20 +1,30 @@
1
1
  #!/usr/bin/env node
2
- import{Command as vn}from"commander";import pt from"openai";var xe=[{id:"stepfun-ai/step-3.7-flash",note:"default"},{id:"meta/llama-3.1-8b-instruct",note:"fast, low cost"},{id:"meta/llama-3.1-70b-instruct",note:"balanced"},{id:"meta/llama-3.3-70b-instruct",note:"balanced"},{id:"meta/llama-3.1-405b-instruct",note:"highest quality Llama"},{id:"nvidia/llama-3.1-nemotron-70b-instruct",note:"NVIDIA tuned"},{id:"qwen/qwen2.5-coder-32b-instruct",note:"coding"},{id:"deepseek-ai/deepseek-r1",note:"reasoning"},{id:"moonshotai/kimi-k2-instruct",note:"agentic / tool use"},{id:"openai/gpt-oss-120b",note:"open-weight GPT"}],ut=/embed|rerank|retriev|reward|guard|safety|parse|clip|vila|neva|fuyu|kosmos|paligemma|deplot|riva|asr|tts|whisper|diffusion|sdxl|flux|cosmos|segment|bge-|e5-|gliner|pii|streampetr|ocdrnet|bevformer/i;function mt(e){return!ut.test(e)}function X(e){if(!e)return[...xe];let t=new Set(e),n=xe.filter(i=>t.has(i.id)),r=new Set(n.map(i=>i.id)),o=e.filter(i=>!r.has(i)&&mt(i)).sort((i,s)=>i.localeCompare(s)).map(i=>({id:i}));return[...n,...o]}var Y=class{client;model;constructor(t){let n=process.env.NIM_API_KEY??"",r=process.env.NIM_BASE_URL??"https://integrate.api.nvidia.com/v1";this.model=process.env.NIM_MODEL??"stepfun-ai/step-3.7-flash";let o=parseInt(process.env.LLM_TIMEOUT??"120000",10);this.client=new pt({apiKey:n,baseURL:r,timeout:o,defaultHeaders:{"User-Agent":"agent-termo/1.0"}})}buildToolDefs(t){return t.map(n=>({type:"function",function:{name:n.name,description:n.description,parameters:n.parameters}}))}getModel(){return this.model}setModel(t){this.model=t}async listModels(){try{let n=(await this.client.models.list({timeout:1e4})).data.map(r=>r.id);if(n.length===0)throw new Error("empty model list");return{models:X(n),live:!0}}catch(t){return{models:X(null),live:!1,error:t instanceof Error?t.message:String(t)}}}async*streamComplete(t,n,r){let o=[],i=new Map,s=await this.client.chat.completions.create({model:this.model,messages:t.map(m=>m.role==="tool"?{role:"tool",content:m.content,tool_call_id:m.id}:{role:m.role,content:m.content}),tools:n,temperature:.3,max_tokens:8192,stream:!0});for await(let m of s){let d=m.choices[0]?.delta;if(!d)continue;let g=d.content??"";if(!(g==="null"||g==="undefined")&&g&&(o.push(g),r?.(g)),d.tool_calls)for(let y of d.tool_calls){let h=y.index??0,f=i.get(h);f?(f.arguments+=y.function?.arguments??"",y.id&&!f.id&&(f.id=y.id)):i.set(h,{id:y.id??crypto.randomUUID(),name:y.function?.name??"",arguments:y.function?.arguments??""})}}let c=o.join(""),a=Array.from(i.values()).map(m=>{let d={};try{d=JSON.parse(m.arguments)}catch{d={_raw:m.arguments}}return{id:m.id,name:m.name,arguments:d}});yield{content:c,toolCalls:a}}async complete(t,n){let o=(await this.client.chat.completions.create({model:this.model,messages:t.map(c=>c.role==="tool"?{role:"tool",content:c.content,tool_call_id:c.id}:{role:c.role,content:c.content}),tools:n,temperature:.3,max_tokens:8192,stream:!1})).choices[0]?.message,i=o?.content?.replace(/\[ Reasoning[^\]]*\][^\[]*\[\/ Reasoning\][^\n]*/gi,"").trim()??"",s=(o?.tool_calls??[]).map(c=>{let a={};try{a=JSON.parse(c.function.arguments??"{}")}catch{a={_raw:c.function.arguments}}return{id:c.id,name:c.function.name,arguments:a}});if(s.length===0&&i.includes('"tool_calls"'))try{let c=JSON.parse(i);if(c.tool_calls?.length){s.push(...c.tool_calls.map(m=>({id:m.id??crypto.randomUUID(),name:m.function?.name??m.name??"",arguments:typeof m.function?.arguments=="string"?JSON.parse(m.function.arguments):m.function?.arguments??{}})));let a=i.indexOf('{"tool_calls"');a!==-1&&(i=i.slice(0,a).trim())}}catch{}return{content:i,toolCalls:s}}};var B=[{name:"file:read",description:"Read the complete contents of a file. Use for examining existing code, config, or documentation.",parameters:{type:"object",properties:{path:{type:"string",description:"File path (absolute or relative to project root)"},limit:{type:"number",description:"Maximum number of lines to read (0 = all)",default:0},offset:{type:"number",description:"Line offset to start reading from (0 = start)",default:0}},required:["path"]}},{name:"file:write",description:"Write or overwrite a complete file. Use this to create new files or replace existing ones entirely.",parameters:{type:"object",properties:{path:{type:"string",description:"File path to write (relative to project root)"},content:{type:"string",description:"Complete file content to write"}},required:["path","content"]}},{name:"file:edit",description:"Edit an existing file by replacing an exact section. The old_string must appear verbatim in the file.",parameters:{type:"object",properties:{path:{type:"string",description:"File to edit"},old_string:{type:"string",description:"Exact text to find and replace (must be unique in file)"},new_string:{type:"string",description:"Replacement text"}},required:["path","old_string","new_string"]}},{name:"file:glob",description:"Find all files matching a glob pattern. Use to discover project structure.",parameters:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern (e.g. "src/**/*.ts", "**/*.json")'},cwd:{type:"string",description:"Root directory to search in (defaults to project root)"}},required:["pattern"]}},{name:"grep",description:"Search for text or regex patterns inside files. Use to find function definitions, imports, etc.",parameters:{type:"object",properties:{pattern:{type:"string",description:"Text or regex pattern to search for"},path:{type:"string",description:"File or directory to search in"},glob:{type:"string",description:"Only search files matching this glob pattern"},case_sensitive:{type:"boolean",description:"Case sensitive search (default true)",default:!0}},required:["pattern","path"]}},{name:"bash:execute",description:"Execute a shell command and return its stdout/stderr output. Destructive commands (rm, dd) require user confirmation.",parameters:{type:"object",properties:{command:{type:"string",description:"Shell command to execute"},cwd:{type:"string",description:"Working directory (defaults to project root)"},timeout:{type:"number",description:"Timeout in milliseconds (default 300000)",default:3e5}},required:["command"]}},{name:"git:status",description:"Show the git working tree status (modified, staged, untracked files).",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"}}}},{name:"git:commit",description:"Stage and commit all changes with a conventional commit message.",parameters:{type:"object",properties:{message:{type:"string",description:'Conventional commit message (e.g. "feat: add login page")'},cwd:{type:"string",description:"Repository root (default: project root)"}},required:["message"]}},{name:"git:push",description:"Push the current branch to the remote repository.",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"}}}},{name:"git:log",description:"Show recent git commit history.",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"},limit:{type:"number",description:"Number of commits to show (default: 20)",default:20}}}}];import{readFile as Re,writeFile as De}from"node:fs/promises";import{resolve as ne,isAbsolute as G,relative as Tt}from"node:path";import{exec as It}from"node:child_process";import{promisify as Ne}from"node:util";import{default as Ct}from"glob";import{simpleGit as J}from"simple-git";import{statSync as St,existsSync as V,mkdirSync as At}from"node:fs";import{chmodSync as ft,mkdirSync as gt,readFileSync as ve,writeFileSync as ht}from"node:fs";import{resolve as R,dirname as Me}from"node:path";import{fileURLToPath as wt}from"node:url";function yt(){try{let e=wt(import.meta.url);return Me(Me(e))}catch{return process.cwd()}}function ee(e){try{let t=ve(e,"utf-8");for(let n of t.split(`
3
- `)){let r=n.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o===-1||o===r.length-1)continue;let i=r.slice(0,o).trim(),s=r.slice(o+1).trim().replace(/^["']|["']$/g,"");process.env[i]||(process.env[i]=s)}}catch{}}var Te=yt();ee(R(Te,".env"));ee(R(".env"));function Ie(){let e=process.env.AGENT_TERMO_DIR;return e?R(process.env.HOME||process.env.USERPROFILE||".",e):R(process.env.HOME||process.env.USERPROFILE||".",".agent-termo")}function te(){try{let e=JSON.parse(ve(R(Ie(),"config.json"),"utf-8"));if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}function Ce(e){let t=Ie(),n=R(t,"config.json"),r={...te(),...e};gt(t,{recursive:!0,mode:448}),ht(n,`${JSON.stringify(r,null,2)}
4
- `,{encoding:"utf-8",mode:384}),process.platform!=="win32"&&ft(n,384)}function bt(){if(process.env.NIM_API_KEY)return;let{nimApiKey:e}=te();typeof e=="string"&&e.trim()&&(process.env.NIM_API_KEY=e)}function xt(){let{nimModel:e}=te();typeof e=="string"&&e.trim()&&(process.env.NIM_MODEL=e)}function Se(e){Ce({nimApiKey:e})}function Ae(e){Ce({nimModel:e})}bt();xt();function Ee(e){return ee(R(e,".env")),{nimApiKey:process.env.NIM_API_KEY??"",nimBaseUrl:process.env.NIM_BASE_URL??"https://integrate.api.nvidia.com/v1",nimModel:process.env.NIM_MODEL??"stepfun-ai/step-3.7-flash",agentTermoDir:process.env.AGENT_TERMO_DIR??".claude",logLevel:process.env.LOG_LEVEL||"info",confirmDestructive:process.env.CONFIRM_DESTRUCTIVE!=="false",allowedCommands:(process.env.ALLOWED_COMMANDS??"git,npm,node,pnpm,yarn,tsx,tsc,npx").split(","),llmTimeout:parseInt(process.env.LLM_TIMEOUT??"120000",10),bashTimeout:parseInt(process.env.BASH_TIMEOUT??"300000",10)}}function Pe(e){return e||Te}function ke(e,t){let n=e.split(`
5
- `),r=t.split(`
6
- `);if(n.length===1&&n[0]==="")return{file:"",lines:r.map((f,M)=>({type:"add",lineNumber:M+1,content:f})),additions:r.length,deletions:0};if(e===t)return{file:"",lines:[],additions:0,deletions:0};let o=n.length,i=r.length,s=i+1,c=new Int32Array((o+1)*(i+1)),a=(h,f)=>c[h*s+f],m=(h,f,M)=>{c[h*s+f]=M};for(let h=1;h<=o;h++)for(let f=1;f<=i;f++)n[h-1]===r[f-1]?m(h,f,a(h-1,f-1)+1):m(h,f,Math.max(a(h-1,f),a(h,f-1)));let d=Mt(a,n,r),g=vt(d),p=0,y=0;for(let h of g)h.type==="add"&&p++,h.type==="remove"&&y++;return{file:"",lines:g,additions:p,deletions:y}}function Mt(e,t,n){let r=[],o=t.length,i=n.length,s=o,c=i;for(;s>0||c>0;)s>0&&c>0&&t[s-1]===n[c-1]?(r.unshift({type:"same",originalIndex:s,proposedIndex:c,originalLine:t[s-1],proposedLine:n[c-1]}),s--,c--):c>0&&(s===0||e(s,c-1)>=e(s-1,c))?(r.unshift({type:"add",proposedIndex:c,originalIndex:s,proposedLine:n[c-1]}),c--):(r.unshift({type:"remove",originalIndex:s,proposedIndex:c,originalLine:t[s-1]}),s--);return r}function vt(e){let t=[],n=0,r=0;for(let o of e)switch(o.type){case"same":{n++,r++,t.push({type:"context",lineNumber:n,content:o.originalLine??""});break}case"remove":{n++,t.push({type:"remove",lineNumber:n,content:o.originalLine??""});break}case"add":{r++,t.push({type:"add",lineNumber:r,content:o.proposedLine??""});break}}return t}var Oe=Ne(It),Et=Ne(Ct),Pt={"file:read":kt,"file:write":Dt,"file:edit":Rt,"file:glob":Nt,grep:Ot,"bash:execute":Lt,"git:status":$t,"git:commit":Ft,"git:push":jt,"git:log":Ut};async function _e(e,t,n){let r=Date.now(),o=crypto.randomUUID();try{let i=Pt[e];return i?await i(t,n):{id:o,name:e,success:!1,error:"Unknown tool: "+e,durationMs:Date.now()-r}}catch(i){return{id:o,name:e,success:!1,error:String(i instanceof Error?i.message:i),durationMs:Date.now()-r}}}function L(e,t){return G(e)?e:ne(t,e)}function $(e,t){try{let n=L(e,t),r=Tt(t,n);return!r.startsWith("..")&&!G(r)}catch{return!1}}function Le(e,t,n,r,o){let i=L(e,n),s=o??"",c=!V(i),a=t===""&&r==="write",d=ke(c?"":s,t),g={path:e,originalContent:s,proposedContent:t,diff:{...d,file:e},isNewFile:c,isDeletion:a},p=t.split(`
7
- `).length,y=a?`Delete ${e} (${p} lines removed)`:c?`Create ${e} (${p} lines)`:`${r==="edit"?"Edit":"Overwrite"} ${e} (${p} lines, +${d.additions}/-${d.deletions})`,h={id:"",name:`${r}:${e}`,success:!0,output:JSON.stringify({message:y,needsApproval:!0,proposedChange:g}),durationMs:0};return{change:g,result:h}}async function $e(e,t){let n=Date.now(),r=L(e.path,t);try{if(e.isDeletion)V(r)&&await De(r,"");else{let o=ne(r,"..");V(o)||At(o,{recursive:!0}),await De(r,e.proposedContent,"utf-8")}return{id:"",name:"file:write",success:!0,output:`Applied: ${e.path}`,durationMs:Date.now()-n}}catch(o){return{id:"",name:"file:write",success:!1,error:"Cannot apply "+e.path+": "+(o instanceof Error?o.message:String(o)),durationMs:Date.now()-n}}}async function kt(e,t){let n=String(e.path??"");if(!n)return{id:"",name:"file:read",success:!1,error:"path is required",durationMs:0};if(!$(n,t))return{id:"",name:"file:read",success:!1,error:"Access denied: "+n,durationMs:0};let r=L(n,t),o=Number(e.limit??0),i=Number(e.offset??0);try{if(St(r).isDirectory())return{id:"",name:"file:read",success:!1,error:'Path "'+n+'" is a directory',durationMs:0};let a=(await Re(r,"utf-8")).split(`
8
- `),m=a.slice(i,o>0?i+o:void 0),d=o>0?"[Showing lines "+(i+1)+"-"+(i+m.length)+" of "+a.length+"]":"";return{id:"",name:"file:read",success:!0,output:(d?d+`
9
- `:"")+m.join(`
10
- `),durationMs:0}}catch(s){return{id:"",name:"file:read",success:!1,error:"Cannot read "+n+": "+(s instanceof Error?s.message:String(s)),durationMs:0}}}async function Dt(e,t){let n=String(e.path??""),r=String(e.content??"");if(!n)return{id:"",name:"file:write",success:!1,error:"path is required",durationMs:0};if(!$(n,t))return{id:"",name:"file:write",success:!1,error:"Access denied: "+n,durationMs:0};let{result:o}=Le(n,r,t,"write");return o}async function Rt(e,t){let n=String(e.path??""),r=String(e.old_string??""),o=String(e.new_string??"");if(!n||!r)return{id:"",name:"file:edit",success:!1,error:"path and old_string are required",durationMs:0};if(!$(n,t))return{id:"",name:"file:edit",success:!1,error:"Access denied: "+n,durationMs:0};let i=L(n,t);try{let s=V(i)?await Re(i,"utf-8"):"";if(!s.includes(r))return{id:"",name:"file:edit",success:!1,error:"old_string not found in "+n+". Check whitespace.",durationMs:0};let c=s.replace(r,o),{result:a}=Le(n,c,t,"edit",s);return a}catch(s){return{id:"",name:"file:edit",success:!1,error:"Cannot edit "+n+": "+(s instanceof Error?s.message:String(s)),durationMs:0}}}async function Nt(e,t){let n=String(e.pattern??"");if(!n)return{id:"",name:"file:glob",success:!1,error:"pattern is required",durationMs:0};let r=e.cwd?String(e.cwd):t;if(!$(r,t))return{id:"",name:"file:glob",success:!1,error:"Access denied",durationMs:0};try{let o=await Et(n,{cwd:r,absolute:!1});return{id:"",name:"file:glob",success:!0,output:o.length>0?o.join(`
11
- `):"(no files matched)",durationMs:0}}catch(o){return{id:"",name:"file:glob",success:!1,error:"glob error: "+(o instanceof Error?o.message:String(o)),durationMs:0}}}async function Ot(e,t){let n=String(e.pattern??""),r=e.path?String(e.path):".",o=e.case_sensitive!==!1;if(!n||!r)return{id:"",name:"grep",success:!1,error:"pattern and path are required",durationMs:0};if(G(r)&&!$(r,t))return{id:"",name:"grep",success:!1,error:"Access denied",durationMs:0};let i=G(r)?r:ne(t,r),s=o?"":"-i",c=e.glob?["--include="+String(e.glob)]:[];try{let a=["grep",s,"-rn","--color=never",n,i,...c].join(" "),{stdout:m,stderr:d}=await Oe(a,{timeout:3e4});return{id:"",name:"grep",success:!0,output:(m||d).trim()||"(no matches found)",durationMs:0}}catch(a){return a.code===1?{id:"",name:"grep",success:!0,output:"(no matches found)",durationMs:0}:{id:"",name:"grep",success:!1,error:"grep error: "+(a instanceof Error?a.message:String(a)),durationMs:0}}}var _t=[/rm\s+-rf\s+['"]?\//i,/dd\s+if=/i,/>\s*\/dev\/sda/i,/mkfs\./i,/:\s*\(\)\s*\{\s*:\|:&?\s*\};?\s*:/i];async function Lt(e,t){let n=String(e.command??""),r=e.cwd?String(e.cwd):t,o=Number(e.timeout??Ee(t).bashTimeout);if(!n)return{id:"",name:"bash:execute",success:!1,error:"command is required",durationMs:0};for(let i of _t)if(i.test(n))return{id:"",name:"bash:execute",success:!1,error:"Dangerous command blocked: "+n.slice(0,50),durationMs:0};try{let{stdout:i,stderr:s}=await Oe(n,{cwd:r,timeout:o});return{id:"",name:"bash:execute",success:!0,output:[i,s].filter(Boolean).join(`
12
- `)||"(no output)",durationMs:0}}catch(i){let s=i;return{id:"",name:"bash:execute",success:!1,error:[s.stdout,s.stderr].filter(Boolean).join(`
13
- `).slice(0,500)||s.message,durationMs:0}}}async function $t(e,t){let n=e.cwd?String(e.cwd):t;try{let o=await J(n).status(),i=o.tracking;return{id:"",name:"git:status",success:!0,output:["Current branch: "+(o.current??"unknown"),i?"tracking: "+i:"","","Modified: "+(o.modified.length>0?o.modified.join(", "):"(none)"),"Created: "+(o.created.length>0?o.created.join(", "):"(none)"),"Deleted: "+(o.deleted.length>0?o.deleted.join(", "):"(none)"),"","Not staged: "+(o.not_added.length>0?o.not_added.join(", "):"(none)"),"","Untracked: "+(o.files.length>0?o.files.join(", "):"(none)")].filter(Boolean).join(`
14
- `),durationMs:0}}catch(r){return{id:"",name:"git:status",success:!1,error:r instanceof Error?r.message:String(r),durationMs:0}}}async function Ft(e,t){let n=String(e.message??""),r=e.cwd?String(e.cwd):t;if(!n)return{id:"",name:"git:commit",success:!1,error:"message is required",durationMs:0};try{let o=J(r);return await o.add("."),{id:"",name:"git:commit",success:!0,output:"Committed "+(await o.commit(n)).commit+" \u2014 "+n,durationMs:0}}catch(o){return{id:"",name:"git:commit",success:!1,error:o instanceof Error?o.message:String(o),durationMs:0}}}async function jt(e,t){let n=e.cwd?String(e.cwd):t;try{return await J(n).push(),{id:"",name:"git:push",success:!0,output:"Pushed to remote.",durationMs:0}}catch(r){return{id:"",name:"git:push",success:!1,error:r instanceof Error?r.message:String(r),durationMs:0}}}async function Ut(e,t){let n=e.cwd?String(e.cwd):t,r=Number(e.limit??20);try{return{id:"",name:"git:log",success:!0,output:(await J(n).log({maxCount:r})).all.map(c=>c.hash.slice(0,7)+" | "+c.date.slice(0,10)+" | "+c.message+" ("+c.author_name+")").join(`
15
- `),durationMs:0}}catch(o){return{id:"",name:"git:log",success:!1,error:o instanceof Error?o.message:String(o),durationMs:0}}}import{readFileSync as oe,appendFileSync as je,writeFileSync as Bn,existsSync as z,mkdirSync as Kt}from"node:fs";import{resolve as F}from"node:path";function Ue(){let e=F(process.env.HOME||process.env.USERPROFILE||".",".agent-termo");try{z(e)||Kt(e,{recursive:!0})}catch{}return e}var Fe=F(Ue(),"memory.md");function Ke(){if(!z(Fe))return"";try{return oe(Fe,"utf-8")}catch{return""}}var re=F(Ue(),"timeline.md");function We(){if(!z(re))return"";try{return oe(re,"utf-8")}catch{return""}}function j(e){let n=`
16
- - [`+new Date().toISOString().replace("T"," ").slice(0,16)+"] "+e;try{je(re,n,"utf-8")}catch{}}async function qe(e){let t=F(e,"docs","MEMORY.md");if(!z(t))return"";try{return oe(t,"utf-8")}catch{return""}}async function U(e,t){let n=F(e,"docs","TIMELINE.md"),r=new Date().toISOString().replace("T"," ").slice(0,16);je(n,`
17
- - [`+r+"] "+t,"utf-8")}import{readdirSync as Wt,readFileSync as qt}from"node:fs";import{resolve as He}from"node:path";function Ht(e){let t=e.match(/^description:\s*(.+)$/m),r=e.match(/^tools:\s*\[(.+)\]/m)?.[1]??"",o=r?r.split(",").map(i=>i.trim().replace(/^["']|["']$/g,"")):["file:read","file:write","file:edit","file:glob","grep","bash:execute","git:status","git:commit","git:push","git:log"];return{description:t?.[1]?.trim()??"",tools:o}}function Ye(e){let t=He(e,"agents");try{return Wt(t).filter(o=>o.endsWith(".md")).map(o=>{let i=o.replace(/\.md$/,""),s=qt(He(t,o),"utf-8"),c=Ht(s),a=s.replace(/^---[\s\S]+?---\n/,"").trim();return{name:i,description:c.description,systemPrompt:a,tools:c.tools}}).sort((o,i)=>o.name.localeCompare(i.name))}catch{return[]}}var Yt=`You are Agent-Termo, a helpful AI assistant in a terminal.
2
+ import{Command as kn}from"commander";import yt from"openai";var Ce=[{id:"stepfun-ai/step-3.7-flash",note:"default"},{id:"meta/llama-3.1-8b-instruct",note:"fast, low cost"},{id:"meta/llama-3.1-70b-instruct",note:"balanced"},{id:"meta/llama-3.3-70b-instruct",note:"balanced"},{id:"meta/llama-3.1-405b-instruct",note:"highest quality Llama"},{id:"nvidia/llama-3.1-nemotron-70b-instruct",note:"NVIDIA tuned"},{id:"qwen/qwen2.5-coder-32b-instruct",note:"coding"},{id:"deepseek-ai/deepseek-r1",note:"reasoning"},{id:"moonshotai/kimi-k2-instruct",note:"agentic / tool use"},{id:"openai/gpt-oss-120b",note:"open-weight GPT"}],gt=/embed|rerank|retriev|reward|guard|safety|parse|clip|vila|neva|fuyu|kosmos|paligemma|deplot|riva|asr|tts|whisper|diffusion|sdxl|flux|cosmos|segment|bge-|e5-|gliner|pii|streampetr|ocdrnet|bevformer/i;function ht(e){return!gt.test(e)}function X(e){if(!e)return[...Ce];let t=new Set(e),n=Ce.filter(i=>t.has(i.id)),o=new Set(n.map(i=>i.id)),r=e.filter(i=>!o.has(i)&&ht(i)).sort((i,a)=>i.localeCompare(a)).map(i=>({id:i}));return[...n,...r]}var Ie={"file:read":"file_read","file:write":"file_write","file:edit":"file_edit","file:delete":"file_delete","file:glob":"file_glob","bash:execute":"bash_execute","git:status":"git_status","git:commit":"git_commit","git:push":"git_push","git:log":"git_log"};function ee(e){return Ie[e]??e.replace(/:/g,"_")}function U(e){return Object.entries(Ie).find(([,t])=>t===e)?.[0]??e}var J=class{client;model;constructor(t){let n=process.env.NIM_API_KEY??"",o=process.env.NIM_BASE_URL??"https://integrate.api.nvidia.com/v1";this.model=process.env.NIM_MODEL??"stepfun-ai/step-3.7-flash";let r=parseInt(process.env.LLM_TIMEOUT??"120000",10);this.client=new yt({apiKey:n,baseURL:o,timeout:r,defaultHeaders:{"User-Agent":"agent-termo/1.0"}})}buildToolDefs(t){return t.map(n=>({type:"function",function:{name:ee(n.name),description:n.description,parameters:n.parameters}}))}getModel(){return this.model}setModel(t){this.model=t}async listModels(){try{let n=(await this.client.models.list({timeout:1e4})).data.map(o=>o.id);if(n.length===0)throw new Error("empty model list");return{models:X(n),live:!0}}catch(t){return{models:X(null),live:!1,error:t instanceof Error?t.message:String(t)}}}async*streamComplete(t,n,o){let r=[],i=new Map,a=await this.client.chat.completions.create({model:this.model,messages:t.map(d=>d.role==="tool"?{role:"tool",content:d.content,tool_call_id:d.id}:d.role==="assistant"&&d.toolCalls?.length?{role:"assistant",content:d.content||null,tool_calls:d.toolCalls.map(u=>({id:u.id,type:"function",function:{name:ee(u.name),arguments:JSON.stringify(u.arguments)}}))}:{role:d.role,content:d.content}),tools:n,temperature:.3,max_tokens:8192,stream:!0});for await(let d of a){let u=d.choices[0]?.delta;if(!u)continue;let g=u.content??"";if(!(g==="null"||g==="undefined")&&g&&(r.push(g),o?.(g)),u.tool_calls)for(let w of u.tool_calls){let y=w.index??0,f=i.get(y);f?(f.arguments+=w.function?.arguments??"",w.id&&!f.id&&(f.id=w.id)):i.set(y,{id:w.id??crypto.randomUUID(),name:w.function?.name??"",arguments:w.function?.arguments??""})}}let c=r.join(""),s=Array.from(i.values()).map(d=>{let u={};try{u=JSON.parse(d.arguments)}catch{u={_raw:d.arguments}}return{id:d.id,name:U(d.name),arguments:u}});yield{content:c,toolCalls:s}}async complete(t,n){let r=(await this.client.chat.completions.create({model:this.model,messages:t.map(c=>c.role==="tool"?{role:"tool",content:c.content,tool_call_id:c.id}:c.role==="assistant"&&c.toolCalls?.length?{role:"assistant",content:c.content||null,tool_calls:c.toolCalls.map(s=>({id:s.id,type:"function",function:{name:ee(s.name),arguments:JSON.stringify(s.arguments)}}))}:{role:c.role,content:c.content}),tools:n,temperature:.3,max_tokens:8192,stream:!1})).choices[0]?.message,i=r?.content?.replace(/\[ Reasoning[^\]]*\][^\[]*\[\/ Reasoning\][^\n]*/gi,"").trim()??"",a=(r?.tool_calls??[]).map(c=>{let s={};try{s=JSON.parse(c.function.arguments??"{}")}catch{s={_raw:c.function.arguments}}return{id:c.id,name:U(c.function.name),arguments:s}});if(a.length===0&&i.includes('"tool_calls"'))try{let c=JSON.parse(i);if(c.tool_calls?.length){a.push(...c.tool_calls.map(d=>({id:d.id??crypto.randomUUID(),name:U(d.function?.name??d.name??""),arguments:typeof d.function?.arguments=="string"?JSON.parse(d.function.arguments):d.function?.arguments??{}})));let s=i.indexOf('{"tool_calls"');s!==-1&&(i=i.slice(0,s).trim())}}catch{}return{content:i,toolCalls:a}}};var te=[{name:"file:read",description:"Read the complete contents of a file. Use for examining existing code, config, or documentation.",parameters:{type:"object",properties:{path:{type:"string",description:"File path (absolute or relative to project root)"},limit:{type:"number",description:"Maximum number of lines to read (0 = all)",default:0},offset:{type:"number",description:"Line offset to start reading from (0 = start)",default:0}},required:["path"]}},{name:"file:write",description:"Write or overwrite a complete file. Use this to create new files or replace existing ones entirely.",parameters:{type:"object",properties:{path:{type:"string",description:"File path to write (relative to project root)"},content:{type:"string",description:"Complete file content to write"}},required:["path","content"]}},{name:"file:edit",description:"Edit an existing file by replacing an exact section. The old_string must appear verbatim in the file.",parameters:{type:"object",properties:{path:{type:"string",description:"File to edit"},old_string:{type:"string",description:"Exact text to find and replace (must be unique in file)"},new_string:{type:"string",description:"Replacement text"}},required:["path","old_string","new_string"]}},{name:"file:delete",description:"Delete a file from the project. Use only when the user explicitly asks to remove it.",parameters:{type:"object",properties:{path:{type:"string",description:"File path to delete (relative to project root)"}},required:["path"]}},{name:"file:glob",description:"Find all files matching a glob pattern. Use to discover project structure.",parameters:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern (e.g. "src/**/*.ts", "**/*.json")'},cwd:{type:"string",description:"Root directory to search in (defaults to project root)"}},required:["pattern"]}},{name:"grep",description:"Search for text or regex patterns inside files. Use to find function definitions, imports, etc.",parameters:{type:"object",properties:{pattern:{type:"string",description:"Text or regex pattern to search for"},path:{type:"string",description:"File or directory to search in"},glob:{type:"string",description:"Only search files matching this glob pattern"},case_sensitive:{type:"boolean",description:"Case sensitive search (default true)",default:!0}},required:["pattern","path"]}},{name:"bash:execute",description:"Execute a shell command and return its stdout/stderr output. Destructive commands (rm, dd) require user confirmation.",parameters:{type:"object",properties:{command:{type:"string",description:"Shell command to execute"},cwd:{type:"string",description:"Working directory (defaults to project root)"},timeout:{type:"number",description:"Timeout in milliseconds (default 300000)",default:3e5}},required:["command"]}},{name:"git:status",description:"Show the git working tree status (modified, staged, untracked files).",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"}}}},{name:"git:commit",description:"Stage and commit all changes with a conventional commit message.",parameters:{type:"object",properties:{message:{type:"string",description:'Conventional commit message (e.g. "feat: add login page")'},cwd:{type:"string",description:"Repository root (default: project root)"}},required:["message"]}},{name:"git:push",description:"Push the current branch to the remote repository.",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"}}}},{name:"git:log",description:"Show recent git commit history.",parameters:{type:"object",properties:{cwd:{type:"string",description:"Repository root (default: project root)"},limit:{type:"number",description:"Number of commits to show (default: 20)",default:20}}}}];import{readFile as oe,writeFile as At,unlink as Et}from"node:fs/promises";import{resolve as ie,isAbsolute as V,relative as Pt}from"node:path";import{exec as kt}from"node:child_process";import{promisify as Le}from"node:util";import{default as Dt}from"glob";import{simpleGit as z}from"simple-git";import{statSync as _t,existsSync as W,mkdirSync as Ot}from"node:fs";import{chmodSync as wt,mkdirSync as bt,readFileSync as Ae,writeFileSync as xt}from"node:fs";import{resolve as _,dirname as Se}from"node:path";import{fileURLToPath as vt}from"node:url";function Mt(){try{let e=vt(import.meta.url);return Se(Se(e))}catch{return process.cwd()}}function ne(e){try{let t=Ae(e,"utf-8");for(let n of t.split(`
3
+ `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let r=o.indexOf("=");if(r===-1||r===o.length-1)continue;let i=o.slice(0,r).trim(),a=o.slice(r+1).trim().replace(/^["']|["']$/g,"");process.env[i]||(process.env[i]=a)}}catch{}}var Ee=Mt();ne(_(Ee,".env"));ne(_(".env"));function Pe(){let e=process.env.AGENT_TERMO_DIR;return e?_(process.env.HOME||process.env.USERPROFILE||".",e):_(process.env.HOME||process.env.USERPROFILE||".",".agent-termo")}function re(){try{let e=JSON.parse(Ae(_(Pe(),"config.json"),"utf-8"));if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{}}function ke(e){let t=Pe(),n=_(t,"config.json"),o={...re(),...e};bt(t,{recursive:!0,mode:448}),xt(n,`${JSON.stringify(o,null,2)}
4
+ `,{encoding:"utf-8",mode:384}),process.platform!=="win32"&&wt(n,384)}function Tt(){if(process.env.NIM_API_KEY)return;let{nimApiKey:e}=re();typeof e=="string"&&e.trim()&&(process.env.NIM_API_KEY=e)}function Ct(){let{nimModel:e}=re();typeof e=="string"&&e.trim()&&(process.env.NIM_MODEL=e)}function De(e){ke({nimApiKey:e})}function _e(e){ke({nimModel:e})}Tt();Ct();function Oe(e){return ne(_(e,".env")),{nimApiKey:process.env.NIM_API_KEY??"",nimBaseUrl:process.env.NIM_BASE_URL??"https://integrate.api.nvidia.com/v1",nimModel:process.env.NIM_MODEL??"stepfun-ai/step-3.7-flash",agentTermoDir:process.env.AGENT_TERMO_DIR??".claude",logLevel:process.env.LOG_LEVEL||"info",confirmDestructive:process.env.CONFIRM_DESTRUCTIVE!=="false",allowedCommands:(process.env.ALLOWED_COMMANDS??"git,npm,node,pnpm,yarn,tsx,tsc,npx").split(","),llmTimeout:parseInt(process.env.LLM_TIMEOUT??"120000",10),bashTimeout:parseInt(process.env.BASH_TIMEOUT??"300000",10)}}function Ne(e){return e||Ee}function Re(e,t){let n=e.split(`
5
+ `),o=t.split(`
6
+ `);if(n.length===1&&n[0]==="")return{file:"",lines:o.map((f,v)=>({type:"add",lineNumber:v+1,content:f})),additions:o.length,deletions:0};if(e===t)return{file:"",lines:[],additions:0,deletions:0};let r=n.length,i=o.length,a=i+1,c=new Int32Array((r+1)*(i+1)),s=(y,f)=>c[y*a+f],d=(y,f,v)=>{c[y*a+f]=v};for(let y=1;y<=r;y++)for(let f=1;f<=i;f++)n[y-1]===o[f-1]?d(y,f,s(y-1,f-1)+1):d(y,f,Math.max(s(y-1,f),s(y,f-1)));let u=It(s,n,o),g=St(u),p=0,w=0;for(let y of g)y.type==="add"&&p++,y.type==="remove"&&w++;return{file:"",lines:g,additions:p,deletions:w}}function It(e,t,n){let o=[],r=t.length,i=n.length,a=r,c=i;for(;a>0||c>0;)a>0&&c>0&&t[a-1]===n[c-1]?(o.unshift({type:"same",originalIndex:a,proposedIndex:c,originalLine:t[a-1],proposedLine:n[c-1]}),a--,c--):c>0&&(a===0||e(a,c-1)>=e(a-1,c))?(o.unshift({type:"add",proposedIndex:c,originalIndex:a,proposedLine:n[c-1]}),c--):(o.unshift({type:"remove",originalIndex:a,proposedIndex:c,originalLine:t[a-1]}),a--);return o}function St(e){let t=[],n=0,o=0;for(let r of e)switch(r.type){case"same":{n++,o++,t.push({type:"context",lineNumber:n,content:r.originalLine??""});break}case"remove":{n++,t.push({type:"remove",lineNumber:n,content:r.originalLine??""});break}case"add":{o++,t.push({type:"add",lineNumber:o,content:r.proposedLine??""});break}}return t}var je=Le(kt),Nt=Le(Dt),Rt={"file:read":Lt,"file:write":jt,"file:edit":Ft,"file:delete":$t,"file:glob":Ut,grep:Wt,"bash:execute":qt,"git:status":Ht,"git:commit":Yt,"git:push":Bt,"git:log":Gt};async function Fe(e,t,n){let o=Date.now(),r=crypto.randomUUID();try{let i=Rt[e];return i?await i(t,n):{id:r,name:e,success:!1,error:"Unknown tool: "+e,durationMs:Date.now()-o}}catch(i){return{id:r,name:e,success:!1,error:String(i instanceof Error?i.message:i),durationMs:Date.now()-o}}}function j(e,t){return V(e)?e:ie(t,e)}function F(e,t){try{let n=j(e,t),o=Pt(t,n);return!o.startsWith("..")&&!V(o)}catch{return!1}}function se(e,t,n,o,r){let i=j(e,n),a=r??"",c=!W(i),s=t===""&&o==="write",u=Re(c?"":a,t),g={path:e,originalContent:a,proposedContent:t,diff:{...u,file:e},isNewFile:c,isDeletion:s},p=t.split(`
7
+ `).length,w=s?`Delete ${e} (${p} lines removed)`:c?`Create ${e} (${p} lines)`:`${o==="edit"?"Edit":"Overwrite"} ${e} (${p} lines, +${u.additions}/-${u.deletions})`,y={id:"",name:`${o}:${e}`,success:!0,output:JSON.stringify({message:w,needsApproval:!0,proposedChange:g}),durationMs:0};return{change:g,result:y}}async function $e(e,t){let n=Date.now(),o=j(e.path,t);try{if(e.isDeletion)W(o)&&await Et(o);else{let r=ie(o,"..");W(r)||Ot(r,{recursive:!0}),await At(o,e.proposedContent,"utf-8")}return{id:"",name:"file:write",success:!0,output:`Applied: ${e.path}`,durationMs:Date.now()-n}}catch(r){return{id:"",name:"file:write",success:!1,error:"Cannot apply "+e.path+": "+(r instanceof Error?r.message:String(r)),durationMs:Date.now()-n}}}async function Lt(e,t){let n=String(e.path??"");if(!n)return{id:"",name:"file:read",success:!1,error:"path is required",durationMs:0};if(!F(n,t))return{id:"",name:"file:read",success:!1,error:"Access denied: "+n,durationMs:0};let o=j(n,t),r=Number(e.limit??0),i=Number(e.offset??0);try{if(_t(o).isDirectory())return{id:"",name:"file:read",success:!1,error:'Path "'+n+'" is a directory',durationMs:0};let s=(await oe(o,"utf-8")).split(`
8
+ `),d=s.slice(i,r>0?i+r:void 0),u=r>0?"[Showing lines "+(i+1)+"-"+(i+d.length)+" of "+s.length+"]":"";return{id:"",name:"file:read",success:!0,output:(u?u+`
9
+ `:"")+d.join(`
10
+ `),durationMs:0}}catch(a){return{id:"",name:"file:read",success:!1,error:"Cannot read "+n+": "+(a instanceof Error?a.message:String(a)),durationMs:0}}}async function jt(e,t){let n=String(e.path??""),o=String(e.content??"");if(!n)return{id:"",name:"file:write",success:!1,error:"path is required",durationMs:0};if(!F(n,t))return{id:"",name:"file:write",success:!1,error:"Access denied: "+n,durationMs:0};let{result:r}=se(n,o,t,"write");return r}async function Ft(e,t){let n=String(e.path??""),o=String(e.old_string??""),r=String(e.new_string??"");if(!n||!o)return{id:"",name:"file:edit",success:!1,error:"path and old_string are required",durationMs:0};if(!F(n,t))return{id:"",name:"file:edit",success:!1,error:"Access denied: "+n,durationMs:0};let i=j(n,t);try{let a=W(i)?await oe(i,"utf-8"):"";if(!a.includes(o))return{id:"",name:"file:edit",success:!1,error:"old_string not found in "+n+". Check whitespace.",durationMs:0};let c=a.replace(o,r),{result:s}=se(n,c,t,"edit",a);return s}catch(a){return{id:"",name:"file:edit",success:!1,error:"Cannot edit "+n+": "+(a instanceof Error?a.message:String(a)),durationMs:0}}}async function $t(e,t){let n=String(e.path??"");if(!n)return{id:"",name:"file:delete",success:!1,error:"path is required",durationMs:0};if(!F(n,t))return{id:"",name:"file:delete",success:!1,error:"Access denied: "+n,durationMs:0};let o=j(n,t);try{if(!W(o))return{id:"",name:"file:delete",success:!1,error:"File not found: "+n,durationMs:0};let r=await oe(o,"utf-8");return se(n,"",t,"write",r).result}catch(r){return{id:"",name:"file:delete",success:!1,error:"Cannot delete "+n+": "+(r instanceof Error?r.message:String(r)),durationMs:0}}}async function Ut(e,t){let n=String(e.pattern??"");if(!n)return{id:"",name:"file:glob",success:!1,error:"pattern is required",durationMs:0};let o=e.cwd?String(e.cwd):t;if(!F(o,t))return{id:"",name:"file:glob",success:!1,error:"Access denied",durationMs:0};try{let r=await Nt(n,{cwd:o,absolute:!1});return{id:"",name:"file:glob",success:!0,output:r.length>0?r.join(`
11
+ `):"(no files matched)",durationMs:0}}catch(r){return{id:"",name:"file:glob",success:!1,error:"glob error: "+(r instanceof Error?r.message:String(r)),durationMs:0}}}async function Wt(e,t){let n=String(e.pattern??""),o=e.path?String(e.path):".",r=e.case_sensitive!==!1;if(!n||!o)return{id:"",name:"grep",success:!1,error:"pattern and path are required",durationMs:0};if(V(o)&&!F(o,t))return{id:"",name:"grep",success:!1,error:"Access denied",durationMs:0};let i=V(o)?o:ie(t,o),a=r?"":"-i",c=e.glob?["--include="+String(e.glob)]:[];try{let s=["grep",a,"-rn","--color=never",n,i,...c].join(" "),{stdout:d,stderr:u}=await je(s,{timeout:3e4});return{id:"",name:"grep",success:!0,output:(d||u).trim()||"(no matches found)",durationMs:0}}catch(s){return s.code===1?{id:"",name:"grep",success:!0,output:"(no matches found)",durationMs:0}:{id:"",name:"grep",success:!1,error:"grep error: "+(s instanceof Error?s.message:String(s)),durationMs:0}}}var Kt=[/rm\s+-rf\s+['"]?\//i,/dd\s+if=/i,/>\s*\/dev\/sda/i,/mkfs\./i,/:\s*\(\)\s*\{\s*:\|:&?\s*\};?\s*:/i];async function qt(e,t){let n=String(e.command??""),o=e.cwd?String(e.cwd):t,r=Number(e.timeout??Oe(t).bashTimeout);if(!n)return{id:"",name:"bash:execute",success:!1,error:"command is required",durationMs:0};for(let i of Kt)if(i.test(n))return{id:"",name:"bash:execute",success:!1,error:"Dangerous command blocked: "+n.slice(0,50),durationMs:0};try{let{stdout:i,stderr:a}=await je(n,{cwd:o,timeout:r});return{id:"",name:"bash:execute",success:!0,output:[i,a].filter(Boolean).join(`
12
+ `)||"(no output)",durationMs:0}}catch(i){let a=i;return{id:"",name:"bash:execute",success:!1,error:[a.stdout,a.stderr].filter(Boolean).join(`
13
+ `).slice(0,500)||a.message,durationMs:0}}}async function Ht(e,t){let n=e.cwd?String(e.cwd):t;try{let r=await z(n).status(),i=r.tracking;return{id:"",name:"git:status",success:!0,output:["Current branch: "+(r.current??"unknown"),i?"tracking: "+i:"","","Modified: "+(r.modified.length>0?r.modified.join(", "):"(none)"),"Created: "+(r.created.length>0?r.created.join(", "):"(none)"),"Deleted: "+(r.deleted.length>0?r.deleted.join(", "):"(none)"),"","Not staged: "+(r.not_added.length>0?r.not_added.join(", "):"(none)"),"","Untracked: "+(r.files.length>0?r.files.join(", "):"(none)")].filter(Boolean).join(`
14
+ `),durationMs:0}}catch(o){return{id:"",name:"git:status",success:!1,error:o instanceof Error?o.message:String(o),durationMs:0}}}async function Yt(e,t){let n=String(e.message??""),o=e.cwd?String(e.cwd):t;if(!n)return{id:"",name:"git:commit",success:!1,error:"message is required",durationMs:0};try{let r=z(o);return await r.add("."),{id:"",name:"git:commit",success:!0,output:"Committed "+(await r.commit(n)).commit+" \u2014 "+n,durationMs:0}}catch(r){return{id:"",name:"git:commit",success:!1,error:r instanceof Error?r.message:String(r),durationMs:0}}}async function Bt(e,t){let n=e.cwd?String(e.cwd):t;try{return await z(n).push(),{id:"",name:"git:push",success:!0,output:"Pushed to remote.",durationMs:0}}catch(o){return{id:"",name:"git:push",success:!1,error:o instanceof Error?o.message:String(o),durationMs:0}}}async function Gt(e,t){let n=e.cwd?String(e.cwd):t,o=Number(e.limit??20);try{return{id:"",name:"git:log",success:!0,output:(await z(n).log({maxCount:o})).all.map(c=>c.hash.slice(0,7)+" | "+c.date.slice(0,10)+" | "+c.message+" ("+c.author_name+")").join(`
15
+ `),durationMs:0}}catch(r){return{id:"",name:"git:log",success:!1,error:r instanceof Error?r.message:String(r),durationMs:0}}}import{readFileSync as ce,appendFileSync as Ke,writeFileSync as Ue,existsSync as $,mkdirSync as qe}from"node:fs";import{resolve as O}from"node:path";function He(){let e=O(process.env.HOME||process.env.USERPROFILE||".",".agent-termo");try{$(e)||qe(e,{recursive:!0})}catch{}return e}var We=O(He(),"memory.md");function Ye(){if(!$(We))return"";try{return ce(We,"utf-8")}catch{return""}}var ae=O(He(),"timeline.md");function Be(){if(!$(ae))return"";try{return ce(ae,"utf-8")}catch{return""}}function K(e){let n=`
16
+ - [`+new Date().toISOString().replace("T"," ").slice(0,16)+"] "+e;try{Ke(ae,n,"utf-8")}catch{}}async function Ge(e){let t=O(e,"docs","MEMORY.md");if(!$(t))return"";try{return ce(t,"utf-8")}catch{return""}}var Jt=`# Project Timeline
17
+
18
+ This document tracks the complete chronological history of the project.
19
+
20
+ ---
21
+
22
+ `,Vt=`# Project Memory
23
+
24
+ ## Project Context
25
+ (Add project context here)
26
+ `;function zt(e){let t=O(e,"docs"),n=O(t,"MEMORY.md"),o=O(t,"TIMELINE.md");return qe(t,{recursive:!0}),$(n)||Ue(n,Vt,"utf-8"),$(o)||Ue(o,Jt,"utf-8"),{memoryPath:n,timelinePath:o}}async function q(e,t){let n;try{n=zt(e).timelinePath}catch{return}let o=new Date().toISOString().replace("T"," ").slice(0,16);try{Ke(n,`
27
+ - [`+o+"] "+t,"utf-8")}catch{}}import{readdirSync as Zt,readFileSync as Qt}from"node:fs";import{resolve as Je}from"node:path";function Xt(e){let t=e.match(/^description:\s*(.+)$/m),o=e.match(/^tools:\s*\[(.+)\]/m)?.[1]??"",r=o?o.split(",").map(i=>i.trim().replace(/^["']|["']$/g,"")):["file:read","file:write","file:edit","file:delete","file:glob","grep","bash:execute","git:status","git:commit","git:push","git:log"];return{description:t?.[1]?.trim()??"",tools:r}}function Ve(e){let t=Je(e,"agents");try{return Zt(t).filter(r=>r.endsWith(".md")).map(r=>{let i=r.replace(/\.md$/,""),a=Qt(Je(t,r),"utf-8"),c=Xt(a),s=a.replace(/^---[\s\S]+?---\n/,"").trim();return{name:i,description:c.description,systemPrompt:s,tools:c.tools}}).sort((r,i)=>r.name.localeCompare(i.name))}catch{return[]}}var en=`You are Agent-Termo, a helpful AI assistant in a terminal.
18
28
 
19
29
  RESPONSE RULES (follow these strictly):
20
30
  - Be concise and direct. 1-3 sentences for simple questions.
@@ -34,6 +44,7 @@ Available functions:
34
44
  - file:read(path) \u2192 read a file
35
45
  - file:write(path, content) \u2192 overwrite a file completely
36
46
  - file:edit(path, old_string, new_string) \u2192 edit a specific line section
47
+ - file:delete(path) \u2192 delete a file after explicit user instruction
37
48
  - file:glob(pattern) \u2192 list files matching a glob (e.g. "src/**/*.ts")
38
49
  - grep(pattern, path, glob?) \u2192 search for text in files
39
50
  - bash:execute(command) \u2192 run a shell command
@@ -43,97 +54,97 @@ When done, say "Done: <brief summary>."
43
54
 
44
55
  AVAILABLE FILES:
45
56
  - docs/MEMORY.md \u2014 project context
46
- - docs/TIMELINE.md \u2014 recent activity log`;function Be(e,t,n){let r=Yt;return e&&(r+=`
57
+ - docs/TIMELINE.md \u2014 recent activity log`;function ze(e,t,n){let o=en;return e&&(o+=`
47
58
 
48
59
  ## Project Memory
49
- `+e),t&&(r+=`
60
+ `+e),t&&(o+=`
50
61
 
51
62
  ## Recent Timeline (last entries)
52
- `+t.slice(-1500)),r}import dn from"chalk";import Bt from"chalk";import{createInterface as Gt}from"node:readline";var T=Bt,x=process.stdout,b="\x1B[",ie="\x1B7",se="\x1B8",ae=4,Vt=12,Jt=40,zt="Ask anything\u2026 or type / for commands",u={active:!1,editing:!1,savedValid:!0,rows:0,model:"",project:"",commands:[],buffer:"",cursor:0,offset:0};function Ve(e){u.commands=e}function N(){return{rows:x.rows||24,cols:x.columns||80}}function A(){return x.columns||80}function v(e,t){return t<=0?"":e.length<=t?e:e.slice(0,Math.max(0,t-1))+"\u2026"}function Zt(e){let t=process.env.HOME||process.env.USERPROFILE||"";return t&&e.startsWith(t)?"~"+e.slice(t.length):e}function Qt(){return!!(x.isTTY&&process.stdin.isTTY&&(x.rows??0)>=Vt&&(x.columns??0)>=Jt)}function Xt(e){if(u.editing&&u.buffer.startsWith("/")&&!u.buffer.includes(" ")){let c=u.buffer.toLowerCase(),a=u.commands.filter(d=>d.name.startsWith(c)),m=a[0];if(a.length===1&&m)return" "+T.cyan(m.name)+T.dim(v(" \u2014 "+m.description,e-m.name.length-1));if(a.length>1)return T.cyan(v(" "+a.map(d=>d.name).join(" "),e))}let t="/help \xB7 /model \xB7 ctrl+c to exit",n=v(" "+u.model,e),r=e-n.length-t.length-2,o=r>=15,i=v(" \xB7 "+Zt(u.project),o?r:Math.max(0,e-n.length)),s=Math.max(1,e-n.length-i.length-t.length);return T.cyan(n)+T.dim(i+(o?" ".repeat(s)+t:""))}function K(){let{rows:e,cols:t}=N(),n=Math.max(1,t-6);u.offset=Math.min(u.offset,Math.max(0,u.buffer.length-n+1)),u.cursor<u.offset&&(u.offset=u.cursor),u.cursor>u.offset+n-1&&(u.offset=u.cursor-n+1);let r=u.editing?T.magenta:T.dim,o=u.buffer?u.buffer.slice(u.offset,u.offset+n).padEnd(n):T.dim(v(zt,n).padEnd(n)),i=e-3,s=(c,a)=>`${b}${c};1H${b}2K${a}`;return[s(i,r("\u256D"+"\u2500".repeat(t-2)+"\u256E")),s(i+1,r("\u2502")+" "+T.magenta.bold("\u276F")+" "+o+" "+r("\u2502")),s(i+2,r("\u2570"+"\u2500".repeat(t-2)+"\u256F")),s(e,Xt(t-1))].join("")}function en(){let{rows:e}=N();return`${b}${e-2};${5+u.cursor-u.offset}H`}function E(){u.active&&(u.editing?x.write(b+"?25l"+K()+en()+b+"?25h"):x.write(ie+K()+se))}function ce(){return Math.max(1,N().rows-ae)}function le(){x.write(`${b}1;${ce()}r`)}function tn(){let{rows:e}=N();if(e===u.rows){E();return}u.rows=e,u.savedValid=!1,x.write(`${b}2J${b}H`),le(),x.write(K()+`${b}${ce()};1H`),u.editing&&E()}function de(e){u.model=e.model,u.project=e.project,!(u.active||!Qt())&&(u.active=!0,u.rows=N().rows,x.write(`${b}2J${b}H`),le(),x.write(K()+`${b}1;1H`),x.on("resize",tn),process.on("exit",nn))}function ue(e){e.model!==void 0&&(u.model=e.model),e.project!==void 0&&(u.project=e.project),E()}function Je(){x.write(`${b}2J${b}H`),u.active&&(le(),x.write(K()+`${b}1;1H`))}function nn(){if(!u.active)return;u.active=!1;let{rows:e}=N(),t=Math.max(1,e-ae+1),n="";for(let i=t;i<=e;i++)n+=`${b}${i};1H${b}2K`;let r=u.editing?"":ie,o=u.editing&&!u.savedValid?`${b}${t};1H`:se;x.write(r+b+"r"+n+o+b+"?25h"+b+"?2004l")}var rn=/\x1b\[200~|\x1b\[201~|\x1b\[[0-9;?]*[ -/]*[@-~]|\x1bO[A-Za-z]|\x1b[\s\S]|[\s\S]/gu,on={"\r":"enter","\n":"enter","":"ctrl+c","":"ctrl+d","\x7F":"backspace","\b":"backspace"," ":"tab","\x1B":"escape","":"home","":"end","":"ctrl+u","\v":"ctrl+k","":"ctrl+w","\f":"ctrl+l","\x1B[A":"up","\x1BOA":"up","\x1B[B":"down","\x1BOB":"down","\x1B[C":"right","\x1BOC":"right","\x1B[D":"left","\x1BOD":"left","\x1B[H":"home","\x1BOH":"home","\x1B[1~":"home","\x1B[F":"end","\x1BOF":"end","\x1B[4~":"end","\x1B[3~":"delete","\x1B[5~":"pageup","\x1B[6~":"pagedown","\x1B[1;5D":"word-left","\x1B[1;3D":"word-left","\x1Bb":"word-left","\x1B[1;5C":"word-right","\x1B[1;3C":"word-right","\x1Bf":"word-right","\x1B\x7F":"ctrl+w"};function sn(e,t){let n=[],r="",o=()=>{r&&n.push({name:"text",text:r}),r=""};for(let i of e.match(rn)??[]){if(i==="\x1B[200~"){o(),t.paste="";continue}if(i==="\x1B[201~"){o(),t.paste!==null&&n.push({name:"paste",text:t.paste}),t.paste=null;continue}if(t.paste!==null){t.paste+=i;continue}let s=on[i];s?(o(),n.push({name:s})):(i.codePointAt(0)??0)>=32&&!i.startsWith("\x1B")&&i!=="\x7F"?r+=i:(o(),n.push({name:"unknown"}))}return o(),n}function Z(e){let t=process.stdin,n={paste:null},r=o=>{for(let i of sn(o.toString(),n))e(i)};return t.setRawMode?.(!0),t.resume(),t.setEncoding("utf8"),x.isTTY&&x.write(`${b}?2004h`),t.on("data",r),()=>{t.off("data",r),x.isTTY&&x.write(`${b}?2004l`),t.setRawMode?.(!1),t.pause()}}function Ge(e,t){let n=t;for(;n>0&&e[n-1]===" ";)n--;for(;n>0&&e[n-1]!==" ";)n--;return n}function an(e,t){let n=t;for(;n<e.length&&e[n]===" ";)n++;for(;n<e.length&&e[n]!==" ";)n++;return n}function ze(e){return[...e.replace(/\r\n|\r|\n/g," ").replace(/\t/g," ")].filter(t=>(t.codePointAt(0)??0)>=32&&t!=="\x7F").join("")}function cn(){if(!u.buffer.startsWith("/")||u.buffer.includes(" "))return;let e=u.buffer.toLowerCase(),t=u.commands.map(o=>o.name).filter(o=>o.startsWith(e)),n=t[0];if(!n)return;let r=n;for(let o of t)for(;!o.startsWith(r);)r=r.slice(0,-1);u.buffer=r,u.cursor=r.length}function ln(){return new Promise(e=>{let t=Gt({input:process.stdin,output:process.stdout});t.once("close",()=>e("/exit")),t.question("> ",n=>{t.removeAllListeners("close"),t.close(),e(n.trim())})})}function me(){let e=[],t=null;return{question(){return u.active?new Promise(n=>{let r=-1,o="",i=!1;u.editing=!0,u.savedValid=!0,u.buffer="",u.cursor=0,u.offset=0,x.write(ie),E();let s=()=>{i=!0,t?.(),t=null,u.editing=!1,u.buffer="",u.cursor=0,u.offset=0,x.write(u.savedValid?se:`${b}${ce()};1H`),E()},c=()=>{s(),process.emit("SIGINT"),process.exit(0)},a=(m,d)=>{u.buffer=m,u.cursor=d,E()};t=Z(m=>{if(i)return;let{buffer:d,cursor:g}=u;switch(m.name){case"enter":{let p=d.trim();p&&e[0]!==p&&e.unshift(p),e.length>100&&e.pop(),s(),n(p);return}case"ctrl+c":d?(r=-1,a("",0)):c();return;case"ctrl+d":d?a(d.slice(0,g)+d.slice(g+1),g):c();return;case"backspace":g>0&&a(d.slice(0,g-1)+d.slice(g),g-1);return;case"delete":a(d.slice(0,g)+d.slice(g+1),g);return;case"left":a(d,Math.max(0,g-1));return;case"right":a(d,Math.min(d.length,g+1));return;case"home":a(d,0);return;case"end":a(d,d.length);return;case"word-left":a(d,Ge(d,g));return;case"word-right":a(d,an(d,g));return;case"ctrl+u":a(d.slice(g),0);return;case"ctrl+k":a(d.slice(0,g),g);return;case"ctrl+w":{let p=Ge(d,g);a(d.slice(0,p)+d.slice(g),p);return}case"ctrl+l":E();return;case"tab":cn(),E();return;case"up":if(r<e.length-1){r===-1&&(o=d),r++;let p=e[r]??"";a(p,p.length)}return;case"down":if(r>=0){r--;let p=r===-1?o:e[r]??"";a(p,p.length)}return;case"text":case"paste":{let p=m.name==="paste"?ze(m.text??""):m.text??"";p&&a(d.slice(0,g)+p+d.slice(g),g+p.length);return}default:return}})}):ln()},close(){t?.(),t=null},showPrompt(){E()}}}function pe(e){if(!process.stdin.isTTY||!x.isTTY)return Promise.resolve(null);let{rows:t,cols:n}=N(),r=Math.max(3,Math.min(10,t-(u.active?ae:0)-5)),o=r+3,i=n-1,s="",c=0,a=Math.max(0,e.items.findIndex(p=>p.value===e.current)),m=()=>{let p=s.toLowerCase().split(/\s+/).filter(Boolean),y=e.items.filter(f=>{let M=(f.label+" "+(f.hint??"")).toLowerCase();return p.every(C=>M.includes(C))}),h=s.trim();return e.allowCustom&&h.includes("/")&&!e.items.some(f=>f.value===h)&&y.push({value:h,label:h,hint:"use as typed"}),y},d=()=>{let p=m();a=Math.min(a,Math.max(0,p.length-1)),a<c&&(c=a),a>=c+r&&(c=a-r+1);let y=[T.bold(v(e.title,i-16))+T.dim(` ${p.length} of ${e.items.length}`),T.dim(" search \u203A ")+v(s,i-14)+T.dim("\u258F")];for(let h=0;h<r;h++){let f=p[c+h];if(!f){y.push(h===0&&p.length===0?T.dim(" no matches"):"");continue}let M=c+h===a,C=f.value===e.current,S=v(f.label,i-6),be=i-3-S.length-(C?2:0)-2,dt=f.hint&&be>8?" "+v(f.hint,be):"";y.push((M?T.magenta(" \u203A "):" ")+(M?T.magenta.bold(S):S)+(C?T.green(" \u2713"):"")+T.dim(dt))}return y.push(T.dim(v(" \u2191\u2193 move \xB7 enter select \xB7 esc cancel \xB7 type to filter",i))),y},g=p=>{let y=d().map(h=>`${b}2K${h}
53
- `).join("");x.write((p?"":`${b}${o}A\r`)+y)};return new Promise(p=>{let y=!1,h=()=>{},f=M=>{y=!0,h(),x.write(`${b}${o}A\r${b}${o}M${b}?25h`),p(M)};x.write(b+"?25l"),g(!0),h=Z(M=>{if(y)return;let C=m(),S=()=>{a=0,c=0};switch(M.name){case"up":a=Math.max(0,a-1);break;case"down":a=Math.min(Math.max(0,C.length-1),a+1);break;case"pageup":a=Math.max(0,a-r);break;case"pagedown":a=Math.min(Math.max(0,C.length-1),a+r);break;case"home":a=0;break;case"end":a=Math.max(0,C.length-1);break;case"backspace":s=s.slice(0,-1),S();break;case"ctrl+u":s="",S();break;case"text":case"paste":s+=ze(M.text??""),S();break;case"enter":f(C[a]?.value??null);return;case"escape":case"ctrl+c":f(null);return;default:return}g(!1)})})}var l=dn,w=process.stdout,Qe=[{name:"/help",description:"show all commands"},{name:"/clear",description:"clear conversation & screen"},{name:"/memory",description:"view Agent-Termo memory"},{name:"/timeline",description:"view recent activity"},{name:"/model",description:"switch NVIDIA NIM model (or /model <id>)"},{name:"/agents",description:"list all agents"},{name:"/history",description:"show message count"},{name:"/exit",description:"quit"}];Ve(Qe);var un=/\x1b\[[0-9;?]*[A-Za-z]/g,mn=e=>e.replace(un,"").length,O=()=>l.dim("\u2500".repeat(Math.max(10,Math.min(A()-2,100))));function fe(e,t){let r=Math.max(40,Math.min(A()-2,64))-2,o=r-2,i=c=>" "+l.magenta("\u2502")+" "+c+" ".repeat(Math.max(0,o-mn(c)))+" "+l.magenta("\u2502"),s=(c,a)=>l.dim(c.padEnd(7))+l.cyan(v(a,o-7));w.write(`
54
- `),w.write(" "+l.magenta("\u256D"+"\u2500".repeat(r)+"\u256E")+`
55
- `),w.write(i(l.magenta.bold("\u273B Agent-Termo"))+`
56
- `),w.write(i(l.dim(v("AI coding agent for your terminal",o)))+`
57
- `),w.write(i("")+`
58
- `),w.write(i(s("model",t))+`
59
- `),w.write(i(s("cwd",e))+`
60
- `),w.write(" "+l.magenta("\u2570"+"\u2500".repeat(r)+"\u256F")+`
61
- `),w.write(`
62
- `),w.write(l.dim(" ")+l.cyan("/help")+l.dim(" commands \xB7 ")+l.cyan("/model")+l.dim(" switch NIM model \xB7 ")+l.cyan("Tab")+l.dim(" completes")+`
63
-
64
- `)}function W(e){return e.split(/(`[^`]+`)/).map(t=>t.length>1&&t.startsWith("`")&&t.endsWith("`")?l.cyan(t.slice(1,-1)):t.replace(/\*\*(.+?)\*\*/g,(n,r)=>l.bold(r))).join("")}var q=class{constructor(t){this.beforeFirstOutput=t}pending="";inCode=!1;first=!0;lastBlank=!1;push(t){this.pending+=t;let n=this.pending.indexOf(`
65
- `);for(;n!==-1;){let r=this.pending.slice(0,n).replace(/\r$/,"");this.pending=this.pending.slice(n+1),this.emit(r),n=this.pending.indexOf(`
66
- `)}}end(){this.pending&&this.emit(this.pending.replace(/\r$/,"")),this.pending=""}get printed(){return!this.first}emit(t){let n=t.trim()==="";if(!this.inCode&&n&&(this.first||this.lastBlank))return;this.lastBlank=n&&!this.inCode,this.first&&(this.beforeFirstOutput?.(),w.write(`
67
- `));let r=this.first?l.magenta("\u25CF "):" ";this.first=!1,w.write(n&&!this.inCode?`
68
- `:r+this.render(t)+`
69
- `)}render(t){let n=/^\s*```\s*([\w+-]*)/.exec(t);if(n)return this.inCode=!this.inCode,this.inCode?l.dim("\u250C\u2500 "+(n[1]||"code")):l.dim("\u2514\u2500");if(this.inCode)return l.dim("\u2502 ")+l.cyan(t.replace(/\t/g," "));let r=/^#{1,6}\s+(.*)$/.exec(t);if(r)return l.bold.magenta(W(r[1]??""));if(/^\s*([-*_])\1{2,}\s*$/.test(t))return l.dim("\u2500".repeat(Math.min(40,A()-4)));let o=/^(\s*)[-*+]\s+(.*)$/.exec(t);if(o)return(o[1]??"")+l.magenta("\u2022")+" "+W(o[2]??"");let i=/^(\s*)(\d+)[.)]\s+(.*)$/.exec(t);if(i)return(i[1]??"")+l.magenta(i[2]+".")+" "+W(i[3]??"");let s=/^>\s?(.*)$/.exec(t);return s?l.dim("\u258E ")+l.italic(W(s[1]??"")):W(t)}};function ge(e){let t=e.split(`
70
- `);w.write(`
63
+ `+t.slice(-1500)),o}import bn from"chalk";import tn from"chalk";import{createInterface as nn}from"node:readline";var T=tn,x=process.stdout,b="\x1B[",le="\x1B7",ue="\x1B8",de=4,rn=12,on=40,sn="Ask anything\u2026 or type / for commands",m={active:!1,editing:!1,savedValid:!0,rows:0,model:"",project:"",commands:[],buffer:"",cursor:0,offset:0};function Qe(e){m.commands=e}function N(){return{rows:x.rows||24,cols:x.columns||80}}function I(){return x.columns||80}function M(e,t){return t<=0?"":e.length<=t?e:e.slice(0,Math.max(0,t-1))+"\u2026"}function an(e){let t=process.env.HOME||process.env.USERPROFILE||"";return t&&e.startsWith(t)?"~"+e.slice(t.length):e}function cn(){return!!(x.isTTY&&process.stdin.isTTY&&(x.rows??0)>=rn&&(x.columns??0)>=on)}function ln(e){if(m.editing&&m.buffer.startsWith("/")&&!m.buffer.includes(" ")){let c=m.buffer.toLowerCase(),s=m.commands.filter(u=>u.name.startsWith(c)),d=s[0];if(s.length===1&&d)return" "+T.cyan(d.name)+T.dim(M(" \u2014 "+d.description,e-d.name.length-1));if(s.length>1)return T.cyan(M(" "+s.map(u=>u.name).join(" "),e))}let t="/help \xB7 /model \xB7 ctrl+c to exit",n=M(" "+m.model,e),o=e-n.length-t.length-2,r=o>=15,i=M(" \xB7 "+an(m.project),r?o:Math.max(0,e-n.length)),a=Math.max(1,e-n.length-i.length-t.length);return T.cyan(n)+T.dim(i+(r?" ".repeat(a)+t:""))}function H(){let{rows:e,cols:t}=N(),n=Math.max(1,t-6);m.offset=Math.min(m.offset,Math.max(0,m.buffer.length-n+1)),m.cursor<m.offset&&(m.offset=m.cursor),m.cursor>m.offset+n-1&&(m.offset=m.cursor-n+1);let o=m.editing?T.magenta:T.dim,r=m.buffer?m.buffer.slice(m.offset,m.offset+n).padEnd(n):T.dim(M(sn,n).padEnd(n)),i=e-3,a=(c,s)=>`${b}${c};1H${b}2K${s}`;return[a(i,o("\u256D"+"\u2500".repeat(t-2)+"\u256E")),a(i+1,o("\u2502")+" "+T.magenta.bold("\u276F")+" "+r+" "+o("\u2502")),a(i+2,o("\u2570"+"\u2500".repeat(t-2)+"\u256F")),a(e,ln(t-1))].join("")}function un(){let{rows:e}=N();return`${b}${e-2};${5+m.cursor-m.offset}H`}function E(){m.active&&(m.editing?x.write(b+"?25l"+H()+un()+b+"?25h"):x.write(le+H()+ue))}function me(){return Math.max(1,N().rows-de)}function pe(){x.write(`${b}1;${me()}r`)}function dn(){let{rows:e}=N();if(e===m.rows){E();return}m.rows=e,m.savedValid=!1,x.write(`${b}2J${b}H`),pe(),x.write(H()+`${b}${me()};1H`),m.editing&&E()}function fe(e){m.model=e.model,m.project=e.project,!(m.active||!cn())&&(m.active=!0,m.rows=N().rows,x.write(`${b}2J${b}H`),pe(),x.write(H()+`${b}1;1H`),x.on("resize",dn),process.on("exit",mn))}function ge(e){e.model!==void 0&&(m.model=e.model),e.project!==void 0&&(m.project=e.project),E()}function Xe(){x.write(`${b}2J${b}H`),m.active&&(pe(),x.write(H()+`${b}1;1H`))}function mn(){if(!m.active)return;m.active=!1;let{rows:e}=N(),t=Math.max(1,e-de+1),n="";for(let i=t;i<=e;i++)n+=`${b}${i};1H${b}2K`;let o=m.editing?"":le,r=m.editing&&!m.savedValid?`${b}${t};1H`:ue;x.write(o+b+"r"+n+r+b+"?25h"+b+"?2004l")}var pn=/\x1b\[200~|\x1b\[201~|\x1b\[[0-9;?]*[ -/]*[@-~]|\x1bO[A-Za-z]|\x1b[\s\S]|[\s\S]/gu,fn={"\r":"enter","\n":"enter","":"ctrl+c","":"ctrl+d","\x7F":"backspace","\b":"backspace"," ":"tab","\x1B":"escape","":"home","":"end","":"ctrl+u","\v":"ctrl+k","":"ctrl+w","\f":"ctrl+l","\x1B[A":"up","\x1BOA":"up","\x1B[B":"down","\x1BOB":"down","\x1B[C":"right","\x1BOC":"right","\x1B[D":"left","\x1BOD":"left","\x1B[H":"home","\x1BOH":"home","\x1B[1~":"home","\x1B[F":"end","\x1BOF":"end","\x1B[4~":"end","\x1B[3~":"delete","\x1B[5~":"pageup","\x1B[6~":"pagedown","\x1B[1;5D":"word-left","\x1B[1;3D":"word-left","\x1Bb":"word-left","\x1B[1;5C":"word-right","\x1B[1;3C":"word-right","\x1Bf":"word-right","\x1B\x7F":"ctrl+w"};function gn(e,t){let n=[],o="",r=()=>{o&&n.push({name:"text",text:o}),o=""};for(let i of e.match(pn)??[]){if(i==="\x1B[200~"){r(),t.paste="";continue}if(i==="\x1B[201~"){r(),t.paste!==null&&n.push({name:"paste",text:t.paste}),t.paste=null;continue}if(t.paste!==null){t.paste+=i;continue}let a=fn[i];a?(r(),n.push({name:a})):(i.codePointAt(0)??0)>=32&&!i.startsWith("\x1B")&&i!=="\x7F"?o+=i:(r(),n.push({name:"unknown"}))}return r(),n}function Z(e){let t=process.stdin,n={paste:null},o=r=>{for(let i of gn(r.toString(),n))e(i)};return t.setRawMode?.(!0),t.resume(),t.setEncoding("utf8"),x.isTTY&&x.write(`${b}?2004h`),t.on("data",o),()=>{t.off("data",o),x.isTTY&&x.write(`${b}?2004l`),t.setRawMode?.(!1),t.pause()}}function Ze(e,t){let n=t;for(;n>0&&e[n-1]===" ";)n--;for(;n>0&&e[n-1]!==" ";)n--;return n}function hn(e,t){let n=t;for(;n<e.length&&e[n]===" ";)n++;for(;n<e.length&&e[n]!==" ";)n++;return n}function et(e){return[...e.replace(/\r\n|\r|\n/g," ").replace(/\t/g," ")].filter(t=>(t.codePointAt(0)??0)>=32&&t!=="\x7F").join("")}function yn(){if(!m.buffer.startsWith("/")||m.buffer.includes(" "))return;let e=m.buffer.toLowerCase(),t=m.commands.map(r=>r.name).filter(r=>r.startsWith(e)),n=t[0];if(!n)return;let o=n;for(let r of t)for(;!r.startsWith(o);)o=o.slice(0,-1);m.buffer=o,m.cursor=o.length}function wn(){return new Promise(e=>{let t=nn({input:process.stdin,output:process.stdout});t.once("close",()=>e("/exit")),t.question("> ",n=>{t.removeAllListeners("close"),t.close(),e(n.trim())})})}function he(){let e=[],t=null;return{question(){return m.active?new Promise(n=>{let o=-1,r="",i=!1;m.editing=!0,m.savedValid=!0,m.buffer="",m.cursor=0,m.offset=0,x.write(le),E();let a=()=>{i=!0,t?.(),t=null,m.editing=!1,m.buffer="",m.cursor=0,m.offset=0,x.write(m.savedValid?ue:`${b}${me()};1H`),E()},c=()=>{a(),process.emit("SIGINT"),process.exit(0)},s=(d,u)=>{m.buffer=d,m.cursor=u,E()};t=Z(d=>{if(i)return;let{buffer:u,cursor:g}=m;switch(d.name){case"enter":{let p=u.trim();p&&e[0]!==p&&e.unshift(p),e.length>100&&e.pop(),a(),n(p);return}case"ctrl+c":u?(o=-1,s("",0)):c();return;case"ctrl+d":u?s(u.slice(0,g)+u.slice(g+1),g):c();return;case"backspace":g>0&&s(u.slice(0,g-1)+u.slice(g),g-1);return;case"delete":s(u.slice(0,g)+u.slice(g+1),g);return;case"left":s(u,Math.max(0,g-1));return;case"right":s(u,Math.min(u.length,g+1));return;case"home":s(u,0);return;case"end":s(u,u.length);return;case"word-left":s(u,Ze(u,g));return;case"word-right":s(u,hn(u,g));return;case"ctrl+u":s(u.slice(g),0);return;case"ctrl+k":s(u.slice(0,g),g);return;case"ctrl+w":{let p=Ze(u,g);s(u.slice(0,p)+u.slice(g),p);return}case"ctrl+l":E();return;case"tab":yn(),E();return;case"up":if(o<e.length-1){o===-1&&(r=u),o++;let p=e[o]??"";s(p,p.length)}return;case"down":if(o>=0){o--;let p=o===-1?r:e[o]??"";s(p,p.length)}return;case"text":case"paste":{let p=d.name==="paste"?et(d.text??""):d.text??"";p&&s(u.slice(0,g)+p+u.slice(g),g+p.length);return}default:return}})}):wn()},close(){t?.(),t=null},showPrompt(){E()}}}function ye(e){if(!process.stdin.isTTY||!x.isTTY)return Promise.resolve(null);let{rows:t,cols:n}=N(),o=Math.max(3,Math.min(10,t-(m.active?de:0)-5)),r=o+3,i=n-1,a="",c=0,s=Math.max(0,e.items.findIndex(p=>p.value===e.current)),d=()=>{let p=a.toLowerCase().split(/\s+/).filter(Boolean),w=e.items.filter(f=>{let v=(f.label+" "+(f.hint??"")).toLowerCase();return p.every(A=>v.includes(A))}),y=a.trim();return e.allowCustom&&y.includes("/")&&!e.items.some(f=>f.value===y)&&w.push({value:y,label:y,hint:"use as typed"}),w},u=()=>{let p=d();s=Math.min(s,Math.max(0,p.length-1)),s<c&&(c=s),s>=c+o&&(c=s-o+1);let w=[T.bold(M(e.title,i-16))+T.dim(` ${p.length} of ${e.items.length}`),T.dim(" search \u203A ")+M(a,i-14)+T.dim("\u258F")];for(let y=0;y<o;y++){let f=p[c+y];if(!f){w.push(y===0&&p.length===0?T.dim(" no matches"):"");continue}let v=c+y===s,A=f.value===e.current,D=M(f.label,i-6),Te=i-3-D.length-(A?2:0)-2,ft=f.hint&&Te>8?" "+M(f.hint,Te):"";w.push((v?T.magenta(" \u203A "):" ")+(v?T.magenta.bold(D):D)+(A?T.green(" \u2713"):"")+T.dim(ft))}return w.push(T.dim(M(" \u2191\u2193 move \xB7 enter select \xB7 esc cancel \xB7 type to filter",i))),w},g=p=>{let w=u().map(y=>`${b}2K${y}
64
+ `).join("");x.write((p?"":`${b}${r}A\r`)+w)};return new Promise(p=>{let w=!1,y=()=>{},f=v=>{w=!0,y(),x.write(`${b}${r}A\r${b}${r}M${b}?25h`),p(v)};x.write(b+"?25l"),g(!0),y=Z(v=>{if(w)return;let A=d(),D=()=>{s=0,c=0};switch(v.name){case"up":s=Math.max(0,s-1);break;case"down":s=Math.min(Math.max(0,A.length-1),s+1);break;case"pageup":s=Math.max(0,s-o);break;case"pagedown":s=Math.min(Math.max(0,A.length-1),s+o);break;case"home":s=0;break;case"end":s=Math.max(0,A.length-1);break;case"backspace":a=a.slice(0,-1),D();break;case"ctrl+u":a="",D();break;case"text":case"paste":a+=et(v.text??""),D();break;case"enter":f(A[s]?.value??null);return;case"escape":case"ctrl+c":f(null);return;default:return}g(!1)})})}var l=bn,h=process.stdout,nt=[{name:"/help",description:"show all commands"},{name:"/clear",description:"clear conversation & screen"},{name:"/memory",description:"view Agent-Termo memory"},{name:"/timeline",description:"view recent activity"},{name:"/model",description:"switch NVIDIA NIM model (or /model <id>)"},{name:"/agents",description:"list all agents"},{name:"/history",description:"show message count"},{name:"/exit",description:"quit"}];Qe(nt);var xn=/\x1b\[[0-9;?]*[A-Za-z]/g,vn=e=>e.replace(xn,"").length,R=()=>l.dim("\u2500".repeat(Math.max(10,Math.min(I()-2,100))));function we(e,t){let o=Math.max(40,Math.min(I()-2,64))-2,r=o-2,i=c=>" "+l.magenta("\u2502")+" "+c+" ".repeat(Math.max(0,r-vn(c)))+" "+l.magenta("\u2502"),a=(c,s)=>l.dim(c.padEnd(7))+l.cyan(M(s,r-7));h.write(`
65
+ `),h.write(" "+l.magenta("\u256D"+"\u2500".repeat(o)+"\u256E")+`
66
+ `),h.write(i(l.magenta.bold("\u273B Agent-Termo"))+`
67
+ `),h.write(i(l.dim(M("AI coding agent for your terminal",r)))+`
68
+ `),h.write(i("")+`
69
+ `),h.write(i(a("model",t))+`
70
+ `),h.write(i(a("cwd",e))+`
71
+ `),h.write(" "+l.magenta("\u2570"+"\u2500".repeat(o)+"\u256F")+`
72
+ `),h.write(`
73
+ `),h.write(l.dim(" ")+l.cyan("/help")+l.dim(" commands \xB7 ")+l.cyan("/model")+l.dim(" switch NIM model \xB7 ")+l.cyan("Tab")+l.dim(" completes")+`
74
+
75
+ `)}function Y(e){return e.split(/(`[^`]+`)/).map(t=>t.length>1&&t.startsWith("`")&&t.endsWith("`")?l.cyan(t.slice(1,-1)):t.replace(/\*\*(.+?)\*\*/g,(n,o)=>l.bold(o))).join("")}var B=class{constructor(t){this.beforeFirstOutput=t}pending="";inCode=!1;first=!0;lastBlank=!1;push(t){this.pending+=t;let n=this.pending.indexOf(`
76
+ `);for(;n!==-1;){let o=this.pending.slice(0,n).replace(/\r$/,"");this.pending=this.pending.slice(n+1),this.emit(o),n=this.pending.indexOf(`
77
+ `)}}end(){this.pending&&this.emit(this.pending.replace(/\r$/,"")),this.pending=""}get printed(){return!this.first}emit(t){let n=t.trim()==="";if(!this.inCode&&n&&(this.first||this.lastBlank))return;this.lastBlank=n&&!this.inCode,this.first&&(this.beforeFirstOutput?.(),h.write(`
78
+ `));let o=this.first?l.magenta("\u25CF "):" ";this.first=!1,h.write(n&&!this.inCode?`
79
+ `:o+this.render(t)+`
80
+ `)}render(t){let n=/^\s*```\s*([\w+-]*)/.exec(t);if(n)return this.inCode=!this.inCode,this.inCode?l.dim("\u250C\u2500 "+(n[1]||"code")):l.dim("\u2514\u2500");if(this.inCode)return l.dim("\u2502 ")+l.cyan(t.replace(/\t/g," "));let o=/^#{1,6}\s+(.*)$/.exec(t);if(o)return l.bold.magenta(Y(o[1]??""));if(/^\s*([-*_])\1{2,}\s*$/.test(t))return l.dim("\u2500".repeat(Math.min(40,I()-4)));let r=/^(\s*)[-*+]\s+(.*)$/.exec(t);if(r)return(r[1]??"")+l.magenta("\u2022")+" "+Y(r[2]??"");let i=/^(\s*)(\d+)[.)]\s+(.*)$/.exec(t);if(i)return(i[1]??"")+l.magenta(i[2]+".")+" "+Y(i[3]??"");let a=/^>\s?(.*)$/.exec(t);return a?l.dim("\u258E ")+l.italic(Y(a[1]??"")):Y(t)}};function be(e){let t=e.split(`
81
+ `);h.write(`
71
82
  `+l.green.bold("\u276F ")+l.bold(t[0]??"")+`
72
- `);for(let n of t.slice(1))w.write(" "+l.bold(n)+`
73
- `)}function P(e){let t=new q;t.push(e),t.end()}function Xe(e,t){let n=Object.entries(t).map(([o,i])=>{let s=typeof i=="string"?i:JSON.stringify(i);return o+"="+v(String(s??"").replace(/\s+/g," "),40)}).join(", "),r=A()-e.length-6;w.write(`
74
- `+l.blue("\u25CF ")+l.bold(e)+l.dim("("+v(n,r)+")")+`
75
- `)}function he(e,t,n){if(n?.needsApproval&&n.proposedChange){pn(n.proposedChange);return}let r=A()-8;if(t.success){let o=(t.output??"").split(`
76
- `).filter(s=>s.trim()!==""),i=o.length>1?`${o.length} lines`:v((o[0]??"").trim()||"done",r);w.write(l.dim(" \u23BF ")+l.green("\u2713 ")+i+`
77
- `)}else{let o=(t.error??"unknown error").split(`
78
- `)[0]??"unknown error";w.write(l.dim(" \u23BF ")+l.red("\u2717 "+v(`${e}: ${o}`,r))+`
79
- `)}}function pn(e){let t=e.diff,n=Math.max(20,A()-14),r=e.isDeletion?l.red("DELETE"):e.isNewFile?l.green("NEW"):l.blue("MODIFY");w.write(`
80
- `+l.bold.cyan(t.file)+" "+r+" "+l.green("+"+t.additions)+" "+l.red("-"+t.deletions)+`
81
- `),w.write(" "+l.dim("\u2500".repeat(Math.max(10,Math.min(A()-4,100))))+`
82
- `);for(let o of t.lines){let i=o.type==="add"?"+":o.type==="remove"?"-":" ",s=o.type==="add"?l.green:o.type==="remove"?l.red:l.dim,c=o.lineNumber>0?String(o.lineNumber).padStart(4):" ",a=v(o.content.replace(/\t/g," "),n);w.write(" "+s(i+c+" \u2502 "+a)+`
83
- `)}w.write(`
84
- `)}function et(e="Accept this change?"){return w.write(`
85
- `+l.yellow("? ")+l.bold(e)+l.dim(" [")+l.green("Y")+l.dim("/")+l.red("n")+l.dim("] ")),new Promise(t=>{let n=!1,r=()=>{},o=i=>{n=!0,r(),w.write(i===!0?l.green("yes")+`
83
+ `);for(let n of t.slice(1))h.write(" "+l.bold(n)+`
84
+ `)}function P(e){let t=new B;t.push(e),t.end()}function rt(e,t){let n=Object.entries(t).map(([r,i])=>{let a=typeof i=="string"?i:JSON.stringify(i);return r+"="+M(String(a??"").replace(/\s+/g," "),40)}).join(", "),o=I()-e.length-6;h.write(`
85
+ `+l.blue("\u25CF ")+l.bold(e)+l.dim("("+M(n,o)+")")+`
86
+ `)}function xe(e,t,n){if(n?.needsApproval&&n.proposedChange){Mn(n.proposedChange);return}let o=I()-8;if(t.success){let r=(t.output??"").split(`
87
+ `).filter(a=>a.trim()!==""),i=r.length>1?`${r.length} lines`:M((r[0]??"").trim()||"done",o);h.write(l.dim(" \u23BF ")+l.green("\u2713 ")+i+`
88
+ `)}else{let r=(t.error??"unknown error").split(`
89
+ `)[0]??"unknown error";h.write(l.dim(" \u23BF ")+l.red("\u2717 "+M(`${e}: ${r}`,o))+`
90
+ `)}}function Mn(e){let t=e.diff,n=Math.max(20,I()-14),o=e.isDeletion?l.red("DELETE"):e.isNewFile?l.green("NEW"):l.blue("MODIFY");h.write(`
91
+ `+l.bold.cyan(t.file)+" "+o+" "+l.green("+"+t.additions)+" "+l.red("-"+t.deletions)+`
92
+ `),h.write(" "+l.dim("\u2500".repeat(Math.max(10,Math.min(I()-4,100))))+`
93
+ `);for(let r of t.lines){let i=r.type==="add"?"+":r.type==="remove"?"-":" ",a=r.type==="add"?l.green:r.type==="remove"?l.red:l.dim,c=r.lineNumber>0?String(r.lineNumber).padStart(4):" ",s=M(r.content.replace(/\t/g," "),n);h.write(" "+a(i+c+" \u2502 "+s)+`
94
+ `)}h.write(`
95
+ `)}function ot(e="Accept this change?"){return h.write(`
96
+ `+l.yellow("? ")+l.bold(e)+l.dim(" [")+l.green("Y")+l.dim("/")+l.red("n")+l.dim("] ")),new Promise(t=>{let n=!1,o=()=>{},r=i=>{n=!0,o(),h.write(i===!0?l.green("yes")+`
86
97
  `:i===!1?l.red("no")+`
87
98
  `:l.red("cancelled")+`
88
- `),t(i===!0?"accept":"reject")};r=Z(i=>{if(n)return;let s=i.text?.[0]?.toLowerCase();i.name==="enter"||s==="y"?o(!0):i.name==="escape"||s==="n"?o(!1):i.name==="ctrl+c"&&o("cancelled")})})}function _(e,t){w.write(`
99
+ `),t(i===!0?"accept":"reject")};o=Z(i=>{if(n)return;let a=i.text?.[0]?.toLowerCase();i.name==="enter"||a==="y"?r(!0):i.name==="escape"||a==="n"?r(!1):i.name==="ctrl+c"&&r("cancelled")})})}function L(e,t){h.write(`
89
100
  `+l.red("\u2717 "+e)+`
90
- `),t&&w.write(l.dim(" Hint: "+t)+`
91
- `)}function H(e){w.write(l.green("\u2713 "+e)+`
92
- `)}function k(e){w.write(l.blue("\u2139 ")+e+`
93
- `)}async function tt(){let e=Ke();if(!e){k("Agent-Termo memory is empty. (Normal for new sessions.)");return}w.write(`
101
+ `),t&&h.write(l.dim(" Hint: "+t)+`
102
+ `)}function G(e){h.write(l.green("\u2713 "+e)+`
103
+ `)}function S(e){h.write(l.blue("\u2139 ")+e+`
104
+ `)}async function it(){let e=Ye();if(!e){S("Agent-Termo memory is empty. (Normal for new sessions.)");return}h.write(`
94
105
  `+l.bold("Agent-Termo memory")+`
95
- `+O()+`
106
+ `+R()+`
96
107
  `+e+`
97
- `+O()+`
108
+ `+R()+`
98
109
 
99
- `)}async function nt(){let e=We();if(!e||e.trim().length===0){k("Timeline is empty.");return}let t=e.split(`
100
- `),n=Math.min(40,t.length);w.write(`
110
+ `)}async function st(){let e=Be();if(!e||e.trim().length===0){S("Timeline is empty.");return}let t=e.split(`
111
+ `),n=Math.min(40,t.length);h.write(`
101
112
  `+l.bold("Agent-Termo timeline")+l.dim(" (recent entries)")+`
102
- `+O()+`
103
- `),w.write(t.slice(-n).join(`
113
+ `+R()+`
114
+ `),h.write(t.slice(-n).join(`
104
115
  `)+`
105
- `+O()+`
106
- `),t.length>n&&w.write(l.dim("\u2026 "+(t.length-n)+" earlier entries hidden")+`
107
- `),w.write(`
108
- `)}function rt(){w.write(`
116
+ `+R()+`
117
+ `),t.length>n&&h.write(l.dim("\u2026 "+(t.length-n)+" earlier entries hidden")+`
118
+ `),h.write(`
119
+ `)}function at(){h.write(`
109
120
  `+l.bold("Commands")+`
110
- `+O()+`
111
- `);for(let t of Qe)w.write(" "+l.cyan(t.name.padEnd(11))+l.dim(t.description)+`
112
- `);w.write(`
121
+ `+R()+`
122
+ `);for(let t of nt)h.write(" "+l.cyan(t.name.padEnd(11))+l.dim(t.description)+`
123
+ `);h.write(`
113
124
  `+l.bold("Keys")+`
114
- `+O()+`
115
- `);let e=[["\u2191 / \u2193","input history"],["Tab","complete a /command"],["Ctrl+A / Ctrl+E","start / end of line"],["Ctrl+W / Ctrl+U","delete word / to line start"],["Ctrl+C","clear the line, or quit when empty"]];for(let[t,n]of e)w.write(" "+l.cyan(t.padEnd(17))+l.dim(n)+`
116
- `);w.write(`
117
- `)}function ot(e){w.write(`
125
+ `+R()+`
126
+ `);let e=[["\u2191 / \u2193","input history"],["Tab","complete a /command"],["Ctrl+A / Ctrl+E","start / end of line"],["Ctrl+W / Ctrl+U","delete word / to line start"],["Ctrl+C","clear the line, or quit when empty"]];for(let[t,n]of e)h.write(" "+l.cyan(t.padEnd(17))+l.dim(n)+`
127
+ `);h.write(`
128
+ `)}function ct(e){h.write(`
118
129
  `+l.bold("Available agents")+`
119
- `+O()+`
120
- `);let t=Math.max(10,A()-34);for(let n of e)w.write(" "+l.cyan(n.name.padEnd(30))+l.dim(v(n.description.replace(/\s+/g," "),t))+`
121
- `);w.write(`
122
- `)}var Ze=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Q=null;function D(e){if(I(),!w.isTTY){w.write(l.dim(e+"\u2026")+`
123
- `);return}let t=Date.now(),n=0,r=v(e,Math.max(10,A()-14)),o=()=>{let i=Math.floor((Date.now()-t)/1e3);w.write("\r\x1B[2K"+l.magenta(Ze[n++%Ze.length]??"\u280B")+" "+l.dim(`${r}\u2026 ${i}s`))};w.write("\x1B[?25l"),o(),Q=setInterval(o,80)}function I(e){Q&&(clearInterval(Q),Q=null,w.write("\r\x1B[2K\x1B[?25h"))}function it(){Je()}var fn=["build","create","write","edit","modify","file","code","function","class","component","debug","fix","git","commit","push","install","npm","run","bash","shell","command","read","grep","check","show","implement","configure","setup","src","package","app","project","api","deploy","test","compile","typescript","javascript","python","node","add","delete"],gn=["qwen/qwen2.5-coder-32b-instruct","moonshotai/kimi-k2-instruct","meta/llama-3.1-405b-instruct"];function hn(e){let t=e.toLowerCase();return fn.some(n=>t.includes(n))}function we(e){let t=new Set;return e.filter(n=>t.has(n.id)?!1:(t.add(n.id),!0))}async function at(e,t,n){for(let r of gn)if(r!==n)try{t.setModel(r);let o=t.buildToolDefs(B);return await t.complete(e,o)}catch{}return t.setModel(n),null}async function wn(e,t){D("Thinking");let n=new q(()=>I());try{await t.streamComplete(e,void 0,o=>n.push(o)).next(),n.end(),I();return}catch{n.end(),I()}D("Retrying");try{let r=await t.complete(e,void 0);I();let o=(r.content??"").trim();o&&(e.push({id:crypto.randomUUID(),role:"assistant",content:o,timestamp:new Date}),P(o))}catch(r){I(),_("LLM error: "+(r instanceof Error?r.message:String(r)))}}function yn(e,t){if(e==="file:write"||e==="file:edit")try{let r=JSON.parse(t);if(r?.needsApproval&&r?.proposedChange)return r.proposedChange}catch{}}async function bn(e){try{let{exec:t}=await import("node:child_process"),{promisify:n}=await import("node:util"),{mkdtemp:r,writeFile:o}=await import("node:fs/promises"),{basename:i}=await import("node:path"),{tmpdir:s}=await import("node:os"),c=n(t),a=e.path,m=await r(s()+"/agent-termo-diff-"),d=m+"/"+i(a);if(await o(d,e.proposedContent,"utf-8"),!e.isNewFile&&e.originalContent.length>0){let g=m+"/original-"+i(a);await o(g,e.originalContent,"utf-8"),c(`code --diff "${g}" "${d}" --wait`).catch(()=>{})}else c(`code "${d}" --wait`).catch(()=>{})}catch{}}async function xn(e,t,n,r){Xe(e,t),D("Running "+e);let o=await _e(e,t,n);I(o.success);let i=yn(e,o.output??"");if(i){r.close(),he(e,{success:o.success,output:o.output,error:o.error},{needsApproval:!0,proposedChange:i}),bn(i);let s=await et("Accept this change?");if(r.showPrompt(),s==="accept"){D("Writing to disk");let c=await $e(i,n);return I(c.success),c.success?(H(c.output??"Change applied"),{toolResult:c,change:i,applied:!0}):(_(c.error??"Failed to apply change"),{toolResult:c,change:i,applied:!1})}else return k("Change rejected \u2014 file was not modified"),{toolResult:o,change:i,applied:!1}}return he(e,o),{toolResult:o,applied:!1}}async function st(e,t,n,r,o){let i=n,s="";for(;i.length>0;){for(let a of i){let m=await xn(a.name,a.arguments,t,r),d=m.toolResult,g=d.success?"OK":"ERR: "+(d.error?d.error.slice(0,80):"unknown error"),p=m.change?m.applied?" (applied)":" (rejected)":"";e.push({id:crypto.randomUUID(),role:"tool",content:(d.success?"Result: ":"Error: ")+(d.success?d.output??"":d.error)+p,timestamp:new Date}),U(t,"Tool: "+a.name+" -- "+g+p),j("Tool: "+a.name+" -- "+g+p)}D("Working");let c;try{let a=o.buildToolDefs(B);c=await o.complete(e,a)}catch{let a=o.getModel();try{c=await at(e,o,a)}finally{o.setModel(a)}if(!c){I(),_("LLM error: no tool-capable model available");break}}I(),s=c.content,i=we(c.toolCalls),s&&s.trim()&&s.trim()!=="null"&&(e.push({id:crypto.randomUUID(),role:"assistant",content:s.trim(),timestamp:new Date}),i.length>0&&P(s.trim()))}return s}async function Mn(e,t,n){let r=e||null;if(!r){D("Fetching NVIDIA NIM models");let{models:o,live:i,error:s}=await t.listModels();if(I(),i||k("Could not fetch the live model list ("+(s??"unknown error")+"). Showing built-in suggestions; you can type any model ID."),r=await pe({title:"Select a model",items:o.map(c=>({value:c.id,label:c.id,hint:c.note})),current:t.getModel(),allowCustom:!0}),!r){k("Model unchanged: "+t.getModel());return}}if(r===t.getModel()){k("Already using "+r);return}t.setModel(r),ue({model:r}),j("Model switched to "+r),U(n,"Model switched to "+r);try{Ae(r),H("Model set to "+r+" (saved as your default)")}catch{H("Model set to "+r+" for this session"),k("Could not save it as your default.")}}async function ct(e){e=Pe(e);let t=await qe(e),n=new Y(e),r=Be(t,"",e),o={id:crypto.randomUUID(),projectRoot:e,startedAt:new Date},i=[{id:crypto.randomUUID(),role:"system",content:r,timestamp:new Date}];de({model:n.getModel(),project:e}),fe(e,n.getModel()),j("Agent-Termo session started. Model: "+n.getModel()),U(e,"Agent-Termo session started. Model: "+n.getModel()),j("Commands: /help /clear /memory /timeline /model /agents /history"),U(e,"Commands: /help /clear /memory /timeline /model /agents /history");let s=me(),c=()=>{s.close(),process.stdout.write(`
124
- `),console.log("Session complete. "+Math.round((Date.now()-o.startedAt.getTime())/6e4)+" minutes."),process.exit(0)};process.on("SIGINT",c);e:for(;;)try{let a=await s.question("");if(!a)continue;if(a==="exit"||a==="quit"){c();break}if(a.startsWith("/")){let p=a.toLowerCase().trim();if(ge(a),p==="/help"||p==="/"){rt();continue e}if(p==="/clear"||p==="/cls"){i.length=1,it(),fe(e,n.getModel()),H("Conversation cleared.");continue e}if(p==="/memory"){await tt();continue e}if(p==="/timeline"||p==="/tl"){await nt();continue e}if(p==="/model"||p.startsWith("/model ")){await Mn(a.trim().slice(6).trim(),n,e);continue e}if(p==="/agents"){let y=Ye(process.env.AGENT_TERMO_DIR||".claude");ot(y);continue e}if(p==="/history"||p==="/hist"){k("Conversation (excluding system): "+(i.length-1)+" messages");continue e}if(p==="/exit"||p==="/quit"){c();break}_("Unknown command: "+p,"Type /help for available commands.");continue e}let m={id:crypto.randomUUID(),role:"user",content:a,timestamp:new Date};i.push(m),ge(a);let d=hn(a),g=d?n.buildToolDefs(B):void 0;if(d){D("Working");try{let p=await n.complete(i,g),y=p.content,h=we(p.toolCalls);if(I(),h.length===0){let f=(y??"").trim().replace(/^null$/,"").trim();f&&(i.push({id:crypto.randomUUID(),role:"assistant",content:f,timestamp:new Date}),P(f))}else{let f=(y??"").trim().replace(/^null$/,"").trim();f&&P(f);let M=await st(i,e,h,s,n);M&&M.trim()&&M.trim()!=="null"&&P(M.trim())}}catch{I();let y=n.getModel(),h=null;try{h=await at(i,n,y)}finally{n.setModel(y)}if(!h){i.pop();continue e}let f=h.content,M=we(h.toolCalls);if(f&&f.trim()&&f.trim()!=="null"&&i.push({id:crypto.randomUUID(),role:"assistant",content:f.trim(),timestamp:new Date}),M.length>0){let C=f.trim().replace(/^null$/,"").trim();C&&P(C);let S=await st(i,e,M,s,n);S&&S.trim()&&S.trim()!=="null"&&P(S.trim())}else f&&f.trim()&&P(f.trim())}}else await wn(i,n);i.length>42&&i.splice(1,i.length-42)}catch(a){I(),_("Session error: "+(a instanceof Error?a.message:String(a)))}}var ye=new vn;async function Tn(){let e=process.stdin,t=process.stdout;if(!e.isTTY||typeof e.setRawMode!="function")throw new Error("NVIDIA NIM API key is missing. Run Agent-Termo in an interactive terminal or set NIM_API_KEY before starting.");return console.log("An NVIDIA NIM API key is required to start Agent-Termo."),console.log("Get your key at https://build.nvidia.com/"),t.write("Enter your API key (input hidden): "),new Promise((n,r)=>{let o="",i=!1,s=()=>{e.off("data",c),e.setRawMode(!1),e.pause(),t.write(`
125
- `)},c=a=>{for(let m of a.toString("utf-8")){if(m===`
126
- `&&i){i=!1;continue}if(i=m==="\r",m===""||m===""){s(),r(new Error("API key setup cancelled."));return}if(m==="\r"||m===`
127
- `){if(!o.trim()){t.write(`
128
- An API key is required. Enter your API key: `);continue}s(),n(o.trim());return}m==="\x7F"||m==="\b"?o=o.slice(0,-1):m>=" "&&(o+=m)}};e.setRawMode(!0),e.resume(),e.on("data",c)})}async function lt(e,t){if(t.apiKey&&(process.env.NIM_API_KEY=t.apiKey),t.model&&(process.env.NIM_MODEL=t.model),t.debug&&(process.env.LOG_LEVEL="debug"),!process.env.NIM_API_KEY?.trim()){let n=await Tn();Se(n),process.env.NIM_API_KEY=n,console.log("API key saved. Agent-Termo will remember it for future sessions.")}console.log(`Starting Agent-Termo in: ${e}`),await ct(e)}ye.name("agent-termo").description("Terminal AI coding agent with Nvidia NIM APIs").version("1.0.2").argument("[project]","Project directory to operate in",process.cwd()).option("-k, --api-key <key>","Nvidia NIM API key").option("-m, --model <model>","Model name to use").option("--debug","Enable debug logging").action(async(e,t)=>{await lt(e,t)});ye.command("init").description("Initialize Agent-Termo in a project directory").argument("[dir]","Directory to initialize",".").action(async e=>{let{mkdirSync:t,writeFileSync:n,existsSync:r}=await import("node:fs"),{resolve:o}=await import("node:path"),i=[o(e,"docs"),o(e,".claude","agents"),o(e,"src")];for(let a of i)t(a,{recursive:!0});let s=o(e,"docs","MEMORY.md");r(s)||n(s,`# Project Memory
130
+ `+R()+`
131
+ `);let t=Math.max(10,I()-34);for(let n of e)h.write(" "+l.cyan(n.name.padEnd(30))+l.dim(M(n.description.replace(/\s+/g," "),t))+`
132
+ `);h.write(`
133
+ `)}var tt=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Q=null;function k(e){if(C(),!h.isTTY){h.write(l.dim(e+"\u2026")+`
134
+ `);return}let t=Date.now(),n=0,o=M(e,Math.max(10,I()-14)),r=()=>{let i=Math.floor((Date.now()-t)/1e3);h.write("\r\x1B[2K"+l.magenta(tt[n++%tt.length]??"\u280B")+" "+l.dim(`${o}\u2026 ${i}s`))};h.write("\x1B[?25l"),r(),Q=setInterval(r,80)}function C(e){Q&&(clearInterval(Q),Q=null,h.write("\r\x1B[2K\x1B[?25h"))}function lt(){Xe()}var Tn=["build","create","write","edit","modify","file","code","function","class","component","debug","fix","git","commit","push","install","npm","run","bash","shell","command","read","grep","check","show","implement","configure","setup","src","package","app","project","api","deploy","test","compile","typescript","javascript","python","node","add","delete"];function Cn(e){let t=e.toLowerCase();return Tn.some(n=>t.includes(n))}function ve(e){let t=new Set;return e.filter(n=>t.has(n.id)?!1:(t.add(n.id),!0))}async function In(e,t){k("Thinking");let n=new B(()=>C());try{await t.streamComplete(e,void 0,r=>n.push(r)).next(),n.end(),C();return}catch{n.end(),C()}k("Retrying");try{let o=await t.complete(e,void 0);C();let r=(o.content??"").trim();r&&(e.push({id:crypto.randomUUID(),role:"assistant",content:r,timestamp:new Date}),P(r))}catch(o){C(),L("LLM error: "+(o instanceof Error?o.message:String(o)))}}function dt(e){let t=(e??"").trim();t=t.replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/i,"").trim();let n;try{n=JSON.parse(t)}catch{let r=t.indexOf("{"),i=t.lastIndexOf("}");if(r===-1||i===-1||i<=r)return[];try{n=JSON.parse(t.slice(r,i+1))}catch{return[]}}return(Array.isArray(n.tool_calls)?n.tool_calls:[]).map(r=>({id:r.id??crypto.randomUUID(),name:U(r.name??r.function?.name??""),arguments:typeof r.function?.arguments=="string"?(()=>{try{return JSON.parse(r.function.arguments)}catch{return{_raw:r.function.arguments}}})():r.function?.arguments??{}}))}function Sn(e,t){if(e==="file:write"||e==="file:edit"||e==="file:delete")try{let o=JSON.parse(t);if(o?.needsApproval&&o?.proposedChange)return o.proposedChange}catch{}}async function An(e){try{let{exec:t}=await import("node:child_process"),{promisify:n}=await import("node:util"),{mkdtemp:o,writeFile:r}=await import("node:fs/promises"),{basename:i}=await import("node:path"),{tmpdir:a}=await import("node:os"),c=n(t),s=e.path,d=await o(a()+"/agent-termo-diff-"),u=d+"/"+i(s);if(await r(u,e.proposedContent,"utf-8"),!e.isNewFile&&e.originalContent.length>0){let g=d+"/original-"+i(s);await r(g,e.originalContent,"utf-8"),c(`code --diff "${g}" "${u}" --wait`).catch(()=>{})}else c(`code "${u}" --wait`).catch(()=>{})}catch{}}async function En(e,t,n,o){rt(e,t),k("Running "+e);let r=await Fe(e,t,n);C(r.success);let i=Sn(e,r.output??"");if(i){o.close(),xe(e,{success:r.success,output:r.output,error:r.error},{needsApproval:!0,proposedChange:i}),An(i);let a=await ot("Accept this change?");if(o.showPrompt(),a==="accept"){k("Writing to disk");let c=await $e(i,n);return C(c.success),c.success?(G(c.output??"Change applied"),{toolResult:c,change:i,applied:!0}):(L(c.error??"Failed to apply change"),{toolResult:c,change:i,applied:!1})}else return S("Change rejected \u2014 file was not modified"),{toolResult:r,change:i,applied:!1}}return xe(e,r),{toolResult:r,applied:!1}}async function ut(e,t,n,o,r){let i=n,a="";for(;i.length>0;){e.push({id:crypto.randomUUID(),role:"assistant",content:a||"",toolCalls:i,timestamp:new Date});for(let s of i){let d=await En(s.name,s.arguments,t,o),u=d.toolResult,g=u.success?"OK":"ERR: "+(u.error?u.error.slice(0,80):"unknown error"),p=d.change?d.applied?" (applied)":" (rejected)":"";e.push({id:s.id,role:"tool",content:(u.success?"Result: ":"Error: ")+(u.success?u.output??"":u.error)+p,timestamp:new Date}),q(t,"Tool: "+s.name+" -- "+g+p),K("Tool: "+s.name+" -- "+g+p)}k("Working");let c;try{let s=r.buildToolDefs(te);c=await r.complete(e,s)}catch{try{let s=await r.complete(e,void 0);c={content:s.content,toolCalls:dt(s.content)}}catch(s){C(),L("LLM error: "+(s instanceof Error?s.message:String(s)));break}}C(),a=c.content,i=ve(c.toolCalls),a&&a.trim()&&a.trim()!=="null"&&(i.length===0&&e.push({id:crypto.randomUUID(),role:"assistant",content:a.trim(),timestamp:new Date}),i.length>0&&P(a.trim()))}return a}async function Pn(e,t,n){let o=e||null;if(!o){k("Fetching NVIDIA NIM models");let{models:r,live:i,error:a}=await t.listModels();if(C(),i||S("Could not fetch the live model list ("+(a??"unknown error")+"). Showing built-in suggestions; you can type any model ID."),o=await ye({title:"Select a model",items:r.map(c=>({value:c.id,label:c.id,hint:c.note})),current:t.getModel(),allowCustom:!0}),!o){S("Model unchanged: "+t.getModel());return}}if(o===t.getModel()){S("Already using "+o);return}t.setModel(o),ge({model:o}),K("Model switched to "+o),q(n,"Model switched to "+o);try{_e(o),G("Model set to "+o+" (saved as your default)")}catch{G("Model set to "+o+" for this session"),S("Could not save it as your default.")}}async function mt(e){e=Ne(e);let t=await Ge(e),n=new J(e),o=ze(t,"",e),r={id:crypto.randomUUID(),projectRoot:e,startedAt:new Date},i=[{id:crypto.randomUUID(),role:"system",content:o,timestamp:new Date}];fe({model:n.getModel(),project:e}),we(e,n.getModel()),K("Agent-Termo session started. Model: "+n.getModel()),q(e,"Agent-Termo session started. Model: "+n.getModel()),K("Commands: /help /clear /memory /timeline /model /agents /history"),q(e,"Commands: /help /clear /memory /timeline /model /agents /history");let a=he(),c=()=>{a.close(),process.stdout.write(`
135
+ `),console.log("Session complete. "+Math.round((Date.now()-r.startedAt.getTime())/6e4)+" minutes."),process.exit(0)};process.on("SIGINT",c);e:for(;;)try{let s=await a.question("");if(!s)continue;if(s==="exit"||s==="quit"){c();break}if(s.startsWith("/")){let p=s.toLowerCase().trim();if(be(s),p==="/help"||p==="/"){at();continue e}if(p==="/clear"||p==="/cls"){i.length=1,lt(),we(e,n.getModel()),G("Conversation cleared.");continue e}if(p==="/memory"){await it();continue e}if(p==="/timeline"||p==="/tl"){await st();continue e}if(p==="/model"||p.startsWith("/model ")){await Pn(s.trim().slice(6).trim(),n,e);continue e}if(p==="/agents"){let w=Ve(process.env.AGENT_TERMO_DIR||".claude");ct(w);continue e}if(p==="/history"||p==="/hist"){S("Conversation (excluding system): "+(i.length-1)+" messages");continue e}if(p==="/exit"||p==="/quit"){c();break}L("Unknown command: "+p,"Type /help for available commands.");continue e}let d={id:crypto.randomUUID(),role:"user",content:s,timestamp:new Date};i.push(d),be(s);let u=Cn(s),g=u?n.buildToolDefs(te):void 0;if(u){k("Working");try{let p=await n.complete(i,g),w=p.content,y=ve(p.toolCalls);if(C(),y.length===0){let f=(w??"").trim().replace(/^null$/,"").trim();f&&(i.push({id:crypto.randomUUID(),role:"assistant",content:f,timestamp:new Date}),P(f))}else{let f=(w??"").trim().replace(/^null$/,"").trim();f&&P(f);let v=await ut(i,e,y,a,n);v&&v.trim()&&v.trim()!=="null"&&P(v.trim())}}catch{C(),S("Tool calls not supported by this model \u2014 retrying without tools.");try{let w=await n.complete(i,void 0),y=ve(w.toolCalls.length>0?w.toolCalls:dt(w.content));if(y.length>0){let f=(w.content??"").trim().replace(/^null$/,"").trim();f&&!f.includes('"tool_calls"')&&P(f);let v=await ut(i,e,y,a,n);v&&v.trim()&&v.trim()!=="null"&&P(v.trim())}else{let f=(w.content??"").trim().replace(/^null$/,"").trim();f&&(i.push({id:crypto.randomUUID(),role:"assistant",content:f,timestamp:new Date}),P(f))}}catch(w){L("LLM error: "+(w instanceof Error?w.message:String(w))),i.pop();continue e}}}else await In(i,n);i.length>42&&i.splice(1,i.length-42)}catch(s){C(),L("Session error: "+(s instanceof Error?s.message:String(s)))}}var Me=new kn;async function Dn(){let e=process.stdin,t=process.stdout;if(!e.isTTY||typeof e.setRawMode!="function")throw new Error("NVIDIA NIM API key is missing. Run Agent-Termo in an interactive terminal or set NIM_API_KEY before starting.");return console.log("An NVIDIA NIM API key is required to start Agent-Termo."),console.log("Get your key at https://build.nvidia.com/"),t.write("Enter your API key (input hidden): "),new Promise((n,o)=>{let r="",i=!1,a=()=>{e.off("data",c),e.setRawMode(!1),e.pause(),t.write(`
136
+ `)},c=s=>{for(let d of s.toString("utf-8")){if(d===`
137
+ `&&i){i=!1;continue}if(i=d==="\r",d===""||d===""){a(),o(new Error("API key setup cancelled."));return}if(d==="\r"||d===`
138
+ `){if(!r.trim()){t.write(`
139
+ An API key is required. Enter your API key: `);continue}a(),n(r.trim());return}d==="\x7F"||d==="\b"?r=r.slice(0,-1):d>=" "&&(r+=d)}};e.setRawMode(!0),e.resume(),e.on("data",c)})}async function pt(e,t){if(t.apiKey&&(process.env.NIM_API_KEY=t.apiKey),t.model&&(process.env.NIM_MODEL=t.model),t.debug&&(process.env.LOG_LEVEL="debug"),!process.env.NIM_API_KEY?.trim()){let n=await Dn();De(n),process.env.NIM_API_KEY=n,console.log("API key saved. Agent-Termo will remember it for future sessions.")}console.log(`Starting Agent-Termo in: ${e}`),await mt(e)}Me.name("agent-termo").description("Terminal AI coding agent with Nvidia NIM APIs").version("1.0.3").argument("[project]","Project directory to operate in",process.cwd()).option("-k, --api-key <key>","Nvidia NIM API key").option("-m, --model <model>","Model name to use").option("--debug","Enable debug logging").action(async(e,t)=>{await pt(e,t)});Me.command("init").description("Initialize Agent-Termo in a project directory").argument("[dir]","Directory to initialize",".").action(async e=>{let{mkdirSync:t,writeFileSync:n,existsSync:o}=await import("node:fs"),{resolve:r}=await import("node:path"),i=[r(e,"docs"),r(e,".claude","agents"),r(e,"src")];for(let s of i)t(s,{recursive:!0});let a=r(e,"docs","MEMORY.md");o(a)||n(a,`# Project Memory
129
140
 
130
141
  ## Project Context
131
142
  (Add project context here)
132
- `,"utf-8");let c=o(e,"docs","TIMELINE.md");r(c)||n(c,`# Project Timeline
143
+ `,"utf-8");let c=r(e,"docs","TIMELINE.md");o(c)||n(c,`# Project Timeline
133
144
 
134
145
  ## Initialization
135
146
  - [date] Agent-Termo initialized
136
147
  `,"utf-8"),console.log(`
137
- \u2713 Initialized Agent-Termo in ${o(e)}`),console.log(" Created: docs/MEMORY.md, docs/TIMELINE.md"),console.log(" Agent-Termo will ask for your NVIDIA NIM API key the first time you launch it.")});async function In(){if(process.argv.slice(2).length===0){await lt(process.cwd(),{});return}await ye.parseAsync(process.argv)}In().catch(e=>{console.error(`
148
+ \u2713 Initialized Agent-Termo in ${r(e)}`),console.log(" Created: docs/MEMORY.md, docs/TIMELINE.md"),console.log(" Agent-Termo will ask for your NVIDIA NIM API key the first time you launch it.")});async function _n(){if(process.argv.slice(2).length===0){await pt(process.cwd(),{});return}await Me.parseAsync(process.argv)}_n().catch(e=>{console.error(`
138
149
  Fatal error: ${e instanceof Error?e.message:e}`),process.exit(1)});
139
150
  //# sourceMappingURL=cli.js.map